@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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React25 = require('react');
3
+ var React26 = require('react');
4
4
  var reactNative = require('react-native');
5
5
  var reactNativeSizeMatters = require('react-native-size-matters');
6
6
  var AntDesign = require('@expo/vector-icons/AntDesign');
@@ -11,24 +11,23 @@ var MaterialIcons = require('@expo/vector-icons/MaterialIcons');
11
11
  var Ionicons = require('@expo/vector-icons/Ionicons');
12
12
  var vectorIcons = require('@expo/vector-icons');
13
13
  var expoLinearGradient = require('expo-linear-gradient');
14
- var Animated11 = require('react-native-reanimated');
14
+ var Animated12 = require('react-native-reanimated');
15
15
  var RNSlider = require('@react-native-community/slider');
16
16
  var bottomSheet = require('@gorhom/bottom-sheet');
17
- var picker = require('@react-native-picker/picker');
18
- var reactNativeWorklets = require('react-native-worklets');
19
- var reactNativeGestureHandler = require('react-native-gesture-handler');
20
17
  var reactNativeSafeAreaContext = require('react-native-safe-area-context');
18
+ var picker = require('@react-native-picker/picker');
19
+ var sonnerNative = require('sonner-native');
21
20
 
22
21
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
23
22
 
24
- var React25__default = /*#__PURE__*/_interopDefault(React25);
23
+ var React26__default = /*#__PURE__*/_interopDefault(React26);
25
24
  var AntDesign__default = /*#__PURE__*/_interopDefault(AntDesign);
26
25
  var Entypo__default = /*#__PURE__*/_interopDefault(Entypo);
27
26
  var Feather__default = /*#__PURE__*/_interopDefault(Feather);
28
27
  var FontAwesome5__default = /*#__PURE__*/_interopDefault(FontAwesome5);
29
28
  var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
30
29
  var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
31
- var Animated11__default = /*#__PURE__*/_interopDefault(Animated11);
30
+ var Animated12__default = /*#__PURE__*/_interopDefault(Animated12);
32
31
  var RNSlider__default = /*#__PURE__*/_interopDefault(RNSlider);
33
32
 
34
33
  // src/theme/ThemeProvider.tsx
@@ -142,6 +141,9 @@ function deriveColors(t, scheme) {
142
141
  successBorder,
143
142
  warningTint,
144
143
  warningBorder,
144
+ overlay: t.overlay ?? "rgba(0,0,0,0.45)",
145
+ accentResolved: t.accent ?? t.primary,
146
+ accentForegroundResolved: t.accentForeground ?? t.primaryForeground,
145
147
  ring: t.primary,
146
148
  // focus ring always = primary
147
149
  input: t.border
@@ -150,23 +152,23 @@ function deriveColors(t, scheme) {
150
152
  }
151
153
 
152
154
  // src/theme/ThemeProvider.tsx
153
- var ThemeContext = React25.createContext({
155
+ var ThemeContext = React26.createContext({
154
156
  colors: deriveColors(defaultLight, "light"),
155
157
  colorScheme: "light"
156
158
  });
157
159
  function ThemeProvider({ children, theme, colorScheme = "system" }) {
158
160
  const systemScheme = reactNative.useColorScheme() ?? "light";
159
161
  const resolvedScheme = colorScheme === "system" ? systemScheme : colorScheme;
160
- const colors = React25.useMemo(() => {
162
+ const colors = React26.useMemo(() => {
161
163
  const base = resolvedScheme === "dark" ? defaultDark : defaultLight;
162
164
  const override = resolvedScheme === "dark" ? theme?.dark : theme?.light;
163
165
  const merged = override ? { ...base, ...override } : base;
164
166
  return deriveColors(merged, resolvedScheme);
165
167
  }, [resolvedScheme, theme]);
166
- return /* @__PURE__ */ React25__default.default.createElement(ThemeContext.Provider, { value: { colors, colorScheme: resolvedScheme } }, children);
168
+ return /* @__PURE__ */ React26__default.default.createElement(ThemeContext.Provider, { value: { colors, colorScheme: resolvedScheme } }, children);
167
169
  }
168
170
  function useTheme() {
169
- const context = React25.useContext(ThemeContext);
171
+ const context = React26.useContext(ThemeContext);
170
172
  if (!context) {
171
173
  throw new Error("useTheme must be used within a ThemeProvider");
172
174
  }
@@ -188,13 +190,13 @@ function impactLight() {
188
190
  if (reactNative.Platform.OS === "web") return;
189
191
  getHaptics().then((h) => h?.impactAsync(h.ImpactFeedbackStyle.Light));
190
192
  }
191
- function notificationSuccess() {
193
+ function impactMedium() {
192
194
  if (reactNative.Platform.OS === "web") return;
193
- getHaptics().then((h) => h?.notificationAsync(h.NotificationFeedbackType.Success));
195
+ getHaptics().then((h) => h?.impactAsync(h.ImpactFeedbackStyle.Medium));
194
196
  }
195
- function notificationError() {
197
+ function notificationSuccess() {
196
198
  if (reactNative.Platform.OS === "web") return;
197
- getHaptics().then((h) => h?.notificationAsync(h.NotificationFeedbackType.Error));
199
+ getHaptics().then((h) => h?.notificationAsync(h.NotificationFeedbackType.Success));
198
200
  }
199
201
  var isWeb = reactNative.Platform.OS === "web";
200
202
  var s = isWeb ? (n) => n : reactNativeSizeMatters.scale;
@@ -235,10 +237,10 @@ function Icon({ name, size, color, family }) {
235
237
  }
236
238
  if (!resolved) return null;
237
239
  const Component = resolved.component;
238
- return React25__default.default.createElement(Component, { name, size, color });
240
+ return React26__default.default.createElement(Component, { name, size, color });
239
241
  }
240
242
  function renderIcon(name, size, color) {
241
- return React25__default.default.createElement(Icon, { name, size, color });
243
+ return React26__default.default.createElement(Icon, { name, size, color });
242
244
  }
243
245
 
244
246
  // src/tokens.ts
@@ -396,17 +398,17 @@ var TYPOGRAPHY = {
396
398
  },
397
399
  "uppercase-tag": {
398
400
  fontFamily: "Poppins-Bold",
399
- fontSize: 8,
401
+ fontSize: 10,
400
402
  fontWeight: "700",
401
- lineHeight: 10,
402
- letterSpacing: 0.32,
403
+ lineHeight: 13,
404
+ letterSpacing: 0.8,
403
405
  textTransform: "uppercase"
404
406
  },
405
407
  "button-lg": {
406
408
  fontFamily: "Poppins-Medium",
407
409
  fontSize: 16,
408
410
  fontWeight: "500",
409
- lineHeight: 20,
411
+ lineHeight: 22,
410
412
  letterSpacing: 0
411
413
  },
412
414
  "button-sm": {
@@ -428,7 +430,7 @@ var containerSizeStyles = {
428
430
  var labelSizeStyles = {
429
431
  sm: { ...TYPOGRAPHY["button-sm"], fontSize: ms(TYPOGRAPHY["button-sm"].fontSize) },
430
432
  md: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize) },
431
- lg: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize + 1) }
433
+ lg: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize + 1), lineHeight: mvs(24) }
432
434
  };
433
435
  var iconSizeMap = { sm: 16, md: 18, lg: 20 };
434
436
  function Button({
@@ -448,16 +450,16 @@ function Button({
448
450
  }) {
449
451
  const { colors } = useTheme();
450
452
  const isDisabled = disabled || loading;
451
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
453
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
452
454
  const handlePressIn = () => {
453
455
  if (isDisabled) return;
454
- reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver, speed: 40, bounciness: 0 }).start();
456
+ reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver, stiffness: 600, damping: 35, mass: 0.8 }).start();
455
457
  };
456
458
  const handlePressOut = () => {
457
- reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver, speed: 40, bounciness: 4 }).start();
459
+ reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver, stiffness: 280, damping: 22, mass: 0.8 }).start();
458
460
  };
459
461
  const handlePress = (e) => {
460
- impactLight();
462
+ impactMedium();
461
463
  onPress?.(e);
462
464
  };
463
465
  const containerVariantStyle = {
@@ -472,9 +474,13 @@ function Button({
472
474
  text: { color: colors.foreground },
473
475
  destructive: { color: colors.destructiveForeground }
474
476
  }[variant];
475
- const effectiveIcon = iconName ? renderIcon(iconName, iconSizeMap[size], iconColor ?? labelVariantStyle.color) : typeof icon === "function" ? icon({ label, size, variant }) : icon;
477
+ const textColor = iconColor ?? labelVariantStyle.color;
478
+ const effectiveIcon = iconName ? renderIcon(iconName, iconSizeMap[size], textColor) : typeof icon === "function" ? icon({ label, size, variant, color: textColor }) : icon;
476
479
  const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" ? colors.primaryForeground : colors.foreground;
477
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [fullWidth && styles.fullWidth, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React25__default.default.createElement(
480
+ const styleArray = Array.isArray(style) ? style : style ? [style] : [];
481
+ const flatStyle = reactNative.StyleSheet.flatten(styleArray);
482
+ const { flex, ...restStyle } = flatStyle || {};
483
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: [fullWidth && styles.fullWidth, flex !== void 0 && { flex }, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React26__default.default.createElement(
478
484
  reactNative.TouchableOpacity,
479
485
  {
480
486
  style: [
@@ -483,7 +489,7 @@ function Button({
483
489
  containerSizeStyles[size],
484
490
  fullWidth && styles.fullWidth,
485
491
  isDisabled && styles.disabled,
486
- style
492
+ restStyle
487
493
  ],
488
494
  disabled: isDisabled,
489
495
  activeOpacity: 1,
@@ -493,20 +499,29 @@ function Button({
493
499
  onPressOut: handlePressOut,
494
500
  ...props
495
501
  },
496
- loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveIcon), /* @__PURE__ */ React25__default.default.createElement(
502
+ loading ? /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, /* @__PURE__ */ React26__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor, style: { marginRight: s(6) } }), /* @__PURE__ */ React26__default.default.createElement(
503
+ reactNative.Text,
504
+ {
505
+ style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
506
+ allowFontScaling: true,
507
+ numberOfLines: 1
508
+ },
509
+ label
510
+ )) : /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, effectiveIcon), /* @__PURE__ */ React26__default.default.createElement(
497
511
  reactNative.Text,
498
512
  {
499
513
  style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
500
- allowFontScaling: true
514
+ allowFontScaling: true,
515
+ numberOfLines: 1
501
516
  },
502
517
  label
503
- ), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveIcon))
518
+ ), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, effectiveIcon))
504
519
  ));
505
520
  }
506
521
  var styles = reactNative.StyleSheet.create({
507
522
  base: {
508
- borderRadius: RADIUS.xl,
509
- // 32pxpill-shaped primary CTA (Airbnb spec)
523
+ borderRadius: RADIUS.md,
524
+ // 14pxAirbnb-aligned rounded rect (not pill)
510
525
  alignItems: "center",
511
526
  justifyContent: "center",
512
527
  flexDirection: "row"
@@ -518,10 +533,47 @@ var styles = reactNative.StyleSheet.create({
518
533
  opacity: 0.45
519
534
  },
520
535
  label: {
521
- fontFamily: "Poppins-Medium"
536
+ fontFamily: "Poppins-Medium",
537
+ flexShrink: 1
522
538
  },
523
539
  labelWithIcon: {
524
540
  marginHorizontal: s(6)
541
+ },
542
+ labelLoading: {
543
+ opacity: 0.6
544
+ }
545
+ });
546
+ function ButtonGroup({ children, gap = 12, vertical = false, style }) {
547
+ return /* @__PURE__ */ React26__default.default.createElement(
548
+ reactNative.View,
549
+ {
550
+ style: [
551
+ styles2.container,
552
+ vertical ? styles2.vertical : styles2.horizontal,
553
+ { gap: s(gap) },
554
+ style
555
+ ]
556
+ },
557
+ React26__default.default.Children.map(
558
+ children,
559
+ (child) => React26__default.default.isValidElement(child) ? React26__default.default.cloneElement(child, {
560
+ style: [
561
+ child.props.style,
562
+ { flex: 1 }
563
+ ]
564
+ }) : child
565
+ )
566
+ );
567
+ }
568
+ var styles2 = reactNative.StyleSheet.create({
569
+ container: {
570
+ width: "100%"
571
+ },
572
+ horizontal: {
573
+ flexDirection: "row"
574
+ },
575
+ vertical: {
576
+ flexDirection: "column"
525
577
  }
526
578
  });
527
579
  var nativeDriver2 = reactNative.Platform.OS !== "web";
@@ -545,7 +597,7 @@ function IconButton({
545
597
  }) {
546
598
  const { colors } = useTheme();
547
599
  const isDisabled = disabled || loading;
548
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
600
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
549
601
  const handlePressIn = () => {
550
602
  if (isDisabled) return;
551
603
  reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver2, speed: 40, bounciness: 0 }).start();
@@ -577,14 +629,14 @@ function IconButton({
577
629
  const showBadge = badge !== void 0 && badge !== false && badge !== 0;
578
630
  const badgeCount = typeof badge === "number" ? Math.min(badge, 99) : null;
579
631
  const showCount = typeof badge === "number" && badge > 0;
580
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [styles2.wrapper, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React25__default.default.createElement(
632
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: [styles3.wrapper, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React26__default.default.createElement(
581
633
  reactNative.TouchableOpacity,
582
634
  {
583
635
  style: [
584
- styles2.base,
636
+ styles3.base,
585
637
  containerVariantStyle,
586
638
  { width: containerSize, height: containerSize },
587
- isDisabled && styles2.disabled,
639
+ isDisabled && styles3.disabled,
588
640
  style
589
641
  ],
590
642
  disabled: isDisabled,
@@ -595,14 +647,14 @@ function IconButton({
595
647
  onPressOut: handlePressOut,
596
648
  ...props
597
649
  },
598
- loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor }) : resolvedIcon
599
- ), showBadge && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [
600
- styles2.badge,
650
+ loading ? /* @__PURE__ */ React26__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor }) : resolvedIcon
651
+ ), showBadge && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [
652
+ styles3.badge,
601
653
  { backgroundColor: colors.primary },
602
- showCount ? styles2.badgeCount : styles2.badgeDot
603
- ] }, showCount && /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles2.badgeText, { color: colors.primaryForeground }] }, badgeCount)));
654
+ showCount ? styles3.badgeCount : styles3.badgeDot
655
+ ] }, showCount && /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles3.badgeText, { color: colors.primaryForeground }] }, badgeCount)));
604
656
  }
605
- var styles2 = reactNative.StyleSheet.create({
657
+ var styles3 = reactNative.StyleSheet.create({
606
658
  wrapper: {
607
659
  alignSelf: "flex-start"
608
660
  },
@@ -679,7 +731,7 @@ function Text3({ variant = "body-md", color, style, children, ...props }) {
679
731
  const { colors } = useTheme();
680
732
  const colorKey = defaultColorVariant[variant] ?? "foreground";
681
733
  const resolvedColor = color ?? colors[colorKey];
682
- return /* @__PURE__ */ React25__default.default.createElement(
734
+ return /* @__PURE__ */ React26__default.default.createElement(
683
735
  reactNative.Text,
684
736
  {
685
737
  style: [variantStyles[variant], { color: resolvedColor }, style],
@@ -690,32 +742,37 @@ function Text3({ variant = "body-md", color, style, children, ...props }) {
690
742
  );
691
743
  }
692
744
  var webInputResetStyle = reactNative.Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
693
- function Input({ label, error, hint, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type = "text", containerStyle, inputWrapperStyle, style, onFocus, onBlur, secureTextEntry, ...props }) {
745
+ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type = "text", containerStyle, inputWrapperStyle, style, onFocus, onBlur, secureTextEntry, editable, ...props }) {
694
746
  const { colors } = useTheme();
695
- const [focused, setFocused] = React25.useState(false);
696
- const [showPassword, setShowPassword] = React25.useState(false);
747
+ const [focused, setFocused] = React26.useState(false);
748
+ const [showPassword, setShowPassword] = React26.useState(false);
749
+ const focusAnim = React26.useRef(new reactNative.Animated.Value(0)).current;
750
+ const isDisabled = disabled || editable === false;
697
751
  const isPassword = type === "password";
698
752
  const effectiveSecure = isPassword ? !showPassword : secureTextEntry;
699
753
  const effectivePrefix = prefixIcon ? renderIcon(prefixIcon, 20, prefixIconColor ?? colors.foregroundMuted) : prefix;
700
- const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.TouchableOpacity, { onPress: () => setShowPassword(!showPassword), style: styles3.passwordToggle, activeOpacity: 0.6 }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.AntDesign, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.foregroundMuted) : suffix;
701
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles3.container, containerStyle] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React25__default.default.createElement(
702
- reactNative.View,
754
+ const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.TouchableOpacity, { onPress: () => setShowPassword(!showPassword), style: styles4.passwordToggle, activeOpacity: 0.6 }, /* @__PURE__ */ React26__default.default.createElement(vectorIcons.AntDesign, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.foregroundMuted) : suffix;
755
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles4.container, isDisabled && styles4.containerDisabled, containerStyle] }, label ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles4.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React26__default.default.createElement(
756
+ reactNative.Animated.View,
703
757
  {
704
758
  style: [
705
- styles3.inputWrapper,
759
+ styles4.inputWrapper,
706
760
  {
707
- borderColor: error ? colors.destructive : focused ? colors.primary : colors.border,
708
- backgroundColor: colors.background
761
+ borderColor: error ? colors.destructive : focusAnim.interpolate({
762
+ inputRange: [0, 1],
763
+ outputRange: [colors.border, colors.primary]
764
+ }),
765
+ backgroundColor: isDisabled ? colors.surface : colors.background
709
766
  },
710
767
  inputWrapperStyle
711
768
  ]
712
769
  },
713
- effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.prefixText, { color: colors.foregroundMuted }, prefixStyle], allowFontScaling: true }, effectivePrefix) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles3.prefixContainer }, effectivePrefix) : null,
714
- /* @__PURE__ */ React25__default.default.createElement(
770
+ effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles4.prefixText, { color: colors.foregroundMuted }, prefixStyle], allowFontScaling: true }, effectivePrefix) : /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles4.prefixContainer }, effectivePrefix) : null,
771
+ /* @__PURE__ */ React26__default.default.createElement(
715
772
  reactNative.TextInput,
716
773
  {
717
774
  style: [
718
- styles3.input,
775
+ styles4.input,
719
776
  {
720
777
  color: colors.foreground
721
778
  },
@@ -724,25 +781,31 @@ function Input({ label, error, hint, prefix, suffix, prefixStyle, suffixStyle, p
724
781
  ],
725
782
  onFocus: (e) => {
726
783
  setFocused(true);
784
+ reactNative.Animated.timing(focusAnim, { toValue: 1, duration: 120, easing: reactNative.Easing.out(reactNative.Easing.ease), useNativeDriver: false }).start();
727
785
  onFocus?.(e);
728
786
  },
729
787
  onBlur: (e) => {
730
788
  setFocused(false);
789
+ reactNative.Animated.timing(focusAnim, { toValue: 0, duration: 80, easing: reactNative.Easing.out(reactNative.Easing.ease), useNativeDriver: false }).start();
731
790
  onBlur?.(e);
732
791
  },
733
792
  placeholderTextColor: colors.foregroundMuted,
734
793
  allowFontScaling: true,
735
794
  secureTextEntry: effectiveSecure,
795
+ editable: isDisabled ? false : editable,
736
796
  ...props
737
797
  }
738
798
  ),
739
- effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.suffixText, { color: colors.foregroundMuted }, suffixStyle], allowFontScaling: true }, effectiveSuffix) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles3.suffixContainer }, effectiveSuffix) : null
740
- ), error ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
799
+ effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles4.suffixText, { color: colors.foregroundMuted }, suffixStyle], allowFontScaling: true }, effectiveSuffix) : /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles4.suffixContainer }, effectiveSuffix) : null
800
+ ), error ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles4.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles4.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
741
801
  }
742
- var styles3 = reactNative.StyleSheet.create({
802
+ var styles4 = reactNative.StyleSheet.create({
743
803
  container: {
744
804
  gap: vs(8)
745
805
  },
806
+ containerDisabled: {
807
+ opacity: 0.6
808
+ },
746
809
  label: {
747
810
  fontFamily: "Poppins-Medium",
748
811
  fontSize: ms(14)
@@ -830,9 +893,9 @@ function Badge({ label, children, variant = "default", size = "md", icon, iconNa
830
893
  }[variant];
831
894
  const effectiveIcon = iconName ? renderIcon(iconName, sizeIconSize[size], iconColor ?? textColor) : icon;
832
895
  const content = children ?? label;
833
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles4.container, containerStyle, sizePadding[size], { gap: sizeIconGap[size] }, style] }, effectiveIcon, typeof content === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles4.label, { color: textColor }, sizeFontSize[size]], allowFontScaling: true }, content) : content);
896
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles5.container, containerStyle, sizePadding[size], { gap: sizeIconGap[size] }, style] }, effectiveIcon, typeof content === "string" ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles5.label, { color: textColor }, sizeFontSize[size]], allowFontScaling: true }, content) : content);
834
897
  }
835
- var styles4 = reactNative.StyleSheet.create({
898
+ var styles5 = reactNative.StyleSheet.create({
836
899
  container: {
837
900
  borderRadius: 9999,
838
901
  alignSelf: "flex-start",
@@ -846,14 +909,15 @@ var styles4 = reactNative.StyleSheet.create({
846
909
  var nativeDriver3 = reactNative.Platform.OS !== "web";
847
910
  function Card({ children, variant = "elevated", onPress, style }) {
848
911
  const { colors } = useTheme();
849
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
912
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
850
913
  const handlePressIn = () => {
851
914
  if (!onPress) return;
852
915
  reactNative.Animated.spring(scale2, {
853
916
  toValue: 0.98,
854
917
  useNativeDriver: nativeDriver3,
855
- speed: 40,
856
- bounciness: 0
918
+ stiffness: 400,
919
+ damping: 30,
920
+ mass: 1
857
921
  }).start();
858
922
  };
859
923
  const handlePressOut = () => {
@@ -861,8 +925,9 @@ function Card({ children, variant = "elevated", onPress, style }) {
861
925
  reactNative.Animated.spring(scale2, {
862
926
  toValue: 1,
863
927
  useNativeDriver: nativeDriver3,
864
- speed: 40,
865
- bounciness: 4
928
+ stiffness: 250,
929
+ damping: 24,
930
+ mass: 1
866
931
  }).start();
867
932
  };
868
933
  const handlePress = () => {
@@ -875,10 +940,10 @@ function Card({ children, variant = "elevated", onPress, style }) {
875
940
  backgroundColor: colors.card,
876
941
  borderColor: colors.border,
877
942
  shadowColor: "#000",
878
- shadowOffset: { width: 0, height: 4 },
879
- shadowOpacity: 0.06,
880
- shadowRadius: 12,
881
- elevation: 3
943
+ shadowOffset: { width: 0, height: 6 },
944
+ shadowOpacity: 0.1,
945
+ shadowRadius: 16,
946
+ elevation: 4
882
947
  },
883
948
  outlined: {
884
949
  backgroundColor: colors.card,
@@ -893,9 +958,9 @@ function Card({ children, variant = "elevated", onPress, style }) {
893
958
  elevation: 0
894
959
  }
895
960
  }[variant];
896
- const cardContent = /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles5.card, variantStyle, style] }, children);
961
+ const cardContent = /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles6.card, variantStyle, style] }, children);
897
962
  if (onPress) {
898
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25__default.default.createElement(
963
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React26__default.default.createElement(
899
964
  reactNative.TouchableOpacity,
900
965
  {
901
966
  onPress: handlePress,
@@ -910,26 +975,26 @@ function Card({ children, variant = "elevated", onPress, style }) {
910
975
  return cardContent;
911
976
  }
912
977
  function CardHeader({ children, style }) {
913
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles5.header, style] }, children);
978
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles6.header, style] }, children);
914
979
  }
915
980
  function CardTitle({ children, style }) {
916
981
  const { colors } = useTheme();
917
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles5.title, { color: colors.foreground }, style], allowFontScaling: true }, children);
982
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles6.title, { color: colors.foreground }, style], allowFontScaling: true }, children);
918
983
  }
919
984
  function CardDescription({ children, style }) {
920
985
  const { colors } = useTheme();
921
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles5.description, { color: colors.foregroundMuted }, style], allowFontScaling: true }, children);
986
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles6.description, { color: colors.foregroundMuted }, style], allowFontScaling: true }, children);
922
987
  }
923
988
  function CardContent({ children, style }) {
924
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles5.content, style] }, children);
989
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles6.content, style] }, children);
925
990
  }
926
991
  function CardFooter({ children, style }) {
927
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles5.footer, style] }, children);
992
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles6.footer, style] }, children);
928
993
  }
929
- var styles5 = reactNative.StyleSheet.create({
994
+ var styles6 = reactNative.StyleSheet.create({
930
995
  card: {
931
- borderRadius: 14,
932
- // RADIUS.md — Airbnb property card spec
996
+ borderRadius: RADIUS.md,
997
+ // 14px — Airbnb property card spec
933
998
  borderWidth: 1
934
999
  },
935
1000
  header: {
@@ -961,25 +1026,27 @@ var styles5 = reactNative.StyleSheet.create({
961
1026
  });
962
1027
  function Separator({ orientation = "horizontal", style }) {
963
1028
  const { colors } = useTheme();
964
- return /* @__PURE__ */ React25__default.default.createElement(
1029
+ return /* @__PURE__ */ React26__default.default.createElement(
965
1030
  reactNative.View,
966
1031
  {
967
1032
  style: [
968
- orientation === "horizontal" ? styles6.horizontal : styles6.vertical,
1033
+ orientation === "horizontal" ? styles7.horizontal : styles7.vertical,
969
1034
  { backgroundColor: colors.border },
970
1035
  style
971
1036
  ]
972
1037
  }
973
1038
  );
974
1039
  }
975
- var styles6 = reactNative.StyleSheet.create({
1040
+ var styles7 = reactNative.StyleSheet.create({
976
1041
  horizontal: {
977
1042
  height: 1,
978
- width: "100%"
1043
+ width: "100%",
1044
+ opacity: 0.7
979
1045
  },
980
1046
  vertical: {
981
1047
  width: 1,
982
- height: "100%"
1048
+ height: "100%",
1049
+ opacity: 0.7
983
1050
  }
984
1051
  });
985
1052
  var sizeMap2 = {
@@ -995,18 +1062,18 @@ var labelFontSize = {
995
1062
  function Spinner({ size = "md", color, label, ...props }) {
996
1063
  const { colors } = useTheme();
997
1064
  if (label) {
998
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles7.wrapper }, /* @__PURE__ */ React25__default.default.createElement(reactNative.ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props }), /* @__PURE__ */ React25__default.default.createElement(
1065
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles8.wrapper }, /* @__PURE__ */ React26__default.default.createElement(reactNative.ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props }), /* @__PURE__ */ React26__default.default.createElement(
999
1066
  reactNative.Text,
1000
1067
  {
1001
- style: [styles7.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
1068
+ style: [styles8.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
1002
1069
  allowFontScaling: true
1003
1070
  },
1004
1071
  label
1005
1072
  ));
1006
1073
  }
1007
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props });
1074
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props });
1008
1075
  }
1009
- var styles7 = reactNative.StyleSheet.create({
1076
+ var styles8 = reactNative.StyleSheet.create({
1010
1077
  wrapper: {
1011
1078
  alignItems: "center",
1012
1079
  gap: vs(6)
@@ -1025,10 +1092,10 @@ function Skeleton({
1025
1092
  style
1026
1093
  }) {
1027
1094
  const { colors, colorScheme } = useTheme();
1028
- const shimmerAnim = React25.useRef(new reactNative.Animated.Value(0)).current;
1029
- const [containerWidth, setContainerWidth] = React25.useState(300);
1095
+ const shimmerAnim = React26.useRef(new reactNative.Animated.Value(0)).current;
1096
+ const [containerWidth, setContainerWidth] = React26.useState(300);
1030
1097
  const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
1031
- React25.useEffect(() => {
1098
+ React26.useEffect(() => {
1032
1099
  const animation = reactNative.Animated.loop(
1033
1100
  reactNative.Animated.timing(shimmerAnim, { toValue: 1, duration: 1200, useNativeDriver: true })
1034
1101
  );
@@ -1042,17 +1109,17 @@ function Skeleton({
1042
1109
  const resolvedWidth = preset === "circle" ? s(diameter) : preset === "text" ? "60%" : width;
1043
1110
  const resolvedHeight = preset === "circle" ? s(diameter) : preset === "text" ? 14 : height;
1044
1111
  const resolvedRadius = preset === "circle" ? 9999 : preset === "text" ? 4 : borderRadius;
1045
- return /* @__PURE__ */ React25__default.default.createElement(
1112
+ return /* @__PURE__ */ React26__default.default.createElement(
1046
1113
  reactNative.View,
1047
1114
  {
1048
1115
  style: [
1049
- styles8.base,
1116
+ styles9.base,
1050
1117
  { width: resolvedWidth, height: resolvedHeight, borderRadius: resolvedRadius, backgroundColor: colors.surface },
1051
1118
  style
1052
1119
  ],
1053
1120
  onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width)
1054
1121
  },
1055
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [reactNative.StyleSheet.absoluteFill, { transform: [{ translateX }] }] }, /* @__PURE__ */ React25__default.default.createElement(
1122
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: [reactNative.StyleSheet.absoluteFill, { transform: [{ translateX }] }] }, /* @__PURE__ */ React26__default.default.createElement(
1056
1123
  expoLinearGradient.LinearGradient,
1057
1124
  {
1058
1125
  colors: ["transparent", shimmerHighlight, "transparent"],
@@ -1063,7 +1130,7 @@ function Skeleton({
1063
1130
  ))
1064
1131
  );
1065
1132
  }
1066
- var styles8 = reactNative.StyleSheet.create({
1133
+ var styles9 = reactNative.StyleSheet.create({
1067
1134
  base: {
1068
1135
  overflow: "hidden"
1069
1136
  }
@@ -1086,12 +1153,22 @@ var statusSizeMap = {
1086
1153
  lg: 13,
1087
1154
  xl: 16
1088
1155
  };
1089
- function Avatar({ src, fallback, size = "md", status, style }) {
1156
+ function getInitials(fallback, fallbackText) {
1157
+ if (fallback) return fallback.slice(0, 2).toUpperCase();
1158
+ if (fallbackText) {
1159
+ const words = fallbackText.trim().split(/\s+/);
1160
+ if (words.length === 1) return words[0].slice(0, 2).toUpperCase();
1161
+ return (words[0][0] + words[words.length - 1][0]).toUpperCase();
1162
+ }
1163
+ return "?";
1164
+ }
1165
+ function Avatar({ src, fallback, fallbackText, size = "md", status, style }) {
1090
1166
  const { colors } = useTheme();
1091
- const [imageError, setImageError] = React25.useState(false);
1092
- const dimension = sizeMap3[size];
1167
+ const [imageError, setImageError] = React26.useState(false);
1168
+ const dimension = typeof size === "number" ? size : sizeMap3[size];
1169
+ const fontSize = typeof size === "number" ? size * 0.38 : fontSizeMap[size];
1093
1170
  const showFallback = !src || imageError;
1094
- const statusSize = statusSizeMap[size];
1171
+ const statusSize = typeof size === "number" ? size * 0.25 : statusSizeMap[size];
1095
1172
  const statusColor = {
1096
1173
  online: "#22c55e",
1097
1174
  offline: "transparent",
@@ -1105,25 +1182,25 @@ function Avatar({ src, fallback, size = "md", status, style }) {
1105
1182
  backgroundColor: colors.surface,
1106
1183
  overflow: "hidden"
1107
1184
  };
1108
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles9.wrapper, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles9.base, containerStyle] }, !showFallback ? /* @__PURE__ */ React25__default.default.createElement(
1185
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles10.wrapper, style] }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles10.base, containerStyle] }, !showFallback ? /* @__PURE__ */ React26__default.default.createElement(
1109
1186
  reactNative.Image,
1110
1187
  {
1111
1188
  source: { uri: src },
1112
1189
  style: { width: dimension, height: dimension },
1113
1190
  onError: () => setImageError(true)
1114
1191
  }
1115
- ) : /* @__PURE__ */ React25__default.default.createElement(
1192
+ ) : /* @__PURE__ */ React26__default.default.createElement(
1116
1193
  reactNative.Text,
1117
1194
  {
1118
- style: [styles9.fallback, { color: colors.foregroundMuted, fontSize: fontSizeMap[size] }],
1195
+ style: [styles10.fallback, { color: colors.foregroundMuted, fontSize }],
1119
1196
  allowFontScaling: true
1120
1197
  },
1121
- fallback?.slice(0, 2).toUpperCase() ?? "?"
1122
- )), status && /* @__PURE__ */ React25__default.default.createElement(
1198
+ getInitials(fallback, fallbackText)
1199
+ )), status && /* @__PURE__ */ React26__default.default.createElement(
1123
1200
  reactNative.View,
1124
1201
  {
1125
1202
  style: [
1126
- styles9.statusDot,
1203
+ styles10.statusDot,
1127
1204
  {
1128
1205
  width: statusSize,
1129
1206
  height: statusSize,
@@ -1136,7 +1213,7 @@ function Avatar({ src, fallback, size = "md", status, style }) {
1136
1213
  }
1137
1214
  ));
1138
1215
  }
1139
- var styles9 = reactNative.StyleSheet.create({
1216
+ var styles10 = reactNative.StyleSheet.create({
1140
1217
  wrapper: {
1141
1218
  alignSelf: "flex-start",
1142
1219
  position: "relative"
@@ -1156,24 +1233,19 @@ var styles9 = reactNative.StyleSheet.create({
1156
1233
  });
1157
1234
  function AlertBanner({ title, description, variant = "default", icon, iconName, iconColor, style }) {
1158
1235
  const { colors } = useTheme();
1159
- const bgColor = variant === "destructive" ? colors.destructiveTint : variant === "success" ? colors.successTint : variant === "warning" ? colors.warningTint : colors.card;
1160
- const borderColor = variant === "destructive" ? colors.destructiveBorder : variant === "success" ? colors.successBorder : variant === "warning" ? colors.warningBorder : colors.border;
1161
1236
  const accentColor = variant === "destructive" ? colors.destructive : variant === "success" ? colors.success : variant === "warning" ? colors.warning : colors.primary;
1162
- const titleColor = variant === "default" ? colors.foreground : accentColor;
1163
- const descColor = variant === "default" ? colors.foregroundMuted : accentColor;
1164
- const defaultIcon = variant === "success" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: 16, color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.MaterialIcons, { name: "error-outline", size: 17, color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.MaterialIcons, { name: "warning-amber", size: 17, color: accentColor }) : /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "info-with-circle", size: 16, color: accentColor });
1165
- const effectiveIcon = iconName ? renderIcon(iconName, 16, iconColor ?? accentColor) : icon ?? defaultIcon;
1166
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles10.container, { backgroundColor: bgColor, borderColor }, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles10.iconSlot }, effectiveIcon), /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles10.content }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles10.title, { color: titleColor }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles10.description, { color: descColor }], allowFontScaling: true }, description) : null));
1237
+ const defaultIcon = variant === "success" ? /* @__PURE__ */ React26__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: ms(16), color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React26__default.default.createElement(vectorIcons.MaterialIcons, { name: "error-outline", size: ms(17), color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React26__default.default.createElement(vectorIcons.MaterialIcons, { name: "warning-amber", size: ms(17), color: accentColor }) : /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "info-with-circle", size: ms(16), color: accentColor });
1238
+ const effectiveIcon = iconName ? renderIcon(iconName, ms(16), iconColor ?? accentColor) : icon ?? defaultIcon;
1239
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles11.container, { backgroundColor: colors.card }, style] }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles11.iconSlot }, effectiveIcon), /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles11.content }, /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles11.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles11.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null));
1167
1240
  }
1168
- var styles10 = reactNative.StyleSheet.create({
1241
+ var styles11 = reactNative.StyleSheet.create({
1169
1242
  container: {
1170
1243
  flexDirection: "row",
1171
1244
  alignItems: "flex-start",
1172
- borderWidth: 0.5,
1173
- borderRadius: 10,
1174
- paddingHorizontal: s(12),
1175
- paddingVertical: vs(10),
1176
- gap: s(10)
1245
+ borderRadius: RADIUS.lg,
1246
+ gap: s(8),
1247
+ paddingVertical: vs(8),
1248
+ paddingHorizontal: s(10)
1177
1249
  },
1178
1250
  iconSlot: {
1179
1251
  marginTop: vs(1)
@@ -1185,21 +1257,20 @@ var styles10 = reactNative.StyleSheet.create({
1185
1257
  title: {
1186
1258
  fontFamily: "Poppins-Medium",
1187
1259
  fontSize: ms(13),
1188
- lineHeight: ms(18)
1260
+ lineHeight: ms(19)
1189
1261
  },
1190
1262
  description: {
1191
1263
  fontFamily: "Poppins-Regular",
1192
1264
  fontSize: ms(12),
1193
- lineHeight: ms(17),
1194
- opacity: 0.85
1265
+ lineHeight: ms(17)
1195
1266
  }
1196
1267
  });
1197
1268
  function Progress({ value = 0, max = 100, variant = "default", style }) {
1198
1269
  const { colors } = useTheme();
1199
1270
  const percent = Math.min(Math.max(value / max * 100, 0), 100);
1200
- const [trackWidth, setTrackWidth] = React25.useState(0);
1201
- const animatedWidth = React25.useRef(new reactNative.Animated.Value(0)).current;
1202
- React25.useEffect(() => {
1271
+ const [trackWidth, setTrackWidth] = React26.useState(0);
1272
+ const animatedWidth = React26.useRef(new reactNative.Animated.Value(0)).current;
1273
+ React26.useEffect(() => {
1203
1274
  if (trackWidth === 0) return;
1204
1275
  reactNative.Animated.spring(animatedWidth, {
1205
1276
  toValue: percent / 100 * trackWidth,
@@ -1209,21 +1280,21 @@ function Progress({ value = 0, max = 100, variant = "default", style }) {
1209
1280
  }).start();
1210
1281
  }, [percent, trackWidth]);
1211
1282
  const indicatorColor = variant === "success" ? colors.success : variant === "warning" ? colors.warning : variant === "destructive" ? colors.destructive : colors.primary;
1212
- return /* @__PURE__ */ React25__default.default.createElement(
1283
+ return /* @__PURE__ */ React26__default.default.createElement(
1213
1284
  reactNative.View,
1214
1285
  {
1215
- style: [styles11.track, { backgroundColor: colors.surface }, style],
1286
+ style: [styles12.track, { backgroundColor: colors.surface }, style],
1216
1287
  onLayout: (e) => setTrackWidth(e.nativeEvent.layout.width)
1217
1288
  },
1218
- /* @__PURE__ */ React25__default.default.createElement(
1289
+ /* @__PURE__ */ React26__default.default.createElement(
1219
1290
  reactNative.Animated.View,
1220
1291
  {
1221
- style: [styles11.indicator, { width: animatedWidth, backgroundColor: indicatorColor }]
1292
+ style: [styles12.indicator, { width: animatedWidth, backgroundColor: indicatorColor }]
1222
1293
  }
1223
1294
  )
1224
1295
  );
1225
1296
  }
1226
- var styles11 = reactNative.StyleSheet.create({
1297
+ var styles12 = reactNative.StyleSheet.create({
1227
1298
  track: {
1228
1299
  height: vs(8),
1229
1300
  borderRadius: 9999,
@@ -1235,72 +1306,71 @@ var styles11 = reactNative.StyleSheet.create({
1235
1306
  borderRadius: 9999
1236
1307
  }
1237
1308
  });
1238
- function EmptyState({ icon, iconName, iconColor, title, description, action, size = "default", style }) {
1309
+ function EmptyState({ icon, iconName, iconColor, title, description, action, actionLabel, onAction, size = "default", style }) {
1239
1310
  const { colors } = useTheme();
1240
1311
  const isCompact = size === "compact";
1241
1312
  const effectiveIcon = iconName ? renderIcon(iconName, isCompact ? 32 : 48, iconColor ?? colors.foregroundMuted) : icon;
1242
- return /* @__PURE__ */ React25__default.default.createElement(
1313
+ return /* @__PURE__ */ React26__default.default.createElement(
1243
1314
  reactNative.View,
1244
1315
  {
1245
1316
  style: [
1246
- styles12.container,
1247
- isCompact && styles12.containerCompact,
1317
+ styles13.container,
1318
+ isCompact && styles13.containerCompact,
1248
1319
  { borderColor: colors.border },
1249
1320
  style
1250
1321
  ]
1251
1322
  },
1252
- effectiveIcon ? /* @__PURE__ */ React25__default.default.createElement(
1323
+ effectiveIcon ? /* @__PURE__ */ React26__default.default.createElement(
1253
1324
  reactNative.View,
1254
1325
  {
1255
1326
  style: [
1256
- styles12.iconWrapper,
1257
- isCompact && styles12.iconWrapperCompact,
1327
+ styles13.iconWrapper,
1328
+ isCompact && styles13.iconWrapperCompact,
1258
1329
  { backgroundColor: colors.surface }
1259
1330
  ]
1260
1331
  },
1261
1332
  effectiveIcon
1262
1333
  ) : null,
1263
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles12.textWrapper }, /* @__PURE__ */ React25__default.default.createElement(
1334
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles13.textWrapper }, /* @__PURE__ */ React26__default.default.createElement(
1264
1335
  reactNative.Text,
1265
1336
  {
1266
- style: [styles12.title, isCompact && styles12.titleCompact, { color: colors.foreground }],
1337
+ style: [styles13.title, isCompact && styles13.titleCompact, { color: colors.foreground }],
1267
1338
  allowFontScaling: true
1268
1339
  },
1269
1340
  title
1270
- ), description && !isCompact ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles12.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null),
1271
- action && !isCompact ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles12.action }, action) : null
1341
+ ), description && !isCompact ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles13.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null),
1342
+ !isCompact && (action ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles13.action }, action) : actionLabel && onAction ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles13.action }, /* @__PURE__ */ React26__default.default.createElement(Button, { label: actionLabel, variant: "primary", onPress: onAction })) : null)
1272
1343
  );
1273
1344
  }
1274
- var styles12 = reactNative.StyleSheet.create({
1345
+ var styles13 = reactNative.StyleSheet.create({
1275
1346
  container: {
1276
1347
  alignItems: "center",
1277
1348
  justifyContent: "center",
1278
1349
  borderWidth: 1,
1279
1350
  borderStyle: "dashed",
1280
- borderRadius: ms(12),
1281
- padding: s(32),
1282
- gap: vs(16)
1283
- },
1284
- containerCompact: {
1285
- padding: s(20),
1286
- gap: vs(10)
1351
+ borderRadius: ms(12)
1287
1352
  },
1353
+ containerCompact: {},
1288
1354
  iconWrapper: {
1289
1355
  width: s(80),
1290
1356
  height: s(80),
1291
1357
  borderRadius: ms(20),
1292
1358
  alignItems: "center",
1293
- justifyContent: "center"
1359
+ justifyContent: "center",
1360
+ marginTop: s(32)
1294
1361
  },
1295
1362
  iconWrapperCompact: {
1296
1363
  width: s(56),
1297
1364
  height: s(56),
1298
- borderRadius: ms(14)
1365
+ borderRadius: ms(14),
1366
+ marginTop: s(20)
1299
1367
  },
1300
1368
  textWrapper: {
1301
1369
  alignItems: "center",
1302
1370
  gap: vs(8),
1303
- maxWidth: s(320)
1371
+ maxWidth: s(320),
1372
+ paddingHorizontal: s(32),
1373
+ marginTop: vs(16)
1304
1374
  },
1305
1375
  title: {
1306
1376
  fontFamily: "Poppins-Medium",
@@ -1308,7 +1378,8 @@ var styles12 = reactNative.StyleSheet.create({
1308
1378
  textAlign: "center"
1309
1379
  },
1310
1380
  titleCompact: {
1311
- fontSize: ms(15)
1381
+ fontSize: ms(15),
1382
+ marginTop: vs(10)
1312
1383
  },
1313
1384
  description: {
1314
1385
  fontFamily: "Poppins-Regular",
@@ -1317,7 +1388,9 @@ var styles12 = reactNative.StyleSheet.create({
1317
1388
  textAlign: "center"
1318
1389
  },
1319
1390
  action: {
1320
- marginTop: vs(8)
1391
+ marginTop: vs(8),
1392
+ marginBottom: s(32),
1393
+ paddingHorizontal: s(32)
1321
1394
  }
1322
1395
  });
1323
1396
  var webInputResetStyle2 = reactNative.Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
@@ -1326,6 +1399,9 @@ function Textarea({
1326
1399
  error,
1327
1400
  hint,
1328
1401
  rows = 4,
1402
+ prefixIcon,
1403
+ prefixIconNode,
1404
+ prefixIconColor,
1329
1405
  containerStyle,
1330
1406
  style,
1331
1407
  onFocus,
@@ -1333,58 +1409,84 @@ function Textarea({
1333
1409
  ...props
1334
1410
  }) {
1335
1411
  const { colors } = useTheme();
1336
- const [focused, setFocused] = React25.useState(false);
1337
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles13.container, containerStyle] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles13.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React25__default.default.createElement(
1338
- reactNative.TextInput,
1412
+ const [focused, setFocused] = React26.useState(false);
1413
+ const resolvedPrefixIcon = prefixIcon ? renderIcon(prefixIcon, ms(16), prefixIconColor ?? colors.foregroundMuted) : prefixIconNode;
1414
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles14.container, containerStyle] }, label ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles14.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React26__default.default.createElement(
1415
+ reactNative.View,
1339
1416
  {
1340
- multiline: true,
1341
- numberOfLines: rows,
1342
- textAlignVertical: "top",
1343
1417
  style: [
1344
- styles13.input,
1418
+ styles14.inputWrapper,
1345
1419
  {
1346
1420
  borderColor: error ? colors.destructive : focused ? colors.ring ?? colors.primary : colors.border,
1347
- color: colors.foreground,
1348
- backgroundColor: colors.background,
1349
- minHeight: rows * vs(30)
1421
+ backgroundColor: colors.background
1422
+ }
1423
+ ]
1424
+ },
1425
+ resolvedPrefixIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles14.prefixIcon }, resolvedPrefixIcon) : null,
1426
+ /* @__PURE__ */ React26__default.default.createElement(
1427
+ reactNative.TextInput,
1428
+ {
1429
+ multiline: true,
1430
+ numberOfLines: rows,
1431
+ textAlignVertical: "top",
1432
+ style: [
1433
+ styles14.input,
1434
+ {
1435
+ color: colors.foreground,
1436
+ minHeight: rows * vs(30)
1437
+ },
1438
+ webInputResetStyle2,
1439
+ style
1440
+ ],
1441
+ onFocus: (e) => {
1442
+ setFocused(true);
1443
+ onFocus?.(e);
1350
1444
  },
1351
- webInputResetStyle2,
1352
- style
1353
- ],
1354
- onFocus: (e) => {
1355
- setFocused(true);
1356
- onFocus?.(e);
1357
- },
1358
- onBlur: (e) => {
1359
- setFocused(false);
1360
- onBlur?.(e);
1361
- },
1362
- placeholderTextColor: colors.foregroundMuted,
1363
- allowFontScaling: true,
1364
- ...props
1365
- }
1366
- ), error ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles13.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles13.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
1445
+ onBlur: (e) => {
1446
+ setFocused(false);
1447
+ onBlur?.(e);
1448
+ },
1449
+ placeholderTextColor: colors.foregroundMuted,
1450
+ allowFontScaling: true,
1451
+ ...props
1452
+ }
1453
+ )
1454
+ ), error ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles14.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles14.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
1367
1455
  }
1368
- var styles13 = reactNative.StyleSheet.create({
1456
+ var styles14 = reactNative.StyleSheet.create({
1369
1457
  container: {
1370
- gap: vs(8)
1458
+ gap: vs(4)
1371
1459
  },
1372
1460
  label: {
1373
1461
  fontFamily: "Poppins-Medium",
1374
- fontSize: ms(13)
1462
+ fontSize: ms(13),
1463
+ lineHeight: vs(18),
1464
+ marginBottom: vs(2)
1375
1465
  },
1376
- input: {
1377
- fontFamily: "Poppins-Regular",
1378
- borderWidth: 2,
1379
- borderRadius: ms(8),
1466
+ inputWrapper: {
1467
+ borderWidth: 1,
1468
+ borderRadius: 8,
1380
1469
  paddingHorizontal: s(14),
1381
1470
  paddingVertical: vs(11),
1382
- fontSize: ms(15),
1383
- includeFontPadding: false
1471
+ gap: s(8)
1472
+ },
1473
+ prefixIcon: {
1474
+ alignItems: "flex-start",
1475
+ justifyContent: "flex-start",
1476
+ paddingTop: vs(2)
1477
+ },
1478
+ input: {
1479
+ fontFamily: "Poppins-Regular",
1480
+ fontSize: ms(14),
1481
+ lineHeight: vs(22),
1482
+ padding: 0,
1483
+ margin: 0
1384
1484
  },
1385
1485
  helperText: {
1386
1486
  fontFamily: "Poppins-Regular",
1387
- fontSize: ms(13)
1487
+ fontSize: ms(12),
1488
+ lineHeight: vs(16),
1489
+ marginTop: vs(4)
1388
1490
  }
1389
1491
  });
1390
1492
  var nativeDriver4 = reactNative.Platform.OS !== "web";
@@ -1396,10 +1498,10 @@ function Checkbox({
1396
1498
  style
1397
1499
  }) {
1398
1500
  const { colors } = useTheme();
1399
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
1400
- const bgOpacity = React25.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
1401
- const checkOpacity = React25.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
1402
- React25.useEffect(() => {
1501
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
1502
+ const bgOpacity = React26.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
1503
+ const checkOpacity = React26.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
1504
+ React26.useEffect(() => {
1403
1505
  reactNative.Animated.parallel([
1404
1506
  reactNative.Animated.timing(bgOpacity, {
1405
1507
  toValue: checked ? 1 : 0,
@@ -1428,10 +1530,10 @@ function Checkbox({
1428
1530
  const handlePressOut = () => {
1429
1531
  reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver4, speed: 40, bounciness: 0 }).start();
1430
1532
  };
1431
- return /* @__PURE__ */ React25__default.default.createElement(
1533
+ return /* @__PURE__ */ React26__default.default.createElement(
1432
1534
  reactNative.TouchableOpacity,
1433
1535
  {
1434
- style: [styles14.row, style],
1536
+ style: [styles15.row, style],
1435
1537
  onPress: () => {
1436
1538
  selectionAsync();
1437
1539
  onCheckedChange?.(!checked);
@@ -1442,11 +1544,11 @@ function Checkbox({
1442
1544
  activeOpacity: 1,
1443
1545
  touchSoundDisabled: true
1444
1546
  },
1445
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25__default.default.createElement(
1547
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React26__default.default.createElement(
1446
1548
  reactNative.Animated.View,
1447
1549
  {
1448
1550
  style: [
1449
- styles14.box,
1551
+ styles15.box,
1450
1552
  {
1451
1553
  borderColor,
1452
1554
  backgroundColor,
@@ -1454,19 +1556,19 @@ function Checkbox({
1454
1556
  }
1455
1557
  ]
1456
1558
  },
1457
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { opacity: checkOpacity } }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles14.checkmark, { borderColor: colors.primaryForeground }] }))
1559
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: { opacity: checkOpacity } }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles15.checkmark, { borderColor: colors.primaryForeground }] }))
1458
1560
  )),
1459
- label ? /* @__PURE__ */ React25__default.default.createElement(
1561
+ label ? /* @__PURE__ */ React26__default.default.createElement(
1460
1562
  reactNative.Text,
1461
1563
  {
1462
- style: [styles14.label, { color: disabled ? colors.foregroundMuted : colors.foreground }],
1564
+ style: [styles15.label, { color: disabled ? colors.foregroundMuted : colors.foreground }],
1463
1565
  allowFontScaling: true
1464
1566
  },
1465
1567
  label
1466
1568
  ) : null
1467
1569
  );
1468
1570
  }
1469
- var styles14 = reactNative.StyleSheet.create({
1571
+ var styles15 = reactNative.StyleSheet.create({
1470
1572
  row: {
1471
1573
  flexDirection: "row",
1472
1574
  alignItems: "center",
@@ -1502,11 +1604,11 @@ var THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2;
1502
1604
  var ICON_SIZE = s(13);
1503
1605
  function Switch({ checked = false, onCheckedChange, disabled, style }) {
1504
1606
  const { colors } = useTheme();
1505
- const translateX = React25.useRef(new reactNative.Animated.Value(checked ? THUMB_TRAVEL : 0)).current;
1506
- const trackOpacity = React25.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
1507
- const checkOpacity = React25.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
1508
- const crossOpacity = React25.useRef(new reactNative.Animated.Value(checked ? 0 : 1)).current;
1509
- React25.useEffect(() => {
1607
+ const translateX = React26.useRef(new reactNative.Animated.Value(checked ? THUMB_TRAVEL : 0)).current;
1608
+ const trackOpacity = React26.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
1609
+ const checkOpacity = React26.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
1610
+ const crossOpacity = React26.useRef(new reactNative.Animated.Value(checked ? 0 : 1)).current;
1611
+ React26.useEffect(() => {
1510
1612
  reactNative.Animated.parallel([
1511
1613
  reactNative.Animated.spring(translateX, {
1512
1614
  toValue: checked ? THUMB_TRAVEL : 0,
@@ -1534,7 +1636,7 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
1534
1636
  inputRange: [0, 1],
1535
1637
  outputRange: [colors.surface, colors.primary]
1536
1638
  });
1537
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [{ opacity: disabled ? 0.45 : 1 }, style] }, /* @__PURE__ */ React25__default.default.createElement(
1639
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [{ opacity: disabled ? 0.45 : 1 }, style] }, /* @__PURE__ */ React26__default.default.createElement(
1538
1640
  reactNative.TouchableOpacity,
1539
1641
  {
1540
1642
  onPress: () => {
@@ -1544,22 +1646,22 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
1544
1646
  disabled,
1545
1647
  activeOpacity: 0.8,
1546
1648
  touchSoundDisabled: true,
1547
- style: styles15.wrapper
1649
+ style: styles16.wrapper
1548
1650
  },
1549
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [styles15.track, { backgroundColor: trackColor }] }, /* @__PURE__ */ React25__default.default.createElement(
1651
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: [styles16.track, { backgroundColor: trackColor }] }, /* @__PURE__ */ React26__default.default.createElement(
1550
1652
  reactNative.Animated.View,
1551
1653
  {
1552
1654
  style: [
1553
- styles15.thumb,
1655
+ styles16.thumb,
1554
1656
  { backgroundColor: colors.primaryForeground, transform: [{ translateX }] }
1555
1657
  ]
1556
1658
  },
1557
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [styles15.iconWrapper, { opacity: checkOpacity }] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "check", size: ICON_SIZE, color: colors.primary })),
1558
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [styles15.iconWrapper, { opacity: crossOpacity }] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted }))
1659
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: [styles16.iconWrapper, { opacity: checkOpacity }] }, /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Feather, { name: "check", size: ICON_SIZE, color: colors.primary })),
1660
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: [styles16.iconWrapper, { opacity: crossOpacity }] }, /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Feather, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted }))
1559
1661
  ))
1560
1662
  ));
1561
1663
  }
1562
- var styles15 = reactNative.StyleSheet.create({
1664
+ var styles16 = reactNative.StyleSheet.create({
1563
1665
  wrapper: {},
1564
1666
  track: {
1565
1667
  width: TRACK_WIDTH,
@@ -1611,9 +1713,9 @@ function Toggle({
1611
1713
  ...props
1612
1714
  }) {
1613
1715
  const { colors } = useTheme();
1614
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
1615
- const pressAnim = React25.useRef(new reactNative.Animated.Value(pressed ? 1 : 0)).current;
1616
- React25.useEffect(() => {
1716
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
1717
+ const pressAnim = React26.useRef(new reactNative.Animated.Value(pressed ? 1 : 0)).current;
1718
+ React26.useEffect(() => {
1617
1719
  reactNative.Animated.timing(pressAnim, {
1618
1720
  toValue: pressed ? 1 : 0,
1619
1721
  duration: 150,
@@ -1623,10 +1725,10 @@ function Toggle({
1623
1725
  }, [pressed, pressAnim]);
1624
1726
  const handlePressIn = () => {
1625
1727
  if (disabled) return;
1626
- reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver6, speed: 40, bounciness: 0 }).start();
1728
+ reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver6, stiffness: 600, damping: 35, mass: 0.8 }).start();
1627
1729
  };
1628
1730
  const handlePressOut = () => {
1629
- reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver6, speed: 40, bounciness: 4 }).start();
1731
+ reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver6, stiffness: 280, damping: 22, mass: 0.8 }).start();
1630
1732
  };
1631
1733
  const borderColor = pressAnim.interpolate({
1632
1734
  inputRange: [0, 1],
@@ -1648,17 +1750,17 @@ function Toggle({
1648
1750
  return prop;
1649
1751
  };
1650
1752
  if (pressed) {
1651
- if (activeIconName) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, renderIcon(activeIconName, iconSize, activeIconColor ?? colors.primary));
1753
+ if (activeIconName) return /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, renderIcon(activeIconName, iconSize, activeIconColor ?? colors.primary));
1652
1754
  const active = renderProp(activeIcon);
1653
- if (active) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, active);
1654
- return /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: iconSize, color: colors.primary });
1755
+ if (active) return /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, active);
1756
+ return /* @__PURE__ */ React26__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: iconSize, color: colors.primary });
1655
1757
  }
1656
- if (iconName) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? colors.foregroundMuted));
1758
+ if (iconName) return /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? colors.foregroundMuted));
1657
1759
  const custom = renderProp(icon);
1658
- if (custom) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, custom);
1659
- return /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "circle", size: iconSize, color: colors.foregroundMuted });
1760
+ if (custom) return /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, custom);
1761
+ return /* @__PURE__ */ React26__default.default.createElement(vectorIcons.FontAwesome5, { name: "circle", size: iconSize, color: colors.foregroundMuted });
1660
1762
  };
1661
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles16.disabled, style] }, /* @__PURE__ */ React25__default.default.createElement(
1763
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles17.disabled, style] }, /* @__PURE__ */ React26__default.default.createElement(
1662
1764
  reactNative.TouchableOpacity,
1663
1765
  {
1664
1766
  onPress: () => {
@@ -1672,20 +1774,20 @@ function Toggle({
1672
1774
  touchSoundDisabled: true,
1673
1775
  ...props
1674
1776
  },
1675
- /* @__PURE__ */ React25__default.default.createElement(
1777
+ /* @__PURE__ */ React26__default.default.createElement(
1676
1778
  reactNative.Animated.View,
1677
1779
  {
1678
1780
  style: [
1679
- styles16.base,
1781
+ styles17.base,
1680
1782
  sizeStyles[size],
1681
1783
  { borderColor, backgroundColor, borderWidth: 2 }
1682
1784
  ]
1683
1785
  },
1684
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles16.inner }, /* @__PURE__ */ React25__default.default.createElement(LeftIcon, null), label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.Text, { style: [styles16.label, { color: textColor }], allowFontScaling: true }, label) : null)
1786
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles17.inner }, /* @__PURE__ */ React26__default.default.createElement(LeftIcon, null), label ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.Text, { style: [styles17.label, { color: textColor }], allowFontScaling: true }, label) : null)
1685
1787
  )
1686
1788
  ));
1687
1789
  }
1688
- var styles16 = reactNative.StyleSheet.create({
1790
+ var styles17 = reactNative.StyleSheet.create({
1689
1791
  base: {
1690
1792
  borderRadius: ms(8)
1691
1793
  },
@@ -1710,7 +1812,7 @@ function RadioItem({
1710
1812
  onSelect
1711
1813
  }) {
1712
1814
  const { colors } = useTheme();
1713
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
1815
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
1714
1816
  const handlePressIn = () => {
1715
1817
  if (option.disabled) return;
1716
1818
  reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver7, speed: 40, bounciness: 0 }).start();
@@ -1718,10 +1820,10 @@ function RadioItem({
1718
1820
  const handlePressOut = () => {
1719
1821
  reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver7, speed: 40, bounciness: 4 }).start();
1720
1822
  };
1721
- return /* @__PURE__ */ React25__default.default.createElement(
1823
+ return /* @__PURE__ */ React26__default.default.createElement(
1722
1824
  reactNative.TouchableOpacity,
1723
1825
  {
1724
- style: styles17.row,
1826
+ style: styles18.row,
1725
1827
  onPress: () => {
1726
1828
  if (!option.disabled) {
1727
1829
  selectionAsync();
@@ -1734,11 +1836,11 @@ function RadioItem({
1734
1836
  touchSoundDisabled: true,
1735
1837
  disabled: option.disabled
1736
1838
  },
1737
- /* @__PURE__ */ React25__default.default.createElement(
1839
+ /* @__PURE__ */ React26__default.default.createElement(
1738
1840
  reactNative.Animated.View,
1739
1841
  {
1740
1842
  style: [
1741
- styles17.radio,
1843
+ styles18.radio,
1742
1844
  {
1743
1845
  borderColor: selected ? colors.primary : colors.border,
1744
1846
  opacity: option.disabled ? 0.45 : 1,
@@ -1746,13 +1848,13 @@ function RadioItem({
1746
1848
  }
1747
1849
  ]
1748
1850
  },
1749
- selected ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles17.dot, { backgroundColor: colors.primary }] }) : null
1851
+ selected ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles18.dot, { backgroundColor: colors.primary }] }) : null
1750
1852
  ),
1751
- /* @__PURE__ */ React25__default.default.createElement(
1853
+ /* @__PURE__ */ React26__default.default.createElement(
1752
1854
  reactNative.Text,
1753
1855
  {
1754
1856
  style: [
1755
- styles17.label,
1857
+ styles18.label,
1756
1858
  { color: option.disabled ? colors.foregroundMuted : colors.foreground }
1757
1859
  ],
1758
1860
  allowFontScaling: true
@@ -1768,7 +1870,7 @@ function RadioGroup({
1768
1870
  orientation = "vertical",
1769
1871
  style
1770
1872
  }) {
1771
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles17.container, orientation === "horizontal" && styles17.horizontal, style] }, options.map((option) => /* @__PURE__ */ React25__default.default.createElement(
1873
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles18.container, orientation === "horizontal" && styles18.horizontal, style] }, options.map((option) => /* @__PURE__ */ React26__default.default.createElement(
1772
1874
  RadioItem,
1773
1875
  {
1774
1876
  key: option.value,
@@ -1778,7 +1880,7 @@ function RadioGroup({
1778
1880
  }
1779
1881
  )));
1780
1882
  }
1781
- var styles17 = reactNative.StyleSheet.create({
1883
+ var styles18 = reactNative.StyleSheet.create({
1782
1884
  container: {
1783
1885
  gap: vs(12)
1784
1886
  },
@@ -1819,20 +1921,20 @@ function TabTrigger({
1819
1921
  variant
1820
1922
  }) {
1821
1923
  const { colors } = useTheme();
1822
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
1924
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
1823
1925
  const handlePressIn = () => {
1824
- reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver8, speed: 40, bounciness: 0 }).start();
1926
+ reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver8, stiffness: 600, damping: 35, mass: 0.8 }).start();
1825
1927
  };
1826
1928
  const handlePressOut = () => {
1827
- reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver8, speed: 40, bounciness: 4 }).start();
1929
+ reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver8, stiffness: 280, damping: 22, mass: 0.8 }).start();
1828
1930
  };
1829
1931
  const isUnderline = variant === "underline";
1830
- return /* @__PURE__ */ React25__default.default.createElement(
1932
+ return /* @__PURE__ */ React26__default.default.createElement(
1831
1933
  reactNative.TouchableOpacity,
1832
1934
  {
1833
1935
  style: [
1834
- styles18.trigger,
1835
- isUnderline && styles18.triggerUnderline,
1936
+ styles19.trigger,
1937
+ isUnderline && styles19.triggerUnderline,
1836
1938
  isUnderline && isActive && { borderBottomColor: colors.primary }
1837
1939
  ],
1838
1940
  onPress,
@@ -1842,13 +1944,13 @@ function TabTrigger({
1842
1944
  activeOpacity: 1,
1843
1945
  touchSoundDisabled: true
1844
1946
  },
1845
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles18.triggerInner }, tab.icon ? typeof tab.icon === "function" ? tab.icon(isActive) : tab.icon : null, /* @__PURE__ */ React25__default.default.createElement(
1947
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles19.triggerInner }, tab.icon ? typeof tab.icon === "function" ? tab.icon(isActive) : tab.icon : null, /* @__PURE__ */ React26__default.default.createElement(
1846
1948
  reactNative.Text,
1847
1949
  {
1848
1950
  style: [
1849
- styles18.triggerLabel,
1951
+ styles19.triggerLabel,
1850
1952
  { color: isActive ? colors.foreground : colors.foregroundMuted },
1851
- isActive && (isUnderline ? styles18.activeTriggerLabelUnderline : styles18.activeTriggerLabel)
1953
+ isActive && (isUnderline ? styles19.activeTriggerLabelUnderline : styles19.activeTriggerLabel)
1852
1954
  ],
1853
1955
  allowFontScaling: true
1854
1956
  },
@@ -1857,27 +1959,27 @@ function TabTrigger({
1857
1959
  );
1858
1960
  }
1859
1961
  function Tabs({ tabs, variant = "pill", value, onValueChange, children, style }) {
1860
- const [internal, setInternal] = React25.useState(tabs[0]?.value ?? "");
1962
+ const [internal, setInternal] = React26.useState(tabs[0]?.value ?? "");
1861
1963
  const { colors } = useTheme();
1862
1964
  const active = value ?? internal;
1863
- const tabLayouts = React25.useRef({});
1864
- const pillX = React25.useRef(new reactNative.Animated.Value(0)).current;
1865
- const pillWidth = React25.useRef(new reactNative.Animated.Value(0)).current;
1866
- const initialised = React25.useRef(false);
1965
+ const tabLayouts = React26.useRef({});
1966
+ const pillX = React26.useRef(new reactNative.Animated.Value(0)).current;
1967
+ const pillWidth = React26.useRef(new reactNative.Animated.Value(0)).current;
1968
+ const initialised = React26.useRef(false);
1867
1969
  const animatePill = (tabValue, animate) => {
1868
1970
  const layout = tabLayouts.current[tabValue];
1869
1971
  if (!layout) return;
1870
1972
  if (animate) {
1871
1973
  reactNative.Animated.parallel([
1872
- reactNative.Animated.spring(pillX, { toValue: layout.x, useNativeDriver: false, speed: 20, bounciness: 0 }),
1873
- reactNative.Animated.spring(pillWidth, { toValue: layout.width, useNativeDriver: false, speed: 20, bounciness: 0 })
1974
+ reactNative.Animated.spring(pillX, { toValue: layout.x, useNativeDriver: false, stiffness: 380, damping: 38, mass: 1 }),
1975
+ reactNative.Animated.spring(pillWidth, { toValue: layout.width, useNativeDriver: false, stiffness: 380, damping: 38, mass: 1 })
1874
1976
  ]).start();
1875
1977
  } else {
1876
1978
  pillX.setValue(layout.x);
1877
1979
  pillWidth.setValue(layout.width);
1878
1980
  }
1879
1981
  };
1880
- React25.useEffect(() => {
1982
+ React26.useEffect(() => {
1881
1983
  if (initialised.current) animatePill(active, true);
1882
1984
  }, [active]);
1883
1985
  const handlePress = (v) => {
@@ -1885,13 +1987,13 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
1885
1987
  if (!value) setInternal(v);
1886
1988
  onValueChange?.(v);
1887
1989
  };
1888
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [
1889
- variant === "pill" ? [styles18.list, { backgroundColor: colors.surface }] : styles18.listUnderline
1890
- ] }, variant === "pill" && /* @__PURE__ */ React25__default.default.createElement(
1990
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [
1991
+ variant === "pill" ? [styles19.list, { backgroundColor: colors.surface }] : styles19.listUnderline
1992
+ ] }, variant === "pill" && /* @__PURE__ */ React26__default.default.createElement(
1891
1993
  reactNative.Animated.View,
1892
1994
  {
1893
1995
  style: [
1894
- styles18.pill,
1996
+ styles19.pill,
1895
1997
  {
1896
1998
  backgroundColor: colors.background,
1897
1999
  position: "absolute",
@@ -1908,7 +2010,7 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
1908
2010
  }
1909
2011
  ]
1910
2012
  }
1911
- ), tabs.map((tab) => /* @__PURE__ */ React25__default.default.createElement(
2013
+ ), tabs.map((tab) => /* @__PURE__ */ React26__default.default.createElement(
1912
2014
  TabTrigger,
1913
2015
  {
1914
2016
  key: tab.value,
@@ -1929,9 +2031,9 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
1929
2031
  }
1930
2032
  function TabsContent({ value, activeValue, children, style }) {
1931
2033
  if (value !== activeValue) return null;
1932
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style }, children);
2034
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style }, children);
1933
2035
  }
1934
- var styles18 = reactNative.StyleSheet.create({
2036
+ var styles19 = reactNative.StyleSheet.create({
1935
2037
  list: {
1936
2038
  flexDirection: "row",
1937
2039
  borderRadius: 12,
@@ -1978,51 +2080,54 @@ var styles18 = reactNative.StyleSheet.create({
1978
2080
  fontSize: ms(14)
1979
2081
  }
1980
2082
  });
2083
+ var easingExpand = Animated12.Easing.bezier(0.23, 1, 0.32, 1);
2084
+ var easingCollapse = Animated12.Easing.in(Animated12.Easing.ease);
1981
2085
  function AccordionItemComponent({
1982
2086
  item,
1983
2087
  isOpen,
1984
2088
  onToggle
1985
2089
  }) {
1986
2090
  const { colors } = useTheme();
1987
- const isExpanded = Animated11.useSharedValue(isOpen);
1988
- const height = Animated11.useSharedValue(0);
1989
- React25__default.default.useEffect(() => {
2091
+ const resolvedIcon = item.iconName ? renderIcon(item.iconName, ms(16), item.iconColor ?? colors.foregroundMuted) : item.icon;
2092
+ const isExpanded = Animated12.useSharedValue(isOpen);
2093
+ const height = Animated12.useSharedValue(0);
2094
+ React26__default.default.useEffect(() => {
1990
2095
  isExpanded.value = isOpen;
1991
2096
  }, [isOpen]);
1992
- const derivedHeight = Animated11.useDerivedValue(
1993
- () => Animated11.withTiming(height.value * Number(isExpanded.value), {
2097
+ const derivedHeight = Animated12.useDerivedValue(
2098
+ () => Animated12.withTiming(height.value * Number(isExpanded.value), {
1994
2099
  duration: 220,
1995
- easing: isExpanded.value ? Animated11.Easing.out(Animated11.Easing.ease) : Animated11.Easing.in(Animated11.Easing.ease)
2100
+ easing: isExpanded.value ? easingExpand : easingCollapse
1996
2101
  })
1997
2102
  );
1998
- const derivedRotation = Animated11.useDerivedValue(
1999
- () => Animated11.withTiming(isExpanded.value ? 1 : 0, {
2103
+ const derivedRotation = Animated12.useDerivedValue(
2104
+ () => Animated12.withTiming(isExpanded.value ? 1 : 0, {
2000
2105
  duration: 220,
2001
- easing: isExpanded.value ? Animated11.Easing.out(Animated11.Easing.ease) : Animated11.Easing.in(Animated11.Easing.ease)
2106
+ easing: isExpanded.value ? easingExpand : easingCollapse
2002
2107
  })
2003
2108
  );
2004
- const bodyStyle = Animated11.useAnimatedStyle(() => ({
2109
+ const bodyStyle = Animated12.useAnimatedStyle(() => ({
2005
2110
  height: derivedHeight.value,
2006
2111
  overflow: "hidden"
2007
2112
  }));
2008
- const rotationStyle = Animated11.useAnimatedStyle(() => ({
2113
+ const rotationStyle = Animated12.useAnimatedStyle(() => ({
2009
2114
  transform: [{ rotate: `${derivedRotation.value * 180}deg` }]
2010
2115
  }));
2011
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles19.item, { backgroundColor: colors.card, borderColor: colors.border }] }, /* @__PURE__ */ React25__default.default.createElement(
2116
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles20.item, { backgroundColor: colors.card, borderColor: colors.border }] }, /* @__PURE__ */ React26__default.default.createElement(
2012
2117
  reactNative.Pressable,
2013
2118
  {
2014
- style: ({ pressed }) => [styles19.trigger, { opacity: pressed ? 0.6 : 1 }],
2119
+ style: ({ pressed }) => [styles20.trigger, { opacity: pressed ? 0.6 : 1 }],
2015
2120
  onPress: () => {
2016
2121
  selectionAsync();
2017
2122
  onToggle();
2018
2123
  }
2019
2124
  },
2020
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles19.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger),
2021
- /* @__PURE__ */ React25__default.default.createElement(Animated11__default.default.View, { style: [styles19.chevron, rotationStyle] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
2022
- ), /* @__PURE__ */ React25__default.default.createElement(Animated11__default.default.View, { style: bodyStyle }, /* @__PURE__ */ React25__default.default.createElement(
2125
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles20.triggerContent }, resolvedIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles20.icon }, resolvedIcon) : null, /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles20.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger)),
2126
+ /* @__PURE__ */ React26__default.default.createElement(Animated12__default.default.View, { style: [styles20.chevron, rotationStyle] }, /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
2127
+ ), /* @__PURE__ */ React26__default.default.createElement(Animated12__default.default.View, { style: bodyStyle }, /* @__PURE__ */ React26__default.default.createElement(
2023
2128
  reactNative.View,
2024
2129
  {
2025
- style: styles19.content,
2130
+ style: styles20.content,
2026
2131
  onLayout: (e) => {
2027
2132
  height.value = e.nativeEvent.layout.height;
2028
2133
  }
@@ -2031,7 +2136,7 @@ function AccordionItemComponent({
2031
2136
  )));
2032
2137
  }
2033
2138
  function Accordion({ items, type = "single", defaultValue, style }) {
2034
- const [openValues, setOpenValues] = React25.useState(() => {
2139
+ const [openValues, setOpenValues] = React26.useState(() => {
2035
2140
  if (!defaultValue) return [];
2036
2141
  return Array.isArray(defaultValue) ? defaultValue : [defaultValue];
2037
2142
  });
@@ -2044,7 +2149,7 @@ function Accordion({ items, type = "single", defaultValue, style }) {
2044
2149
  );
2045
2150
  }
2046
2151
  };
2047
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles19.list, style] }, items.map((item) => /* @__PURE__ */ React25__default.default.createElement(
2152
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles20.list, style] }, items.map((item) => /* @__PURE__ */ React26__default.default.createElement(
2048
2153
  AccordionItemComponent,
2049
2154
  {
2050
2155
  key: item.value,
@@ -2054,7 +2159,7 @@ function Accordion({ items, type = "single", defaultValue, style }) {
2054
2159
  }
2055
2160
  )));
2056
2161
  }
2057
- var styles19 = reactNative.StyleSheet.create({
2162
+ var styles20 = reactNative.StyleSheet.create({
2058
2163
  list: {
2059
2164
  gap: s(6)
2060
2165
  },
@@ -2070,10 +2175,19 @@ var styles19 = reactNative.StyleSheet.create({
2070
2175
  paddingHorizontal: s(14),
2071
2176
  paddingVertical: vs(12)
2072
2177
  },
2178
+ triggerContent: {
2179
+ flexDirection: "row",
2180
+ alignItems: "center",
2181
+ gap: s(8),
2182
+ flex: 1
2183
+ },
2184
+ icon: {
2185
+ alignItems: "center",
2186
+ justifyContent: "center"
2187
+ },
2073
2188
  triggerText: {
2074
2189
  fontFamily: "Poppins-Medium",
2075
- fontSize: ms(14),
2076
- flex: 1
2190
+ fontSize: ms(14)
2077
2191
  },
2078
2192
  chevron: {
2079
2193
  marginLeft: s(8)
@@ -2102,7 +2216,7 @@ function Slider({
2102
2216
  style
2103
2217
  }) {
2104
2218
  const { colors } = useTheme();
2105
- const lastSteppedValue = React25.useRef(value);
2219
+ const lastSteppedValue = React26.useRef(value);
2106
2220
  const handleValueChange = (v) => {
2107
2221
  if (step && v !== lastSteppedValue.current) {
2108
2222
  lastSteppedValue.current = v;
@@ -2110,7 +2224,7 @@ function Slider({
2110
2224
  }
2111
2225
  onValueChange?.(v);
2112
2226
  };
2113
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles20.wrapper, style], accessibilityLabel }, label || showValue ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles20.header }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles20.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles20.valueText, { color: colors.foregroundMuted }], allowFontScaling: true }, formatValue2(value)) : null) : null, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: disabled ? styles20.disabled : void 0 }, /* @__PURE__ */ React25__default.default.createElement(
2227
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles21.wrapper, style], accessibilityLabel }, label || showValue ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles21.header }, label ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles21.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles21.valueText, { color: colors.foregroundMuted }], allowFontScaling: true }, formatValue2(value)) : null) : null, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: disabled ? styles21.disabled : void 0 }, /* @__PURE__ */ React26__default.default.createElement(
2114
2228
  RNSlider__default.default,
2115
2229
  {
2116
2230
  value,
@@ -2123,12 +2237,12 @@ function Slider({
2123
2237
  minimumTrackTintColor: colors.primary,
2124
2238
  maximumTrackTintColor: colors.surface,
2125
2239
  thumbTintColor: colors.primary,
2126
- style: styles20.slider,
2240
+ style: styles21.slider,
2127
2241
  accessibilityLabel
2128
2242
  }
2129
2243
  )));
2130
2244
  }
2131
- var styles20 = reactNative.StyleSheet.create({
2245
+ var styles21 = reactNative.StyleSheet.create({
2132
2246
  wrapper: {
2133
2247
  gap: vs(8)
2134
2248
  },
@@ -2153,27 +2267,41 @@ var styles20 = reactNative.StyleSheet.create({
2153
2267
  opacity: 0.45
2154
2268
  }
2155
2269
  });
2270
+ var SCREEN_HEIGHT = reactNative.Dimensions.get("window").height;
2271
+ var DEFAULT_MAX_HEIGHT = SCREEN_HEIGHT * 0.85;
2272
+ var isAndroid = reactNative.Platform.OS === "android";
2156
2273
  function Sheet({
2157
2274
  open,
2158
2275
  onClose,
2159
2276
  title,
2277
+ subtitle,
2160
2278
  description,
2279
+ showCloseButton = false,
2161
2280
  children,
2162
2281
  style,
2282
+ contentStyle,
2163
2283
  scrollable,
2164
- maxHeight
2284
+ maxHeight,
2285
+ keyboardBehavior,
2286
+ keyboardBlurBehavior = "restore",
2287
+ enableBlurKeyboardOnGesture = true,
2288
+ android_keyboardInputMode = "adjustPan",
2289
+ footer,
2290
+ snapPoints
2165
2291
  }) {
2166
2292
  const { colors } = useTheme();
2167
- const ref = React25.useRef(null);
2168
- React25.useEffect(() => {
2293
+ const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
2294
+ const ref = React26.useRef(null);
2295
+ const effectiveKeyboardBehavior = keyboardBehavior ?? "interactive";
2296
+ React26.useEffect(() => {
2169
2297
  if (open) {
2170
- impactLight();
2298
+ impactMedium();
2171
2299
  ref.current?.present();
2172
2300
  } else {
2173
2301
  ref.current?.dismiss();
2174
2302
  }
2175
2303
  }, [open]);
2176
- const renderBackdrop = (props) => /* @__PURE__ */ React25__default.default.createElement(
2304
+ const renderBackdrop = React26.useCallback((props) => /* @__PURE__ */ React26__default.default.createElement(
2177
2305
  bottomSheet.BottomSheetBackdrop,
2178
2306
  {
2179
2307
  ...props,
@@ -2181,24 +2309,63 @@ function Sheet({
2181
2309
  appearsOnIndex: 0,
2182
2310
  pressBehavior: "close"
2183
2311
  }
2184
- );
2185
- const headerNode = title || description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles21.header }, title ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles21.title, { color: colors.foreground }], allowFontScaling: true }, title) : null, description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles21.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null) : null;
2312
+ ), []);
2313
+ const renderFooter = React26.useCallback((props) => {
2314
+ if (!footer) return null;
2315
+ return /* @__PURE__ */ React26__default.default.createElement(bottomSheet.BottomSheetFooter, { ...props }, footer);
2316
+ }, [footer]);
2317
+ const effectiveSubtitle = subtitle ?? description;
2318
+ const showHeader = !!(title || effectiveSubtitle || showCloseButton);
2319
+ const headerNode = showHeader ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles22.header }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles22.headerRow }, title ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles22.title, { color: colors.foreground }], allowFontScaling: true }, title) : /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: { flex: 1 } }), showCloseButton ? /* @__PURE__ */ React26__default.default.createElement(
2320
+ reactNative.TouchableOpacity,
2321
+ {
2322
+ onPress: onClose,
2323
+ style: styles22.closeButton,
2324
+ activeOpacity: 0.6,
2325
+ touchSoundDisabled: true
2326
+ },
2327
+ /* @__PURE__ */ React26__default.default.createElement(vectorIcons.AntDesign, { name: "close", size: ms(18), color: colors.foregroundMuted })
2328
+ ) : null), effectiveSubtitle ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles22.subtitle, { color: colors.foregroundMuted }], allowFontScaling: true }, effectiveSubtitle) : null) : null;
2186
2329
  const useScroll = scrollable || !!maxHeight;
2187
- return /* @__PURE__ */ React25__default.default.createElement(
2330
+ const effectiveMaxHeight = maxHeight ?? DEFAULT_MAX_HEIGHT;
2331
+ const useDynamicSizing = !snapPoints;
2332
+ return /* @__PURE__ */ React26__default.default.createElement(
2188
2333
  bottomSheet.BottomSheetModal,
2189
2334
  {
2190
2335
  ref,
2191
- enableDynamicSizing: true,
2336
+ enableDynamicSizing: useDynamicSizing,
2337
+ snapPoints,
2338
+ maxDynamicContentSize: useDynamicSizing ? effectiveMaxHeight : void 0,
2192
2339
  onDismiss: onClose,
2193
2340
  backdropComponent: renderBackdrop,
2194
- backgroundStyle: [styles21.background, { backgroundColor: colors.card }],
2195
- handleIndicatorStyle: [styles21.handle, { backgroundColor: colors.border }],
2196
- enablePanDownToClose: true
2341
+ footerComponent: footer ? renderFooter : void 0,
2342
+ backgroundStyle: [styles22.background, { backgroundColor: colors.card }],
2343
+ handleIndicatorStyle: [styles22.handle, { backgroundColor: colors.border }],
2344
+ enablePanDownToClose: true,
2345
+ topInset: insets.top,
2346
+ keyboardBehavior: effectiveKeyboardBehavior,
2347
+ keyboardBlurBehavior,
2348
+ android_keyboardInputMode,
2349
+ enableBlurKeyboardOnGesture
2197
2350
  },
2198
- /* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetView, { style: maxHeight ? { maxHeight } : void 0 }, useScroll ? /* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetScrollView, { contentContainerStyle: [styles21.content, style] }, headerNode, children) : /* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetView, { style: [styles21.content, style] }, headerNode, children))
2351
+ useScroll ? /* @__PURE__ */ React26__default.default.createElement(
2352
+ bottomSheet.BottomSheetScrollView,
2353
+ {
2354
+ contentContainerStyle: [
2355
+ styles22.scrollContent,
2356
+ style
2357
+ ],
2358
+ style: contentStyle,
2359
+ showsVerticalScrollIndicator: true,
2360
+ indicatorStyle: "black",
2361
+ persistentScrollbar: isAndroid
2362
+ },
2363
+ headerNode,
2364
+ children
2365
+ ) : /* @__PURE__ */ React26__default.default.createElement(bottomSheet.BottomSheetView, { style: [styles22.content, contentStyle, style] }, headerNode, children)
2199
2366
  );
2200
2367
  }
2201
- var styles21 = reactNative.StyleSheet.create({
2368
+ var styles22 = reactNative.StyleSheet.create({
2202
2369
  background: {
2203
2370
  borderTopLeftRadius: ms(16),
2204
2371
  borderTopRightRadius: ms(16)
@@ -2208,26 +2375,43 @@ var styles21 = reactNative.StyleSheet.create({
2208
2375
  height: vs(4),
2209
2376
  borderRadius: ms(2)
2210
2377
  },
2211
- content: {
2212
- paddingHorizontal: s(24),
2213
- paddingBottom: vs(32)
2214
- },
2215
2378
  header: {
2216
- gap: vs(8),
2217
- marginBottom: vs(16)
2379
+ paddingHorizontal: s(16),
2380
+ paddingTop: vs(4),
2381
+ paddingBottom: vs(12),
2382
+ gap: vs(4)
2383
+ },
2384
+ headerRow: {
2385
+ flexDirection: "row",
2386
+ alignItems: "center",
2387
+ justifyContent: "space-between"
2218
2388
  },
2219
2389
  title: {
2220
2390
  fontFamily: "Poppins-SemiBold",
2221
- fontSize: ms(18)
2391
+ fontSize: ms(18),
2392
+ flex: 1
2222
2393
  },
2223
- description: {
2394
+ subtitle: {
2224
2395
  fontFamily: "Poppins-Regular",
2225
2396
  fontSize: ms(14),
2226
2397
  lineHeight: mvs(20)
2398
+ },
2399
+ closeButton: {
2400
+ padding: s(4),
2401
+ marginLeft: s(8)
2402
+ },
2403
+ content: {
2404
+ paddingHorizontal: s(16),
2405
+ paddingBottom: vs(32)
2406
+ },
2407
+ scrollContent: {
2408
+ paddingHorizontal: s(16),
2409
+ paddingBottom: vs(32),
2410
+ paddingRight: s(16)
2227
2411
  }
2228
2412
  });
2229
2413
  var isIOS = reactNative.Platform.OS === "ios";
2230
- var isAndroid = reactNative.Platform.OS === "android";
2414
+ var isAndroid2 = reactNative.Platform.OS === "android";
2231
2415
  var isWeb2 = reactNative.Platform.OS === "web";
2232
2416
  var nativeDriver9 = reactNative.Platform.OS !== "web";
2233
2417
  function Select({
@@ -2241,10 +2425,10 @@ function Select({
2241
2425
  style
2242
2426
  }) {
2243
2427
  const { colors } = useTheme();
2244
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
2245
- const [pickerVisible, setPickerVisible] = React25.useState(false);
2246
- const [pendingValue, setPendingValue] = React25.useState(value);
2247
- const pickerRef = React25.useRef(null);
2428
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
2429
+ const [pickerVisible, setPickerVisible] = React26.useState(false);
2430
+ const [pendingValue, setPendingValue] = React26.useState(value);
2431
+ const pickerRef = React26.useRef(null);
2248
2432
  const selected = options.find((o) => o.value === value);
2249
2433
  const handlePressIn = () => {
2250
2434
  if (disabled) return;
@@ -2259,7 +2443,7 @@ function Select({
2259
2443
  if (isIOS) {
2260
2444
  setPendingValue(value);
2261
2445
  setPickerVisible(true);
2262
- } else if (isAndroid) {
2446
+ } else if (isAndroid2) {
2263
2447
  pickerRef.current?.focus();
2264
2448
  }
2265
2449
  };
@@ -2273,11 +2457,11 @@ function Select({
2273
2457
  }
2274
2458
  setPickerVisible(false);
2275
2459
  };
2276
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles22.container, style] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles22.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }], opacity: disabled ? 0.45 : 1 } }, /* @__PURE__ */ React25__default.default.createElement(
2460
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles23.container, style] }, label ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles23.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }], opacity: disabled ? 0.45 : 1 } }, /* @__PURE__ */ React26__default.default.createElement(
2277
2461
  reactNative.TouchableOpacity,
2278
2462
  {
2279
2463
  style: [
2280
- styles22.trigger,
2464
+ styles23.trigger,
2281
2465
  {
2282
2466
  borderColor: error ? colors.destructive : colors.border,
2283
2467
  backgroundColor: colors.background
@@ -2289,11 +2473,11 @@ function Select({
2289
2473
  activeOpacity: 1,
2290
2474
  touchSoundDisabled: true
2291
2475
  },
2292
- /* @__PURE__ */ React25__default.default.createElement(
2476
+ /* @__PURE__ */ React26__default.default.createElement(
2293
2477
  reactNative.Text,
2294
2478
  {
2295
2479
  style: [
2296
- styles22.triggerText,
2480
+ styles23.triggerText,
2297
2481
  { color: selected ? colors.foreground : colors.foregroundMuted }
2298
2482
  ],
2299
2483
  numberOfLines: 1,
@@ -2301,8 +2485,8 @@ function Select({
2301
2485
  },
2302
2486
  selected?.label ?? placeholder
2303
2487
  ),
2304
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-down", size: 20, color: colors.foregroundMuted })
2305
- )) : null, isIOS ? /* @__PURE__ */ React25__default.default.createElement(
2488
+ /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 20, color: colors.foregroundMuted })
2489
+ )) : null, isIOS ? /* @__PURE__ */ React26__default.default.createElement(
2306
2490
  reactNative.Modal,
2307
2491
  {
2308
2492
  visible: pickerVisible,
@@ -2310,16 +2494,16 @@ function Select({
2310
2494
  animationType: "slide",
2311
2495
  onRequestClose: handleDismiss
2312
2496
  },
2313
- /* @__PURE__ */ React25__default.default.createElement(reactNative.TouchableOpacity, { style: styles22.iosBackdrop, activeOpacity: 1, onPress: handleDismiss }),
2314
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles22.iosSheet, { backgroundColor: colors.card }] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles22.iosToolbar, { borderBottomColor: colors.border }] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles22.iosToolbarTitle, { color: colors.foreground }], allowFontScaling: true }, label) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, null), /* @__PURE__ */ React25__default.default.createElement(reactNative.TouchableOpacity, { onPress: handleConfirm, style: styles22.iosDoneBtn, hitSlop: { top: 8, bottom: 8, left: 8, right: 8 } }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles22.iosDoneBtnText, { color: colors.primary }], allowFontScaling: true }, "Done"))), /* @__PURE__ */ React25__default.default.createElement(
2497
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.TouchableOpacity, { style: styles23.iosBackdrop, activeOpacity: 1, onPress: handleDismiss }),
2498
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles23.iosSheet, { backgroundColor: colors.card }] }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles23.iosToolbar, { borderBottomColor: colors.border }] }, label ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles23.iosToolbarTitle, { color: colors.foreground }], allowFontScaling: true }, label) : /* @__PURE__ */ React26__default.default.createElement(reactNative.View, null), /* @__PURE__ */ React26__default.default.createElement(reactNative.TouchableOpacity, { onPress: handleConfirm, style: styles23.iosDoneBtn, hitSlop: { top: 8, bottom: 8, left: 8, right: 8 } }, /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles23.iosDoneBtnText, { color: colors.primary }], allowFontScaling: true }, "Done"))), /* @__PURE__ */ React26__default.default.createElement(
2315
2499
  picker.Picker,
2316
2500
  {
2317
2501
  selectedValue: pendingValue ?? "",
2318
2502
  onValueChange: (val) => setPendingValue(val),
2319
2503
  itemStyle: { color: colors.foreground }
2320
2504
  },
2321
- !value ? /* @__PURE__ */ React25__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", color: colors.foregroundMuted, enabled: false }) : null,
2322
- options.map((o) => /* @__PURE__ */ React25__default.default.createElement(
2505
+ !value ? /* @__PURE__ */ React26__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", color: colors.foregroundMuted, enabled: false }) : null,
2506
+ options.map((o) => /* @__PURE__ */ React26__default.default.createElement(
2323
2507
  picker.Picker.Item,
2324
2508
  {
2325
2509
  key: o.value,
@@ -2330,7 +2514,7 @@ function Select({
2330
2514
  }
2331
2515
  ))
2332
2516
  ))
2333
- ) : null, isAndroid ? /* @__PURE__ */ React25__default.default.createElement(
2517
+ ) : null, isAndroid2 ? /* @__PURE__ */ React26__default.default.createElement(
2334
2518
  picker.Picker,
2335
2519
  {
2336
2520
  ref: pickerRef,
@@ -2344,10 +2528,10 @@ function Select({
2344
2528
  mode: "dialog",
2345
2529
  enabled: !disabled,
2346
2530
  prompt: label,
2347
- style: styles22.androidHiddenPicker
2531
+ style: styles23.androidHiddenPicker
2348
2532
  },
2349
- !value ? /* @__PURE__ */ React25__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", enabled: false }) : null,
2350
- options.map((o) => /* @__PURE__ */ React25__default.default.createElement(
2533
+ !value ? /* @__PURE__ */ React26__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", enabled: false }) : null,
2534
+ options.map((o) => /* @__PURE__ */ React26__default.default.createElement(
2351
2535
  picker.Picker.Item,
2352
2536
  {
2353
2537
  key: o.value,
@@ -2356,7 +2540,7 @@ function Select({
2356
2540
  enabled: !o.disabled
2357
2541
  }
2358
2542
  ))
2359
- ) : null, isWeb2 ? /* @__PURE__ */ React25__default.default.createElement(
2543
+ ) : null, isWeb2 ? /* @__PURE__ */ React26__default.default.createElement(
2360
2544
  picker.Picker,
2361
2545
  {
2362
2546
  selectedValue: value ?? "",
@@ -2367,7 +2551,7 @@ function Select({
2367
2551
  },
2368
2552
  enabled: !disabled,
2369
2553
  style: [
2370
- styles22.webPicker,
2554
+ styles23.webPicker,
2371
2555
  {
2372
2556
  borderColor: error ? colors.destructive : colors.border,
2373
2557
  color: selected ? colors.foreground : colors.foregroundMuted,
@@ -2376,8 +2560,8 @@ function Select({
2376
2560
  }
2377
2561
  ]
2378
2562
  },
2379
- /* @__PURE__ */ React25__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", enabled: false }),
2380
- options.map((o) => /* @__PURE__ */ React25__default.default.createElement(
2563
+ /* @__PURE__ */ React26__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", enabled: false }),
2564
+ options.map((o) => /* @__PURE__ */ React26__default.default.createElement(
2381
2565
  picker.Picker.Item,
2382
2566
  {
2383
2567
  key: o.value,
@@ -2386,9 +2570,9 @@ function Select({
2386
2570
  enabled: !o.disabled
2387
2571
  }
2388
2572
  ))
2389
- ) : null, error ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles22.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null);
2573
+ ) : null, error ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles23.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null);
2390
2574
  }
2391
- var styles22 = reactNative.StyleSheet.create({
2575
+ var styles23 = reactNative.StyleSheet.create({
2392
2576
  container: {
2393
2577
  gap: vs(8)
2394
2578
  },
@@ -2458,172 +2642,46 @@ var styles22 = reactNative.StyleSheet.create({
2458
2642
  fontSize: ms(15)
2459
2643
  }
2460
2644
  });
2461
- var ToastContext = React25.createContext({
2462
- toast: () => {
2463
- },
2464
- dismiss: () => {
2465
- }
2466
- });
2467
2645
  function useToast() {
2468
- return React25.useContext(ToastContext);
2469
- }
2470
- var SWIPE_THRESHOLD = 80;
2471
- var VELOCITY_THRESHOLD = 800;
2472
- function ToastNotification({ item, onDismiss }) {
2473
- const { colors } = useTheme();
2474
- const translateY = Animated11.useSharedValue(-80);
2475
- const translateX = Animated11.useSharedValue(0);
2476
- const opacity = Animated11.useSharedValue(0);
2477
- React25.useEffect(() => {
2478
- translateY.value = Animated11.withTiming(0, { duration: 120, easing: Animated11.Easing.out(Animated11.Easing.exp) });
2479
- opacity.value = Animated11.withTiming(1, { duration: 100 });
2480
- const timer = setTimeout(() => {
2481
- translateY.value = Animated11.withTiming(-80, { duration: 200 });
2482
- opacity.value = Animated11.withTiming(0, { duration: 200 }, (done) => {
2483
- if (done) reactNativeWorklets.scheduleOnRN(onDismiss);
2484
- });
2485
- }, item.duration ?? 3e3);
2486
- return () => clearTimeout(timer);
2487
- }, []);
2488
- const panGesture = reactNativeGestureHandler.Gesture.Pan().onUpdate((e) => {
2489
- translateX.value = e.translationX;
2490
- }).onEnd((e) => {
2491
- const shouldDismiss = Math.abs(translateX.value) > SWIPE_THRESHOLD || Math.abs(e.velocityX) > VELOCITY_THRESHOLD;
2492
- if (shouldDismiss) {
2493
- const direction = translateX.value > 0 ? 1 : -1;
2494
- translateX.value = Animated11.withTiming(direction * 500, { duration: 200 }, (done) => {
2495
- if (done) reactNativeWorklets.scheduleOnRN(onDismiss);
2496
- });
2497
- opacity.value = Animated11.withTiming(0, { duration: 150 });
2498
- } else {
2499
- translateX.value = Animated11.withSpring(0, { damping: 20, stiffness: 300 });
2500
- }
2501
- });
2502
- const animatedStyle = Animated11.useAnimatedStyle(() => ({
2503
- opacity: opacity.value,
2504
- transform: [{ translateY: translateY.value }, { translateX: translateX.value }]
2505
- }));
2506
- const variant = item.variant ?? "default";
2507
- const bgColor = {
2508
- default: colors.card,
2509
- destructive: colors.destructiveTint,
2510
- success: colors.successTint,
2511
- warning: colors.warningTint
2512
- }[variant];
2513
- const borderColor = {
2514
- default: colors.border,
2515
- destructive: colors.destructiveBorder,
2516
- success: colors.successBorder,
2517
- warning: colors.warningBorder
2518
- }[variant];
2519
- const accentColor = {
2520
- default: colors.primary,
2521
- destructive: colors.destructive,
2522
- success: colors.success,
2523
- warning: colors.warning
2524
- }[variant];
2525
- const titleColor = variant === "default" ? colors.foreground : accentColor;
2526
- const descColor = variant === "default" ? colors.foregroundMuted : accentColor;
2527
- const defaultIcon = variant === "success" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: 16, color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.AntDesign, { name: "exclamation-circle", size: 16, color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.MaterialIcons, { name: "warning-amber", size: 17, color: accentColor }) : /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "info-with-circle", size: 16, color: accentColor });
2528
- const leftIcon = item.iconName ? renderIcon(item.iconName, 16, item.iconColor ?? accentColor) : item.icon ?? defaultIcon;
2529
- return /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: panGesture }, /* @__PURE__ */ React25__default.default.createElement(Animated11__default.default.View, { style: [styles23.toast, { backgroundColor: bgColor, borderColor }, animatedStyle] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles23.leftIconContainer }, leftIcon), /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles23.toastContent }, item.title ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.toastTitle, { color: titleColor }], allowFontScaling: true }, item.title) : null, item.description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.toastDescription, { color: descColor }], allowFontScaling: true }, item.description) : null), item.action && /* @__PURE__ */ React25__default.default.createElement(
2530
- reactNative.TouchableOpacity,
2531
- {
2532
- onPress: () => {
2533
- item.action.onPress();
2534
- onDismiss();
2535
- },
2536
- style: styles23.actionButton,
2537
- touchSoundDisabled: true
2538
- },
2539
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.actionLabel, { color: accentColor }], allowFontScaling: true }, item.action.label)
2540
- ), /* @__PURE__ */ React25__default.default.createElement(reactNative.TouchableOpacity, { onPress: onDismiss, style: styles23.dismissButton, touchSoundDisabled: true }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.AntDesign, { name: "close-circle", size: 16, color: descColor }))));
2646
+ return {
2647
+ toast: sonnerNative.toast,
2648
+ dismiss: sonnerNative.toast.dismiss
2649
+ };
2541
2650
  }
2542
2651
  function ToastProvider({ children }) {
2543
- const [toasts, setToasts] = React25.useState([]);
2652
+ const { colorScheme } = useTheme();
2544
2653
  const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
2545
- const toast = React25.useCallback((item) => {
2546
- const id = Math.random().toString(36).slice(2);
2547
- if (item.variant === "success") {
2548
- notificationSuccess();
2549
- } else if (item.variant === "destructive") {
2550
- notificationError();
2551
- } else if (item.variant === "warning") {
2552
- notificationError();
2553
- } else {
2554
- impactLight();
2654
+ return /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, children, /* @__PURE__ */ React26__default.default.createElement(
2655
+ sonnerNative.Toaster,
2656
+ {
2657
+ theme: colorScheme,
2658
+ position: "top-center",
2659
+ richColors: false,
2660
+ gap: vs(8),
2661
+ offset: insets.top + vs(8),
2662
+ visibleToasts: 3,
2663
+ closeButton: false,
2664
+ swipeToDismissDirection: "up",
2665
+ duration: 4e3,
2666
+ toastOptions: {
2667
+ style: {
2668
+ borderRadius: ms(12),
2669
+ paddingHorizontal: s(12),
2670
+ paddingVertical: vs(10)
2671
+ },
2672
+ titleStyle: {
2673
+ fontFamily: "Poppins-Medium",
2674
+ fontSize: ms(13)
2675
+ },
2676
+ descriptionStyle: {
2677
+ fontFamily: "Poppins-Regular",
2678
+ fontSize: ms(12),
2679
+ opacity: 0.85
2680
+ }
2681
+ }
2555
2682
  }
2556
- setToasts((prev) => [{ ...item, id }, ...prev].slice(0, 3));
2557
- }, []);
2558
- const dismiss = React25.useCallback((id) => {
2559
- setToasts((prev) => prev.filter((t) => t.id !== id));
2560
- }, []);
2561
- return /* @__PURE__ */ React25__default.default.createElement(ToastContext.Provider, { value: { toast, dismiss } }, children, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles23.container, reactNative.Platform.OS === "web" && styles23.containerWeb, { top: insets.top + 8 }], pointerEvents: "box-none" }, toasts.map((item) => /* @__PURE__ */ React25__default.default.createElement(ToastNotification, { key: item.id, item, onDismiss: () => dismiss(item.id) }))));
2683
+ ));
2562
2684
  }
2563
- var styles23 = reactNative.StyleSheet.create({
2564
- container: {
2565
- position: "absolute",
2566
- left: s(16),
2567
- right: s(16),
2568
- gap: vs(8),
2569
- zIndex: 9999
2570
- },
2571
- containerWeb: {
2572
- left: void 0,
2573
- right: void 0,
2574
- alignSelf: "center",
2575
- width: s(400)
2576
- },
2577
- toast: {
2578
- flexDirection: "row",
2579
- alignItems: "flex-start",
2580
- borderRadius: ms(10),
2581
- borderWidth: 0.5,
2582
- paddingHorizontal: s(12),
2583
- paddingVertical: vs(10),
2584
- shadowColor: "#000",
2585
- shadowOffset: { width: 0, height: 2 },
2586
- shadowOpacity: 0.06,
2587
- shadowRadius: 4,
2588
- elevation: 3
2589
- },
2590
- toastContent: {
2591
- flex: 1,
2592
- gap: vs(2)
2593
- },
2594
- leftIconContainer: {
2595
- marginTop: vs(1),
2596
- alignItems: "center",
2597
- justifyContent: "center",
2598
- marginRight: s(10)
2599
- },
2600
- toastTitle: {
2601
- fontFamily: "Poppins-Medium",
2602
- fontSize: ms(13),
2603
- lineHeight: ms(18)
2604
- },
2605
- toastDescription: {
2606
- fontFamily: "Poppins-Regular",
2607
- fontSize: ms(12),
2608
- lineHeight: ms(17),
2609
- opacity: 0.85
2610
- },
2611
- actionButton: {
2612
- paddingHorizontal: s(8),
2613
- paddingVertical: vs(4),
2614
- marginLeft: s(4)
2615
- },
2616
- actionLabel: {
2617
- fontFamily: "Poppins-Medium",
2618
- fontSize: ms(12),
2619
- textDecorationLine: "underline"
2620
- },
2621
- dismissButton: {
2622
- padding: s(6),
2623
- marginLeft: s(2),
2624
- marginTop: vs(0)
2625
- }
2626
- });
2627
2685
  function formatCurrency(raw, separator) {
2628
2686
  const digits = raw.replace(/\D/g, "");
2629
2687
  if (!digits) return "";
@@ -2657,7 +2715,7 @@ function CurrencyInput({
2657
2715
  const inputStyle = size === "large" ? { fontFamily: "Poppins-Regular", fontSize: ms(36) } : { fontFamily: "Poppins-Regular" };
2658
2716
  const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.foregroundMuted);
2659
2717
  const displayValue = value && prefix && value.startsWith(prefix) ? value.slice(prefix.length) : value;
2660
- return /* @__PURE__ */ React25__default.default.createElement(
2718
+ return /* @__PURE__ */ React26__default.default.createElement(
2661
2719
  Input,
2662
2720
  {
2663
2721
  value: displayValue,
@@ -2675,6 +2733,18 @@ function CurrencyInput({
2675
2733
  }
2676
2734
  );
2677
2735
  }
2736
+ var variantFontSize = {
2737
+ hero: ms(48),
2738
+ large: ms(32),
2739
+ medium: ms(18),
2740
+ small: ms(14)
2741
+ };
2742
+ var variantLetterSpacing = {
2743
+ hero: -2,
2744
+ large: -1,
2745
+ medium: -0.5,
2746
+ small: 0
2747
+ };
2678
2748
  function formatValue(value, prefix, showDecimals) {
2679
2749
  const num = typeof value === "string" ? parseFloat(value.replace(/[^0-9.-]/g, "")) : value;
2680
2750
  if (isNaN(num)) return `${prefix}0`;
@@ -2687,17 +2757,32 @@ function formatValue(value, prefix, showDecimals) {
2687
2757
  }
2688
2758
  return `${sign}${prefix}${intPart}`;
2689
2759
  }
2690
- function CurrencyDisplay({ value, prefix = "$", showDecimals = false, textColor, style }) {
2760
+ function CurrencyDisplay({ value, prefix = "$", showDecimals = false, textColor, variant, autoScale, maxFontSize, style }) {
2691
2761
  const { colors } = useTheme();
2692
2762
  const formatted = formatValue(value, prefix, showDecimals);
2693
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles24.container, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles24.amount, { color: textColor ?? colors.foreground }], allowFontScaling: true }, formatted));
2763
+ const baseFontSize = variant ? variantFontSize[variant] : ms(56);
2764
+ const fontSize = maxFontSize ?? baseFontSize;
2765
+ const letterSpacing = variant ? variantLetterSpacing[variant] : -2;
2766
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles24.container, style] }, /* @__PURE__ */ React26__default.default.createElement(
2767
+ reactNative.Text,
2768
+ {
2769
+ style: [styles24.amount, { color: textColor ?? colors.foreground, fontSize, letterSpacing }],
2770
+ allowFontScaling: true,
2771
+ numberOfLines: autoScale ? 1 : void 0,
2772
+ adjustsFontSizeToFit: autoScale,
2773
+ minimumFontScale: autoScale ? 0.5 : void 0
2774
+ },
2775
+ formatted
2776
+ ));
2694
2777
  }
2695
2778
  var styles24 = reactNative.StyleSheet.create({
2696
- container: {},
2779
+ container: {
2780
+ alignSelf: "flex-start"
2781
+ },
2697
2782
  amount: {
2698
2783
  fontFamily: "Poppins-Bold",
2699
- fontSize: ms(56),
2700
- letterSpacing: -2
2784
+ includeFontPadding: false,
2785
+ textAlignVertical: "top"
2701
2786
  }
2702
2787
  });
2703
2788
  var nativeDriver10 = reactNative.Platform.OS !== "web";
@@ -2724,22 +2809,24 @@ function ListItem({
2724
2809
  captionStyle
2725
2810
  }) {
2726
2811
  const { colors } = useTheme();
2727
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
2812
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
2728
2813
  const handlePressIn = () => {
2729
2814
  if (!onPress || disabled) return;
2730
2815
  reactNative.Animated.spring(scale2, {
2731
2816
  toValue: 0.97,
2732
2817
  useNativeDriver: nativeDriver10,
2733
- speed: 40,
2734
- bounciness: 0
2818
+ stiffness: 350,
2819
+ damping: 28,
2820
+ mass: 0.9
2735
2821
  }).start();
2736
2822
  };
2737
2823
  const handlePressOut = () => {
2738
2824
  reactNative.Animated.spring(scale2, {
2739
2825
  toValue: 1,
2740
2826
  useNativeDriver: nativeDriver10,
2741
- speed: 40,
2742
- bounciness: 4
2827
+ stiffness: 220,
2828
+ damping: 20,
2829
+ mass: 0.9
2743
2830
  }).start();
2744
2831
  };
2745
2832
  const handlePress = () => {
@@ -2750,7 +2837,7 @@ function ListItem({
2750
2837
  const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted) : rightRender ?? trailing;
2751
2838
  const cardStyle = variant === "card" ? {
2752
2839
  backgroundColor: colors.card,
2753
- borderRadius: 12,
2840
+ borderRadius: RADIUS.md,
2754
2841
  borderWidth: 1,
2755
2842
  borderColor: colors.border,
2756
2843
  shadowColor: "#000",
@@ -2759,7 +2846,7 @@ function ListItem({
2759
2846
  shadowRadius: 6,
2760
2847
  elevation: 2
2761
2848
  } : {};
2762
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles25.disabled] }, /* @__PURE__ */ React25__default.default.createElement(
2849
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles25.disabled] }, /* @__PURE__ */ React26__default.default.createElement(
2763
2850
  reactNative.TouchableOpacity,
2764
2851
  {
2765
2852
  style: [styles25.container, cardStyle, style],
@@ -2770,8 +2857,8 @@ function ListItem({
2770
2857
  activeOpacity: 1,
2771
2858
  touchSoundDisabled: true
2772
2859
  },
2773
- effectiveLeft ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles25.leftContainer }, effectiveLeft) : null,
2774
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles25.content }, /* @__PURE__ */ React25__default.default.createElement(
2860
+ effectiveLeft ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles25.leftContainer }, effectiveLeft) : null,
2861
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles25.content }, /* @__PURE__ */ React26__default.default.createElement(
2775
2862
  reactNative.Text,
2776
2863
  {
2777
2864
  style: [styles25.title, { color: colors.foreground }, titleStyle],
@@ -2779,7 +2866,7 @@ function ListItem({
2779
2866
  allowFontScaling: true
2780
2867
  },
2781
2868
  title
2782
- ), subtitle ? /* @__PURE__ */ React25__default.default.createElement(
2869
+ ), subtitle ? /* @__PURE__ */ React26__default.default.createElement(
2783
2870
  reactNative.Text,
2784
2871
  {
2785
2872
  style: [styles25.subtitle, { color: colors.foregroundMuted }, subtitleStyle],
@@ -2787,7 +2874,7 @@ function ListItem({
2787
2874
  allowFontScaling: true
2788
2875
  },
2789
2876
  subtitle
2790
- ) : null, caption ? /* @__PURE__ */ React25__default.default.createElement(
2877
+ ) : null, caption ? /* @__PURE__ */ React26__default.default.createElement(
2791
2878
  reactNative.Text,
2792
2879
  {
2793
2880
  style: [styles25.caption, { color: colors.foregroundMuted }, captionStyle],
@@ -2796,20 +2883,23 @@ function ListItem({
2796
2883
  },
2797
2884
  caption
2798
2885
  ) : null),
2799
- effectiveRight !== void 0 ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles25.rightContainer }, typeof effectiveRight === "string" ? /* @__PURE__ */ React25__default.default.createElement(
2886
+ effectiveRight !== void 0 ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles25.rightContainer }, typeof effectiveRight === "string" ? /* @__PURE__ */ React26__default.default.createElement(
2800
2887
  reactNative.Text,
2801
2888
  {
2802
2889
  style: [styles25.rightText, { color: colors.foregroundMuted }],
2803
2890
  allowFontScaling: true
2804
2891
  },
2805
2892
  effectiveRight
2806
- ) : effectiveRight) : showChevron ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-right", size: 20, color: colors.foregroundMuted }) : null
2807
- ), showSeparator ? /* @__PURE__ */ React25__default.default.createElement(
2893
+ ) : effectiveRight) : showChevron ? /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-right", size: 20, color: colors.foregroundMuted }) : null
2894
+ ), showSeparator ? /* @__PURE__ */ React26__default.default.createElement(
2808
2895
  reactNative.View,
2809
2896
  {
2810
2897
  style: [
2811
2898
  styles25.separator,
2812
- { backgroundColor: colors.border, marginLeft: effectiveLeft ? s(16) + s(44) + s(12) : s(16) }
2899
+ {
2900
+ backgroundColor: colors.border,
2901
+ marginLeft: effectiveLeft ? s(44) + s(12) : 0
2902
+ }
2813
2903
  ]
2814
2904
  }
2815
2905
  ) : null);
@@ -2818,7 +2908,7 @@ var styles25 = reactNative.StyleSheet.create({
2818
2908
  container: {
2819
2909
  flexDirection: "row",
2820
2910
  alignItems: "center",
2821
- paddingHorizontal: s(16),
2911
+ paddingHorizontal: 0,
2822
2912
  paddingVertical: vs(10),
2823
2913
  gap: s(12)
2824
2914
  },
@@ -2864,18 +2954,148 @@ var styles25 = reactNative.StyleSheet.create({
2864
2954
  },
2865
2955
  separator: {
2866
2956
  height: reactNative.StyleSheet.hairlineWidth,
2867
- marginRight: s(16)
2957
+ marginRight: 0
2868
2958
  },
2869
2959
  disabled: {
2870
2960
  opacity: 0.45
2871
2961
  }
2872
2962
  });
2873
2963
  var nativeDriver11 = reactNative.Platform.OS !== "web";
2964
+ function MenuItem({
2965
+ label,
2966
+ iconName,
2967
+ icon,
2968
+ iconColor,
2969
+ rightRender,
2970
+ showChevron = true,
2971
+ onPress,
2972
+ disabled = false,
2973
+ variant = "plain",
2974
+ showSeparator = false,
2975
+ style,
2976
+ labelStyle
2977
+ }) {
2978
+ const { colors } = useTheme();
2979
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
2980
+ const handlePressIn = () => {
2981
+ if (disabled) return;
2982
+ reactNative.Animated.spring(scale2, {
2983
+ toValue: 0.97,
2984
+ useNativeDriver: nativeDriver11,
2985
+ stiffness: 350,
2986
+ damping: 28,
2987
+ mass: 0.9
2988
+ }).start();
2989
+ };
2990
+ const handlePressOut = () => {
2991
+ reactNative.Animated.spring(scale2, {
2992
+ toValue: 1,
2993
+ useNativeDriver: nativeDriver11,
2994
+ stiffness: 220,
2995
+ damping: 20,
2996
+ mass: 0.9
2997
+ }).start();
2998
+ };
2999
+ const handlePress = () => {
3000
+ selectionAsync();
3001
+ onPress();
3002
+ };
3003
+ const resolvedIcon = iconName ? renderIcon(iconName, 22, iconColor ?? colors.foreground) : icon;
3004
+ const cardStyle = variant === "card" ? {
3005
+ backgroundColor: colors.card,
3006
+ borderRadius: RADIUS.md,
3007
+ borderWidth: 1,
3008
+ borderColor: colors.border,
3009
+ shadowColor: "#000",
3010
+ shadowOffset: { width: 0, height: 2 },
3011
+ shadowOpacity: 0.06,
3012
+ shadowRadius: 6,
3013
+ elevation: 2
3014
+ } : {};
3015
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles26.disabled] }, /* @__PURE__ */ React26__default.default.createElement(
3016
+ reactNative.TouchableOpacity,
3017
+ {
3018
+ style: [styles26.container, cardStyle, style],
3019
+ onPress: handlePress,
3020
+ onPressIn: handlePressIn,
3021
+ onPressOut: handlePressOut,
3022
+ disabled,
3023
+ activeOpacity: 1,
3024
+ touchSoundDisabled: true
3025
+ },
3026
+ resolvedIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles26.iconContainer }, resolvedIcon) : null,
3027
+ /* @__PURE__ */ React26__default.default.createElement(
3028
+ reactNative.Text,
3029
+ {
3030
+ style: [styles26.label, { color: colors.foreground }, labelStyle],
3031
+ numberOfLines: 1,
3032
+ allowFontScaling: true
3033
+ },
3034
+ label
3035
+ ),
3036
+ rightRender !== void 0 ? /* @__PURE__ */ React26__default.default.createElement(
3037
+ reactNative.View,
3038
+ {
3039
+ style: styles26.rightContainer,
3040
+ onStartShouldSetResponder: () => true,
3041
+ onResponderRelease: () => {
3042
+ }
3043
+ },
3044
+ rightRender
3045
+ ) : showChevron ? /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "chevron-right", size: 18, color: colors.foregroundMuted }) : null
3046
+ ), showSeparator ? /* @__PURE__ */ React26__default.default.createElement(
3047
+ reactNative.View,
3048
+ {
3049
+ style: [
3050
+ styles26.separator,
3051
+ {
3052
+ backgroundColor: colors.border,
3053
+ marginLeft: resolvedIcon ? s(22) + s(12) : 0,
3054
+ opacity: 0.6
3055
+ }
3056
+ ]
3057
+ }
3058
+ ) : null);
3059
+ }
3060
+ var styles26 = reactNative.StyleSheet.create({
3061
+ container: {
3062
+ flexDirection: "row",
3063
+ alignItems: "center",
3064
+ paddingHorizontal: 0,
3065
+ paddingVertical: vs(16),
3066
+ minHeight: vs(54),
3067
+ gap: s(12)
3068
+ },
3069
+ iconContainer: {
3070
+ width: s(22),
3071
+ alignItems: "center",
3072
+ justifyContent: "center",
3073
+ flexShrink: 0
3074
+ },
3075
+ label: {
3076
+ fontFamily: "Poppins-Medium",
3077
+ fontSize: ms(15),
3078
+ flex: 1
3079
+ },
3080
+ rightContainer: {
3081
+ alignItems: "flex-end",
3082
+ justifyContent: "center",
3083
+ flexShrink: 0
3084
+ },
3085
+ separator: {
3086
+ height: reactNative.StyleSheet.hairlineWidth,
3087
+ marginRight: 0
3088
+ },
3089
+ disabled: {
3090
+ opacity: 0.45
3091
+ }
3092
+ });
3093
+ var nativeDriver12 = reactNative.Platform.OS !== "web";
2874
3094
  function Chip({ label, selected = false, onPress, icon, iconName, style }) {
2875
3095
  const { colors } = useTheme();
2876
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
2877
- const pressAnim = React25.useRef(new reactNative.Animated.Value(selected ? 1 : 0)).current;
2878
- React25.useEffect(() => {
3096
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
3097
+ const pressAnim = React26.useRef(new reactNative.Animated.Value(selected ? 1 : 0)).current;
3098
+ React26.useEffect(() => {
2879
3099
  reactNative.Animated.timing(pressAnim, {
2880
3100
  toValue: selected ? 1 : 0,
2881
3101
  duration: 150,
@@ -2886,7 +3106,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
2886
3106
  const handlePressIn = () => {
2887
3107
  reactNative.Animated.spring(scale2, {
2888
3108
  toValue: 0.95,
2889
- useNativeDriver: nativeDriver11,
3109
+ useNativeDriver: nativeDriver12,
2890
3110
  speed: 40,
2891
3111
  bounciness: 0
2892
3112
  }).start();
@@ -2894,7 +3114,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
2894
3114
  const handlePressOut = () => {
2895
3115
  reactNative.Animated.spring(scale2, {
2896
3116
  toValue: 1,
2897
- useNativeDriver: nativeDriver11,
3117
+ useNativeDriver: nativeDriver12,
2898
3118
  speed: 40,
2899
3119
  bounciness: 4
2900
3120
  }).start();
@@ -2916,7 +3136,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
2916
3136
  outputRange: [colors.border, colors.primary]
2917
3137
  });
2918
3138
  const resolvedIcon = iconName ? renderIcon(iconName, ms(13), selected ? colors.primaryForeground : colors.foreground) : icon;
2919
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [styles26.wrapper, { transform: [{ scale: scale2 }] }, style] }, /* @__PURE__ */ React25__default.default.createElement(
3139
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: [styles27.wrapper, { transform: [{ scale: scale2 }] }, style] }, /* @__PURE__ */ React26__default.default.createElement(
2920
3140
  reactNative.TouchableOpacity,
2921
3141
  {
2922
3142
  onPress: handlePress,
@@ -2925,7 +3145,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
2925
3145
  activeOpacity: 1,
2926
3146
  touchSoundDisabled: true
2927
3147
  },
2928
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [styles26.chip, { backgroundColor, borderColor }] }, resolvedIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles26.chipIcon }, resolvedIcon) : null, /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.Text, { style: [styles26.label, { color: textColor }], allowFontScaling: true }, label))
3148
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: [styles27.chip, { backgroundColor, borderColor }] }, resolvedIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles27.chipIcon }, resolvedIcon) : null, /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.Text, { style: [styles27.label, { color: textColor }], allowFontScaling: true }, label))
2929
3149
  ));
2930
3150
  }
2931
3151
  function ChipGroup({ options, value, onValueChange, multiSelect = false, style }) {
@@ -2950,17 +3170,19 @@ function ChipGroup({ options, value, onValueChange, multiSelect = false, style }
2950
3170
  }
2951
3171
  return optionValue === value;
2952
3172
  };
2953
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles26.group, style] }, options.map((opt) => /* @__PURE__ */ React25__default.default.createElement(
3173
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles27.group, style] }, options.map((opt) => /* @__PURE__ */ React26__default.default.createElement(
2954
3174
  Chip,
2955
3175
  {
2956
3176
  key: opt.value,
2957
3177
  label: opt.label,
2958
3178
  selected: isSelected(opt.value),
2959
- onPress: () => handlePress(opt.value)
3179
+ onPress: opt.disabled ? void 0 : () => handlePress(opt.value),
3180
+ iconName: opt.iconName,
3181
+ style: opt.disabled ? { opacity: 0.4 } : void 0
2960
3182
  }
2961
3183
  )));
2962
3184
  }
2963
- var styles26 = reactNative.StyleSheet.create({
3185
+ var styles27 = reactNative.StyleSheet.create({
2964
3186
  wrapper: {},
2965
3187
  chip: {
2966
3188
  borderRadius: 999,
@@ -2998,16 +3220,16 @@ function ConfirmDialog({
2998
3220
  onCancel
2999
3221
  }) {
3000
3222
  const { colors } = useTheme();
3001
- const ref = React25.useRef(null);
3002
- React25.useEffect(() => {
3223
+ const ref = React26.useRef(null);
3224
+ React26.useEffect(() => {
3003
3225
  if (visible) {
3004
- impactLight();
3226
+ impactMedium();
3005
3227
  ref.current?.present();
3006
3228
  } else {
3007
3229
  ref.current?.dismiss();
3008
3230
  }
3009
3231
  }, [visible]);
3010
- const renderBackdrop = (props) => /* @__PURE__ */ React25__default.default.createElement(
3232
+ const renderBackdrop = (props) => /* @__PURE__ */ React26__default.default.createElement(
3011
3233
  bottomSheet.BottomSheetBackdrop,
3012
3234
  {
3013
3235
  ...props,
@@ -3016,25 +3238,28 @@ function ConfirmDialog({
3016
3238
  pressBehavior: "close"
3017
3239
  }
3018
3240
  );
3019
- return /* @__PURE__ */ React25__default.default.createElement(
3241
+ return /* @__PURE__ */ React26__default.default.createElement(
3020
3242
  bottomSheet.BottomSheetModal,
3021
3243
  {
3022
3244
  ref,
3023
3245
  enableDynamicSizing: true,
3024
3246
  onDismiss: onCancel,
3025
3247
  backdropComponent: renderBackdrop,
3026
- backgroundStyle: [styles27.background, { backgroundColor: colors.card }],
3027
- handleIndicatorStyle: [styles27.handle, { backgroundColor: colors.border }],
3248
+ backgroundStyle: [styles28.background, { backgroundColor: colors.card }],
3249
+ handleIndicatorStyle: [styles28.handle, { backgroundColor: colors.border }],
3028
3250
  enablePanDownToClose: true
3029
3251
  },
3030
- /* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetView, { style: styles27.content }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles27.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles27.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles27.actions }, /* @__PURE__ */ React25__default.default.createElement(
3252
+ /* @__PURE__ */ React26__default.default.createElement(bottomSheet.BottomSheetView, { style: styles28.content }, /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles28.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles28.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles28.actions }, /* @__PURE__ */ React26__default.default.createElement(
3031
3253
  Button,
3032
3254
  {
3033
3255
  label: confirmLabel,
3034
3256
  variant: confirmVariant,
3035
3257
  fullWidth: true,
3036
- onPress: onConfirm,
3037
- icon: /* @__PURE__ */ React25__default.default.createElement(
3258
+ onPress: () => {
3259
+ notificationSuccess();
3260
+ onConfirm();
3261
+ },
3262
+ icon: /* @__PURE__ */ React26__default.default.createElement(
3038
3263
  vectorIcons.Feather,
3039
3264
  {
3040
3265
  name: confirmVariant === "destructive" ? "trash-2" : "check",
@@ -3043,19 +3268,22 @@ function ConfirmDialog({
3043
3268
  }
3044
3269
  )
3045
3270
  }
3046
- ), /* @__PURE__ */ React25__default.default.createElement(
3271
+ ), /* @__PURE__ */ React26__default.default.createElement(
3047
3272
  Button,
3048
3273
  {
3049
3274
  label: cancelLabel,
3050
3275
  variant: "secondary",
3051
3276
  fullWidth: true,
3052
- onPress: onCancel,
3053
- icon: /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: 15, color: colors.foreground })
3277
+ onPress: () => {
3278
+ selectionAsync();
3279
+ onCancel();
3280
+ },
3281
+ icon: /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Feather, { name: "x", size: 15, color: colors.foreground })
3054
3282
  }
3055
3283
  )))
3056
3284
  );
3057
3285
  }
3058
- var styles27 = reactNative.StyleSheet.create({
3286
+ var styles28 = reactNative.StyleSheet.create({
3059
3287
  background: {
3060
3288
  borderTopLeftRadius: ms(16),
3061
3289
  borderTopRightRadius: ms(16)
@@ -3085,17 +3313,27 @@ var styles27 = reactNative.StyleSheet.create({
3085
3313
  marginTop: vs(8)
3086
3314
  }
3087
3315
  });
3088
- function LabelValue({ label, value, style }) {
3316
+ function LabelValue({ label, value, iconName, iconColor, style }) {
3089
3317
  const { colors } = useTheme();
3090
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles28.container, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles28.label, { color: colors.foregroundMuted }], allowFontScaling: true }, label), typeof value === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles28.value, { color: colors.foreground }], allowFontScaling: true }, value) : value);
3318
+ const resolvedIcon = iconName ? renderIcon(iconName, ms(14), iconColor ?? colors.foregroundMuted) : null;
3319
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles29.container, style] }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles29.labelSide }, resolvedIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles29.icon }, resolvedIcon) : null, /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles29.label, { color: colors.foregroundMuted }], allowFontScaling: true }, label)), typeof value === "string" ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles29.value, { color: colors.foreground }], allowFontScaling: true }, value) : value);
3091
3320
  }
3092
- var styles28 = reactNative.StyleSheet.create({
3321
+ var styles29 = reactNative.StyleSheet.create({
3093
3322
  container: {
3094
3323
  flexDirection: "row",
3095
3324
  justifyContent: "space-between",
3096
3325
  alignItems: "center",
3097
3326
  gap: s(12)
3098
3327
  },
3328
+ labelSide: {
3329
+ flexDirection: "row",
3330
+ alignItems: "center",
3331
+ gap: s(4)
3332
+ },
3333
+ icon: {
3334
+ alignItems: "center",
3335
+ justifyContent: "center"
3336
+ },
3099
3337
  label: {
3100
3338
  fontFamily: "Poppins-Regular",
3101
3339
  fontSize: ms(13),
@@ -3108,22 +3346,19 @@ var styles28 = reactNative.StyleSheet.create({
3108
3346
  textAlign: "right"
3109
3347
  }
3110
3348
  });
3111
- var MONTH_NAMES = [
3112
- "January",
3113
- "February",
3114
- "March",
3115
- "April",
3116
- "May",
3117
- "June",
3118
- "July",
3119
- "August",
3120
- "September",
3121
- "October",
3122
- "November",
3123
- "December"
3124
- ];
3125
- function MonthPicker({ value, onChange, style }) {
3349
+ var MONTH_NAMES = {
3350
+ en: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
3351
+ es: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"],
3352
+ pt: ["janeiro", "fevereiro", "mar\xE7o", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro"],
3353
+ fr: ["janvier", "f\xE9vrier", "mars", "avril", "mai", "juin", "juillet", "ao\xFBt", "septembre", "octobre", "novembre", "d\xE9cembre"]
3354
+ };
3355
+ function MonthPicker({ value, onChange, locale = "en", formatLabel, style }) {
3126
3356
  const { colors } = useTheme();
3357
+ const getLabel = () => {
3358
+ if (formatLabel) return formatLabel(value);
3359
+ const names = MONTH_NAMES[locale] ?? MONTH_NAMES.en;
3360
+ return `${names[value.month - 1]} ${value.year}`;
3361
+ };
3127
3362
  const handlePrev = () => {
3128
3363
  selectionAsync();
3129
3364
  if (value.month === 1) {
@@ -3140,27 +3375,27 @@ function MonthPicker({ value, onChange, style }) {
3140
3375
  onChange({ month: value.month + 1, year: value.year });
3141
3376
  }
3142
3377
  };
3143
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles29.container, style] }, /* @__PURE__ */ React25__default.default.createElement(
3378
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles30.container, style] }, /* @__PURE__ */ React26__default.default.createElement(
3144
3379
  reactNative.TouchableOpacity,
3145
3380
  {
3146
- style: styles29.arrow,
3381
+ style: styles30.arrow,
3147
3382
  onPress: handlePrev,
3148
3383
  activeOpacity: 0.6,
3149
3384
  touchSoundDisabled: true
3150
3385
  },
3151
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-left", size: 22, color: colors.foreground })
3152
- ), /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles29.label, { color: colors.foreground }], allowFontScaling: true }, MONTH_NAMES[value.month - 1], " ", value.year), /* @__PURE__ */ React25__default.default.createElement(
3386
+ /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "chevron-left", size: 22, color: colors.foreground })
3387
+ ), /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles30.label, { color: colors.foreground }], allowFontScaling: true }, getLabel()), /* @__PURE__ */ React26__default.default.createElement(
3153
3388
  reactNative.TouchableOpacity,
3154
3389
  {
3155
- style: styles29.arrow,
3390
+ style: styles30.arrow,
3156
3391
  onPress: handleNext,
3157
3392
  activeOpacity: 0.6,
3158
3393
  touchSoundDisabled: true
3159
3394
  },
3160
- /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-right", size: 22, color: colors.foreground })
3395
+ /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "chevron-right", size: 22, color: colors.foreground })
3161
3396
  ));
3162
3397
  }
3163
- var styles29 = reactNative.StyleSheet.create({
3398
+ var styles30 = reactNative.StyleSheet.create({
3164
3399
  container: {
3165
3400
  flexDirection: "row",
3166
3401
  alignItems: "center",
@@ -3181,9 +3416,9 @@ var styles29 = reactNative.StyleSheet.create({
3181
3416
  }
3182
3417
  });
3183
3418
  function useHover() {
3184
- const [hovered, setHovered] = React25.useState(false);
3185
- const onMouseEnter = React25.useCallback(() => setHovered(true), []);
3186
- const onMouseLeave = React25.useCallback(() => setHovered(false), []);
3419
+ const [hovered, setHovered] = React26.useState(false);
3420
+ const onMouseEnter = React26.useCallback(() => setHovered(true), []);
3421
+ const onMouseLeave = React26.useCallback(() => setHovered(false), []);
3187
3422
  if (reactNative.Platform.OS !== "web") {
3188
3423
  return { hovered: false, hoverHandlers: {} };
3189
3424
  }
@@ -3191,7 +3426,7 @@ function useHover() {
3191
3426
  }
3192
3427
 
3193
3428
  // src/components/MediaCard/MediaCard.tsx
3194
- var nativeDriver12 = reactNative.Platform.OS !== "web";
3429
+ var nativeDriver13 = reactNative.Platform.OS !== "web";
3195
3430
  var aspectRatioMap = {
3196
3431
  "1:1": 1,
3197
3432
  "4:3": 3 / 4,
@@ -3216,15 +3451,15 @@ function MediaCard({
3216
3451
  footer
3217
3452
  }) {
3218
3453
  const { colors } = useTheme();
3219
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
3454
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
3220
3455
  const { hovered, hoverHandlers } = useHover();
3221
3456
  const handlePressIn = () => {
3222
3457
  if (!onPress) return;
3223
- reactNative.Animated.spring(scale2, { toValue: 0.98, useNativeDriver: nativeDriver12, speed: 40, bounciness: 0 }).start();
3458
+ reactNative.Animated.spring(scale2, { toValue: 0.98, useNativeDriver: nativeDriver13, speed: 40, bounciness: 0 }).start();
3224
3459
  };
3225
3460
  const handlePressOut = () => {
3226
3461
  if (!onPress) return;
3227
- reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver12, speed: 40, bounciness: 4 }).start();
3462
+ reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver13, speed: 40, bounciness: 4 }).start();
3228
3463
  };
3229
3464
  const handlePress = () => {
3230
3465
  if (!onPress) return;
@@ -3233,27 +3468,27 @@ function MediaCard({
3233
3468
  };
3234
3469
  const ratio = aspectRatioMap[aspectRatio];
3235
3470
  const resolvedActionIcon = actionIconName ? renderIcon(actionIconName, 18, actionActive ? colors.primary : colors.background) : actionIcon ?? renderIcon("heart", 18, actionActive ? colors.primary : colors.background);
3236
- const cardContent = /* @__PURE__ */ React25__default.default.createElement(
3471
+ const cardContent = /* @__PURE__ */ React26__default.default.createElement(
3237
3472
  reactNative.View,
3238
3473
  {
3239
3474
  style: [
3240
- styles30.card,
3241
- hovered && styles30.cardHovered,
3475
+ styles31.card,
3476
+ hovered && styles31.cardHovered,
3242
3477
  style
3243
3478
  ],
3244
3479
  ...reactNative.Platform.OS === "web" ? hoverHandlers : {}
3245
3480
  },
3246
- /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles30.imageContainer, imageStyle] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: { paddingTop: `${ratio * 100}%` } }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: reactNative.StyleSheet.absoluteFill }, imageSource ? /* @__PURE__ */ React25__default.default.createElement(
3481
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles31.imageContainer, imageStyle] }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: { paddingTop: `${ratio * 100}%` } }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: reactNative.StyleSheet.absoluteFill }, imageSource ? /* @__PURE__ */ React26__default.default.createElement(
3247
3482
  reactNative.Image,
3248
3483
  {
3249
3484
  source: imageSource,
3250
- style: styles30.image,
3485
+ style: styles31.image,
3251
3486
  resizeMode: "cover"
3252
3487
  }
3253
- ) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles30.imagePlaceholder, { backgroundColor: colors.surface }] }))), badge && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles30.badgeContainer }, badge), (onActionPress || actionIcon || actionIconName) && /* @__PURE__ */ React25__default.default.createElement(
3488
+ ) : /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles31.imagePlaceholder, { backgroundColor: colors.surface }] }))), badge && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles31.badgeContainer }, badge), (onActionPress || actionIcon || actionIconName) && /* @__PURE__ */ React26__default.default.createElement(
3254
3489
  reactNative.TouchableOpacity,
3255
3490
  {
3256
- style: [styles30.actionButton, { backgroundColor: "rgba(0,0,0,0.24)" }],
3491
+ style: [styles31.actionButton, { backgroundColor: "rgba(0,0,0,0.24)" }],
3257
3492
  onPress: () => {
3258
3493
  impactLight();
3259
3494
  onActionPress?.();
@@ -3263,10 +3498,10 @@ function MediaCard({
3263
3498
  },
3264
3499
  resolvedActionIcon
3265
3500
  )),
3266
- (title || subtitle || caption || footer) && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles30.meta }, title ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles30.title, { color: colors.foreground }], numberOfLines: 2, allowFontScaling: true }, title) : null, subtitle ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles30.subtitle, { color: colors.foregroundSubtle }], numberOfLines: 1, allowFontScaling: true }, subtitle) : null, caption ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles30.caption, { color: colors.foregroundMuted }], numberOfLines: 1, allowFontScaling: true }, caption) : null, footer)
3501
+ (title || subtitle || caption || footer) && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles31.meta }, title ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles31.title, { color: colors.foreground }], numberOfLines: 2, allowFontScaling: true }, title) : null, subtitle ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles31.subtitle, { color: colors.foregroundSubtle }], numberOfLines: 1, allowFontScaling: true }, subtitle) : null, caption ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles31.caption, { color: colors.foregroundMuted }], numberOfLines: 1, allowFontScaling: true }, caption) : null, footer)
3267
3502
  );
3268
3503
  if (onPress) {
3269
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25__default.default.createElement(
3504
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React26__default.default.createElement(
3270
3505
  reactNative.TouchableOpacity,
3271
3506
  {
3272
3507
  onPress: handlePress,
@@ -3280,7 +3515,7 @@ function MediaCard({
3280
3515
  }
3281
3516
  return cardContent;
3282
3517
  }
3283
- var styles30 = reactNative.StyleSheet.create({
3518
+ var styles31 = reactNative.StyleSheet.create({
3284
3519
  card: {
3285
3520
  borderRadius: RADIUS.md,
3286
3521
  // 14px — Airbnb property card spec
@@ -3320,6 +3555,7 @@ var styles30 = reactNative.StyleSheet.create({
3320
3555
  },
3321
3556
  meta: {
3322
3557
  paddingTop: vs(8),
3558
+ paddingBottom: vs(4),
3323
3559
  gap: vs(2)
3324
3560
  },
3325
3561
  title: {
@@ -3338,29 +3574,29 @@ var styles30 = reactNative.StyleSheet.create({
3338
3574
  lineHeight: mvs(16)
3339
3575
  }
3340
3576
  });
3341
- var nativeDriver13 = reactNative.Platform.OS !== "web";
3577
+ var nativeDriver14 = reactNative.Platform.OS !== "web";
3342
3578
  function CategoryChip({
3343
3579
  item,
3344
3580
  selected,
3345
3581
  onPress
3346
3582
  }) {
3347
3583
  const { colors } = useTheme();
3348
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
3584
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
3349
3585
  const handlePressIn = () => {
3350
- reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver13, speed: 40, bounciness: 0 }).start();
3586
+ reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver14, speed: 40, bounciness: 0 }).start();
3351
3587
  };
3352
3588
  const handlePressOut = () => {
3353
- reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver13, speed: 40, bounciness: 4 }).start();
3589
+ reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver14, speed: 40, bounciness: 4 }).start();
3354
3590
  };
3355
3591
  const bgColor = selected ? colors.primary : colors.surface;
3356
3592
  const textColor = selected ? colors.primaryForeground : colors.foregroundSubtle;
3357
3593
  const borderColor = selected ? colors.primary : colors.border;
3358
3594
  const resolvedIcon = typeof item.icon === "string" ? renderIcon(item.icon, 16, textColor) : item.icon ?? null;
3359
- return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25__default.default.createElement(
3595
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React26__default.default.createElement(
3360
3596
  reactNative.TouchableOpacity,
3361
3597
  {
3362
3598
  style: [
3363
- styles31.chip,
3599
+ styles32.chip,
3364
3600
  {
3365
3601
  backgroundColor: bgColor,
3366
3602
  borderColor
@@ -3372,9 +3608,9 @@ function CategoryChip({
3372
3608
  activeOpacity: 1,
3373
3609
  touchSoundDisabled: true
3374
3610
  },
3375
- resolvedIcon && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles31.chipIcon }, resolvedIcon),
3376
- /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles31.chipLabel, { color: textColor }], allowFontScaling: true }, item.label),
3377
- item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles31.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles31.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99)))
3611
+ resolvedIcon && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles32.chipIcon }, resolvedIcon),
3612
+ /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles32.chipLabel, { color: textColor }], allowFontScaling: true }, item.label),
3613
+ item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles32.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles32.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99)))
3378
3614
  ));
3379
3615
  }
3380
3616
  function CategoryStrip({
@@ -3396,15 +3632,15 @@ function CategoryStrip({
3396
3632
  onValueChange?.(v === value ? "" : v);
3397
3633
  }
3398
3634
  };
3399
- return /* @__PURE__ */ React25__default.default.createElement(
3635
+ return /* @__PURE__ */ React26__default.default.createElement(
3400
3636
  reactNative.ScrollView,
3401
3637
  {
3402
3638
  horizontal: true,
3403
3639
  showsHorizontalScrollIndicator: false,
3404
- contentContainerStyle: [styles31.container, style],
3405
- style: styles31.scroll
3640
+ contentContainerStyle: [styles32.container, style],
3641
+ style: styles32.scroll
3406
3642
  },
3407
- categories.map((cat) => /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React25__default.default.createElement(
3643
+ categories.map((cat) => /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React26__default.default.createElement(
3408
3644
  CategoryChip,
3409
3645
  {
3410
3646
  item: cat,
@@ -3414,7 +3650,7 @@ function CategoryStrip({
3414
3650
  )))
3415
3651
  );
3416
3652
  }
3417
- var styles31 = reactNative.StyleSheet.create({
3653
+ var styles32 = reactNative.StyleSheet.create({
3418
3654
  scroll: {
3419
3655
  flexGrow: 0
3420
3656
  },
@@ -3455,7 +3691,7 @@ var styles31 = reactNative.StyleSheet.create({
3455
3691
  lineHeight: 14
3456
3692
  }
3457
3693
  });
3458
- var nativeDriver14 = reactNative.Platform.OS !== "web";
3694
+ var nativeDriver15 = reactNative.Platform.OS !== "web";
3459
3695
  function Pressable2({
3460
3696
  children,
3461
3697
  onPress,
@@ -3467,13 +3703,13 @@ function Pressable2({
3467
3703
  hoverScale = 1.02,
3468
3704
  ...touchableProps
3469
3705
  }) {
3470
- const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
3706
+ const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
3471
3707
  const { hovered, hoverHandlers } = useHover();
3472
3708
  const handlePressIn = () => {
3473
3709
  if (disabled) return;
3474
3710
  reactNative.Animated.spring(scale2, {
3475
3711
  toValue: pressScale,
3476
- useNativeDriver: nativeDriver14,
3712
+ useNativeDriver: nativeDriver15,
3477
3713
  speed: 40,
3478
3714
  bounciness: 0
3479
3715
  }).start();
@@ -3482,7 +3718,7 @@ function Pressable2({
3482
3718
  if (disabled) return;
3483
3719
  reactNative.Animated.spring(scale2, {
3484
3720
  toValue: 1,
3485
- useNativeDriver: nativeDriver14,
3721
+ useNativeDriver: nativeDriver15,
3486
3722
  speed: 40,
3487
3723
  bounciness
3488
3724
  }).start();
@@ -3493,7 +3729,7 @@ function Pressable2({
3493
3729
  onPress();
3494
3730
  };
3495
3731
  const hoverScaleValue = hovered && hoverScale !== 1 ? hoverScale : 1;
3496
- return /* @__PURE__ */ React25__default.default.createElement(
3732
+ return /* @__PURE__ */ React26__default.default.createElement(
3497
3733
  reactNative.Animated.View,
3498
3734
  {
3499
3735
  style: [
@@ -3502,7 +3738,7 @@ function Pressable2({
3502
3738
  ],
3503
3739
  ...reactNative.Platform.OS === "web" ? hoverHandlers : {}
3504
3740
  },
3505
- /* @__PURE__ */ React25__default.default.createElement(
3741
+ /* @__PURE__ */ React26__default.default.createElement(
3506
3742
  reactNative.TouchableOpacity,
3507
3743
  {
3508
3744
  onPress: handlePress,
@@ -3517,17 +3753,123 @@ function Pressable2({
3517
3753
  )
3518
3754
  );
3519
3755
  }
3756
+ var weightMap = {
3757
+ normal: "Poppins-Regular",
3758
+ medium: "Poppins-Medium",
3759
+ semibold: "Poppins-SemiBold",
3760
+ bold: "Poppins-Bold"
3761
+ };
3762
+ function DetailRow({
3763
+ label,
3764
+ value,
3765
+ separator = "dotted",
3766
+ labelWeight = "normal",
3767
+ valueColor,
3768
+ leftIcon,
3769
+ leftIconName,
3770
+ leftIconColor,
3771
+ rightIconName,
3772
+ rightIconColor,
3773
+ style,
3774
+ labelStyle,
3775
+ valueStyle
3776
+ }) {
3777
+ const { colors } = useTheme();
3778
+ const resolvedLeftIcon = leftIconName ? renderIcon(leftIconName, ms(14), leftIconColor ?? colors.foregroundMuted) : leftIcon;
3779
+ const resolvedRightIcon = rightIconName ? renderIcon(rightIconName, ms(14), rightIconColor ?? colors.foregroundMuted) : null;
3780
+ const separatorStyle = separator === "none" ? null : {
3781
+ flex: 1,
3782
+ height: 1,
3783
+ borderBottomWidth: 1,
3784
+ borderStyle: separator,
3785
+ borderColor: "rgba(128,128,128,0.3)",
3786
+ marginHorizontal: s(4)
3787
+ };
3788
+ return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles33.row, style] }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles33.labelSide }, resolvedLeftIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles33.icon }, resolvedLeftIcon) : null, typeof label === "string" ? /* @__PURE__ */ React26__default.default.createElement(
3789
+ reactNative.Text,
3790
+ {
3791
+ style: [styles33.labelText, { color: colors.foregroundMuted, fontFamily: weightMap[labelWeight] }, labelStyle],
3792
+ allowFontScaling: true
3793
+ },
3794
+ label
3795
+ ) : label), separatorStyle ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: separatorStyle }) : /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles33.spacer }), /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles33.valueSide }, /* @__PURE__ */ React26__default.default.createElement(
3796
+ reactNative.Text,
3797
+ {
3798
+ style: [styles33.valueText, { color: valueColor ?? colors.foreground }, valueStyle],
3799
+ allowFontScaling: true
3800
+ },
3801
+ value
3802
+ ), resolvedRightIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles33.icon }, resolvedRightIcon) : null));
3803
+ }
3804
+ var styles33 = reactNative.StyleSheet.create({
3805
+ row: {
3806
+ flexDirection: "row",
3807
+ alignItems: "center",
3808
+ gap: s(4)
3809
+ },
3810
+ labelSide: {
3811
+ flexDirection: "row",
3812
+ alignItems: "center",
3813
+ gap: s(4),
3814
+ flexShrink: 0
3815
+ },
3816
+ icon: {
3817
+ alignItems: "center",
3818
+ justifyContent: "center"
3819
+ },
3820
+ spacer: {
3821
+ flex: 1
3822
+ },
3823
+ labelText: {
3824
+ fontSize: ms(13),
3825
+ lineHeight: mvs(18)
3826
+ },
3827
+ valueSide: {
3828
+ flexDirection: "row",
3829
+ alignItems: "center",
3830
+ gap: s(4),
3831
+ flexShrink: 0
3832
+ },
3833
+ valueText: {
3834
+ fontFamily: "Poppins-SemiBold",
3835
+ fontSize: ms(13),
3836
+ lineHeight: mvs(18)
3837
+ }
3838
+ });
3839
+
3840
+ // src/utils/typography.ts
3841
+ function getResponsiveFontSize(text, maxSize, steps = [
3842
+ { maxLen: 10, subtract: 0 },
3843
+ { maxLen: 12, subtract: 4 },
3844
+ { maxLen: 14, subtract: 6 }
3845
+ ]) {
3846
+ const len = text.length;
3847
+ const sorted = [...steps].sort((a, b) => a.maxLen - b.maxLen);
3848
+ for (const step of sorted) {
3849
+ if (len <= step.maxLen) return maxSize - step.subtract;
3850
+ }
3851
+ return maxSize - 8;
3852
+ }
3520
3853
 
3521
3854
  Object.defineProperty(exports, "BottomSheetModalProvider", {
3522
3855
  enumerable: true,
3523
3856
  get: function () { return bottomSheet.BottomSheetModalProvider; }
3524
3857
  });
3858
+ Object.defineProperty(exports, "SheetTextInput", {
3859
+ enumerable: true,
3860
+ get: function () { return bottomSheet.BottomSheetTextInput; }
3861
+ });
3862
+ Object.defineProperty(exports, "toast", {
3863
+ enumerable: true,
3864
+ get: function () { return sonnerNative.toast; }
3865
+ });
3525
3866
  exports.Accordion = Accordion;
3526
3867
  exports.AlertBanner = AlertBanner;
3527
3868
  exports.Avatar = Avatar;
3528
3869
  exports.BREAKPOINTS = BREAKPOINTS;
3529
3870
  exports.Badge = Badge;
3530
3871
  exports.Button = Button;
3872
+ exports.ButtonGroup = ButtonGroup;
3531
3873
  exports.Card = Card;
3532
3874
  exports.CardContent = CardContent;
3533
3875
  exports.CardDescription = CardDescription;
@@ -3542,6 +3884,7 @@ exports.ConfirmDialog = ConfirmDialog;
3542
3884
  exports.CurrencyDisplay = CurrencyDisplay;
3543
3885
  exports.CurrencyInput = CurrencyInput;
3544
3886
  exports.CurrencyInputLarge = CurrencyInput;
3887
+ exports.DetailRow = DetailRow;
3545
3888
  exports.EmptyState = EmptyState;
3546
3889
  exports.ICON_SIZES = ICON_SIZES;
3547
3890
  exports.Icon = Icon;
@@ -3550,6 +3893,7 @@ exports.Input = Input;
3550
3893
  exports.LabelValue = LabelValue;
3551
3894
  exports.ListItem = ListItem;
3552
3895
  exports.MediaCard = MediaCard;
3896
+ exports.MenuItem = MenuItem;
3553
3897
  exports.MonthPicker = MonthPicker;
3554
3898
  exports.Pressable = Pressable2;
3555
3899
  exports.Progress = Progress;
@@ -3575,6 +3919,7 @@ exports.Toggle = Toggle;
3575
3919
  exports.defaultDark = defaultDark;
3576
3920
  exports.defaultLight = defaultLight;
3577
3921
  exports.deriveColors = deriveColors;
3922
+ exports.getResponsiveFontSize = getResponsiveFontSize;
3578
3923
  exports.renderIcon = renderIcon;
3579
3924
  exports.useTheme = useTheme;
3580
3925
  exports.useToast = useToast;