@blinkdotnew/mobile-ui 2.0.0-alpha.9 → 2.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.
package/dist/index.mjs CHANGED
@@ -7,66 +7,283 @@ var blinkConfig = createTamagui({
7
7
 
8
8
  // src/index.ts
9
9
  import { defaultConfig as defaultConfig2 } from "@tamagui/config/v5";
10
+
11
+ // src/config/design-themes.ts
12
+ var BLINK_DESIGN_THEMES = {
13
+ "mono": {
14
+ id: "mono",
15
+ name: "Mono",
16
+ description: "Black/white neutral",
17
+ palette: { primary: "#18181B", primary_foreground: "#FAFAFA", secondary: "#F4F4F5", secondary_foreground: "#27272A", accent: "#3F3F46", background: "#FFFFFF", dark_mode: "#09090B" }
18
+ },
19
+ "ocean-teal": {
20
+ id: "ocean-teal",
21
+ name: "Ocean Teal",
22
+ description: "SaaS, fintech, healthcare",
23
+ palette: { primary: "#0D9488", primary_foreground: "#FFFFFF", secondary: "#F0FDFA", secondary_foreground: "#134E4A", accent: "#2DD4BF", background: "#FFFFFF", dark_mode: "#042F2E" }
24
+ },
25
+ "warm-amber": {
26
+ id: "warm-amber",
27
+ name: "Warm Amber",
28
+ description: "E-commerce, food, hospitality",
29
+ palette: { primary: "#D97706", primary_foreground: "#FFFFFF", secondary: "#FFFBEB", secondary_foreground: "#78350F", accent: "#FBBF24", background: "#FFFEF7", dark_mode: "#451A03" }
30
+ },
31
+ "rose-coral": {
32
+ id: "rose-coral",
33
+ name: "Rose Coral",
34
+ description: "Lifestyle, beauty, fashion",
35
+ palette: { primary: "#E11D48", primary_foreground: "#FFFFFF", secondary: "#FFF1F2", secondary_foreground: "#881337", accent: "#FB7185", background: "#FFFAFA", dark_mode: "#4C0519" }
36
+ },
37
+ "lavender": {
38
+ id: "lavender",
39
+ name: "Lavender",
40
+ description: "Creative, wellness, meditation",
41
+ palette: { primary: "#7C3AED", primary_foreground: "#FFFFFF", secondary: "#F5F3FF", secondary_foreground: "#4C1D95", accent: "#A78BFA", background: "#FEFEFF", dark_mode: "#2E1065" }
42
+ },
43
+ "glacier": {
44
+ id: "glacier",
45
+ name: "Glacier",
46
+ description: "Professional, corporate, analytics",
47
+ palette: { primary: "#0EA5E9", primary_foreground: "#FFFFFF", secondary: "#F0F9FF", secondary_foreground: "#0C4A6E", accent: "#38BDF8", background: "#FFFFFF", dark_mode: "#082F49" }
48
+ },
49
+ "forest": {
50
+ id: "forest",
51
+ name: "Forest",
52
+ description: "Sustainability, nature, outdoor",
53
+ palette: { primary: "#16A34A", primary_foreground: "#FFFFFF", secondary: "#F0FDF4", secondary_foreground: "#14532D", accent: "#4ADE80", background: "#FEFFFE", dark_mode: "#052E16" }
54
+ },
55
+ "obsidian": {
56
+ id: "obsidian",
57
+ name: "Obsidian",
58
+ description: "Developer tools, gaming, tech",
59
+ palette: { primary: "#475569", primary_foreground: "#FFFFFF", secondary: "#F1F5F9", secondary_foreground: "#1E293B", accent: "#64748B", background: "#FFFFFF", dark_mode: "#0F172A" }
60
+ },
61
+ "solar": {
62
+ id: "solar",
63
+ name: "Solar",
64
+ description: "Energy, optimistic, kid-friendly",
65
+ palette: { primary: "#CA8A04", primary_foreground: "#FFFFFF", secondary: "#FEFCE8", secondary_foreground: "#713F12", accent: "#FACC15", background: "#FFFEF5", dark_mode: "#422006" }
66
+ },
67
+ "orchid": {
68
+ id: "orchid",
69
+ name: "Orchid",
70
+ description: "Beauty, fashion, luxury",
71
+ palette: { primary: "#C026D3", primary_foreground: "#FFFFFF", secondary: "#FDF4FF", secondary_foreground: "#701A75", accent: "#E879F9", background: "#FFFEFF", dark_mode: "#4A044E" }
72
+ },
73
+ "indigo": {
74
+ id: "indigo",
75
+ name: "Indigo",
76
+ description: "Enterprise, fintech, trust",
77
+ palette: { primary: "#4F46E5", primary_foreground: "#FFFFFF", secondary: "#EEF2FF", secondary_foreground: "#312E81", accent: "#818CF8", background: "#FEFEFF", dark_mode: "#1E1B4B" }
78
+ },
79
+ "cosmic-night": {
80
+ id: "cosmic-night",
81
+ name: "Cosmic Night",
82
+ description: "Dark mode, futuristic, gaming",
83
+ palette: { primary: "#6366F1", primary_foreground: "#FFFFFF", secondary: "#1E1B4B", secondary_foreground: "#E0E7FF", accent: "#A855F7", background: "#0F0D1A", dark_mode: "#030014" }
84
+ },
85
+ "soft-pop": {
86
+ id: "soft-pop",
87
+ name: "Soft Pop",
88
+ description: "Playful, modern, creative",
89
+ palette: { primary: "#14B8A6", primary_foreground: "#FFFFFF", secondary: "#FDF2F8", secondary_foreground: "#134E4A", accent: "#F472B6", background: "#FFFBFE", dark_mode: "#0D1117" }
90
+ },
91
+ "neo-brutalism": {
92
+ id: "neo-brutalism",
93
+ name: "Neo Brutalism",
94
+ description: "Bold, striking, artistic",
95
+ palette: { primary: "#FF6B35", primary_foreground: "#000000", secondary: "#FFE66D", secondary_foreground: "#1A1A1A", accent: "#FF3366", background: "#FFFEF0", dark_mode: "#1A1A1A" }
96
+ },
97
+ "vintage-paper": {
98
+ id: "vintage-paper",
99
+ name: "Vintage Paper",
100
+ description: "Classic, warm, nostalgic",
101
+ palette: { primary: "#B45309", primary_foreground: "#FFFFFF", secondary: "#FEF3C7", secondary_foreground: "#78350F", accent: "#92400E", background: "#FFFDF7", dark_mode: "#292524" }
102
+ },
103
+ "modern-minimal": {
104
+ id: "modern-minimal",
105
+ name: "Modern Minimal",
106
+ description: "Clean, professional, corporate",
107
+ palette: { primary: "#2563EB", primary_foreground: "#FFFFFF", secondary: "#F8FAFC", secondary_foreground: "#1E40AF", accent: "#3B82F6", background: "#FFFFFF", dark_mode: "#0F172A" }
108
+ },
109
+ "bubblegum": {
110
+ id: "bubblegum",
111
+ name: "Bubblegum",
112
+ description: "Fun, feminine, youthful",
113
+ palette: { primary: "#EC4899", primary_foreground: "#FFFFFF", secondary: "#FDF4FF", secondary_foreground: "#9D174D", accent: "#F472B6", background: "#FFFBFF", dark_mode: "#500724" }
114
+ }
115
+ };
116
+ function hexToRgb(hex) {
117
+ const h = hex.replace("#", "");
118
+ return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];
119
+ }
120
+ function rgbToHex(r, g, b) {
121
+ return "#" + [r, g, b].map((v) => Math.round(Math.max(0, Math.min(255, v))).toString(16).padStart(2, "0")).join("");
122
+ }
123
+ function mixColors(c1, c2, t) {
124
+ const [r1, g1, b1] = hexToRgb(c1);
125
+ const [r2, g2, b2] = hexToRgb(c2);
126
+ return rgbToHex(r1 + (r2 - r1) * t, g1 + (g2 - g1) * t, b1 + (b2 - b1) * t);
127
+ }
128
+ function generateLightPalette(p) {
129
+ return [
130
+ p.background,
131
+ p.secondary,
132
+ mixColors(p.secondary, p.accent, 0.15),
133
+ mixColors(p.secondary, p.accent, 0.3),
134
+ mixColors(p.accent, p.primary, 0.1),
135
+ mixColors(p.accent, p.primary, 0.3),
136
+ mixColors(p.accent, p.primary, 0.5),
137
+ mixColors(p.accent, p.primary, 0.7),
138
+ p.primary,
139
+ mixColors(p.primary, p.secondary_foreground, 0.3),
140
+ p.secondary_foreground,
141
+ p.dark_mode
142
+ ];
143
+ }
144
+ function generateDarkPalette(p) {
145
+ return [
146
+ p.dark_mode,
147
+ mixColors(p.dark_mode, p.secondary_foreground, 0.15),
148
+ mixColors(p.dark_mode, p.secondary_foreground, 0.25),
149
+ mixColors(p.dark_mode, p.secondary_foreground, 0.35),
150
+ mixColors(p.secondary_foreground, p.accent, 0.2),
151
+ mixColors(p.secondary_foreground, p.accent, 0.4),
152
+ mixColors(p.secondary_foreground, p.accent, 0.6),
153
+ mixColors(p.accent, p.primary, 0.5),
154
+ p.primary,
155
+ p.accent,
156
+ mixColors(p.accent, p.primary_foreground, 0.5),
157
+ p.primary_foreground
158
+ ];
159
+ }
160
+ function getBlinkThemePalettes(themeId) {
161
+ const theme = BLINK_DESIGN_THEMES[themeId];
162
+ if (!theme) throw new Error(`Unknown theme: ${themeId}`);
163
+ const p = theme.palette;
164
+ return {
165
+ base: {
166
+ light: generateLightPalette(p),
167
+ dark: generateDarkPalette(p)
168
+ },
169
+ accent: {
170
+ light: generateDarkPalette(p),
171
+ dark: generateLightPalette(p)
172
+ }
173
+ };
174
+ }
175
+ var BLINK_DESIGN_THEME_IDS = Object.keys(BLINK_DESIGN_THEMES);
176
+ function getBlinkDesignTheme(themeId) {
177
+ return BLINK_DESIGN_THEMES[themeId];
178
+ }
179
+
180
+ // src/index.ts
10
181
  import {
11
- View as View6,
12
- XStack as XStack27,
13
- YStack as YStack32,
182
+ View as View7,
183
+ Stack,
184
+ SizableStack,
185
+ ThemeableStack,
186
+ Frame,
187
+ XStack as XStack44,
188
+ YStack as YStack49,
14
189
  ZStack,
15
- ScrollView as ScrollView5,
16
- Circle as Circle8,
190
+ ScrollView as ScrollView6,
191
+ Circle as Circle12,
17
192
  Square,
193
+ Spacer,
194
+ EnsureFlexed,
195
+ Group,
18
196
  XGroup,
19
197
  YGroup,
198
+ Header,
199
+ Footer,
200
+ Main,
201
+ Nav,
202
+ Article,
203
+ Aside,
20
204
  H1 as H12,
21
205
  H2 as H22,
22
206
  H3 as H32,
23
207
  H4 as H42,
24
208
  H5 as H52,
25
209
  H6 as H62,
210
+ Heading,
26
211
  Paragraph,
27
- SizableText as SizableText34,
212
+ SizableText as SizableText51,
28
213
  Text,
29
214
  Label,
30
- Button as Button8,
31
- Input as Input3,
215
+ Button as Button13,
216
+ Input as Input5,
32
217
  TextArea,
33
- Switch as Switch2,
218
+ Switch as Switch3,
34
219
  Checkbox,
35
- Slider,
220
+ Slider as Slider2,
36
221
  RadioGroup,
37
- Select,
222
+ Select as Select2,
38
223
  Fieldset,
224
+ Form,
39
225
  Card as Card2,
40
226
  Avatar as Avatar2,
41
- Separator as Separator5,
42
- Image as Image6,
227
+ Separator as Separator7,
228
+ Image as Image9,
43
229
  Progress,
44
230
  Spinner as Spinner2,
45
231
  ListItem as ListItem2,
46
- Sheet as Sheet3,
47
- Dialog,
48
- AlertDialog as AlertDialog2,
49
- Popover as Popover2,
232
+ Anchor,
233
+ Sheet as Sheet5,
234
+ Dialog as Dialog2,
235
+ AlertDialog as AlertDialog3,
236
+ Popover as Popover3,
50
237
  Tooltip,
51
238
  TooltipSimple,
239
+ Portal,
240
+ PortalHost,
241
+ PortalItem,
242
+ PortalProvider,
52
243
  Tabs,
53
244
  Accordion,
54
245
  ToggleGroup,
55
- Adapt,
56
- PortalProvider,
246
+ AnimatePresence,
247
+ Adapt as Adapt4,
57
248
  VisuallyHidden,
58
249
  Unspaced,
59
- Anchor,
60
- Form,
61
- Theme,
250
+ Theme as Theme2,
62
251
  TamaguiProvider,
63
252
  TamaguiProvider as TamaguiProvider2,
64
253
  createTamagui as createTamagui2,
65
- styled as styled12,
254
+ createFont,
255
+ createMedia,
256
+ createTheme,
257
+ createTokens,
258
+ createVariable,
259
+ createStyledContext,
260
+ addTheme,
261
+ updateTheme,
262
+ replaceTheme,
263
+ styled as styled14,
66
264
  withStaticProperties as withStaticProperties2,
265
+ isWeb,
266
+ isClient,
267
+ getConfig,
268
+ getToken,
269
+ getTokens,
270
+ getTokenValue,
271
+ composeRefs,
272
+ composeEventHandlers,
67
273
  useTheme,
68
- useMedia,
69
- useThemeName
274
+ useMedia as useMedia2,
275
+ useThemeName,
276
+ useControllableState,
277
+ useEvent,
278
+ useForceUpdate,
279
+ useIsomorphicLayoutEffect,
280
+ useComposedRefs,
281
+ useWindowDimensions,
282
+ useDidFinishSSR,
283
+ useDebounce,
284
+ useDebounceValue,
285
+ usePresence,
286
+ useIsPresent
70
287
  } from "tamagui";
71
288
 
72
289
  // src/primitives/Button.tsx
@@ -856,17 +1073,43 @@ function BlinkTooltip({ content, children, side = "top" }) {
856
1073
  ] });
857
1074
  }
858
1075
 
1076
+ // src/interface/BrandIcons.tsx
1077
+ import Svg, { Path, Rect } from "react-native-svg";
1078
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
1079
+ function GoogleLogo({ size = 20 }) {
1080
+ return /* @__PURE__ */ jsxs8(Svg, { width: size, height: size, viewBox: "0 0 24 24", children: [
1081
+ /* @__PURE__ */ jsx13(Path, { fill: "#4285F4", d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" }),
1082
+ /* @__PURE__ */ jsx13(Path, { fill: "#34A853", d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" }),
1083
+ /* @__PURE__ */ jsx13(Path, { fill: "#FBBC05", d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l3.66-2.84z" }),
1084
+ /* @__PURE__ */ jsx13(Path, { fill: "#EA4335", d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" })
1085
+ ] });
1086
+ }
1087
+ function AppleLogo({ size = 20, color = "#000" }) {
1088
+ return /* @__PURE__ */ jsx13(Svg, { width: size, height: size, viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx13(Path, { fill: color, d: "M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z" }) });
1089
+ }
1090
+ function GitHubLogo({ size = 20, color = "#fff" }) {
1091
+ return /* @__PURE__ */ jsx13(Svg, { width: size, height: size, viewBox: "0 0 98 96", children: /* @__PURE__ */ jsx13(Path, { fillRule: "evenodd", clipRule: "evenodd", fill: color, d: "M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" }) });
1092
+ }
1093
+ function MicrosoftLogo({ size = 20 }) {
1094
+ return /* @__PURE__ */ jsxs8(Svg, { width: size, height: size, viewBox: "0 0 21 21", children: [
1095
+ /* @__PURE__ */ jsx13(Rect, { width: "10", height: "10", fill: "#F25022" }),
1096
+ /* @__PURE__ */ jsx13(Rect, { x: "11", width: "10", height: "10", fill: "#7FBA00" }),
1097
+ /* @__PURE__ */ jsx13(Rect, { y: "11", width: "10", height: "10", fill: "#00A4EF" }),
1098
+ /* @__PURE__ */ jsx13(Rect, { x: "11", y: "11", width: "10", height: "10", fill: "#FFB900" })
1099
+ ] });
1100
+ }
1101
+
859
1102
  // src/layouts/StepPageLayout.tsx
860
1103
  import { SizableText as SizableText13, YStack as YStack7 } from "tamagui";
861
- import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
1104
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
862
1105
  function StepPageLayout({ title, description, children, bottom }) {
863
- return /* @__PURE__ */ jsxs8(YStack7, { flex: 1, padding: "$4", maxWidth: 500, marginHorizontal: "auto", width: "100%", children: [
864
- /* @__PURE__ */ jsx13(YStack7, { gap: "$5", children: /* @__PURE__ */ jsxs8(YStack7, { gap: "$2", children: [
865
- /* @__PURE__ */ jsx13(SizableText13, { size: "$8", fontWeight: "700", children: title }),
866
- description && /* @__PURE__ */ jsx13(SizableText13, { size: "$5", fontWeight: "400", color: "$color10", children: description })
1106
+ return /* @__PURE__ */ jsxs9(YStack7, { flex: 1, padding: "$4", maxWidth: 500, marginHorizontal: "auto", width: "100%", children: [
1107
+ /* @__PURE__ */ jsx14(YStack7, { gap: "$5", children: /* @__PURE__ */ jsxs9(YStack7, { gap: "$2", children: [
1108
+ /* @__PURE__ */ jsx14(SizableText13, { size: "$8", fontWeight: "700", children: title }),
1109
+ description && /* @__PURE__ */ jsx14(SizableText13, { size: "$5", fontWeight: "400", color: "$color10", children: description })
867
1110
  ] }) }),
868
- /* @__PURE__ */ jsx13(YStack7, { paddingTop: "$5", gap: "$4", children }),
869
- bottom && /* @__PURE__ */ jsx13(YStack7, { paddingTop: "$4", children: bottom })
1111
+ /* @__PURE__ */ jsx14(YStack7, { paddingTop: "$5", gap: "$4", children }),
1112
+ bottom && /* @__PURE__ */ jsx14(YStack7, { paddingTop: "$4", children: bottom })
870
1113
  ] });
871
1114
  }
872
1115
 
@@ -891,12 +1134,12 @@ var ScreenLayout = styled10(YStack8, {
891
1134
 
892
1135
  // src/layouts/Section.tsx
893
1136
  import { SizableText as SizableText14, YStack as YStack9 } from "tamagui";
894
- import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
1137
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
895
1138
  function Section({ title, description, children, gap = "$3" }) {
896
- return /* @__PURE__ */ jsxs9(YStack9, { gap, children: [
897
- title && /* @__PURE__ */ jsxs9(YStack9, { gap: "$1", children: [
898
- /* @__PURE__ */ jsx14(SizableText14, { size: "$5", fontWeight: "600", color: "$color12", children: title }),
899
- description && /* @__PURE__ */ jsx14(SizableText14, { size: "$3", color: "$color9", children: description })
1139
+ return /* @__PURE__ */ jsxs10(YStack9, { gap, children: [
1140
+ title && /* @__PURE__ */ jsxs10(YStack9, { gap: "$1", children: [
1141
+ /* @__PURE__ */ jsx15(SizableText14, { size: "$5", fontWeight: "600", color: "$color12", children: title }),
1142
+ description && /* @__PURE__ */ jsx15(SizableText14, { size: "$3", color: "$color9", children: description })
900
1143
  ] }),
901
1144
  children
902
1145
  ] });
@@ -904,7 +1147,7 @@ function Section({ title, description, children, gap = "$3" }) {
904
1147
 
905
1148
  // src/layouts/ListItem.tsx
906
1149
  import { styled as styled11, SizableText as SizableText15, XStack as XStack7, YStack as YStack10, View as View5 } from "tamagui";
907
- import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
1150
+ import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
908
1151
  var ListItemFrame = styled11(XStack7, {
909
1152
  name: "BlinkListItem",
910
1153
  alignItems: "center",
@@ -922,11 +1165,11 @@ var ListItemFrame = styled11(XStack7, {
922
1165
  }
923
1166
  });
924
1167
  function ListItem({ icon, title, subtitle, right, onPress }) {
925
- return /* @__PURE__ */ jsxs10(ListItemFrame, { pressable: !!onPress, onPress, children: [
926
- icon && /* @__PURE__ */ jsx15(View5, { children: icon }),
927
- /* @__PURE__ */ jsxs10(YStack10, { flex: 1, gap: "$1", children: [
928
- /* @__PURE__ */ jsx15(SizableText15, { size: "$4", fontWeight: "500", color: "$color12", children: title }),
929
- subtitle && /* @__PURE__ */ jsx15(SizableText15, { size: "$2", color: "$color9", children: subtitle })
1168
+ return /* @__PURE__ */ jsxs11(ListItemFrame, { pressable: !!onPress, onPress, children: [
1169
+ icon && /* @__PURE__ */ jsx16(View5, { children: icon }),
1170
+ /* @__PURE__ */ jsxs11(YStack10, { flex: 1, gap: "$1", children: [
1171
+ /* @__PURE__ */ jsx16(SizableText15, { size: "$4", fontWeight: "500", color: "$color12", children: title }),
1172
+ subtitle && /* @__PURE__ */ jsx16(SizableText15, { size: "$2", color: "$color9", children: subtitle })
930
1173
  ] }),
931
1174
  right
932
1175
  ] });
@@ -934,28 +1177,28 @@ function ListItem({ icon, title, subtitle, right, onPress }) {
934
1177
 
935
1178
  // src/layouts/Divider.tsx
936
1179
  import { Separator as Separator3, SizableText as SizableText16, XStack as XStack8 } from "tamagui";
937
- import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
1180
+ import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
938
1181
  function Divider({ label }) {
939
- if (!label) return /* @__PURE__ */ jsx16(Separator3, { borderColor: "$color4" });
940
- return /* @__PURE__ */ jsxs11(XStack8, { alignItems: "center", gap: "$3", children: [
941
- /* @__PURE__ */ jsx16(Separator3, { flex: 1, borderColor: "$color4" }),
942
- /* @__PURE__ */ jsx16(SizableText16, { size: "$2", color: "$color9", children: label }),
943
- /* @__PURE__ */ jsx16(Separator3, { flex: 1, borderColor: "$color4" })
1182
+ if (!label) return /* @__PURE__ */ jsx17(Separator3, { borderColor: "$color4" });
1183
+ return /* @__PURE__ */ jsxs12(XStack8, { alignItems: "center", gap: "$3", children: [
1184
+ /* @__PURE__ */ jsx17(Separator3, { flex: 1, borderColor: "$color4" }),
1185
+ /* @__PURE__ */ jsx17(SizableText16, { size: "$2", color: "$color9", children: label }),
1186
+ /* @__PURE__ */ jsx17(Separator3, { flex: 1, borderColor: "$color4" })
944
1187
  ] });
945
1188
  }
946
1189
 
947
1190
  // src/layouts/KeyboardStickyFooter.tsx
948
1191
  import { YStack as YStack11 } from "tamagui";
949
- import { jsx as jsx17 } from "react/jsx-runtime";
1192
+ import { jsx as jsx18 } from "react/jsx-runtime";
950
1193
  function KeyboardStickyFooter({ children, offset }) {
951
- return /* @__PURE__ */ jsx17(YStack11, { maxWidth: 500, alignSelf: "center", paddingTop: "$8", paddingBottom: "$4", style: { paddingBottom: offset }, children });
1194
+ return /* @__PURE__ */ jsx18(YStack11, { maxWidth: 500, alignSelf: "center", paddingTop: "$8", paddingBottom: "$4", style: { paddingBottom: offset }, children });
952
1195
  }
953
1196
 
954
1197
  // src/layouts/SafeArea.tsx
955
1198
  import { YStack as YStack12 } from "tamagui";
956
- import { jsx as jsx18 } from "react/jsx-runtime";
1199
+ import { jsx as jsx19 } from "react/jsx-runtime";
957
1200
  function SafeArea({ children, edges = ["top", "bottom"] }) {
958
- return /* @__PURE__ */ jsx18(
1201
+ return /* @__PURE__ */ jsx19(
959
1202
  YStack12,
960
1203
  {
961
1204
  flex: 1,
@@ -972,149 +1215,347 @@ function SafeArea({ children, edges = ["top", "bottom"] }) {
972
1215
  // src/layouts/Grid.tsx
973
1216
  import { Children } from "react";
974
1217
  import { XStack as XStack9, YStack as YStack13 } from "tamagui";
975
- import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
1218
+ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
976
1219
  function Grid({ children, columns = 2, gap = "$3" }) {
977
1220
  const items = Children.toArray(children);
978
1221
  const rows = [];
979
1222
  for (let i = 0; i < items.length; i += columns) {
980
1223
  rows.push(items.slice(i, i + columns));
981
1224
  }
982
- return /* @__PURE__ */ jsx19(YStack13, { gap, children: rows.map((row, ri) => /* @__PURE__ */ jsxs12(XStack9, { gap, children: [
983
- row.map((item, ci) => /* @__PURE__ */ jsx19(YStack13, { flex: 1, children: item }, ci)),
984
- row.length < columns && Array.from({ length: columns - row.length }).map((_, i) => /* @__PURE__ */ jsx19(YStack13, { flex: 1 }, `pad-${i}`))
1225
+ return /* @__PURE__ */ jsx20(YStack13, { gap, children: rows.map((row, ri) => /* @__PURE__ */ jsxs13(XStack9, { gap, children: [
1226
+ row.map((item, ci) => /* @__PURE__ */ jsx20(YStack13, { flex: 1, children: item }, ci)),
1227
+ row.length < columns && Array.from({ length: columns - row.length }).map((_, i) => /* @__PURE__ */ jsx20(YStack13, { flex: 1 }, `pad-${i}`))
985
1228
  ] }, ri)) });
986
1229
  }
987
1230
  function Container({ children, maxWidth = 500, centered = true, padding = "$4" }) {
988
- return /* @__PURE__ */ jsx19(YStack13, { width: "100%", maxWidth, alignSelf: centered ? "center" : void 0, padding, children });
1231
+ return /* @__PURE__ */ jsx20(YStack13, { width: "100%", maxWidth, alignSelf: centered ? "center" : void 0, padding, children });
989
1232
  }
990
1233
 
991
1234
  // src/patterns/PaywallScreen.tsx
992
- import { Button as Button3, SizableText as SizableText17, XStack as XStack10, YStack as YStack14, Circle as Circle2 } from "tamagui";
993
- import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1235
+ import { useState as useState5, useEffect as useEffect3 } from "react";
1236
+ import { Button as Button3, Circle as Circle2, SizableText as SizableText17, XStack as XStack10, YStack as YStack14, ScrollView as ScrollView2 } from "tamagui";
1237
+ import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
1238
+ function useCountdown(minutes) {
1239
+ const [seconds, setSeconds] = useState5((minutes ?? 0) * 60);
1240
+ useEffect3(() => {
1241
+ if (!minutes) return;
1242
+ setSeconds(minutes * 60);
1243
+ const id = setInterval(() => setSeconds((s) => s > 0 ? s - 1 : 0), 1e3);
1244
+ return () => clearInterval(id);
1245
+ }, [minutes]);
1246
+ const mm = String(Math.floor(seconds / 60)).padStart(2, "0");
1247
+ const ss = String(seconds % 60).padStart(2, "0");
1248
+ return { display: `${mm}:${ss}`, expired: seconds <= 0 };
1249
+ }
1250
+ function normalizeFeature(f) {
1251
+ return typeof f === "string" ? { title: f } : f;
1252
+ }
1253
+ function BenefitRow({ feature, tone, muted }) {
1254
+ const f = normalizeFeature(feature);
1255
+ return /* @__PURE__ */ jsxs14(XStack10, { gap: "$3", alignItems: "center", children: [
1256
+ /* @__PURE__ */ jsx21(Circle2, { size: 40, backgroundColor: "$color3", children: f.icon ?? /* @__PURE__ */ jsx21(SizableText17, { size: "$5", color: "$color9", children: "\u2726" }) }),
1257
+ /* @__PURE__ */ jsxs14(YStack14, { flex: 1, gap: "$0.5", children: [
1258
+ /* @__PURE__ */ jsx21(SizableText17, { size: "$4", fontWeight: "700", color: tone, children: f.title }),
1259
+ f.description ? /* @__PURE__ */ jsx21(SizableText17, { size: "$2", color: muted, children: f.description }) : null
1260
+ ] })
1261
+ ] });
1262
+ }
1263
+ function PlanRow({ plan, selected, onPress }) {
1264
+ return /* @__PURE__ */ jsxs14(
1265
+ XStack10,
1266
+ {
1267
+ width: "100%",
1268
+ padding: "$3",
1269
+ paddingHorizontal: "$3.5",
1270
+ borderRadius: "$5",
1271
+ borderWidth: 2,
1272
+ borderColor: selected ? "$color9" : "$color5",
1273
+ backgroundColor: selected ? "$color3" : "$color1",
1274
+ pressStyle: { scale: 0.98, opacity: 0.9 },
1275
+ animation: "quick",
1276
+ onPress,
1277
+ cursor: "pointer",
1278
+ alignItems: "center",
1279
+ gap: "$3",
1280
+ position: "relative",
1281
+ children: [
1282
+ plan.popular && /* @__PURE__ */ jsx21(YStack14, { position: "absolute", top: -10, right: 12, backgroundColor: "$color9", paddingHorizontal: "$2", paddingVertical: 2, borderRadius: "$10", children: /* @__PURE__ */ jsx21(SizableText17, { size: "$1", color: "white", fontWeight: "700", children: "BEST VALUE" }) }),
1283
+ /* @__PURE__ */ jsx21(Circle2, { size: 22, borderWidth: 2, borderColor: selected ? "$color9" : "$color7", backgroundColor: selected ? "$color9" : "transparent", children: selected && /* @__PURE__ */ jsx21(Circle2, { size: 8, backgroundColor: "white" }) }),
1284
+ /* @__PURE__ */ jsxs14(YStack14, { flex: 1, gap: "$0.5", children: [
1285
+ /* @__PURE__ */ jsxs14(XStack10, { gap: "$2", alignItems: "center", children: [
1286
+ /* @__PURE__ */ jsx21(SizableText17, { size: "$4", fontWeight: "700", children: plan.name }),
1287
+ plan.trial && /* @__PURE__ */ jsx21(YStack14, { backgroundColor: "$green3", paddingHorizontal: "$1.5", paddingVertical: 2, borderRadius: "$10", children: /* @__PURE__ */ jsx21(SizableText17, { size: "$1", color: "$green9", fontWeight: "700", children: plan.trial }) })
1288
+ ] }),
1289
+ plan.tagline ? /* @__PURE__ */ jsx21(SizableText17, { size: "$2", color: "$color10", children: plan.tagline }) : null
1290
+ ] }),
1291
+ /* @__PURE__ */ jsxs14(YStack14, { alignItems: "flex-end", gap: "$0.5", children: [
1292
+ /* @__PURE__ */ jsxs14(XStack10, { alignItems: "baseline", gap: "$1", children: [
1293
+ /* @__PURE__ */ jsx21(SizableText17, { size: "$5", fontWeight: "800", children: plan.price }),
1294
+ /* @__PURE__ */ jsxs14(SizableText17, { size: "$2", color: "$color10", children: [
1295
+ "/",
1296
+ plan.period
1297
+ ] })
1298
+ ] }),
1299
+ plan.savings && /* @__PURE__ */ jsx21(YStack14, { backgroundColor: "$green3", paddingHorizontal: "$1.5", paddingVertical: 1, borderRadius: "$10", children: /* @__PURE__ */ jsx21(SizableText17, { size: "$1", color: "$green9", fontWeight: "700", children: plan.savings }) }),
1300
+ plan.pricePerWeek && /* @__PURE__ */ jsx21(SizableText17, { size: "$1", color: "$color10", children: plan.pricePerWeek })
1301
+ ] })
1302
+ ]
1303
+ }
1304
+ );
1305
+ }
1306
+ function ComparisonIcon({ enabled }) {
1307
+ return /* @__PURE__ */ jsx21(Circle2, { size: 24, backgroundColor: enabled ? "$green3" : "$color4", children: /* @__PURE__ */ jsx21(SizableText17, { size: "$2", color: enabled ? "$green10" : "$color8", fontWeight: "700", children: enabled ? "\u2713" : "\u2715" }) });
1308
+ }
1309
+ function TestimonialCard({ t }) {
1310
+ return /* @__PURE__ */ jsxs14(YStack14, { minWidth: 240, backgroundColor: "$color2", borderRadius: "$6", padding: "$3.5", gap: "$2.5", children: [
1311
+ /* @__PURE__ */ jsxs14(SizableText17, { size: "$3", color: "$color11", fontStyle: "italic", children: [
1312
+ "\u201C",
1313
+ t.quote,
1314
+ "\u201D"
1315
+ ] }),
1316
+ /* @__PURE__ */ jsxs14(XStack10, { gap: "$2", alignItems: "center", children: [
1317
+ /* @__PURE__ */ jsx21(Circle2, { size: 32, backgroundColor: "$color5", children: /* @__PURE__ */ jsx21(SizableText17, { size: "$2", fontWeight: "700", children: t.author[0] }) }),
1318
+ /* @__PURE__ */ jsxs14(YStack14, { children: [
1319
+ /* @__PURE__ */ jsx21(SizableText17, { size: "$2", fontWeight: "700", children: t.author }),
1320
+ t.meta ? /* @__PURE__ */ jsx21(SizableText17, { size: "$1", color: "$color10", children: t.meta }) : null
1321
+ ] })
1322
+ ] })
1323
+ ] });
1324
+ }
1325
+ function CreatorHeader({ c }) {
1326
+ return /* @__PURE__ */ jsxs14(XStack10, { alignItems: "center", justifyContent: "center", gap: "$3", children: [
1327
+ c.avatar && /* @__PURE__ */ jsx21(Circle2, { size: 72, overflow: "hidden", backgroundColor: "$color3", children: c.avatar }),
1328
+ /* @__PURE__ */ jsxs14(YStack14, { alignItems: "center", gap: "$1", children: [
1329
+ /* @__PURE__ */ jsx21(SizableText17, { size: "$6", fontWeight: "800", children: c.name }),
1330
+ c.meta ? /* @__PURE__ */ jsx21(SizableText17, { size: "$3", color: "$color10", children: c.meta }) : null
1331
+ ] })
1332
+ ] });
1333
+ }
1334
+ function TrustBadges({ badges }) {
1335
+ return /* @__PURE__ */ jsx21(XStack10, { justifyContent: "center", gap: "$4", paddingTop: "$1", children: badges.map((b, i) => /* @__PURE__ */ jsxs14(YStack14, { alignItems: "center", gap: "$1", children: [
1336
+ /* @__PURE__ */ jsx21(Circle2, { size: 28, backgroundColor: "$color3", children: b.icon ?? /* @__PURE__ */ jsx21(SizableText17, { size: "$2", color: "$color9", children: "\u2726" }) }),
1337
+ /* @__PURE__ */ jsx21(SizableText17, { size: "$1", color: "$color10", textAlign: "center", children: b.label })
1338
+ ] }, i)) });
1339
+ }
994
1340
  function PaywallScreen({
995
- title = "Upgrade Your Experience",
996
- subtitle = "Choose the plan that works for you",
1341
+ variant = "default",
1342
+ eyebrow,
1343
+ title = "Unlock Premium",
1344
+ subtitle,
1345
+ features = [],
997
1346
  plans,
998
1347
  selectedPlan,
999
1348
  onSelectPlan,
1000
1349
  onContinue,
1350
+ onClose,
1001
1351
  onRestore,
1002
- continueLabel = "Continue"
1352
+ onTerms,
1353
+ onPrivacy,
1354
+ continueLabel = "Continue",
1355
+ reassurance = "Cancel anytime",
1356
+ hero,
1357
+ socialProof,
1358
+ countdownMinutes,
1359
+ badge,
1360
+ comparisonRows = [],
1361
+ testimonials = [],
1362
+ creator,
1363
+ topSlot,
1364
+ footerSlot,
1365
+ trustBadges
1003
1366
  }) {
1004
- return /* @__PURE__ */ jsxs13(YStack14, { flex: 1, padding: "$4", gap: "$5", backgroundColor: "$background", children: [
1005
- /* @__PURE__ */ jsxs13(YStack14, { gap: "$2", paddingTop: "$6", children: [
1006
- /* @__PURE__ */ jsx20(SizableText17, { size: "$9", fontWeight: "700", textAlign: "center", children: title }),
1007
- /* @__PURE__ */ jsx20(SizableText17, { size: "$4", color: "$color10", textAlign: "center", children: subtitle })
1008
- ] }),
1009
- /* @__PURE__ */ jsx20(YStack14, { gap: "$3", flex: 1, children: plans.map((plan) => /* @__PURE__ */ jsxs13(
1367
+ const selected = selectedPlan ?? plans.find((p) => p.popular)?.id ?? plans[0]?.id;
1368
+ const countdown = useCountdown(countdownMinutes);
1369
+ const dark = variant === "immersive-dark";
1370
+ const bg = dark ? "$color1" : "$background";
1371
+ const tone = dark ? "$color12" : "$color11";
1372
+ const muted = "$color10";
1373
+ return /* @__PURE__ */ jsxs14(YStack14, { flex: 1, backgroundColor: bg, children: [
1374
+ onClose && /* @__PURE__ */ jsx21(XStack10, { position: "absolute", top: "$4", right: "$4", zIndex: 10, children: /* @__PURE__ */ jsx21(Button3, { size: "$3", circular: true, chromeless: true, onPress: onClose, pressStyle: { opacity: 0.6 }, children: /* @__PURE__ */ jsx21(SizableText17, { size: "$5", color: muted, children: "\u2715" }) }) }),
1375
+ /* @__PURE__ */ jsx21(ScrollView2, { flex: 1, contentContainerStyle: { paddingBottom: 240 }, children: /* @__PURE__ */ jsxs14(YStack14, { paddingHorizontal: "$5", paddingTop: "$8", gap: "$5", children: [
1376
+ topSlot,
1377
+ creator && variant === "creator-sheet" ? /* @__PURE__ */ jsx21(CreatorHeader, { c: creator }) : null,
1378
+ hero && /* @__PURE__ */ jsx21(YStack14, { alignItems: "center", paddingVertical: "$3", children: hero }),
1379
+ badge && /* @__PURE__ */ jsx21(XStack10, { justifyContent: "center", children: /* @__PURE__ */ jsx21(YStack14, { backgroundColor: "$color9", paddingHorizontal: "$3", paddingVertical: "$1", borderRadius: "$10", children: /* @__PURE__ */ jsx21(SizableText17, { size: "$2", color: "white", fontWeight: "700", children: badge }) }) }),
1380
+ /* @__PURE__ */ jsxs14(YStack14, { gap: "$1.5", alignItems: "center", children: [
1381
+ eyebrow ? /* @__PURE__ */ jsx21(SizableText17, { size: "$2", fontWeight: "700", color: "$color9", textTransform: "uppercase", children: eyebrow }) : null,
1382
+ /* @__PURE__ */ jsx21(SizableText17, { size: "$9", fontWeight: "800", textAlign: "center", color: tone, children: title }),
1383
+ subtitle && /* @__PURE__ */ jsx21(SizableText17, { size: "$4", color: muted, textAlign: "center", children: subtitle }),
1384
+ socialProof && /* @__PURE__ */ jsx21(SizableText17, { size: "$3", color: "$color9", fontWeight: "600", textAlign: "center", paddingTop: "$1", children: socialProof })
1385
+ ] }),
1386
+ countdownMinutes && !countdown.expired ? /* @__PURE__ */ jsxs14(XStack10, { justifyContent: "center", padding: "$2", backgroundColor: "$red3", borderRadius: "$4", alignSelf: "center", paddingHorizontal: "$4", gap: "$2", alignItems: "center", children: [
1387
+ /* @__PURE__ */ jsx21(SizableText17, { size: "$2", color: "$red9", fontWeight: "600", children: "Offer ends in" }),
1388
+ /* @__PURE__ */ jsx21(SizableText17, { size: "$5", color: "$red9", fontWeight: "800", fontFamily: "$mono", children: countdown.display })
1389
+ ] }) : null,
1390
+ features.length > 0 && /* @__PURE__ */ jsx21(YStack14, { gap: "$3.5", children: features.map((feature, i) => /* @__PURE__ */ jsx21(BenefitRow, { feature, tone, muted }, i)) }),
1391
+ variant === "social-proof" && testimonials.length > 0 ? /* @__PURE__ */ jsx21(ScrollView2, { horizontal: true, showsHorizontalScrollIndicator: false, children: /* @__PURE__ */ jsx21(XStack10, { gap: "$3", paddingRight: "$4", children: testimonials.map((t, i) => /* @__PURE__ */ jsx21(TestimonialCard, { t }, `${t.author}-${i}`)) }) }) : null,
1392
+ variant === "comparison" && comparisonRows.length > 0 ? /* @__PURE__ */ jsxs14(YStack14, { backgroundColor: dark ? "$color2" : "$color1", borderRadius: "$6", padding: "$3.5", gap: "$2", borderWidth: 1, borderColor: "$color4", children: [
1393
+ /* @__PURE__ */ jsxs14(XStack10, { alignItems: "center", children: [
1394
+ /* @__PURE__ */ jsx21(SizableText17, { flex: 1, size: "$2", fontWeight: "700", color: muted, children: "Feature" }),
1395
+ /* @__PURE__ */ jsx21(SizableText17, { width: 64, size: "$2", fontWeight: "700", textAlign: "center", color: muted, children: "Free" }),
1396
+ /* @__PURE__ */ jsx21(SizableText17, { width: 84, size: "$2", fontWeight: "700", textAlign: "center", color: "$color9", children: "Premium" })
1397
+ ] }),
1398
+ comparisonRows.map((row) => /* @__PURE__ */ jsxs14(XStack10, { alignItems: "center", paddingVertical: "$1.5", children: [
1399
+ /* @__PURE__ */ jsx21(SizableText17, { flex: 1, size: "$3", color: tone, children: row.label }),
1400
+ /* @__PURE__ */ jsx21(XStack10, { width: 64, justifyContent: "center", children: /* @__PURE__ */ jsx21(ComparisonIcon, { enabled: row.free }) }),
1401
+ /* @__PURE__ */ jsx21(XStack10, { width: 84, justifyContent: "center", children: /* @__PURE__ */ jsx21(ComparisonIcon, { enabled: row.premium }) })
1402
+ ] }, row.label))
1403
+ ] }) : null,
1404
+ /* @__PURE__ */ jsx21(YStack14, { gap: "$3", children: plans.map((plan) => /* @__PURE__ */ jsx21(
1405
+ PlanRow,
1406
+ {
1407
+ plan,
1408
+ selected: selected === plan.id,
1409
+ onPress: () => onSelectPlan?.(plan.id)
1410
+ },
1411
+ plan.id
1412
+ )) })
1413
+ ] }) }),
1414
+ /* @__PURE__ */ jsxs14(
1010
1415
  YStack14,
1011
1416
  {
1417
+ position: "absolute",
1418
+ bottom: 0,
1419
+ left: 0,
1420
+ right: 0,
1012
1421
  padding: "$4",
1013
- borderRadius: "$5",
1014
- borderWidth: 2,
1015
- borderColor: selectedPlan === plan.id ? "$color9" : "$color4",
1016
- backgroundColor: selectedPlan === plan.id ? "$color2" : "$color1",
1017
- pressStyle: { scale: 0.98 },
1018
- onPress: () => onSelectPlan?.(plan.id),
1019
- cursor: "pointer",
1422
+ paddingBottom: "$6",
1423
+ backgroundColor: bg,
1424
+ borderTopWidth: 1,
1425
+ borderTopColor: "$color4",
1426
+ gap: "$2.5",
1020
1427
  children: [
1021
- /* @__PURE__ */ jsxs13(XStack10, { justifyContent: "space-between", alignItems: "center", children: [
1022
- /* @__PURE__ */ jsxs13(YStack14, { children: [
1023
- /* @__PURE__ */ jsx20(SizableText17, { size: "$5", fontWeight: "600", children: plan.name }),
1024
- /* @__PURE__ */ jsxs13(XStack10, { alignItems: "baseline", gap: "$1", children: [
1025
- /* @__PURE__ */ jsx20(SizableText17, { size: "$8", fontWeight: "700", children: plan.price }),
1026
- /* @__PURE__ */ jsxs13(SizableText17, { size: "$3", color: "$color9", children: [
1027
- "/",
1028
- plan.period
1029
- ] })
1030
- ] })
1031
- ] }),
1032
- plan.popular && /* @__PURE__ */ jsx20(YStack14, { backgroundColor: "$color9", paddingHorizontal: "$2", paddingVertical: "$1", borderRadius: "$10", children: /* @__PURE__ */ jsx20(SizableText17, { size: "$1", color: "$color1", fontWeight: "600", children: "POPULAR" }) })
1428
+ /* @__PURE__ */ jsx21(
1429
+ Button3,
1430
+ {
1431
+ size: "$5",
1432
+ backgroundColor: "$color9",
1433
+ color: "$color1",
1434
+ onPress: onContinue,
1435
+ pressStyle: { backgroundColor: "$color8", scale: 0.98 },
1436
+ animation: "quick",
1437
+ borderRadius: "$10",
1438
+ fontWeight: "700",
1439
+ children: continueLabel
1440
+ }
1441
+ ),
1442
+ reassurance && /* @__PURE__ */ jsx21(SizableText17, { size: "$2", color: "$color9", textAlign: "center", children: reassurance }),
1443
+ /* @__PURE__ */ jsxs14(XStack10, { justifyContent: "center", gap: "$3", children: [
1444
+ onRestore && /* @__PURE__ */ jsx21(SizableText17, { size: "$2", color: "$color8", onPress: onRestore, pressStyle: { opacity: 0.6 }, children: "Restore" }),
1445
+ onTerms && /* @__PURE__ */ jsx21(SizableText17, { size: "$2", color: "$color8", onPress: onTerms, pressStyle: { opacity: 0.6 }, children: "Terms" }),
1446
+ onPrivacy && /* @__PURE__ */ jsx21(SizableText17, { size: "$2", color: "$color8", onPress: onPrivacy, pressStyle: { opacity: 0.6 }, children: "Privacy" })
1033
1447
  ] }),
1034
- /* @__PURE__ */ jsx20(YStack14, { gap: "$2", paddingTop: "$3", children: plan.features.map((feature, i) => /* @__PURE__ */ jsxs13(XStack10, { gap: "$2", alignItems: "center", children: [
1035
- /* @__PURE__ */ jsx20(Circle2, { size: 6, backgroundColor: "$green9" }),
1036
- /* @__PURE__ */ jsx20(SizableText17, { size: "$3", color: "$color11", children: feature })
1037
- ] }, i)) })
1448
+ trustBadges && trustBadges.length > 0 && /* @__PURE__ */ jsx21(TrustBadges, { badges: trustBadges }),
1449
+ footerSlot
1038
1450
  ]
1039
- },
1040
- plan.id
1041
- )) }),
1042
- /* @__PURE__ */ jsxs13(YStack14, { gap: "$3", paddingBottom: "$4", children: [
1043
- /* @__PURE__ */ jsx20(
1044
- Button3,
1045
- {
1046
- size: "$5",
1047
- backgroundColor: "$color9",
1048
- color: "$color1",
1049
- onPress: onContinue,
1050
- hoverStyle: { backgroundColor: "$color10" },
1051
- pressStyle: { backgroundColor: "$color8" },
1052
- borderRadius: "$5",
1053
- children: continueLabel
1054
- }
1055
- ),
1056
- onRestore && /* @__PURE__ */ jsx20(Button3, { size: "$3", chromeless: true, onPress: onRestore, children: /* @__PURE__ */ jsx20(SizableText17, { size: "$3", color: "$color9", children: "Restore Purchases" }) })
1057
- ] })
1451
+ }
1452
+ )
1058
1453
  ] });
1059
1454
  }
1060
1455
 
1061
1456
  // src/patterns/OnboardingCarousel.tsx
1062
- import { useState as useState5 } from "react";
1457
+ import { useState as useState6 } from "react";
1063
1458
  import { Button as Button4, SizableText as SizableText18, XStack as XStack11, YStack as YStack15, Circle as Circle3 } from "tamagui";
1064
- import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
1459
+ import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
1065
1460
  function OnboardingCarousel({
1066
1461
  steps,
1462
+ variant = "default",
1463
+ brand,
1464
+ topLeading,
1067
1465
  onComplete,
1068
1466
  onSkip,
1069
1467
  completeLabel = "Get Started",
1070
1468
  skipLabel = "Skip",
1071
- nextLabel = "Next"
1469
+ nextLabel = "Next",
1470
+ footerSlot
1072
1471
  }) {
1073
- const [current, setCurrent] = useState5(0);
1472
+ const [current, setCurrent] = useState6(0);
1473
+ if (steps.length === 0) {
1474
+ return /* @__PURE__ */ jsx22(YStack15, { flex: 1, backgroundColor: "$background", padding: "$4", alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx22(SizableText18, { size: "$5", color: "$color10", textAlign: "center", children: "Add at least one onboarding step." }) });
1475
+ }
1074
1476
  const isLast = current === steps.length - 1;
1075
1477
  const step = steps[current];
1076
- return /* @__PURE__ */ jsxs14(YStack15, { flex: 1, backgroundColor: "$background", padding: "$4", justifyContent: "space-between", children: [
1077
- /* @__PURE__ */ jsx21(XStack11, { justifyContent: "flex-end", paddingTop: "$4", children: !isLast && onSkip && /* @__PURE__ */ jsx21(Button4, { chromeless: true, onPress: onSkip, children: /* @__PURE__ */ jsx21(SizableText18, { size: "$4", color: "$color9", children: skipLabel }) }) }),
1078
- /* @__PURE__ */ jsxs14(YStack15, { flex: 1, alignItems: "center", justifyContent: "center", gap: "$5", paddingHorizontal: "$4", children: [
1079
- step?.icon && /* @__PURE__ */ jsx21(Circle3, { size: 120, backgroundColor: "$color2", alignItems: "center", justifyContent: "center", children: step.icon }),
1080
- /* @__PURE__ */ jsxs14(YStack15, { gap: "$3", alignItems: "center", children: [
1081
- /* @__PURE__ */ jsx21(SizableText18, { size: "$9", fontWeight: "700", textAlign: "center", children: step?.title }),
1082
- /* @__PURE__ */ jsx21(SizableText18, { size: "$4", color: "$color10", textAlign: "center", maxWidth: 300, children: step?.description })
1478
+ const hero = step?.hero ?? step?.icon;
1479
+ const isEditorial = variant === "editorial";
1480
+ const isSelection = variant === "selection-step";
1481
+ const isPermission = variant === "permission-prompt";
1482
+ const topPadding = isEditorial ? "$6" : "$4";
1483
+ const titleSize = isEditorial ? "$10" : "$9";
1484
+ const backgroundColor = variant === "calm-gradient" ? "$color2" : "$background";
1485
+ const heroBackground = isPermission ? "$color3" : isSelection ? "$color1" : "$color2";
1486
+ const heroRadius = variant === "card-tilt" || isSelection ? "$8" : "$10";
1487
+ const buttonTone = variant === "editorial" ? "$color12" : "$color9";
1488
+ return /* @__PURE__ */ jsxs15(YStack15, { flex: 1, backgroundColor, padding: "$4", justifyContent: "space-between", children: [
1489
+ step?.background ? /* @__PURE__ */ jsx22(YStack15, { position: "absolute", left: 0, right: 0, top: 0, bottom: 0, children: step.background }) : null,
1490
+ /* @__PURE__ */ jsxs15(XStack11, { justifyContent: "space-between", alignItems: "center", paddingTop: topPadding, children: [
1491
+ /* @__PURE__ */ jsx22(XStack11, { minWidth: 40, children: topLeading }),
1492
+ brand ? /* @__PURE__ */ jsx22(YStack15, { alignItems: "center", flex: 1, children: brand }) : /* @__PURE__ */ jsx22(YStack15, { flex: 1 }),
1493
+ !isLast && onSkip && /* @__PURE__ */ jsx22(Button4, { chromeless: true, onPress: onSkip, children: /* @__PURE__ */ jsx22(SizableText18, { size: "$4", color: "$color9", children: skipLabel }) })
1494
+ ] }),
1495
+ /* @__PURE__ */ jsxs15(YStack15, { flex: 1, alignItems: "center", justifyContent: "center", gap: "$5", paddingHorizontal: "$4", children: [
1496
+ hero ? variant === "card-tilt" || isSelection ? /* @__PURE__ */ jsx22(
1497
+ YStack15,
1498
+ {
1499
+ width: "100%",
1500
+ maxWidth: 340,
1501
+ minHeight: 260,
1502
+ borderRadius: heroRadius,
1503
+ backgroundColor: heroBackground,
1504
+ padding: "$3",
1505
+ alignItems: "center",
1506
+ justifyContent: "center",
1507
+ borderWidth: variant === "card-tilt" ? 3 : 1,
1508
+ borderColor: "$color4",
1509
+ shadowColor: "$shadowColor",
1510
+ shadowOpacity: 0.14,
1511
+ shadowRadius: 18,
1512
+ shadowOffset: { width: 0, height: 10 },
1513
+ style: variant === "card-tilt" ? { transform: [{ rotate: "-5deg" }] } : void 0,
1514
+ children: hero
1515
+ }
1516
+ ) : /* @__PURE__ */ jsx22(Circle3, { size: isPermission ? 140 : 120, backgroundColor: heroBackground, alignItems: "center", justifyContent: "center", children: hero }) : null,
1517
+ /* @__PURE__ */ jsxs15(YStack15, { gap: "$3", alignItems: "center", children: [
1518
+ step?.eyebrow ? /* @__PURE__ */ jsx22(SizableText18, { size: "$2", color: "$color9", fontWeight: "700", textTransform: "uppercase", children: step.eyebrow }) : null,
1519
+ /* @__PURE__ */ jsx22(SizableText18, { size: titleSize, fontWeight: "700", textAlign: "center", children: step?.title }),
1520
+ /* @__PURE__ */ jsx22(SizableText18, { size: "$4", color: "$color10", textAlign: "center", maxWidth: 300, children: step?.description })
1083
1521
  ] })
1084
1522
  ] }),
1085
- /* @__PURE__ */ jsxs14(YStack15, { gap: "$3", paddingBottom: "$2", children: [
1086
- /* @__PURE__ */ jsx21(XStack11, { justifyContent: "center", gap: "$2", children: steps.map((_, i) => /* @__PURE__ */ jsx21(
1523
+ /* @__PURE__ */ jsxs15(YStack15, { gap: "$3", paddingBottom: "$2", children: [
1524
+ /* @__PURE__ */ jsx22(XStack11, { justifyContent: "center", gap: "$2", children: steps.map((_, i) => /* @__PURE__ */ jsx22(
1087
1525
  Circle3,
1088
1526
  {
1089
- size: 8,
1527
+ size: variant === "card-tilt" ? 10 : 8,
1528
+ width: i === current && variant !== "default" ? 24 : void 0,
1090
1529
  backgroundColor: i === current ? "$color9" : "$color4",
1530
+ borderRadius: "$10",
1091
1531
  animation: "quick"
1092
1532
  },
1093
1533
  i
1094
1534
  )) }),
1095
- /* @__PURE__ */ jsx21(
1535
+ /* @__PURE__ */ jsx22(
1096
1536
  Button4,
1097
1537
  {
1098
1538
  size: "$5",
1099
- backgroundColor: "$color9",
1539
+ backgroundColor: buttonTone,
1100
1540
  color: "$color1",
1101
- borderRadius: "$5",
1102
- hoverStyle: { backgroundColor: "$color10" },
1541
+ borderRadius: variant === "editorial" ? "$10" : "$5",
1542
+ hoverStyle: { backgroundColor: variant === "editorial" ? "$color11" : "$color10" },
1103
1543
  pressStyle: { backgroundColor: "$color8" },
1104
1544
  onPress: () => isLast ? onComplete?.() : setCurrent((c) => c + 1),
1105
- children: isLast ? completeLabel : nextLabel
1545
+ children: isLast ? step?.ctaLabel ?? completeLabel : step?.ctaLabel ?? nextLabel
1106
1546
  }
1107
- )
1547
+ ),
1548
+ footerSlot
1108
1549
  ] })
1109
1550
  ] });
1110
1551
  }
1111
1552
 
1112
1553
  // src/patterns/ChatBubble.tsx
1113
1554
  import { SizableText as SizableText19, XStack as XStack12, YStack as YStack16, Circle as Circle4, Image as Image3 } from "tamagui";
1114
- import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
1555
+ import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
1115
1556
  function ChatBubble({ message, showAvatar = true }) {
1116
1557
  const isUser = message.sender === "user";
1117
- return /* @__PURE__ */ jsxs15(
1558
+ return /* @__PURE__ */ jsxs16(
1118
1559
  XStack12,
1119
1560
  {
1120
1561
  alignSelf: isUser ? "flex-end" : "flex-start",
@@ -1122,8 +1563,8 @@ function ChatBubble({ message, showAvatar = true }) {
1122
1563
  gap: "$2",
1123
1564
  flexDirection: isUser ? "row-reverse" : "row",
1124
1565
  children: [
1125
- showAvatar && !isUser && /* @__PURE__ */ jsx22(Circle4, { size: 32, backgroundColor: "$color4", overflow: "hidden", children: message.avatar ? /* @__PURE__ */ jsx22(Image3, { source: { uri: message.avatar }, width: 32, height: 32, objectFit: "cover" }) : /* @__PURE__ */ jsx22(SizableText19, { size: "$2", fontWeight: "600", color: "$color11", children: message.senderName?.[0]?.toUpperCase() ?? "?" }) }),
1126
- /* @__PURE__ */ jsxs15(
1566
+ showAvatar && !isUser && /* @__PURE__ */ jsx23(Circle4, { size: 32, backgroundColor: "$color4", overflow: "hidden", children: message.avatar ? /* @__PURE__ */ jsx23(Image3, { source: { uri: message.avatar }, width: 32, height: 32, objectFit: "cover" }) : /* @__PURE__ */ jsx23(SizableText19, { size: "$2", fontWeight: "600", color: "$color11", children: message.senderName?.[0]?.toUpperCase() ?? "?" }) }),
1567
+ /* @__PURE__ */ jsxs16(
1127
1568
  YStack16,
1128
1569
  {
1129
1570
  backgroundColor: isUser ? "$color9" : "$color3",
@@ -1134,8 +1575,8 @@ function ChatBubble({ message, showAvatar = true }) {
1134
1575
  borderBottomLeftRadius: isUser ? "$5" : "$2",
1135
1576
  gap: "$1",
1136
1577
  children: [
1137
- /* @__PURE__ */ jsx22(SizableText19, { size: "$3", color: isUser ? "$color1" : "$color12", children: message.text }),
1138
- message.timestamp && /* @__PURE__ */ jsx22(SizableText19, { size: "$1", color: isUser ? "$color3" : "$color9", alignSelf: "flex-end", children: message.timestamp })
1578
+ /* @__PURE__ */ jsx23(SizableText19, { size: "$3", color: isUser ? "$color1" : "$color12", children: message.text }),
1579
+ message.timestamp && /* @__PURE__ */ jsx23(SizableText19, { size: "$1", color: isUser ? "$color3" : "$color9", alignSelf: "flex-end", children: message.timestamp })
1139
1580
  ]
1140
1581
  }
1141
1582
  )
@@ -1146,9 +1587,9 @@ function ChatBubble({ message, showAvatar = true }) {
1146
1587
 
1147
1588
  // src/patterns/SettingsScreen.tsx
1148
1589
  import { Separator as Separator4, SizableText as SizableText20, Switch, XStack as XStack13, YStack as YStack17 } from "tamagui";
1149
- import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
1590
+ import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
1150
1591
  function SettingsItemRow({ item }) {
1151
- return /* @__PURE__ */ jsxs16(
1592
+ return /* @__PURE__ */ jsxs17(
1152
1593
  XStack13,
1153
1594
  {
1154
1595
  alignItems: "center",
@@ -1160,21 +1601,21 @@ function SettingsItemRow({ item }) {
1160
1601
  onPress: item.onPress,
1161
1602
  cursor: item.onPress ? "pointer" : void 0,
1162
1603
  children: [
1163
- item.icon && /* @__PURE__ */ jsx23(YStack17, { width: 24, alignItems: "center", children: item.icon }),
1164
- /* @__PURE__ */ jsxs16(YStack17, { flex: 1, gap: "$1", children: [
1165
- /* @__PURE__ */ jsx23(SizableText20, { size: "$4", fontWeight: "500", children: item.title }),
1166
- item.subtitle && /* @__PURE__ */ jsx23(SizableText20, { size: "$2", color: "$color9", children: item.subtitle })
1604
+ item.icon && /* @__PURE__ */ jsx24(YStack17, { width: 24, alignItems: "center", children: item.icon }),
1605
+ /* @__PURE__ */ jsxs17(YStack17, { flex: 1, gap: "$1", children: [
1606
+ /* @__PURE__ */ jsx24(SizableText20, { size: "$4", fontWeight: "500", children: item.title }),
1607
+ item.subtitle && /* @__PURE__ */ jsx24(SizableText20, { size: "$2", color: "$color9", children: item.subtitle })
1167
1608
  ] }),
1168
- item.type === "toggle" ? /* @__PURE__ */ jsx23(Switch, { size: "$3", checked: item.value, onCheckedChange: item.onValueChange, children: /* @__PURE__ */ jsx23(Switch.Thumb, { animation: "quick" }) }) : item.right ? item.right : item.onPress && /* @__PURE__ */ jsx23(SizableText20, { size: "$5", color: "$color8", children: "\u203A" })
1609
+ item.type === "toggle" ? /* @__PURE__ */ jsx24(Switch, { size: "$3", checked: item.value, onCheckedChange: item.onValueChange, children: /* @__PURE__ */ jsx24(Switch.Thumb, { animation: "quick" }) }) : item.right ? item.right : item.onPress && /* @__PURE__ */ jsx24(SizableText20, { size: "$5", color: "$color8", children: "\u203A" })
1169
1610
  ]
1170
1611
  }
1171
1612
  );
1172
1613
  }
1173
1614
  function SettingsScreen({ sections, header }) {
1174
- return /* @__PURE__ */ jsxs16(YStack17, { flex: 1, backgroundColor: "$background", children: [
1615
+ return /* @__PURE__ */ jsxs17(YStack17, { flex: 1, backgroundColor: "$background", children: [
1175
1616
  header,
1176
- /* @__PURE__ */ jsx23(YStack17, { gap: "$4", paddingVertical: "$2", children: sections.map((section, si) => /* @__PURE__ */ jsxs16(YStack17, { children: [
1177
- section.title && /* @__PURE__ */ jsx23(
1617
+ /* @__PURE__ */ jsx24(YStack17, { gap: "$4", paddingVertical: "$2", children: sections.map((section, si) => /* @__PURE__ */ jsxs17(YStack17, { children: [
1618
+ section.title && /* @__PURE__ */ jsx24(
1178
1619
  SizableText20,
1179
1620
  {
1180
1621
  size: "$2",
@@ -1186,9 +1627,9 @@ function SettingsScreen({ sections, header }) {
1186
1627
  children: section.title
1187
1628
  }
1188
1629
  ),
1189
- /* @__PURE__ */ jsx23(YStack17, { backgroundColor: "$color1", borderRadius: "$4", marginHorizontal: "$3", overflow: "hidden", children: section.items.map((item, ii) => /* @__PURE__ */ jsxs16(YStack17, { children: [
1190
- /* @__PURE__ */ jsx23(SettingsItemRow, { item }),
1191
- ii < section.items.length - 1 && /* @__PURE__ */ jsx23(Separator4, { borderColor: "$color3", marginLeft: "$12" })
1630
+ /* @__PURE__ */ jsx24(YStack17, { backgroundColor: "$color1", borderRadius: "$4", marginHorizontal: "$3", overflow: "hidden", children: section.items.map((item, ii) => /* @__PURE__ */ jsxs17(YStack17, { children: [
1631
+ /* @__PURE__ */ jsx24(SettingsItemRow, { item }),
1632
+ ii < section.items.length - 1 && /* @__PURE__ */ jsx24(Separator4, { borderColor: "$color3", marginLeft: "$12" })
1192
1633
  ] }, item.id)) })
1193
1634
  ] }, si)) })
1194
1635
  ] });
@@ -1196,15 +1637,15 @@ function SettingsScreen({ sections, header }) {
1196
1637
 
1197
1638
  // src/patterns/EmptyState.tsx
1198
1639
  import { Button as Button5, SizableText as SizableText21, YStack as YStack18 } from "tamagui";
1199
- import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
1640
+ import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
1200
1641
  function EmptyState({ icon, title, description, actionLabel, onAction }) {
1201
- return /* @__PURE__ */ jsxs17(YStack18, { flex: 1, alignItems: "center", justifyContent: "center", gap: "$4", padding: "$6", children: [
1642
+ return /* @__PURE__ */ jsxs18(YStack18, { flex: 1, alignItems: "center", justifyContent: "center", gap: "$4", padding: "$6", children: [
1202
1643
  icon,
1203
- /* @__PURE__ */ jsxs17(YStack18, { gap: "$2", alignItems: "center", children: [
1204
- /* @__PURE__ */ jsx24(SizableText21, { size: "$6", fontWeight: "600", textAlign: "center", children: title }),
1205
- description && /* @__PURE__ */ jsx24(SizableText21, { size: "$4", color: "$color9", textAlign: "center", maxWidth: 280, children: description })
1644
+ /* @__PURE__ */ jsxs18(YStack18, { gap: "$2", alignItems: "center", children: [
1645
+ /* @__PURE__ */ jsx25(SizableText21, { size: "$6", fontWeight: "600", textAlign: "center", children: title }),
1646
+ description && /* @__PURE__ */ jsx25(SizableText21, { size: "$4", color: "$color9", textAlign: "center", maxWidth: 280, children: description })
1206
1647
  ] }),
1207
- actionLabel && onAction && /* @__PURE__ */ jsx24(
1648
+ actionLabel && onAction && /* @__PURE__ */ jsx25(
1208
1649
  Button5,
1209
1650
  {
1210
1651
  size: "$4",
@@ -1222,17 +1663,17 @@ function EmptyState({ icon, title, description, actionLabel, onAction }) {
1222
1663
 
1223
1664
  // src/patterns/ProfileHeader.tsx
1224
1665
  import { Circle as Circle5, Image as Image4, SizableText as SizableText22, XStack as XStack14, YStack as YStack19 } from "tamagui";
1225
- import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
1666
+ import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
1226
1667
  function ProfileHeader({ name, subtitle, avatar, stats, actions }) {
1227
- return /* @__PURE__ */ jsxs18(YStack19, { alignItems: "center", gap: "$4", paddingVertical: "$6", paddingHorizontal: "$4", children: [
1228
- /* @__PURE__ */ jsx25(Circle5, { size: 80, backgroundColor: "$color4", overflow: "hidden", children: avatar ? /* @__PURE__ */ jsx25(Image4, { source: { uri: avatar }, width: 80, height: 80, objectFit: "cover" }) : /* @__PURE__ */ jsx25(SizableText22, { size: "$9", fontWeight: "700", color: "$color11", children: name[0]?.toUpperCase() ?? "?" }) }),
1229
- /* @__PURE__ */ jsxs18(YStack19, { alignItems: "center", gap: "$1", children: [
1230
- /* @__PURE__ */ jsx25(SizableText22, { size: "$7", fontWeight: "700", children: name }),
1231
- subtitle && /* @__PURE__ */ jsx25(SizableText22, { size: "$4", color: "$color10", children: subtitle })
1668
+ return /* @__PURE__ */ jsxs19(YStack19, { alignItems: "center", gap: "$4", paddingVertical: "$6", paddingHorizontal: "$4", children: [
1669
+ /* @__PURE__ */ jsx26(Circle5, { size: 80, backgroundColor: "$color4", overflow: "hidden", children: avatar ? /* @__PURE__ */ jsx26(Image4, { source: { uri: avatar }, width: 80, height: 80, objectFit: "cover" }) : /* @__PURE__ */ jsx26(SizableText22, { size: "$9", fontWeight: "700", color: "$color11", children: name[0]?.toUpperCase() ?? "?" }) }),
1670
+ /* @__PURE__ */ jsxs19(YStack19, { alignItems: "center", gap: "$1", children: [
1671
+ /* @__PURE__ */ jsx26(SizableText22, { size: "$7", fontWeight: "700", children: name }),
1672
+ subtitle && /* @__PURE__ */ jsx26(SizableText22, { size: "$4", color: "$color10", children: subtitle })
1232
1673
  ] }),
1233
- stats && stats.length > 0 && /* @__PURE__ */ jsx25(XStack14, { gap: "$6", children: stats.map((stat, i) => /* @__PURE__ */ jsxs18(YStack19, { alignItems: "center", gap: "$1", children: [
1234
- /* @__PURE__ */ jsx25(SizableText22, { size: "$6", fontWeight: "700", children: stat.value }),
1235
- /* @__PURE__ */ jsx25(SizableText22, { size: "$2", color: "$color9", children: stat.label })
1674
+ stats && stats.length > 0 && /* @__PURE__ */ jsx26(XStack14, { gap: "$6", children: stats.map((stat, i) => /* @__PURE__ */ jsxs19(YStack19, { alignItems: "center", gap: "$1", children: [
1675
+ /* @__PURE__ */ jsx26(SizableText22, { size: "$6", fontWeight: "700", children: stat.value }),
1676
+ /* @__PURE__ */ jsx26(SizableText22, { size: "$2", color: "$color9", children: stat.label })
1236
1677
  ] }, i)) }),
1237
1678
  actions
1238
1679
  ] });
@@ -1240,27 +1681,27 @@ function ProfileHeader({ name, subtitle, avatar, stats, actions }) {
1240
1681
 
1241
1682
  // src/patterns/AppHeader.tsx
1242
1683
  import { SizableText as SizableText23, XStack as XStack15, YStack as YStack20 } from "tamagui";
1243
- import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
1684
+ import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
1244
1685
  function AppHeader({ title, subtitle, variant = "simple", onBack, avatar, left, right, transparent, borderless }) {
1245
1686
  const leftContent = (() => {
1246
- if (variant === "back") return /* @__PURE__ */ jsx26(SizableText23, { size: "$6", paddingRight: "$2", onPress: onBack, pressStyle: { opacity: 0.6 }, cursor: "pointer", children: "\u2039" });
1247
- if (variant === "profile") return /* @__PURE__ */ jsx26(Avatar, { uri: avatar, name: title, size: "sm" });
1687
+ if (variant === "back") return /* @__PURE__ */ jsx27(SizableText23, { size: "$6", paddingRight: "$2", onPress: onBack, pressStyle: { opacity: 0.6 }, cursor: "pointer", children: "\u2039" });
1688
+ if (variant === "profile") return /* @__PURE__ */ jsx27(Avatar, { uri: avatar, name: title, size: "sm" });
1248
1689
  if (variant === "centered") return left ?? null;
1249
1690
  return null;
1250
1691
  })();
1251
1692
  const rightContent = variant === "profile" || variant === "centered" ? right ?? null : null;
1252
- return /* @__PURE__ */ jsx26(
1693
+ return /* @__PURE__ */ jsx27(
1253
1694
  YStack20,
1254
1695
  {
1255
1696
  paddingTop: "$6",
1256
1697
  backgroundColor: transparent ? "transparent" : "$background",
1257
1698
  borderBottomWidth: borderless ? 0 : 1,
1258
1699
  borderBottomColor: "$borderColor",
1259
- children: /* @__PURE__ */ jsxs19(XStack15, { height: 56, alignItems: "center", paddingHorizontal: "$4", gap: "$3", children: [
1700
+ children: /* @__PURE__ */ jsxs20(XStack15, { height: 56, alignItems: "center", paddingHorizontal: "$4", gap: "$3", children: [
1260
1701
  leftContent,
1261
- /* @__PURE__ */ jsxs19(YStack20, { flex: 1, alignItems: variant === "centered" ? "center" : "flex-start", children: [
1262
- /* @__PURE__ */ jsx26(SizableText23, { size: "$6", fontWeight: "700", numberOfLines: 1, children: title }),
1263
- subtitle && /* @__PURE__ */ jsx26(SizableText23, { size: "$2", color: "$color9", numberOfLines: 1, children: subtitle })
1702
+ /* @__PURE__ */ jsxs20(YStack20, { flex: 1, alignItems: variant === "centered" ? "center" : "flex-start", children: [
1703
+ /* @__PURE__ */ jsx27(SizableText23, { size: "$6", fontWeight: "700", numberOfLines: 1, children: title }),
1704
+ subtitle && /* @__PURE__ */ jsx27(SizableText23, { size: "$2", color: "$color9", numberOfLines: 1, children: subtitle })
1264
1705
  ] }),
1265
1706
  rightContent
1266
1707
  ] })
@@ -1270,106 +1711,182 @@ function AppHeader({ title, subtitle, variant = "simple", onBack, avatar, left,
1270
1711
 
1271
1712
  // src/patterns/BottomSheet.tsx
1272
1713
  import { Sheet, SizableText as SizableText24, XStack as XStack16, YStack as YStack21 } from "tamagui";
1273
- import { ScrollView as ScrollView2 } from "react-native";
1274
- import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
1275
- function BottomSheet({ open, onOpenChange, title, children, snapPoints = [85], dismissOnSnapToBottom = true, showHandle = true, showClose = false }) {
1276
- return /* @__PURE__ */ jsxs20(Sheet, { modal: true, open, onOpenChange, snapPoints, dismissOnSnapToBottom, animation: "medium", children: [
1277
- /* @__PURE__ */ jsx27(Sheet.Overlay, { animation: "lazy", enterStyle: { opacity: 0 }, exitStyle: { opacity: 0 } }),
1278
- showHandle && /* @__PURE__ */ jsx27(Sheet.Handle, {}),
1279
- /* @__PURE__ */ jsxs20(Sheet.Frame, { borderTopLeftRadius: "$6", borderTopRightRadius: "$6", backgroundColor: "$background", children: [
1280
- (title || showClose) && /* @__PURE__ */ jsxs20(XStack16, { paddingHorizontal: "$4", paddingTop: "$3", paddingBottom: "$2", alignItems: "center", justifyContent: "space-between", children: [
1281
- /* @__PURE__ */ jsx27(SizableText24, { size: "$6", fontWeight: "600", flexShrink: 1, children: title }),
1282
- showClose && /* @__PURE__ */ jsx27(
1283
- XStack16,
1284
- {
1285
- width: 28,
1286
- height: 28,
1287
- borderRadius: "$10",
1288
- backgroundColor: "$color4",
1289
- alignItems: "center",
1290
- justifyContent: "center",
1291
- pressStyle: { opacity: 0.7 },
1292
- onPress: () => onOpenChange(false),
1293
- children: /* @__PURE__ */ jsx27(SizableText24, { size: "$3", color: "$color10", fontWeight: "600", children: "\u2715" })
1294
- }
1295
- )
1296
- ] }),
1297
- /* @__PURE__ */ jsx27(ScrollView2, { contentContainerStyle: { paddingBottom: 40 }, children: /* @__PURE__ */ jsx27(YStack21, { padding: "$4", children }) })
1298
- ] })
1299
- ] });
1714
+ import { ScrollView as ScrollView3 } from "react-native";
1715
+ import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
1716
+ function BottomSheet({ open, onOpenChange, title, children, snapPoints = [85], dismissOnSnapToBottom = true, showHandle = true, showClose = false, zIndex = 1e5 }) {
1717
+ return /* @__PURE__ */ jsxs21(
1718
+ Sheet,
1719
+ {
1720
+ modal: true,
1721
+ forceRemoveScrollEnabled: open,
1722
+ open,
1723
+ onOpenChange,
1724
+ snapPoints,
1725
+ dismissOnSnapToBottom,
1726
+ zIndex,
1727
+ animation: "medium",
1728
+ children: [
1729
+ /* @__PURE__ */ jsx28(Sheet.Overlay, { animation: "lazy", enterStyle: { opacity: 0 }, exitStyle: { opacity: 0 } }),
1730
+ showHandle && /* @__PURE__ */ jsx28(Sheet.Handle, {}),
1731
+ /* @__PURE__ */ jsxs21(Sheet.Frame, { children: [
1732
+ (title || showClose) && /* @__PURE__ */ jsxs21(XStack16, { paddingHorizontal: "$4", paddingTop: "$3", paddingBottom: "$2", alignItems: "center", justifyContent: "space-between", children: [
1733
+ /* @__PURE__ */ jsx28(SizableText24, { size: "$6", fontWeight: "600", flexShrink: 1, children: title }),
1734
+ showClose && /* @__PURE__ */ jsx28(
1735
+ XStack16,
1736
+ {
1737
+ width: 28,
1738
+ height: 28,
1739
+ borderRadius: "$10",
1740
+ backgroundColor: "$color4",
1741
+ alignItems: "center",
1742
+ justifyContent: "center",
1743
+ pressStyle: { opacity: 0.7 },
1744
+ onPress: () => onOpenChange(false),
1745
+ children: /* @__PURE__ */ jsx28(SizableText24, { size: "$3", color: "$color10", fontWeight: "600", children: "\u2715" })
1746
+ }
1747
+ )
1748
+ ] }),
1749
+ /* @__PURE__ */ jsx28(ScrollView3, { contentContainerStyle: { paddingBottom: 40 }, children: /* @__PURE__ */ jsx28(YStack21, { padding: "$4", children }) })
1750
+ ] })
1751
+ ]
1752
+ }
1753
+ );
1300
1754
  }
1301
1755
 
1302
1756
  // src/patterns/LoginScreen.tsx
1303
- import { useState as useState6 } from "react";
1304
- import { Button as Button6, SizableText as SizableText25, Spinner, XStack as XStack17, YStack as YStack22 } from "tamagui";
1305
- import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
1306
- function LoginScreen({ title = "Welcome", subtitle = "Sign in to continue", logo, providers = [], onProviderPress, showEmailForm, onEmailSubmit, onForgotPassword, onCreateAccount, onTerms, onPrivacy, loading }) {
1307
- const [email, setEmail] = useState6("");
1308
- const [password, setPassword] = useState6("");
1309
- return /* @__PURE__ */ jsxs21(YStack22, { flex: 1, padding: "$4", gap: "$5", backgroundColor: "$background", justifyContent: "center", children: [
1310
- /* @__PURE__ */ jsxs21(YStack22, { alignItems: "center", gap: "$2", children: [
1311
- logo && /* @__PURE__ */ jsx28(YStack22, { paddingBottom: "$3", children: logo }),
1312
- /* @__PURE__ */ jsx28(SizableText25, { size: "$9", fontWeight: "700", textAlign: "center", children: title }),
1313
- /* @__PURE__ */ jsx28(SizableText25, { size: "$4", color: "$color10", textAlign: "center", children: subtitle })
1314
- ] }),
1315
- providers.length > 0 && /* @__PURE__ */ jsx28(YStack22, { gap: "$2.5", children: providers.map((p) => /* @__PURE__ */ jsx28(
1316
- Button6,
1757
+ import { useState as useState7 } from "react";
1758
+ import { Button as Button6, Circle as Circle6, SizableText as SizableText25, Spinner, XStack as XStack17, YStack as YStack22 } from "tamagui";
1759
+ import { Fragment as Fragment2, jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
1760
+ var BRAND_ICON_MAP = {
1761
+ google: ({ size }) => /* @__PURE__ */ jsx29(GoogleLogo, { size }),
1762
+ apple: ({ size, color }) => /* @__PURE__ */ jsx29(AppleLogo, { size, color }),
1763
+ github: ({ size, color }) => /* @__PURE__ */ jsx29(GitHubLogo, { size, color }),
1764
+ microsoft: ({ size }) => /* @__PURE__ */ jsx29(MicrosoftLogo, { size }),
1765
+ custom: ({ size = 20 }) => /* @__PURE__ */ jsx29(Circle6, { size, backgroundColor: "$color4", alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx29(SizableText25, { fontSize: size * 0.6, color: "$color10", children: "\u2022" }) })
1766
+ };
1767
+ var BRAND_STYLES = {
1768
+ google: { backgroundColor: "$color1", borderColor: "$color5", textColor: "$color12" },
1769
+ apple: { backgroundColor: "$color12", borderColor: "$color12", textColor: "$color1" },
1770
+ github: { backgroundColor: "$color12", borderColor: "$color12", textColor: "$color1" },
1771
+ microsoft: { backgroundColor: "$color1", borderColor: "$color5", textColor: "$color12" },
1772
+ custom: { backgroundColor: "$color1", borderColor: "$color5", textColor: "$color12" }
1773
+ };
1774
+ function ProviderBadge({ provider }) {
1775
+ const brand = provider.brand ?? "custom";
1776
+ if (provider.icon) return /* @__PURE__ */ jsx29(Fragment2, { children: provider.icon });
1777
+ const renderIcon = BRAND_ICON_MAP[brand];
1778
+ const iconColor = brand === "apple" || brand === "github" ? "#fff" : void 0;
1779
+ return renderIcon({ size: 20, color: iconColor });
1780
+ }
1781
+ function LoginScreen({
1782
+ variant = "default",
1783
+ title = "Welcome",
1784
+ subtitle = "Sign in to continue",
1785
+ logo,
1786
+ providers = [],
1787
+ hero,
1788
+ backgroundSlot,
1789
+ footerSlot,
1790
+ providerButtonStyle = "brand",
1791
+ onProviderPress,
1792
+ showEmailForm,
1793
+ onEmailSubmit,
1794
+ onForgotPassword,
1795
+ onCreateAccount,
1796
+ onTerms,
1797
+ onPrivacy,
1798
+ loading
1799
+ }) {
1800
+ const [email, setEmail] = useState7("");
1801
+ const [password, setPassword] = useState7("");
1802
+ const isEditorial = variant === "editorial";
1803
+ const isCenteredCard = variant === "centered-card";
1804
+ return /* @__PURE__ */ jsxs22(YStack22, { flex: 1, padding: "$4", gap: "$5", backgroundColor: "$background", justifyContent: "center", children: [
1805
+ backgroundSlot ? /* @__PURE__ */ jsx29(YStack22, { position: "absolute", left: 0, right: 0, top: 0, bottom: 0, children: backgroundSlot }) : null,
1806
+ /* @__PURE__ */ jsxs22(
1807
+ YStack22,
1317
1808
  {
1318
- size: "$5",
1319
- borderWidth: 1.5,
1320
- borderColor: "$color5",
1321
- backgroundColor: "$color1",
1322
- borderRadius: "$4",
1323
- disabled: loading,
1324
- onPress: () => onProviderPress?.(p.id),
1325
- hoverStyle: { backgroundColor: "$color2" },
1326
- pressStyle: { backgroundColor: "$color3" },
1327
- children: /* @__PURE__ */ jsxs21(XStack17, { alignItems: "center", gap: "$2", children: [
1328
- p.icon,
1329
- /* @__PURE__ */ jsx28(SizableText25, { size: "$4", fontWeight: "500", children: p.name })
1330
- ] })
1331
- },
1332
- p.id
1333
- )) }),
1334
- showEmailForm && providers.length > 0 && /* @__PURE__ */ jsx28(Divider, { label: "or" }),
1335
- showEmailForm && /* @__PURE__ */ jsxs21(YStack22, { gap: "$3", children: [
1336
- /* @__PURE__ */ jsx28(Input, { label: "Email", placeholder: "your@email.com", value: email, onChangeText: setEmail, keyboardType: "email-address", autoCapitalize: "none" }),
1337
- /* @__PURE__ */ jsx28(Input, { label: "Password", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", value: password, onChangeText: setPassword, secureTextEntry: true }),
1338
- onForgotPassword && /* @__PURE__ */ jsx28(XStack17, { justifyContent: "flex-end", children: /* @__PURE__ */ jsx28(SizableText25, { size: "$3", color: "$color9", onPress: onForgotPassword, children: "Forgot password?" }) }),
1339
- /* @__PURE__ */ jsx28(
1340
- Button6,
1341
- {
1342
- size: "$5",
1343
- backgroundColor: "$color9",
1344
- color: "$color1",
1345
- borderRadius: "$5",
1346
- disabled: loading,
1347
- onPress: () => onEmailSubmit?.(email, password),
1348
- hoverStyle: { backgroundColor: "$color10" },
1349
- pressStyle: { backgroundColor: "$color8" },
1350
- icon: loading ? /* @__PURE__ */ jsx28(Spinner, { size: "small", color: "$color1" }) : void 0,
1351
- children: "Sign In"
1352
- }
1353
- ),
1354
- onCreateAccount && /* @__PURE__ */ jsx28(Button6, { size: "$3", chromeless: true, onPress: onCreateAccount, children: /* @__PURE__ */ jsx28(SizableText25, { size: "$3", color: "$color9", children: "Create Account" }) })
1355
- ] }),
1356
- (onTerms || onPrivacy) && /* @__PURE__ */ jsx28(YStack22, { paddingTop: "$2", alignItems: "center", children: /* @__PURE__ */ jsxs21(SizableText25, { size: "$2", color: "$color8", textAlign: "center", children: [
1357
- "By continuing you agree to our",
1358
- " ",
1359
- onTerms && /* @__PURE__ */ jsx28(SizableText25, { size: "$2", color: "$color9", onPress: onTerms, children: "Terms of Service" }),
1360
- onTerms && onPrivacy && " & ",
1361
- onPrivacy && /* @__PURE__ */ jsx28(SizableText25, { size: "$2", color: "$color9", onPress: onPrivacy, children: "Privacy Policy" })
1362
- ] }) })
1809
+ gap: "$5",
1810
+ backgroundColor: isCenteredCard ? "$color1" : "transparent",
1811
+ borderRadius: isCenteredCard ? "$7" : void 0,
1812
+ padding: isCenteredCard ? "$4" : void 0,
1813
+ borderWidth: isCenteredCard ? 1 : 0,
1814
+ borderColor: isCenteredCard ? "$color4" : void 0,
1815
+ children: [
1816
+ /* @__PURE__ */ jsxs22(YStack22, { alignItems: "center", gap: "$2", children: [
1817
+ logo && /* @__PURE__ */ jsx29(YStack22, { paddingBottom: "$3", children: logo }),
1818
+ hero ? /* @__PURE__ */ jsx29(YStack22, { paddingBottom: "$2", children: hero }) : null,
1819
+ /* @__PURE__ */ jsx29(SizableText25, { size: isEditorial ? "$10" : "$9", fontWeight: "700", textAlign: "center", fontFamily: isEditorial ? "$heading" : void 0, children: title }),
1820
+ /* @__PURE__ */ jsx29(SizableText25, { size: "$4", color: "$color10", textAlign: "center", children: subtitle })
1821
+ ] }),
1822
+ providers.length > 0 && /* @__PURE__ */ jsx29(YStack22, { gap: "$2.5", children: providers.map((p) => /* @__PURE__ */ jsx29(
1823
+ Button6,
1824
+ {
1825
+ size: "$5",
1826
+ borderWidth: 1.5,
1827
+ borderColor: providerButtonStyle === "brand" ? BRAND_STYLES[p.brand ?? "custom"].borderColor : "$color5",
1828
+ backgroundColor: providerButtonStyle === "brand" ? BRAND_STYLES[p.brand ?? "custom"].backgroundColor : "$color1",
1829
+ borderRadius: isEditorial ? "$6" : "$4",
1830
+ disabled: loading,
1831
+ onPress: () => onProviderPress?.(p.id),
1832
+ hoverStyle: { backgroundColor: providerButtonStyle === "brand" ? BRAND_STYLES[p.brand ?? "custom"].backgroundColor : "$color2" },
1833
+ pressStyle: { backgroundColor: "$color3" },
1834
+ children: /* @__PURE__ */ jsxs22(XStack17, { alignItems: "center", justifyContent: "space-between", width: "100%", gap: "$2", children: [
1835
+ /* @__PURE__ */ jsxs22(XStack17, { alignItems: "center", gap: "$2.5", children: [
1836
+ /* @__PURE__ */ jsx29(ProviderBadge, { provider: p }),
1837
+ /* @__PURE__ */ jsxs22(YStack22, { alignItems: "flex-start", children: [
1838
+ /* @__PURE__ */ jsx29(SizableText25, { size: "$4", fontWeight: "600", color: providerButtonStyle === "brand" ? BRAND_STYLES[p.brand ?? "custom"].textColor : void 0, children: p.name }),
1839
+ p.description ? /* @__PURE__ */ jsx29(SizableText25, { size: "$2", color: "$color10", children: p.description }) : null
1840
+ ] })
1841
+ ] }),
1842
+ /* @__PURE__ */ jsx29(SizableText25, { size: "$4", color: providerButtonStyle === "brand" ? BRAND_STYLES[p.brand ?? "custom"].textColor : "$color9", children: "\u2192" })
1843
+ ] })
1844
+ },
1845
+ p.id
1846
+ )) }),
1847
+ showEmailForm && providers.length > 0 && /* @__PURE__ */ jsx29(Divider, { label: "or" }),
1848
+ showEmailForm && /* @__PURE__ */ jsxs22(YStack22, { gap: "$3", children: [
1849
+ /* @__PURE__ */ jsx29(Input, { label: "Email", placeholder: "your@email.com", value: email, onChangeText: setEmail, keyboardType: "email-address", autoCapitalize: "none" }),
1850
+ /* @__PURE__ */ jsx29(Input, { label: "Password", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", value: password, onChangeText: setPassword, secureTextEntry: true }),
1851
+ onForgotPassword && /* @__PURE__ */ jsx29(XStack17, { justifyContent: "flex-end", children: /* @__PURE__ */ jsx29(SizableText25, { size: "$3", color: "$color9", onPress: onForgotPassword, children: "Forgot password?" }) }),
1852
+ /* @__PURE__ */ jsx29(
1853
+ Button6,
1854
+ {
1855
+ size: "$5",
1856
+ backgroundColor: "$color9",
1857
+ color: "$color1",
1858
+ borderRadius: "$5",
1859
+ disabled: loading,
1860
+ onPress: () => onEmailSubmit?.(email, password),
1861
+ hoverStyle: { backgroundColor: "$color10" },
1862
+ pressStyle: { backgroundColor: "$color8" },
1863
+ icon: loading ? /* @__PURE__ */ jsx29(Spinner, { size: "small", color: "$color1" }) : void 0,
1864
+ children: "Sign In"
1865
+ }
1866
+ ),
1867
+ onCreateAccount && /* @__PURE__ */ jsx29(Button6, { size: "$3", chromeless: true, onPress: onCreateAccount, children: /* @__PURE__ */ jsx29(SizableText25, { size: "$3", color: "$color9", children: "Create Account" }) })
1868
+ ] }),
1869
+ (onTerms || onPrivacy) && /* @__PURE__ */ jsx29(YStack22, { paddingTop: "$2", alignItems: "center", children: /* @__PURE__ */ jsxs22(SizableText25, { size: "$2", color: "$color8", textAlign: "center", children: [
1870
+ "By continuing you agree to our",
1871
+ " ",
1872
+ onTerms && /* @__PURE__ */ jsx29(SizableText25, { size: "$2", color: "$color9", onPress: onTerms, children: "Terms of Service" }),
1873
+ onTerms && onPrivacy && " & ",
1874
+ onPrivacy && /* @__PURE__ */ jsx29(SizableText25, { size: "$2", color: "$color9", onPress: onPrivacy, children: "Privacy Policy" })
1875
+ ] }) }),
1876
+ footerSlot
1877
+ ]
1878
+ }
1879
+ )
1363
1880
  ] });
1364
1881
  }
1365
1882
 
1366
1883
  // src/patterns/TabBar.tsx
1367
1884
  import { SizableText as SizableText26, XStack as XStack18, YStack as YStack23 } from "tamagui";
1368
- import { jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
1885
+ import { jsx as jsx30, jsxs as jsxs23 } from "react/jsx-runtime";
1369
1886
  function TabBar({ tabs, activeTab, onTabPress, showLabels = true }) {
1370
- return /* @__PURE__ */ jsx29(XStack18, { height: 56, borderTopWidth: 1, borderTopColor: "$borderColor", backgroundColor: "$background", paddingBottom: "$2", children: tabs.map((tab) => {
1887
+ return /* @__PURE__ */ jsx30(XStack18, { height: 56, borderTopWidth: 1, borderTopColor: "$borderColor", backgroundColor: "$background", paddingBottom: "$2", children: tabs.map((tab) => {
1371
1888
  const active = tab.id === activeTab;
1372
- return /* @__PURE__ */ jsxs22(
1889
+ return /* @__PURE__ */ jsxs23(
1373
1890
  YStack23,
1374
1891
  {
1375
1892
  flex: 1,
@@ -1379,8 +1896,8 @@ function TabBar({ tabs, activeTab, onTabPress, showLabels = true }) {
1379
1896
  pressStyle: { opacity: 0.6 },
1380
1897
  onPress: () => onTabPress(tab.id),
1381
1898
  children: [
1382
- tab.icon && /* @__PURE__ */ jsx29(SizableText26, { size: "$5", color: active ? "$color9" : "$color8", children: tab.icon }),
1383
- showLabels && /* @__PURE__ */ jsx29(SizableText26, { size: "$1", color: active ? "$color9" : "$color8", fontWeight: active ? "600" : "400", children: tab.label })
1899
+ tab.icon && /* @__PURE__ */ jsx30(SizableText26, { size: "$5", color: active ? "$color9" : "$color8", children: tab.icon }),
1900
+ showLabels && /* @__PURE__ */ jsx30(SizableText26, { size: "$1", color: active ? "$color9" : "$color8", fontWeight: active ? "600" : "400", children: tab.label })
1384
1901
  ]
1385
1902
  },
1386
1903
  tab.id
@@ -1390,11 +1907,11 @@ function TabBar({ tabs, activeTab, onTabPress, showLabels = true }) {
1390
1907
 
1391
1908
  // src/patterns/SearchBar.tsx
1392
1909
  import { Input as Input2, SizableText as SizableText27, XStack as XStack19 } from "tamagui";
1393
- import { jsx as jsx30, jsxs as jsxs23 } from "react/jsx-runtime";
1910
+ import { jsx as jsx31, jsxs as jsxs24 } from "react/jsx-runtime";
1394
1911
  function SearchBar({ value, onChangeText, placeholder = "Search\u2026", onFilter, onCancel, autoFocus }) {
1395
- return /* @__PURE__ */ jsxs23(XStack19, { height: 44, borderRadius: "$10", backgroundColor: "$color2", alignItems: "center", paddingHorizontal: "$3", gap: "$2", children: [
1396
- /* @__PURE__ */ jsx30(SizableText27, { size: "$4", color: "$color8", children: "\u2315" }),
1397
- /* @__PURE__ */ jsx30(
1912
+ return /* @__PURE__ */ jsxs24(XStack19, { height: 44, borderRadius: "$10", backgroundColor: "$color2", alignItems: "center", paddingHorizontal: "$3", gap: "$2", children: [
1913
+ /* @__PURE__ */ jsx31(SizableText27, { size: "$4", color: "$color8", children: "\u2315" }),
1914
+ /* @__PURE__ */ jsx31(
1398
1915
  Input2,
1399
1916
  {
1400
1917
  flex: 1,
@@ -1408,14 +1925,14 @@ function SearchBar({ value, onChangeText, placeholder = "Search\u2026", onFilter
1408
1925
  autoFocus
1409
1926
  }
1410
1927
  ),
1411
- onFilter && /* @__PURE__ */ jsx30(SizableText27, { size: "$4", color: "$color9", pressStyle: { opacity: 0.6 }, onPress: onFilter, children: "\u2ACF" }),
1412
- onCancel && /* @__PURE__ */ jsx30(SizableText27, { size: "$3", color: "$color9", pressStyle: { opacity: 0.6 }, onPress: onCancel, children: "Cancel" })
1928
+ onFilter && /* @__PURE__ */ jsx31(SizableText27, { size: "$4", color: "$color9", pressStyle: { opacity: 0.6 }, onPress: onFilter, children: "\u2ACF" }),
1929
+ onCancel && /* @__PURE__ */ jsx31(SizableText27, { size: "$3", color: "$color9", pressStyle: { opacity: 0.6 }, onPress: onCancel, children: "Cancel" })
1413
1930
  ] });
1414
1931
  }
1415
1932
 
1416
1933
  // src/patterns/FloatingActionButton.tsx
1417
1934
  import { SizableText as SizableText28, XStack as XStack20 } from "tamagui";
1418
- import { jsx as jsx31, jsxs as jsxs24 } from "react/jsx-runtime";
1935
+ import { jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
1419
1936
  var sizes = { sm: 44, md: 56, lg: 68 };
1420
1937
  var positionStyles = {
1421
1938
  "bottom-right": { right: 20 },
@@ -1424,7 +1941,7 @@ var positionStyles = {
1424
1941
  };
1425
1942
  function FloatingActionButton({ icon, label, onPress, position = "bottom-right", size = "md" }) {
1426
1943
  const dim = sizes[size];
1427
- return /* @__PURE__ */ jsxs24(
1944
+ return /* @__PURE__ */ jsxs25(
1428
1945
  XStack20,
1429
1946
  {
1430
1947
  position: "absolute",
@@ -1442,8 +1959,8 @@ function FloatingActionButton({ icon, label, onPress, position = "bottom-right",
1442
1959
  pressStyle: { scale: 0.95, opacity: 0.9 },
1443
1960
  onPress,
1444
1961
  children: [
1445
- icon && /* @__PURE__ */ jsx31(SizableText28, { color: "$color1", children: icon }),
1446
- label && /* @__PURE__ */ jsx31(SizableText28, { color: "$color1", size: "$4", fontWeight: "600", children: label })
1962
+ icon && /* @__PURE__ */ jsx32(SizableText28, { color: "$color1", children: icon }),
1963
+ label && /* @__PURE__ */ jsx32(SizableText28, { color: "$color1", size: "$4", fontWeight: "600", children: label })
1447
1964
  ]
1448
1965
  }
1449
1966
  );
@@ -1451,72 +1968,85 @@ function FloatingActionButton({ icon, label, onPress, position = "bottom-right",
1451
1968
 
1452
1969
  // src/patterns/ActionSheet.tsx
1453
1970
  import { Sheet as Sheet2, SizableText as SizableText29, XStack as XStack21, YStack as YStack24 } from "tamagui";
1454
- import { jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
1455
- function ActionSheet({ open, onOpenChange, title, items, onSelect, cancelLabel = "Cancel" }) {
1456
- return /* @__PURE__ */ jsxs25(Sheet2, { modal: true, open, onOpenChange, snapPoints: [50], dismissOnSnapToBottom: true, animation: "medium", children: [
1457
- /* @__PURE__ */ jsx32(Sheet2.Overlay, { animation: "lazy", enterStyle: { opacity: 0 }, exitStyle: { opacity: 0 } }),
1458
- /* @__PURE__ */ jsx32(Sheet2.Handle, {}),
1459
- /* @__PURE__ */ jsxs25(Sheet2.Frame, { borderTopLeftRadius: "$6", borderTopRightRadius: "$6", backgroundColor: "$background", children: [
1460
- title && /* @__PURE__ */ jsx32(SizableText29, { size: "$3", color: "$color8", textAlign: "center", paddingTop: "$3", paddingBottom: "$1", children: title }),
1461
- /* @__PURE__ */ jsx32(YStack24, { paddingHorizontal: "$3", paddingTop: "$2", children: items.map((item) => /* @__PURE__ */ jsxs25(
1462
- XStack21,
1463
- {
1464
- height: 52,
1465
- alignItems: "center",
1466
- gap: "$3",
1467
- paddingHorizontal: "$3",
1468
- borderRadius: "$4",
1469
- pressStyle: { backgroundColor: "$color3" },
1470
- onPress: () => {
1471
- onSelect(item.id);
1472
- onOpenChange(false);
1473
- },
1474
- children: [
1475
- item.icon && /* @__PURE__ */ jsx32(SizableText29, { size: "$5", children: item.icon }),
1476
- /* @__PURE__ */ jsx32(
1477
- SizableText29,
1478
- {
1479
- size: "$5",
1480
- flex: 1,
1481
- color: item.destructive ? "$red9" : "$color12",
1482
- fontWeight: item.destructive ? "600" : "400",
1483
- children: item.label
1484
- }
1485
- )
1486
- ]
1487
- },
1488
- item.id
1489
- )) }),
1490
- /* @__PURE__ */ jsx32(YStack24, { paddingHorizontal: "$3", paddingVertical: "$3", borderTopWidth: 1, borderTopColor: "$borderColor", marginTop: "$2", children: /* @__PURE__ */ jsx32(
1491
- XStack21,
1492
- {
1493
- height: 48,
1494
- alignItems: "center",
1495
- justifyContent: "center",
1496
- borderRadius: "$4",
1497
- pressStyle: { backgroundColor: "$color3" },
1498
- onPress: () => onOpenChange(false),
1499
- children: /* @__PURE__ */ jsx32(SizableText29, { size: "$5", fontWeight: "600", color: "$color9", children: cancelLabel })
1500
- }
1501
- ) })
1502
- ] })
1503
- ] });
1971
+ import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
1972
+ function ActionSheet({ open, onOpenChange, title, items, onSelect, cancelLabel = "Cancel", zIndex = 1e5 }) {
1973
+ return /* @__PURE__ */ jsxs26(
1974
+ Sheet2,
1975
+ {
1976
+ modal: true,
1977
+ forceRemoveScrollEnabled: open,
1978
+ open,
1979
+ onOpenChange,
1980
+ snapPoints: [50],
1981
+ dismissOnSnapToBottom: true,
1982
+ zIndex,
1983
+ animation: "medium",
1984
+ children: [
1985
+ /* @__PURE__ */ jsx33(Sheet2.Overlay, { animation: "lazy", enterStyle: { opacity: 0 }, exitStyle: { opacity: 0 } }),
1986
+ /* @__PURE__ */ jsx33(Sheet2.Handle, {}),
1987
+ /* @__PURE__ */ jsxs26(Sheet2.Frame, { children: [
1988
+ title && /* @__PURE__ */ jsx33(SizableText29, { size: "$3", color: "$color8", textAlign: "center", paddingTop: "$3", paddingBottom: "$1", children: title }),
1989
+ /* @__PURE__ */ jsx33(YStack24, { paddingHorizontal: "$3", paddingTop: "$2", children: items.map((item) => /* @__PURE__ */ jsxs26(
1990
+ XStack21,
1991
+ {
1992
+ height: 52,
1993
+ alignItems: "center",
1994
+ gap: "$3",
1995
+ paddingHorizontal: "$3",
1996
+ borderRadius: "$4",
1997
+ pressStyle: { backgroundColor: "$color3" },
1998
+ onPress: () => {
1999
+ onSelect(item.id);
2000
+ onOpenChange(false);
2001
+ },
2002
+ children: [
2003
+ item.icon && /* @__PURE__ */ jsx33(SizableText29, { size: "$5", children: item.icon }),
2004
+ /* @__PURE__ */ jsx33(
2005
+ SizableText29,
2006
+ {
2007
+ size: "$5",
2008
+ flex: 1,
2009
+ color: item.destructive ? "$red9" : "$color12",
2010
+ fontWeight: item.destructive ? "600" : "400",
2011
+ children: item.label
2012
+ }
2013
+ )
2014
+ ]
2015
+ },
2016
+ item.id
2017
+ )) }),
2018
+ /* @__PURE__ */ jsx33(YStack24, { paddingHorizontal: "$3", paddingVertical: "$3", borderTopWidth: 1, borderTopColor: "$borderColor", marginTop: "$2", children: /* @__PURE__ */ jsx33(
2019
+ XStack21,
2020
+ {
2021
+ height: 48,
2022
+ alignItems: "center",
2023
+ justifyContent: "center",
2024
+ borderRadius: "$4",
2025
+ pressStyle: { backgroundColor: "$color3" },
2026
+ onPress: () => onOpenChange(false),
2027
+ children: /* @__PURE__ */ jsx33(SizableText29, { size: "$5", fontWeight: "600", color: "$color9", children: cancelLabel })
2028
+ }
2029
+ ) })
2030
+ ] })
2031
+ ]
2032
+ }
2033
+ );
1504
2034
  }
1505
2035
 
1506
2036
  // src/patterns/Skeleton.tsx
1507
2037
  import { YStack as YStack25 } from "tamagui";
1508
- import { jsx as jsx33 } from "react/jsx-runtime";
2038
+ import { jsx as jsx34 } from "react/jsx-runtime";
1509
2039
  function Skeleton({ width, height, borderRadius, variant = "rectangular" }) {
1510
2040
  const size = variant === "circular" ? height ?? 40 : height;
1511
2041
  const w = variant === "text" ? width ?? "100%" : width;
1512
2042
  const h = variant === "text" ? height ?? 16 : size;
1513
2043
  const r = variant === "circular" ? 9999 : borderRadius ?? 8;
1514
- return /* @__PURE__ */ jsx33(YStack25, { width: w, height: h, borderRadius: r, backgroundColor: "$color3", opacity: 0.6, animation: "slow", enterStyle: { opacity: 0.3 }, exitStyle: { opacity: 0.3 } });
2044
+ return /* @__PURE__ */ jsx34(YStack25, { width: w, height: h, borderRadius: r, backgroundColor: "$color3", opacity: 0.6, animation: "slow", enterStyle: { opacity: 0.3 }, exitStyle: { opacity: 0.3 } });
1515
2045
  }
1516
2046
 
1517
2047
  // src/patterns/NotificationBanner.tsx
1518
2048
  import { SizableText as SizableText30, XStack as XStack22, YStack as YStack26 } from "tamagui";
1519
- import { jsx as jsx34, jsxs as jsxs26 } from "react/jsx-runtime";
2049
+ import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
1520
2050
  var variantColors = {
1521
2051
  info: { bg: "$blue3", text: "$blue11" },
1522
2052
  success: { bg: "$green3", text: "$green11" },
@@ -1525,7 +2055,7 @@ var variantColors = {
1525
2055
  };
1526
2056
  function NotificationBanner({ title, message, variant = "info", onPress, onDismiss, icon }) {
1527
2057
  const colors = variantColors[variant];
1528
- return /* @__PURE__ */ jsxs26(
2058
+ return /* @__PURE__ */ jsxs27(
1529
2059
  XStack22,
1530
2060
  {
1531
2061
  backgroundColor: colors.bg,
@@ -1536,48 +2066,48 @@ function NotificationBanner({ title, message, variant = "info", onPress, onDismi
1536
2066
  onPress,
1537
2067
  pressStyle: onPress ? { opacity: 0.8 } : void 0,
1538
2068
  children: [
1539
- icon && /* @__PURE__ */ jsx34(YStack26, { paddingTop: "$0.5", children: icon }),
1540
- /* @__PURE__ */ jsxs26(YStack26, { flex: 1, gap: "$1", children: [
1541
- /* @__PURE__ */ jsx34(SizableText30, { size: "$4", fontWeight: "600", color: colors.text, children: title }),
1542
- message && /* @__PURE__ */ jsx34(SizableText30, { size: "$3", color: colors.text, opacity: 0.8, children: message })
2069
+ icon && /* @__PURE__ */ jsx35(YStack26, { paddingTop: "$0.5", children: icon }),
2070
+ /* @__PURE__ */ jsxs27(YStack26, { flex: 1, gap: "$1", children: [
2071
+ /* @__PURE__ */ jsx35(SizableText30, { size: "$4", fontWeight: "600", color: colors.text, children: title }),
2072
+ message && /* @__PURE__ */ jsx35(SizableText30, { size: "$3", color: colors.text, opacity: 0.8, children: message })
1543
2073
  ] }),
1544
- onDismiss && /* @__PURE__ */ jsx34(SizableText30, { size: "$3", color: colors.text, opacity: 0.6, onPress: onDismiss, padding: "$1", children: "\u2715" })
2074
+ onDismiss && /* @__PURE__ */ jsx35(SizableText30, { size: "$3", color: colors.text, opacity: 0.6, onPress: onDismiss, padding: "$1", children: "\u2715" })
1545
2075
  ]
1546
2076
  }
1547
2077
  );
1548
2078
  }
1549
2079
 
1550
2080
  // src/patterns/ProgressSteps.tsx
1551
- import { Circle as Circle6, SizableText as SizableText31, XStack as XStack23, YStack as YStack27 } from "tamagui";
1552
- import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
2081
+ import { Circle as Circle7, SizableText as SizableText31, XStack as XStack23, YStack as YStack27 } from "tamagui";
2082
+ import { jsx as jsx36, jsxs as jsxs28 } from "react/jsx-runtime";
1553
2083
  function ProgressSteps({ steps, currentStep, variant = "dots" }) {
1554
2084
  if (variant === "bar") {
1555
2085
  const progress = steps.length > 1 ? currentStep / (steps.length - 1) * 100 : 100;
1556
- return /* @__PURE__ */ jsxs27(YStack27, { gap: "$2", children: [
1557
- /* @__PURE__ */ jsx35(YStack27, { height: 4, backgroundColor: "$color4", borderRadius: 2, overflow: "hidden", children: /* @__PURE__ */ jsx35(YStack27, { height: 4, width: `${progress}%`, backgroundColor: "$color9", borderRadius: 2, animation: "quick" }) }),
1558
- /* @__PURE__ */ jsx35(XStack23, { justifyContent: "space-between", children: steps.map((label, i) => /* @__PURE__ */ jsx35(SizableText31, { size: "$2", color: i <= currentStep ? "$color9" : "$color8", children: label }, i)) })
2086
+ return /* @__PURE__ */ jsxs28(YStack27, { gap: "$2", children: [
2087
+ /* @__PURE__ */ jsx36(YStack27, { height: 4, backgroundColor: "$color4", borderRadius: 2, overflow: "hidden", children: /* @__PURE__ */ jsx36(YStack27, { height: 4, width: `${progress}%`, backgroundColor: "$color9", borderRadius: 2, animation: "quick" }) }),
2088
+ /* @__PURE__ */ jsx36(XStack23, { justifyContent: "space-between", children: steps.map((label, i) => /* @__PURE__ */ jsx36(SizableText31, { size: "$2", color: i <= currentStep ? "$color9" : "$color8", children: label }, i)) })
1559
2089
  ] });
1560
2090
  }
1561
- return /* @__PURE__ */ jsx35(XStack23, { alignItems: "center", justifyContent: "center", gap: "$0", children: steps.map((label, i) => /* @__PURE__ */ jsxs27(XStack23, { alignItems: "center", gap: "$0", children: [
1562
- /* @__PURE__ */ jsxs27(YStack27, { alignItems: "center", gap: "$1.5", children: [
1563
- /* @__PURE__ */ jsx35(Circle6, { size: variant === "numbered" ? 28 : 10, backgroundColor: i <= currentStep ? "$color9" : "$color4", animation: "quick", children: variant === "numbered" && /* @__PURE__ */ jsx35(SizableText31, { size: "$2", fontWeight: "600", color: i <= currentStep ? "$color1" : "$color8", children: i + 1 }) }),
1564
- /* @__PURE__ */ jsx35(SizableText31, { size: "$1", color: i <= currentStep ? "$color11" : "$color8", numberOfLines: 1, children: label })
2091
+ return /* @__PURE__ */ jsx36(XStack23, { alignItems: "center", justifyContent: "center", gap: "$0", children: steps.map((label, i) => /* @__PURE__ */ jsxs28(XStack23, { alignItems: "center", gap: "$0", children: [
2092
+ /* @__PURE__ */ jsxs28(YStack27, { alignItems: "center", gap: "$1.5", children: [
2093
+ /* @__PURE__ */ jsx36(Circle7, { size: variant === "numbered" ? 28 : 10, backgroundColor: i <= currentStep ? "$color9" : "$color4", animation: "quick", children: variant === "numbered" && /* @__PURE__ */ jsx36(SizableText31, { size: "$2", fontWeight: "600", color: i <= currentStep ? "$color1" : "$color8", children: i + 1 }) }),
2094
+ /* @__PURE__ */ jsx36(SizableText31, { size: "$1", color: i <= currentStep ? "$color11" : "$color8", numberOfLines: 1, children: label })
1565
2095
  ] }),
1566
- i < steps.length - 1 && /* @__PURE__ */ jsx35(YStack27, { height: 2, width: 32, backgroundColor: i < currentStep ? "$color9" : "$color4", marginBottom: "$4" })
2096
+ i < steps.length - 1 && /* @__PURE__ */ jsx36(YStack27, { height: 2, width: 32, backgroundColor: i < currentStep ? "$color9" : "$color4", marginBottom: "$4" })
1567
2097
  ] }, i)) });
1568
2098
  }
1569
2099
 
1570
2100
  // src/patterns/SwipeableRow.tsx
1571
- import { useState as useState7 } from "react";
2101
+ import { useState as useState8 } from "react";
1572
2102
  import { Button as Button7, SizableText as SizableText32, XStack as XStack24, YStack as YStack28 } from "tamagui";
1573
- import { Fragment as Fragment2, jsx as jsx36, jsxs as jsxs28 } from "react/jsx-runtime";
2103
+ import { Fragment as Fragment3, jsx as jsx37, jsxs as jsxs29 } from "react/jsx-runtime";
1574
2104
  function SwipeableRow({ children, leftActions, rightActions }) {
1575
- const [showActions, setShowActions] = useState7(false);
2105
+ const [showActions, setShowActions] = useState8(false);
1576
2106
  const actions = [...leftActions ?? [], ...rightActions ?? []];
1577
- if (actions.length === 0) return /* @__PURE__ */ jsx36(Fragment2, { children });
1578
- return /* @__PURE__ */ jsxs28(YStack28, { children: [
1579
- /* @__PURE__ */ jsx36(YStack28, { onLongPress: () => setShowActions((v) => !v), pressStyle: { opacity: 0.9 }, children }),
1580
- showActions && /* @__PURE__ */ jsx36(XStack24, { gap: "$2", padding: "$2", animation: "quick", enterStyle: { opacity: 0, scale: 0.95 }, children: actions.map((action) => /* @__PURE__ */ jsx36(
2107
+ if (actions.length === 0) return /* @__PURE__ */ jsx37(Fragment3, { children });
2108
+ return /* @__PURE__ */ jsxs29(YStack28, { children: [
2109
+ /* @__PURE__ */ jsx37(YStack28, { onLongPress: () => setShowActions((v) => !v), pressStyle: { opacity: 0.9 }, children }),
2110
+ showActions && /* @__PURE__ */ jsx37(XStack24, { gap: "$2", padding: "$2", animation: "quick", enterStyle: { opacity: 0, scale: 0.95 }, children: actions.map((action) => /* @__PURE__ */ jsx37(
1581
2111
  Button7,
1582
2112
  {
1583
2113
  flex: 1,
@@ -1588,7 +2118,7 @@ function SwipeableRow({ children, leftActions, rightActions }) {
1588
2118
  action.onPress();
1589
2119
  setShowActions(false);
1590
2120
  },
1591
- children: /* @__PURE__ */ jsx36(SizableText32, { size: "$2", fontWeight: "600", color: "white", children: action.label })
2121
+ children: /* @__PURE__ */ jsx37(SizableText32, { size: "$2", fontWeight: "600", color: "white", children: action.label })
1592
2122
  },
1593
2123
  action.id
1594
2124
  )) })
@@ -1598,9 +2128,9 @@ function SwipeableRow({ children, leftActions, rightActions }) {
1598
2128
  // src/patterns/MediaCard.tsx
1599
2129
  import { Image as Image5, SizableText as SizableText33, XStack as XStack25, YStack as YStack29 } from "tamagui";
1600
2130
  import { LinearGradient } from "tamagui/linear-gradient";
1601
- import { jsx as jsx37, jsxs as jsxs29 } from "react/jsx-runtime";
2131
+ import { jsx as jsx38, jsxs as jsxs30 } from "react/jsx-runtime";
1602
2132
  function MediaCard({ image, title, subtitle, overlay = "gradient", aspectRatio = 16 / 9, onPress, badge }) {
1603
- return /* @__PURE__ */ jsx37(
2133
+ return /* @__PURE__ */ jsx38(
1604
2134
  YStack29,
1605
2135
  {
1606
2136
  borderRadius: "$4",
@@ -1608,9 +2138,9 @@ function MediaCard({ image, title, subtitle, overlay = "gradient", aspectRatio =
1608
2138
  onPress,
1609
2139
  pressStyle: onPress ? { scale: 0.98, opacity: 0.9 } : void 0,
1610
2140
  animation: "quick",
1611
- children: /* @__PURE__ */ jsxs29(YStack29, { aspectRatio, children: [
1612
- /* @__PURE__ */ jsx37(Image5, { source: { uri: image }, width: "100%", height: "100%", objectFit: "cover" }),
1613
- overlay === "gradient" && /* @__PURE__ */ jsx37(
2141
+ children: /* @__PURE__ */ jsxs30(YStack29, { aspectRatio, children: [
2142
+ /* @__PURE__ */ jsx38(Image5, { source: { uri: image }, width: "100%", height: "100%", objectFit: "cover" }),
2143
+ overlay === "gradient" && /* @__PURE__ */ jsx38(
1614
2144
  LinearGradient,
1615
2145
  {
1616
2146
  colors: ["transparent", "rgba(0,0,0,0.7)"],
@@ -1623,8 +2153,8 @@ function MediaCard({ image, title, subtitle, overlay = "gradient", aspectRatio =
1623
2153
  height: "60%"
1624
2154
  }
1625
2155
  ),
1626
- overlay === "dark" && /* @__PURE__ */ jsx37(YStack29, { position: "absolute", fullscreen: true, backgroundColor: "rgba(0,0,0,0.4)" }),
1627
- badge && /* @__PURE__ */ jsx37(
2156
+ overlay === "dark" && /* @__PURE__ */ jsx38(YStack29, { position: "absolute", fullscreen: true, backgroundColor: "rgba(0,0,0,0.4)" }),
2157
+ badge && /* @__PURE__ */ jsx38(
1628
2158
  XStack25,
1629
2159
  {
1630
2160
  position: "absolute",
@@ -1634,12 +2164,12 @@ function MediaCard({ image, title, subtitle, overlay = "gradient", aspectRatio =
1634
2164
  paddingHorizontal: "$2",
1635
2165
  paddingVertical: "$1",
1636
2166
  borderRadius: "$2",
1637
- children: /* @__PURE__ */ jsx37(SizableText33, { size: "$1", fontWeight: "600", color: "$color1", children: badge })
2167
+ children: /* @__PURE__ */ jsx38(SizableText33, { size: "$1", fontWeight: "600", color: "$color1", children: badge })
1638
2168
  }
1639
2169
  ),
1640
- /* @__PURE__ */ jsxs29(YStack29, { position: "absolute", bottom: 0, left: 0, right: 0, padding: "$3", gap: "$1", children: [
1641
- /* @__PURE__ */ jsx37(SizableText33, { size: "$5", fontWeight: "600", color: "white", children: title }),
1642
- subtitle && /* @__PURE__ */ jsx37(SizableText33, { size: "$3", color: "rgba(255,255,255,0.8)", children: subtitle })
2170
+ /* @__PURE__ */ jsxs30(YStack29, { position: "absolute", bottom: 0, left: 0, right: 0, padding: "$3", gap: "$1", children: [
2171
+ /* @__PURE__ */ jsx38(SizableText33, { size: "$5", fontWeight: "600", color: "white", children: title }),
2172
+ subtitle && /* @__PURE__ */ jsx38(SizableText33, { size: "$3", color: "rgba(255,255,255,0.8)", children: subtitle })
1643
2173
  ] })
1644
2174
  ] })
1645
2175
  }
@@ -1647,17 +2177,17 @@ function MediaCard({ image, title, subtitle, overlay = "gradient", aspectRatio =
1647
2177
  }
1648
2178
 
1649
2179
  // src/patterns/Carousel.tsx
1650
- import { Children as Children2, useState as useState8 } from "react";
1651
- import { Circle as Circle7, XStack as XStack26, YStack as YStack30 } from "tamagui";
1652
- import { ScrollView as ScrollView3 } from "react-native";
1653
- import { jsx as jsx38, jsxs as jsxs30 } from "react/jsx-runtime";
2180
+ import { Children as Children2, useState as useState9 } from "react";
2181
+ import { Circle as Circle8, XStack as XStack26, YStack as YStack30 } from "tamagui";
2182
+ import { ScrollView as ScrollView4 } from "react-native";
2183
+ import { jsx as jsx39, jsxs as jsxs31 } from "react/jsx-runtime";
1654
2184
  function Carousel({ children, gap = "$3", snapToInterval, showIndicators = false }) {
1655
- const [activeIndex, setActiveIndex] = useState8(0);
2185
+ const [activeIndex, setActiveIndex] = useState9(0);
1656
2186
  const count = Children2.count(children);
1657
2187
  const gapPx = gap === "$2" ? 8 : gap === "$3" ? 12 : 16;
1658
- return /* @__PURE__ */ jsxs30(YStack30, { gap: "$3", children: [
1659
- /* @__PURE__ */ jsx38(
1660
- ScrollView3,
2188
+ return /* @__PURE__ */ jsxs31(YStack30, { gap: "$3", children: [
2189
+ /* @__PURE__ */ jsx39(
2190
+ ScrollView4,
1661
2191
  {
1662
2192
  horizontal: true,
1663
2193
  showsHorizontalScrollIndicator: false,
@@ -1670,85 +2200,1715 @@ function Carousel({ children, gap = "$3", snapToInterval, showIndicators = false
1670
2200
  children
1671
2201
  }
1672
2202
  ),
1673
- showIndicators && count > 1 && /* @__PURE__ */ jsx38(XStack26, { justifyContent: "center", gap: "$1.5", children: Array.from({ length: count }, (_, i) => /* @__PURE__ */ jsx38(Circle7, { size: 6, backgroundColor: i === activeIndex ? "$color9" : "$color4", animation: "quick" }, i)) })
2203
+ showIndicators && count > 1 && /* @__PURE__ */ jsx39(XStack26, { justifyContent: "center", gap: "$1.5", children: Array.from({ length: count }, (_, i) => /* @__PURE__ */ jsx39(Circle8, { size: 6, backgroundColor: i === activeIndex ? "$color9" : "$color4", animation: "quick" }, i)) })
1674
2204
  ] });
1675
2205
  }
1676
2206
 
1677
2207
  // src/patterns/PullToRefresh.tsx
1678
2208
  import { YStack as YStack31 } from "tamagui";
1679
- import { RefreshControl, ScrollView as ScrollView4 } from "react-native";
1680
- import { jsx as jsx39 } from "react/jsx-runtime";
2209
+ import { RefreshControl, ScrollView as ScrollView5 } from "react-native";
2210
+ import { jsx as jsx40 } from "react/jsx-runtime";
1681
2211
  function PullToRefresh({ children, onRefresh, refreshing = false }) {
1682
- return /* @__PURE__ */ jsx39(
1683
- ScrollView4,
2212
+ return /* @__PURE__ */ jsx40(
2213
+ ScrollView5,
1684
2214
  {
1685
2215
  contentContainerStyle: { flexGrow: 1 },
1686
- refreshControl: /* @__PURE__ */ jsx39(RefreshControl, { refreshing, onRefresh }),
1687
- children: /* @__PURE__ */ jsx39(YStack31, { flex: 1, children })
2216
+ refreshControl: /* @__PURE__ */ jsx40(RefreshControl, { refreshing, onRefresh }),
2217
+ children: /* @__PURE__ */ jsx40(YStack31, { flex: 1, children })
1688
2218
  }
1689
2219
  );
1690
2220
  }
2221
+
2222
+ // src/patterns/ProductCard.tsx
2223
+ import { Button as Button8, Image as Image6, SizableText as SizableText34, XStack as XStack27, YStack as YStack32 } from "tamagui";
2224
+ import { jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
2225
+ function Stars({ rating = 0 }) {
2226
+ return /* @__PURE__ */ jsx41(XStack27, { gap: "$0.5", children: Array.from({ length: 5 }, (_, i) => /* @__PURE__ */ jsx41(SizableText34, { size: "$2", color: i < Math.round(rating) ? "$yellow9" : "$color5", children: "\u2605" }, i)) });
2227
+ }
2228
+ function CardContent2({ title, price, originalPrice, rating, reviewCount, onAddToCart }) {
2229
+ return /* @__PURE__ */ jsxs32(YStack32, { flex: 1, gap: "$1.5", justifyContent: "space-between", children: [
2230
+ /* @__PURE__ */ jsxs32(YStack32, { gap: "$1", children: [
2231
+ /* @__PURE__ */ jsx41(SizableText34, { size: "$4", fontWeight: "600", numberOfLines: 2, children: title }),
2232
+ rating !== void 0 && /* @__PURE__ */ jsxs32(XStack27, { gap: "$1.5", alignItems: "center", children: [
2233
+ /* @__PURE__ */ jsx41(Stars, { rating }),
2234
+ reviewCount !== void 0 && /* @__PURE__ */ jsxs32(SizableText34, { size: "$2", color: "$color9", children: [
2235
+ "(",
2236
+ reviewCount,
2237
+ ")"
2238
+ ] })
2239
+ ] })
2240
+ ] }),
2241
+ /* @__PURE__ */ jsxs32(XStack27, { alignItems: "center", justifyContent: "space-between", children: [
2242
+ /* @__PURE__ */ jsxs32(XStack27, { gap: "$2", alignItems: "baseline", children: [
2243
+ /* @__PURE__ */ jsx41(SizableText34, { size: "$6", fontWeight: "700", children: price }),
2244
+ originalPrice && /* @__PURE__ */ jsx41(SizableText34, { size: "$3", color: "$color8", textDecorationLine: "line-through", children: originalPrice })
2245
+ ] }),
2246
+ onAddToCart && /* @__PURE__ */ jsx41(
2247
+ Button8,
2248
+ {
2249
+ size: "$3",
2250
+ backgroundColor: "$color9",
2251
+ color: "$color1",
2252
+ borderRadius: "$10",
2253
+ onPress: (e) => {
2254
+ e.stopPropagation?.();
2255
+ onAddToCart();
2256
+ },
2257
+ pressStyle: { backgroundColor: "$color8", scale: 0.95 },
2258
+ animation: "quick",
2259
+ children: "+ Cart"
2260
+ }
2261
+ )
2262
+ ] })
2263
+ ] });
2264
+ }
2265
+ function ProductCard({ image, title, price, originalPrice, rating, reviewCount, badge, onPress, onAddToCart, variant = "vertical" }) {
2266
+ const isHorizontal = variant === "horizontal";
2267
+ const Wrapper = isHorizontal ? XStack27 : YStack32;
2268
+ return /* @__PURE__ */ jsxs32(
2269
+ Wrapper,
2270
+ {
2271
+ backgroundColor: "$color1",
2272
+ borderRadius: "$5",
2273
+ overflow: "hidden",
2274
+ borderWidth: 1,
2275
+ borderColor: "$color4",
2276
+ onPress,
2277
+ animation: "quick",
2278
+ pressStyle: onPress ? { scale: 0.98, opacity: 0.9 } : void 0,
2279
+ ...isHorizontal ? { height: 140 } : {},
2280
+ children: [
2281
+ /* @__PURE__ */ jsxs32(YStack32, { ...isHorizontal ? { width: 140 } : { aspectRatio: 4 / 3 }, position: "relative", children: [
2282
+ /* @__PURE__ */ jsx41(Image6, { source: { uri: image }, width: "100%", height: "100%", objectFit: "cover" }),
2283
+ badge && /* @__PURE__ */ jsx41(
2284
+ XStack27,
2285
+ {
2286
+ position: "absolute",
2287
+ top: "$2",
2288
+ left: "$2",
2289
+ backgroundColor: "$red9",
2290
+ paddingHorizontal: "$2",
2291
+ paddingVertical: "$1",
2292
+ borderRadius: "$10",
2293
+ children: /* @__PURE__ */ jsx41(SizableText34, { size: "$1", fontWeight: "700", color: "white", children: badge })
2294
+ }
2295
+ )
2296
+ ] }),
2297
+ /* @__PURE__ */ jsx41(YStack32, { flex: 1, padding: "$3", children: /* @__PURE__ */ jsx41(CardContent2, { ...{ title, price, originalPrice, rating, reviewCount, onAddToCart } }) })
2298
+ ]
2299
+ }
2300
+ );
2301
+ }
2302
+
2303
+ // src/patterns/PricingTable.tsx
2304
+ import { Button as Button9, Circle as Circle9, SizableText as SizableText35, XStack as XStack28, YStack as YStack33 } from "tamagui";
2305
+ import { jsx as jsx42, jsxs as jsxs33 } from "react/jsx-runtime";
2306
+ function BillingToggle({ annual, onToggle }) {
2307
+ return /* @__PURE__ */ jsx42(XStack28, { alignSelf: "center", backgroundColor: "$color3", borderRadius: "$10", padding: "$1", gap: "$0.5", children: ["Monthly", "Annual"].map((label, i) => {
2308
+ const active = i === 1 ? annual : !annual;
2309
+ return /* @__PURE__ */ jsx42(
2310
+ XStack28,
2311
+ {
2312
+ paddingHorizontal: "$4",
2313
+ paddingVertical: "$2",
2314
+ borderRadius: "$10",
2315
+ backgroundColor: active ? "$color9" : "transparent",
2316
+ onPress: () => onToggle(i === 1),
2317
+ pressStyle: { opacity: 0.8 },
2318
+ animation: "quick",
2319
+ children: /* @__PURE__ */ jsx42(SizableText35, { size: "$3", fontWeight: "600", color: active ? "$color1" : "$color10", children: label })
2320
+ },
2321
+ label
2322
+ );
2323
+ }) });
2324
+ }
2325
+ function PlanRow2({ plan, selected, onSelect }) {
2326
+ return /* @__PURE__ */ jsxs33(
2327
+ XStack28,
2328
+ {
2329
+ padding: "$4",
2330
+ borderRadius: "$6",
2331
+ borderWidth: 2,
2332
+ borderColor: selected ? "$color9" : "$color4",
2333
+ backgroundColor: selected ? "$color2" : "$color1",
2334
+ alignItems: "center",
2335
+ gap: "$3",
2336
+ onPress: onSelect,
2337
+ pressStyle: { scale: 0.98, opacity: 0.9 },
2338
+ animation: "quick",
2339
+ cursor: "pointer",
2340
+ position: "relative",
2341
+ children: [
2342
+ plan.popular && /* @__PURE__ */ jsx42(XStack28, { position: "absolute", top: -10, right: 12, backgroundColor: "$color9", paddingHorizontal: "$2.5", paddingVertical: 2, borderRadius: "$10", children: /* @__PURE__ */ jsx42(SizableText35, { size: "$1", fontWeight: "700", color: "$color1", children: "BEST VALUE" }) }),
2343
+ /* @__PURE__ */ jsx42(
2344
+ Circle9,
2345
+ {
2346
+ size: 22,
2347
+ borderWidth: 2,
2348
+ borderColor: selected ? "$color9" : "$color6",
2349
+ backgroundColor: selected ? "$color9" : "transparent",
2350
+ children: selected && /* @__PURE__ */ jsx42(Circle9, { size: 8, backgroundColor: "$color1" })
2351
+ }
2352
+ ),
2353
+ /* @__PURE__ */ jsxs33(YStack33, { flex: 1, gap: "$0.5", children: [
2354
+ /* @__PURE__ */ jsxs33(XStack28, { alignItems: "center", gap: "$2", children: [
2355
+ /* @__PURE__ */ jsx42(SizableText35, { size: "$5", fontWeight: "700", children: plan.name }),
2356
+ plan.trial && /* @__PURE__ */ jsx42(XStack28, { backgroundColor: "$green3", paddingHorizontal: "$2", paddingVertical: 2, borderRadius: "$10", children: /* @__PURE__ */ jsx42(SizableText35, { size: "$1", fontWeight: "700", color: "$green9", children: plan.trial }) })
2357
+ ] }),
2358
+ plan.description && /* @__PURE__ */ jsx42(SizableText35, { size: "$2", color: "$color10", children: plan.description })
2359
+ ] }),
2360
+ /* @__PURE__ */ jsx42(SizableText35, { size: "$5", fontWeight: "800", children: plan.price })
2361
+ ]
2362
+ }
2363
+ );
2364
+ }
2365
+ function FeatureList({ features }) {
2366
+ return /* @__PURE__ */ jsx42(YStack33, { gap: "$2.5", paddingHorizontal: "$1", children: features.map((f, i) => /* @__PURE__ */ jsxs33(XStack28, { gap: "$2.5", alignItems: "center", children: [
2367
+ /* @__PURE__ */ jsx42(Circle9, { size: 20, backgroundColor: f.included ? "$green3" : "$color3", children: /* @__PURE__ */ jsx42(SizableText35, { size: "$1", fontWeight: "700", color: f.included ? "$green9" : "$color8", children: f.included ? "\u2713" : "\u2014" }) }),
2368
+ /* @__PURE__ */ jsx42(SizableText35, { size: "$3", color: f.included ? "$color11" : "$color8", flex: 1, children: f.label })
2369
+ ] }, i)) });
2370
+ }
2371
+ function PricingTable({ plans, selectedPlan, onSelectPlan, annual = false, onToggleBilling, onContinue, continueLabel, reassurance }) {
2372
+ const selected = selectedPlan ?? plans.find((p) => p.popular)?.id ?? plans[0]?.id;
2373
+ const activePlan = plans.find((p) => p.id === selected);
2374
+ return /* @__PURE__ */ jsxs33(YStack33, { gap: "$4", children: [
2375
+ onToggleBilling && /* @__PURE__ */ jsx42(BillingToggle, { annual, onToggle: onToggleBilling }),
2376
+ activePlan && activePlan.features.length > 0 && /* @__PURE__ */ jsx42(YStack33, { backgroundColor: "$color1", borderRadius: "$6", padding: "$4", gap: "$3", borderWidth: 1, borderColor: "$color4", children: /* @__PURE__ */ jsx42(FeatureList, { features: activePlan.features }) }),
2377
+ /* @__PURE__ */ jsx42(YStack33, { gap: "$3", children: plans.map((plan) => /* @__PURE__ */ jsx42(
2378
+ PlanRow2,
2379
+ {
2380
+ plan,
2381
+ selected: selected === plan.id,
2382
+ onSelect: () => onSelectPlan?.(plan.id)
2383
+ },
2384
+ plan.id
2385
+ )) }),
2386
+ reassurance && /* @__PURE__ */ jsx42(SizableText35, { size: "$2", color: "$color10", textAlign: "center", children: reassurance }),
2387
+ onContinue && /* @__PURE__ */ jsx42(
2388
+ Button9,
2389
+ {
2390
+ size: "$5",
2391
+ backgroundColor: "$color9",
2392
+ color: "$color1",
2393
+ borderRadius: "$10",
2394
+ fontWeight: "700",
2395
+ onPress: onContinue,
2396
+ pressStyle: { scale: 0.97, backgroundColor: "$color8" },
2397
+ animation: "quick",
2398
+ children: continueLabel ?? activePlan?.cta ?? "Get Started"
2399
+ }
2400
+ )
2401
+ ] });
2402
+ }
2403
+
2404
+ // src/patterns/CountdownBanner.tsx
2405
+ import { useState as useState10, useEffect as useEffect4, useRef, useCallback as useCallback2 } from "react";
2406
+ import { SizableText as SizableText36, XStack as XStack29, YStack as YStack34 } from "tamagui";
2407
+ import { jsx as jsx43, jsxs as jsxs34 } from "react/jsx-runtime";
2408
+ function useCountdown2(endTime, minutes, onExpire) {
2409
+ const getRemaining = useCallback2(() => {
2410
+ if (endTime) return Math.max(0, Math.floor((endTime.getTime() - Date.now()) / 1e3));
2411
+ return 0;
2412
+ }, [endTime]);
2413
+ const [seconds, setSeconds] = useState10(() => endTime ? getRemaining() : (minutes ?? 0) * 60);
2414
+ const firedRef = useRef(false);
2415
+ useEffect4(() => {
2416
+ if (endTime) setSeconds(getRemaining());
2417
+ else setSeconds((minutes ?? 0) * 60);
2418
+ firedRef.current = false;
2419
+ }, [endTime, minutes, getRemaining]);
2420
+ useEffect4(() => {
2421
+ if (seconds <= 0) return;
2422
+ const id = setInterval(() => {
2423
+ setSeconds((s) => {
2424
+ const next = endTime ? Math.max(0, Math.floor((endTime.getTime() - Date.now()) / 1e3)) : s - 1;
2425
+ if (next <= 0 && !firedRef.current) {
2426
+ firedRef.current = true;
2427
+ onExpire?.();
2428
+ }
2429
+ return Math.max(0, next);
2430
+ });
2431
+ }, 1e3);
2432
+ return () => clearInterval(id);
2433
+ }, [seconds > 0, endTime, onExpire]);
2434
+ const hh = String(Math.floor(seconds / 3600)).padStart(2, "0");
2435
+ const mm = String(Math.floor(seconds % 3600 / 60)).padStart(2, "0");
2436
+ const ss = String(seconds % 60).padStart(2, "0");
2437
+ const display = seconds >= 3600 ? `${hh}:${mm}:${ss}` : `${mm}:${ss}`;
2438
+ return { display, expired: seconds <= 0 };
2439
+ }
2440
+ function TimeBox({ value }) {
2441
+ return /* @__PURE__ */ jsx43(XStack29, { backgroundColor: "rgba(0,0,0,0.15)", paddingHorizontal: "$2", paddingVertical: "$1", borderRadius: "$3", children: /* @__PURE__ */ jsx43(SizableText36, { size: "$6", fontWeight: "800", color: "white", fontFamily: "$mono", children: value }) });
2442
+ }
2443
+ function CountdownBanner({ endTime, minutes, label = "Offer ends in", onExpire, variant = "banner" }) {
2444
+ const { display, expired } = useCountdown2(endTime, minutes, onExpire);
2445
+ if (expired) return null;
2446
+ const parts = display.split(":");
2447
+ if (variant === "badge") {
2448
+ return /* @__PURE__ */ jsxs34(XStack29, { backgroundColor: "$red9", paddingHorizontal: "$2.5", paddingVertical: "$1", borderRadius: "$10", gap: "$1.5", alignItems: "center", children: [
2449
+ /* @__PURE__ */ jsx43(SizableText36, { size: "$1", fontWeight: "600", color: "white", children: label }),
2450
+ /* @__PURE__ */ jsx43(SizableText36, { size: "$2", fontWeight: "800", color: "white", fontFamily: "$mono", children: display })
2451
+ ] });
2452
+ }
2453
+ if (variant === "compact") {
2454
+ return /* @__PURE__ */ jsxs34(XStack29, { backgroundColor: "$red3", paddingHorizontal: "$3", paddingVertical: "$2", borderRadius: "$4", gap: "$2", alignItems: "center", alignSelf: "center", children: [
2455
+ /* @__PURE__ */ jsx43(SizableText36, { size: "$3", fontWeight: "600", color: "$red9", children: label }),
2456
+ /* @__PURE__ */ jsx43(SizableText36, { size: "$5", fontWeight: "800", color: "$red9", fontFamily: "$mono", children: display })
2457
+ ] });
2458
+ }
2459
+ return /* @__PURE__ */ jsxs34(YStack34, { backgroundColor: "$red9", paddingVertical: "$3", paddingHorizontal: "$4", gap: "$1.5", alignItems: "center", children: [
2460
+ /* @__PURE__ */ jsx43(SizableText36, { size: "$3", fontWeight: "600", color: "white", opacity: 0.9, children: label }),
2461
+ /* @__PURE__ */ jsx43(XStack29, { gap: "$1.5", alignItems: "center", children: parts.map((p, i) => /* @__PURE__ */ jsxs34(XStack29, { gap: "$1.5", alignItems: "center", children: [
2462
+ i > 0 && /* @__PURE__ */ jsx43(SizableText36, { size: "$6", fontWeight: "800", color: "white", children: ":" }),
2463
+ /* @__PURE__ */ jsx43(TimeBox, { value: p })
2464
+ ] }, i)) })
2465
+ ] });
2466
+ }
2467
+
2468
+ // src/patterns/TestimonialCard.tsx
2469
+ import { Image as Image7, SizableText as SizableText37, XStack as XStack30, YStack as YStack35 } from "tamagui";
2470
+ import { jsx as jsx44, jsxs as jsxs35 } from "react/jsx-runtime";
2471
+ function Stars2({ count = 0 }) {
2472
+ if (!count) return null;
2473
+ return /* @__PURE__ */ jsx44(XStack30, { gap: "$0.5", children: Array.from({ length: 5 }, (_, i) => /* @__PURE__ */ jsx44(SizableText37, { size: "$3", color: i < Math.round(count) ? "$yellow9" : "$color5", children: "\u2605" }, i)) });
2474
+ }
2475
+ function AuthorRow({ author, role, avatar }) {
2476
+ return /* @__PURE__ */ jsxs35(XStack30, { gap: "$2.5", alignItems: "center", children: [
2477
+ avatar && /* @__PURE__ */ jsx44(Image7, { source: { uri: avatar }, width: 36, height: 36, borderRadius: 18, objectFit: "cover" }),
2478
+ /* @__PURE__ */ jsxs35(YStack35, { children: [
2479
+ /* @__PURE__ */ jsx44(SizableText37, { size: "$3", fontWeight: "600", children: author }),
2480
+ role && /* @__PURE__ */ jsx44(SizableText37, { size: "$2", color: "$color9", children: role })
2481
+ ] })
2482
+ ] });
2483
+ }
2484
+ function TestimonialCard2({ quote, author, role, avatar, rating, variant = "card" }) {
2485
+ if (variant === "minimal") {
2486
+ return /* @__PURE__ */ jsxs35(YStack35, { gap: "$3", paddingVertical: "$2", children: [
2487
+ /* @__PURE__ */ jsx44(Stars2, { count: rating }),
2488
+ /* @__PURE__ */ jsxs35(SizableText37, { size: "$4", color: "$color11", fontStyle: "italic", lineHeight: 24, children: [
2489
+ '"',
2490
+ quote,
2491
+ '"'
2492
+ ] }),
2493
+ /* @__PURE__ */ jsx44(AuthorRow, { author, role, avatar })
2494
+ ] });
2495
+ }
2496
+ if (variant === "featured") {
2497
+ return /* @__PURE__ */ jsxs35(YStack35, { backgroundColor: "$color3", padding: "$5", borderRadius: "$6", gap: "$4", alignItems: "center", children: [
2498
+ /* @__PURE__ */ jsx44(SizableText37, { size: "$8", color: "$color9", opacity: 0.3, fontWeight: "800", children: '"' }),
2499
+ /* @__PURE__ */ jsx44(Stars2, { count: rating }),
2500
+ /* @__PURE__ */ jsxs35(SizableText37, { size: "$5", color: "$color12", fontStyle: "italic", textAlign: "center", lineHeight: 28, children: [
2501
+ '"',
2502
+ quote,
2503
+ '"'
2504
+ ] }),
2505
+ /* @__PURE__ */ jsx44(AuthorRow, { author, role, avatar })
2506
+ ] });
2507
+ }
2508
+ return /* @__PURE__ */ jsxs35(
2509
+ YStack35,
2510
+ {
2511
+ backgroundColor: "$color1",
2512
+ padding: "$4",
2513
+ borderRadius: "$5",
2514
+ borderWidth: 1,
2515
+ borderColor: "$color4",
2516
+ gap: "$3",
2517
+ children: [
2518
+ /* @__PURE__ */ jsx44(Stars2, { count: rating }),
2519
+ /* @__PURE__ */ jsxs35(SizableText37, { size: "$4", color: "$color11", fontStyle: "italic", lineHeight: 24, children: [
2520
+ '"',
2521
+ quote,
2522
+ '"'
2523
+ ] }),
2524
+ /* @__PURE__ */ jsx44(AuthorRow, { author, role, avatar })
2525
+ ]
2526
+ }
2527
+ );
2528
+ }
2529
+
2530
+ // src/patterns/ConfirmDialog.tsx
2531
+ import { AlertDialog as AlertDialog2, Button as Button10, SizableText as SizableText38, XStack as XStack31, YStack as YStack36 } from "tamagui";
2532
+ import { jsx as jsx45, jsxs as jsxs36 } from "react/jsx-runtime";
2533
+ function ConfirmDialog({
2534
+ open,
2535
+ onOpenChange,
2536
+ title,
2537
+ description,
2538
+ confirmLabel = "Confirm",
2539
+ cancelLabel = "Cancel",
2540
+ onConfirm,
2541
+ onCancel,
2542
+ destructive = false,
2543
+ icon
2544
+ }) {
2545
+ const handleCancel = () => {
2546
+ onCancel?.();
2547
+ onOpenChange(false);
2548
+ };
2549
+ const handleConfirm = () => {
2550
+ onConfirm?.();
2551
+ onOpenChange(false);
2552
+ };
2553
+ return /* @__PURE__ */ jsx45(AlertDialog2, { open, onOpenChange, children: /* @__PURE__ */ jsxs36(AlertDialog2.Portal, { children: [
2554
+ /* @__PURE__ */ jsx45(
2555
+ AlertDialog2.Overlay,
2556
+ {
2557
+ opacity: 0.5,
2558
+ enterStyle: { opacity: 0 },
2559
+ exitStyle: { opacity: 0 },
2560
+ animation: "quick"
2561
+ },
2562
+ "overlay"
2563
+ ),
2564
+ /* @__PURE__ */ jsx45(
2565
+ AlertDialog2.Content,
2566
+ {
2567
+ bordered: true,
2568
+ elevate: true,
2569
+ width: "90%",
2570
+ maxWidth: 400,
2571
+ enterStyle: { y: -20, opacity: 0, scale: 0.9 },
2572
+ exitStyle: { y: 10, opacity: 0, scale: 0.95 },
2573
+ x: 0,
2574
+ y: 0,
2575
+ scale: 1,
2576
+ opacity: 1,
2577
+ animation: "quick",
2578
+ children: /* @__PURE__ */ jsxs36(YStack36, { gap: "$4", padding: "$4", children: [
2579
+ icon && /* @__PURE__ */ jsx45(YStack36, { alignItems: "center", children: icon }),
2580
+ /* @__PURE__ */ jsxs36(YStack36, { gap: "$2", alignItems: icon ? "center" : "flex-start", children: [
2581
+ /* @__PURE__ */ jsx45(AlertDialog2.Title, { size: "$6", fontWeight: "700", children: title }),
2582
+ description && /* @__PURE__ */ jsx45(
2583
+ AlertDialog2.Description,
2584
+ {
2585
+ size: "$3",
2586
+ color: "$color10",
2587
+ textAlign: icon ? "center" : "left",
2588
+ children: description
2589
+ }
2590
+ )
2591
+ ] }),
2592
+ /* @__PURE__ */ jsxs36(XStack31, { gap: "$3", justifyContent: "flex-end", children: [
2593
+ /* @__PURE__ */ jsx45(
2594
+ Button10,
2595
+ {
2596
+ flex: 1,
2597
+ size: "$4",
2598
+ borderRadius: "$4",
2599
+ variant: "outlined",
2600
+ borderColor: "$color7",
2601
+ onPress: handleCancel,
2602
+ pressStyle: { opacity: 0.7 },
2603
+ animation: "quick",
2604
+ children: /* @__PURE__ */ jsx45(SizableText38, { fontWeight: "600", children: cancelLabel })
2605
+ }
2606
+ ),
2607
+ /* @__PURE__ */ jsx45(
2608
+ Button10,
2609
+ {
2610
+ flex: 1,
2611
+ size: "$4",
2612
+ borderRadius: "$4",
2613
+ backgroundColor: destructive ? "$red9" : "$color9",
2614
+ onPress: handleConfirm,
2615
+ pressStyle: { backgroundColor: destructive ? "$red8" : "$color8", scale: 0.97 },
2616
+ animation: "quick",
2617
+ children: /* @__PURE__ */ jsx45(SizableText38, { fontWeight: "600", color: "white", children: confirmLabel })
2618
+ }
2619
+ )
2620
+ ] })
2621
+ ] })
2622
+ },
2623
+ "content"
2624
+ )
2625
+ ] }) });
2626
+ }
2627
+
2628
+ // src/patterns/Chip.tsx
2629
+ import { useCallback as useCallback3 } from "react";
2630
+ import { SizableText as SizableText39, XStack as XStack32 } from "tamagui";
2631
+ import { jsx as jsx46, jsxs as jsxs37 } from "react/jsx-runtime";
2632
+ var sizes2 = { sm: { h: 28, px: "$2", text: "$2" }, md: { h: 34, px: "$3", text: "$3" }, lg: { h: 42, px: "$4", text: "$4" } };
2633
+ function Chip({ label, selected, onPress, onRemove, variant = "filled", size = "md", icon, color }) {
2634
+ const s = sizes2[size];
2635
+ const filled = variant === "filled";
2636
+ const active = selected ?? false;
2637
+ const bg = active ? color ?? "$color9" : filled ? "$color3" : "transparent";
2638
+ const border = active ? color ?? "$color9" : "$color6";
2639
+ const fg = active ? "$color1" : "$color11";
2640
+ return /* @__PURE__ */ jsxs37(
2641
+ XStack32,
2642
+ {
2643
+ height: s.h,
2644
+ borderRadius: "$10",
2645
+ paddingHorizontal: s.px,
2646
+ backgroundColor: bg,
2647
+ borderWidth: filled ? 0 : 1,
2648
+ borderColor: border,
2649
+ alignItems: "center",
2650
+ gap: "$1.5",
2651
+ pressStyle: { scale: 0.96, opacity: 0.85 },
2652
+ animation: "quick",
2653
+ onPress,
2654
+ cursor: "pointer",
2655
+ children: [
2656
+ active && /* @__PURE__ */ jsx46(SizableText39, { size: s.text, color: fg, children: "\u2713" }),
2657
+ icon && /* @__PURE__ */ jsx46(SizableText39, { color: fg, children: icon }),
2658
+ /* @__PURE__ */ jsx46(SizableText39, { size: s.text, color: fg, fontWeight: "500", children: label }),
2659
+ onRemove && /* @__PURE__ */ jsx46(
2660
+ SizableText39,
2661
+ {
2662
+ size: "$2",
2663
+ color: fg,
2664
+ opacity: 0.7,
2665
+ pressStyle: { opacity: 1 },
2666
+ onPress: (e) => {
2667
+ e.stopPropagation?.();
2668
+ onRemove();
2669
+ },
2670
+ marginLeft: "$1",
2671
+ children: "\u2715"
2672
+ }
2673
+ )
2674
+ ]
2675
+ }
2676
+ );
2677
+ }
2678
+ function ChipGroup({ chips, selected = [], onSelectionChange, multiSelect = true, variant, size }) {
2679
+ const toggle = useCallback3((id) => {
2680
+ if (!onSelectionChange) return;
2681
+ const isSelected = selected.includes(id);
2682
+ if (multiSelect) {
2683
+ onSelectionChange(isSelected ? selected.filter((s) => s !== id) : [...selected, id]);
2684
+ } else {
2685
+ onSelectionChange(isSelected ? [] : [id]);
2686
+ }
2687
+ }, [selected, onSelectionChange, multiSelect]);
2688
+ return /* @__PURE__ */ jsx46(XStack32, { flexWrap: "wrap", gap: "$2", children: chips.map((chip) => /* @__PURE__ */ jsx46(
2689
+ Chip,
2690
+ {
2691
+ label: chip.label,
2692
+ icon: chip.icon,
2693
+ selected: selected.includes(chip.id),
2694
+ onPress: () => toggle(chip.id),
2695
+ variant,
2696
+ size
2697
+ },
2698
+ chip.id
2699
+ )) });
2700
+ }
2701
+
2702
+ // src/patterns/OTPInput.tsx
2703
+ import { useCallback as useCallback4, useRef as useRef2, useState as useState11 } from "react";
2704
+ import { Platform } from "react-native";
2705
+ import { Input as Input3, SizableText as SizableText40, XStack as XStack33, YStack as YStack37 } from "tamagui";
2706
+ import { jsx as jsx47, jsxs as jsxs38 } from "react/jsx-runtime";
2707
+ function OTPInput({ length = 6, value = "", onChange, onComplete, error, autoFocus, secureEntry }) {
2708
+ const inputRef = useRef2(null);
2709
+ const [focused, setFocused] = useState11(false);
2710
+ const digits = value.padEnd(length, " ").slice(0, length);
2711
+ const handleChange = useCallback4((text) => {
2712
+ const cleaned = text.replace(/\D/g, "").slice(0, length);
2713
+ onChange?.(cleaned);
2714
+ if (cleaned.length === length) onComplete?.(cleaned);
2715
+ }, [length, onChange, onComplete]);
2716
+ const focusInput = useCallback4(() => {
2717
+ inputRef.current?.focus();
2718
+ }, []);
2719
+ return /* @__PURE__ */ jsxs38(YStack37, { position: "relative", children: [
2720
+ /* @__PURE__ */ jsx47(XStack33, { gap: "$2", justifyContent: "center", children: Array.from({ length }, (_, i) => {
2721
+ const char = digits[i]?.trim();
2722
+ const isCursor = focused && value.length === i;
2723
+ return /* @__PURE__ */ jsxs38(
2724
+ YStack37,
2725
+ {
2726
+ width: 48,
2727
+ height: 56,
2728
+ borderRadius: "$3",
2729
+ borderWidth: 2,
2730
+ borderColor: error ? "$red9" : isCursor ? "$color9" : char ? "$color7" : "$color5",
2731
+ backgroundColor: error ? "$red2" : isCursor ? "$color2" : "$color1",
2732
+ alignItems: "center",
2733
+ justifyContent: "center",
2734
+ animation: "quick",
2735
+ pointerEvents: "none",
2736
+ children: [
2737
+ /* @__PURE__ */ jsx47(SizableText40, { size: "$7", fontWeight: "600", color: "$color12", children: char ? secureEntry ? "\u25CF" : char : "" }),
2738
+ isCursor && /* @__PURE__ */ jsx47(
2739
+ YStack37,
2740
+ {
2741
+ position: "absolute",
2742
+ bottom: 10,
2743
+ width: 20,
2744
+ height: 2,
2745
+ backgroundColor: "$color9",
2746
+ animation: "quick"
2747
+ }
2748
+ )
2749
+ ]
2750
+ },
2751
+ i
2752
+ );
2753
+ }) }),
2754
+ Platform.OS === "web" ? /* @__PURE__ */ jsx47(
2755
+ "input",
2756
+ {
2757
+ ref: inputRef,
2758
+ type: "text",
2759
+ inputMode: "numeric",
2760
+ pattern: "[0-9]*",
2761
+ autoComplete: "one-time-code",
2762
+ maxLength: length,
2763
+ value,
2764
+ autoFocus,
2765
+ onChange: (e) => handleChange(e.target.value),
2766
+ onFocus: () => setFocused(true),
2767
+ onBlur: () => setFocused(false),
2768
+ style: {
2769
+ position: "absolute",
2770
+ top: 0,
2771
+ left: 0,
2772
+ right: 0,
2773
+ bottom: 0,
2774
+ width: "100%",
2775
+ height: "100%",
2776
+ opacity: 0,
2777
+ fontSize: 16,
2778
+ caretColor: "transparent",
2779
+ cursor: "pointer"
2780
+ }
2781
+ }
2782
+ ) : /* @__PURE__ */ jsx47(
2783
+ Input3,
2784
+ {
2785
+ ref: inputRef,
2786
+ value,
2787
+ onChangeText: handleChange,
2788
+ keyboardType: "number-pad",
2789
+ maxLength: length,
2790
+ autoFocus,
2791
+ onFocus: () => setFocused(true),
2792
+ onBlur: () => setFocused(false),
2793
+ position: "absolute",
2794
+ top: 0,
2795
+ left: 0,
2796
+ right: 0,
2797
+ bottom: 0,
2798
+ opacity: 0,
2799
+ fontSize: 16
2800
+ }
2801
+ )
2802
+ ] });
2803
+ }
2804
+
2805
+ // src/patterns/PasswordInput.tsx
2806
+ import { useState as useState12, useCallback as useCallback5 } from "react";
2807
+ import { Input as Input4, SizableText as SizableText41, XStack as XStack34, YStack as YStack38 } from "tamagui";
2808
+ import { jsx as jsx48, jsxs as jsxs39 } from "react/jsx-runtime";
2809
+ function getStrength(pw) {
2810
+ if (!pw) return { label: "", color: "$color6", width: "0%" };
2811
+ const score = [pw.length >= 8, /[A-Z]/.test(pw), /[0-9]/.test(pw), /[^A-Za-z0-9]/.test(pw)].filter(Boolean).length;
2812
+ if (score <= 1) return { label: "Weak", color: "$red9", width: "33%" };
2813
+ if (score <= 2) return { label: "Medium", color: "$yellow9", width: "66%" };
2814
+ return { label: "Strong", color: "$green9", width: "100%" };
2815
+ }
2816
+ function PasswordInput({ value = "", onChangeText, placeholder = "Password", label, error, size = "$4", strengthIndicator }) {
2817
+ const [visible, setVisible] = useState12(false);
2818
+ const toggle = useCallback5(() => setVisible((v) => !v), []);
2819
+ const strength = getStrength(value);
2820
+ return /* @__PURE__ */ jsxs39(YStack38, { gap: "$1.5", children: [
2821
+ label && /* @__PURE__ */ jsx48(SizableText41, { size: "$3", color: "$color11", fontWeight: "500", children: label }),
2822
+ /* @__PURE__ */ jsxs39(
2823
+ XStack34,
2824
+ {
2825
+ borderWidth: 1,
2826
+ borderColor: error ? "$red9" : "$color6",
2827
+ borderRadius: "$3",
2828
+ backgroundColor: "$color2",
2829
+ alignItems: "center",
2830
+ paddingRight: "$2",
2831
+ focusStyle: { borderColor: "$color9" },
2832
+ children: [
2833
+ /* @__PURE__ */ jsx48(
2834
+ Input4,
2835
+ {
2836
+ flex: 1,
2837
+ size,
2838
+ value,
2839
+ onChangeText,
2840
+ placeholder,
2841
+ placeholderTextColor: "$color8",
2842
+ secureTextEntry: !visible,
2843
+ backgroundColor: "transparent",
2844
+ borderWidth: 0
2845
+ }
2846
+ ),
2847
+ /* @__PURE__ */ jsx48(
2848
+ SizableText41,
2849
+ {
2850
+ size: "$4",
2851
+ color: "$color8",
2852
+ paddingHorizontal: "$2",
2853
+ pressStyle: { opacity: 0.6 },
2854
+ onPress: toggle,
2855
+ cursor: "pointer",
2856
+ children: visible ? "\u25C9" : "\u25CE"
2857
+ }
2858
+ )
2859
+ ]
2860
+ }
2861
+ ),
2862
+ strengthIndicator && value.length > 0 && /* @__PURE__ */ jsxs39(YStack38, { gap: "$1", children: [
2863
+ /* @__PURE__ */ jsx48(YStack38, { height: 3, backgroundColor: "$color4", borderRadius: 2, overflow: "hidden", children: /* @__PURE__ */ jsx48(YStack38, { height: 3, width: strength.width, backgroundColor: strength.color, borderRadius: 2, animation: "quick" }) }),
2864
+ /* @__PURE__ */ jsx48(SizableText41, { size: "$1", color: strength.color, children: strength.label })
2865
+ ] }),
2866
+ error && /* @__PURE__ */ jsx48(SizableText41, { size: "$2", color: "$red9", children: error })
2867
+ ] });
2868
+ }
2869
+
2870
+ // src/patterns/AvatarGroup.tsx
2871
+ import { Circle as Circle10, Image as Image8, SizableText as SizableText42, XStack as XStack35 } from "tamagui";
2872
+ import { jsx as jsx49, jsxs as jsxs40 } from "react/jsx-runtime";
2873
+ function getInitials(name) {
2874
+ if (!name) return "?";
2875
+ return name.split(" ").map((p) => p[0]).join("").toUpperCase().slice(0, 2);
2876
+ }
2877
+ function AvatarItem({ uri, name, color, size }) {
2878
+ return /* @__PURE__ */ jsx49(
2879
+ Circle10,
2880
+ {
2881
+ size,
2882
+ backgroundColor: color ?? "$color4",
2883
+ borderWidth: 2,
2884
+ borderColor: "$background",
2885
+ overflow: "hidden",
2886
+ alignItems: "center",
2887
+ justifyContent: "center",
2888
+ children: uri ? /* @__PURE__ */ jsx49(Image8, { source: { uri }, width: size, height: size, objectFit: "cover" }) : /* @__PURE__ */ jsx49(SizableText42, { size: "$2", fontWeight: "600", color: color ? "$color1" : "$color11", children: getInitials(name) })
2889
+ }
2890
+ );
2891
+ }
2892
+ function AvatarGroup({ avatars, max = 4, size = 36, overlap = 10 }) {
2893
+ const visible = avatars.slice(0, max);
2894
+ const remaining = avatars.length - max;
2895
+ return /* @__PURE__ */ jsxs40(XStack35, { alignItems: "center", children: [
2896
+ visible.map((avatar, i) => /* @__PURE__ */ jsx49(XStack35, { marginLeft: i === 0 ? 0 : -overlap, zIndex: visible.length - i, children: /* @__PURE__ */ jsx49(AvatarItem, { ...avatar, size }) }, i)),
2897
+ remaining > 0 && /* @__PURE__ */ jsx49(XStack35, { marginLeft: -overlap, zIndex: 0, children: /* @__PURE__ */ jsx49(
2898
+ Circle10,
2899
+ {
2900
+ size,
2901
+ backgroundColor: "$color6",
2902
+ borderWidth: 2,
2903
+ borderColor: "$background",
2904
+ alignItems: "center",
2905
+ justifyContent: "center",
2906
+ children: /* @__PURE__ */ jsxs40(SizableText42, { size: "$2", fontWeight: "600", color: "$color11", children: [
2907
+ "+",
2908
+ remaining
2909
+ ] })
2910
+ }
2911
+ ) })
2912
+ ] });
2913
+ }
2914
+
2915
+ // src/patterns/SwipeCards.tsx
2916
+ import { useState as useState13, useCallback as useCallback6 } from "react";
2917
+ import { Circle as Circle11, SizableText as SizableText43, XStack as XStack36, YStack as YStack39 } from "tamagui";
2918
+ import { jsx as jsx50, jsxs as jsxs41 } from "react/jsx-runtime";
2919
+ var STACK_SIZE = 3;
2920
+ var CARD_OFFSETS = [
2921
+ { scale: 1, y: 0, opacity: 1 },
2922
+ { scale: 0.95, y: 8, opacity: 0.9 },
2923
+ { scale: 0.9, y: 16, opacity: 0.8 }
2924
+ ];
2925
+ function SwipeCards({
2926
+ items,
2927
+ renderCard,
2928
+ onSwipeLeft,
2929
+ onSwipeRight,
2930
+ onEmpty,
2931
+ leftLabel = "Nope",
2932
+ rightLabel = "Like",
2933
+ emptyMessage = "No more cards"
2934
+ }) {
2935
+ const [index, setIndex] = useState13(0);
2936
+ const [exitDir, setExitDir] = useState13(null);
2937
+ const remaining = items.slice(index);
2938
+ const isEmpty = remaining.length === 0;
2939
+ const handleSwipe = useCallback6((dir) => {
2940
+ if (isEmpty) return;
2941
+ const current = items[index];
2942
+ setExitDir(dir);
2943
+ const timer = setTimeout(() => {
2944
+ setExitDir(null);
2945
+ setIndex((i) => {
2946
+ const next = i + 1;
2947
+ if (next >= items.length) onEmpty?.();
2948
+ return next;
2949
+ });
2950
+ dir === "left" ? onSwipeLeft?.(current) : onSwipeRight?.(current);
2951
+ }, 250);
2952
+ return () => clearTimeout(timer);
2953
+ }, [isEmpty, index, items, onEmpty, onSwipeLeft, onSwipeRight]);
2954
+ if (isEmpty) {
2955
+ return /* @__PURE__ */ jsx50(YStack39, { flex: 1, alignItems: "center", justifyContent: "center", gap: "$3", padding: "$4", children: /* @__PURE__ */ jsx50(SizableText43, { size: "$5", color: "$color8", children: emptyMessage }) });
2956
+ }
2957
+ return /* @__PURE__ */ jsxs41(YStack39, { flex: 1, gap: "$4", children: [
2958
+ /* @__PURE__ */ jsx50(YStack39, { flex: 1, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx50(YStack39, { width: "100%", maxWidth: 340, aspectRatio: 3 / 4, position: "relative", children: remaining.slice(0, STACK_SIZE).reverse().map((item, reverseIdx) => {
2959
+ const stackIdx = Math.min(remaining.length, STACK_SIZE) - 1 - reverseIdx;
2960
+ const isTop = stackIdx === 0;
2961
+ const offset = CARD_OFFSETS[stackIdx] ?? CARD_OFFSETS[2];
2962
+ const exitX = exitDir === "left" ? -400 : exitDir === "right" ? 400 : 0;
2963
+ const exitRotate = exitDir === "left" ? "-15deg" : exitDir === "right" ? "15deg" : "0deg";
2964
+ return /* @__PURE__ */ jsxs41(
2965
+ YStack39,
2966
+ {
2967
+ position: "absolute",
2968
+ top: 0,
2969
+ left: 0,
2970
+ right: 0,
2971
+ bottom: 0,
2972
+ animation: "quick",
2973
+ borderRadius: "$5",
2974
+ overflow: "hidden",
2975
+ backgroundColor: "$background",
2976
+ elevation: isTop ? 4 : 1,
2977
+ shadowColor: "$shadowColor",
2978
+ shadowRadius: isTop ? 16 : 4,
2979
+ scale: isTop && exitDir ? 1 : offset.scale,
2980
+ opacity: isTop && exitDir ? 0 : offset.opacity,
2981
+ y: isTop && exitDir ? 0 : offset.y,
2982
+ x: isTop ? exitX : 0,
2983
+ rotate: isTop ? exitRotate : "0deg",
2984
+ children: [
2985
+ renderCard(item),
2986
+ isTop && exitDir === "left" && /* @__PURE__ */ jsx50(
2987
+ YStack39,
2988
+ {
2989
+ position: "absolute",
2990
+ top: "$4",
2991
+ right: "$4",
2992
+ borderWidth: 3,
2993
+ borderColor: "$red10",
2994
+ borderRadius: "$3",
2995
+ padding: "$2",
2996
+ rotate: "15deg",
2997
+ children: /* @__PURE__ */ jsx50(SizableText43, { size: "$7", fontWeight: "800", color: "$red10", children: leftLabel.toUpperCase() })
2998
+ }
2999
+ ),
3000
+ isTop && exitDir === "right" && /* @__PURE__ */ jsx50(
3001
+ YStack39,
3002
+ {
3003
+ position: "absolute",
3004
+ top: "$4",
3005
+ left: "$4",
3006
+ borderWidth: 3,
3007
+ borderColor: "$green10",
3008
+ borderRadius: "$3",
3009
+ padding: "$2",
3010
+ rotate: "-15deg",
3011
+ children: /* @__PURE__ */ jsx50(SizableText43, { size: "$7", fontWeight: "800", color: "$green10", children: rightLabel.toUpperCase() })
3012
+ }
3013
+ )
3014
+ ]
3015
+ },
3016
+ item.id
3017
+ );
3018
+ }) }) }),
3019
+ /* @__PURE__ */ jsxs41(XStack36, { justifyContent: "center", gap: "$6", paddingBottom: "$4", children: [
3020
+ /* @__PURE__ */ jsx50(
3021
+ Circle11,
3022
+ {
3023
+ size: 60,
3024
+ backgroundColor: "$red3",
3025
+ borderWidth: 2,
3026
+ borderColor: "$red7",
3027
+ pressStyle: { scale: 0.9, backgroundColor: "$red5" },
3028
+ animation: "quick",
3029
+ onPress: () => handleSwipe("left"),
3030
+ alignItems: "center",
3031
+ justifyContent: "center",
3032
+ children: /* @__PURE__ */ jsx50(SizableText43, { size: "$6", color: "$red10", fontWeight: "700", children: "\u2715" })
3033
+ }
3034
+ ),
3035
+ /* @__PURE__ */ jsx50(
3036
+ Circle11,
3037
+ {
3038
+ size: 60,
3039
+ backgroundColor: "$green3",
3040
+ borderWidth: 2,
3041
+ borderColor: "$green7",
3042
+ pressStyle: { scale: 0.9, backgroundColor: "$green5" },
3043
+ animation: "quick",
3044
+ onPress: () => handleSwipe("right"),
3045
+ alignItems: "center",
3046
+ justifyContent: "center",
3047
+ children: /* @__PURE__ */ jsx50(SizableText43, { size: "$6", color: "$green10", fontWeight: "700", children: "\u2665" })
3048
+ }
3049
+ )
3050
+ ] })
3051
+ ] });
3052
+ }
3053
+
3054
+ // src/patterns/GlassCard.tsx
3055
+ import { styled as styled12, YStack as YStack40 } from "tamagui";
3056
+ import { jsx as jsx51 } from "react/jsx-runtime";
3057
+ var BLUR = { light: 8, medium: 16, heavy: 24 };
3058
+ var TINT_BG = {
3059
+ light: "rgba(255,255,255,0.15)",
3060
+ dark: "rgba(0,0,0,0.25)"
3061
+ };
3062
+ var GlassFrame = styled12(YStack40, {
3063
+ borderWidth: 1,
3064
+ borderColor: "rgba(255,255,255,0.2)",
3065
+ overflow: "hidden"
3066
+ });
3067
+ function GlassCard({
3068
+ children,
3069
+ intensity = "medium",
3070
+ tint = "light",
3071
+ borderRadius = "$4",
3072
+ padding = "$4",
3073
+ elevated = false
3074
+ }) {
3075
+ const blur = BLUR[intensity];
3076
+ return /* @__PURE__ */ jsx51(
3077
+ GlassFrame,
3078
+ {
3079
+ borderRadius,
3080
+ padding,
3081
+ backgroundColor: TINT_BG[tint],
3082
+ elevation: elevated ? 4 : 0,
3083
+ shadowColor: elevated ? "$shadowColor" : void 0,
3084
+ shadowRadius: elevated ? 20 : void 0,
3085
+ shadowOpacity: elevated ? 0.3 : void 0,
3086
+ style: { backdropFilter: `blur(${blur}px)`, WebkitBackdropFilter: `blur(${blur}px)` },
3087
+ children
3088
+ }
3089
+ );
3090
+ }
3091
+
3092
+ // src/patterns/DataTable.tsx
3093
+ import { useMemo, useState as useState14 } from "react";
3094
+ import { SizableText as SizableText44, Separator as Separator5, XStack as XStack37, YStack as YStack41, useMedia, styled as styled13, View as View6 } from "tamagui";
3095
+ import { jsx as jsx52, jsxs as jsxs42 } from "react/jsx-runtime";
3096
+ var TH = styled13(View6, { padding: "$3", justifyContent: "center" });
3097
+ var TD = styled13(View6, { padding: "$3", justifyContent: "center" });
3098
+ function StatusBadge({ status }) {
3099
+ const isActive = status.toLowerCase() === "active";
3100
+ return /* @__PURE__ */ jsxs42(XStack37, { gap: "$2", alignItems: "center", children: [
3101
+ /* @__PURE__ */ jsx52(
3102
+ View6,
3103
+ {
3104
+ width: 8,
3105
+ height: 8,
3106
+ borderRadius: 4,
3107
+ backgroundColor: isActive ? "$green9" : "$orange9"
3108
+ }
3109
+ ),
3110
+ /* @__PURE__ */ jsx52(SizableText44, { size: "$3", color: "$color11", children: status })
3111
+ ] });
3112
+ }
3113
+ function HeaderCell({ col, sort, onSort }) {
3114
+ const active = sort?.key === col.key;
3115
+ const indicator = active ? sort.dir === "asc" ? " \u25B2" : " \u25BC" : "";
3116
+ return /* @__PURE__ */ jsx52(
3117
+ TH,
3118
+ {
3119
+ width: col.width,
3120
+ flexDirection: "row",
3121
+ alignItems: "center",
3122
+ cursor: col.sortable ? "pointer" : void 0,
3123
+ onPress: col.sortable ? onSort : void 0,
3124
+ pressStyle: col.sortable ? { opacity: 0.7 } : void 0,
3125
+ children: /* @__PURE__ */ jsxs42(
3126
+ SizableText44,
3127
+ {
3128
+ size: "$2",
3129
+ fontWeight: "700",
3130
+ color: active ? "$color12" : "$color9",
3131
+ textTransform: "uppercase",
3132
+ letterSpacing: 0.5,
3133
+ children: [
3134
+ col.header,
3135
+ indicator
3136
+ ]
3137
+ }
3138
+ )
3139
+ },
3140
+ col.key
3141
+ );
3142
+ }
3143
+ function TableRow({ row, columns, onPress, odd }) {
3144
+ return /* @__PURE__ */ jsx52(
3145
+ XStack37,
3146
+ {
3147
+ backgroundColor: odd ? "$color2" : "transparent",
3148
+ borderBottomWidth: 0.5,
3149
+ borderColor: "$color4",
3150
+ hoverStyle: { backgroundColor: "$color3" },
3151
+ cursor: onPress ? "pointer" : void 0,
3152
+ onPress: onPress ? () => onPress(row) : void 0,
3153
+ pressStyle: onPress ? { opacity: 0.85 } : void 0,
3154
+ animation: "quick",
3155
+ children: columns.map((col) => /* @__PURE__ */ jsx52(TD, { width: col.width, flex: col.width ? void 0 : 1, children: col.render ? col.render(row[col.key], row) : /* @__PURE__ */ jsx52(SizableText44, { size: "$3", color: "$color11", children: String(row[col.key] ?? "") }) }, col.key))
3156
+ }
3157
+ );
3158
+ }
3159
+ function CardRow({ row, columns, onPress }) {
3160
+ return /* @__PURE__ */ jsx52(
3161
+ YStack41,
3162
+ {
3163
+ backgroundColor: "$color1",
3164
+ borderRadius: "$4",
3165
+ borderWidth: 1,
3166
+ borderColor: "$color4",
3167
+ padding: "$3",
3168
+ gap: "$2",
3169
+ onPress: onPress ? () => onPress(row) : void 0,
3170
+ pressStyle: onPress ? { scale: 0.98, opacity: 0.9 } : void 0,
3171
+ animation: "quick",
3172
+ children: columns.map((col, i) => /* @__PURE__ */ jsxs42(YStack41, { children: [
3173
+ i > 0 && /* @__PURE__ */ jsx52(Separator5, { marginVertical: "$1.5", borderColor: "$color4" }),
3174
+ /* @__PURE__ */ jsxs42(XStack37, { justifyContent: "space-between", alignItems: "center", children: [
3175
+ /* @__PURE__ */ jsx52(SizableText44, { size: "$2", color: "$color9", fontWeight: "600", children: col.header }),
3176
+ col.render ? col.render(row[col.key], row) : /* @__PURE__ */ jsx52(SizableText44, { size: "$3", color: "$color11", children: String(row[col.key] ?? "") })
3177
+ ] })
3178
+ ] }, col.key))
3179
+ }
3180
+ );
3181
+ }
3182
+ function DataTable({ columns, data, onRowPress, emptyMessage = "No data" }) {
3183
+ const [sort, setSort] = useState14(null);
3184
+ const media = useMedia();
3185
+ const isSmall = media.sm;
3186
+ const sorted = useMemo(() => {
3187
+ if (!sort) return data;
3188
+ return [...data].sort((a, b) => {
3189
+ const av = a[sort.key], bv = b[sort.key];
3190
+ const cmp = typeof av === "number" && typeof bv === "number" ? av - bv : String(av ?? "").localeCompare(String(bv ?? ""));
3191
+ return sort.dir === "asc" ? cmp : -cmp;
3192
+ });
3193
+ }, [data, sort]);
3194
+ const toggleSort = (key) => setSort((s) => s?.key === key ? { key, dir: s.dir === "asc" ? "desc" : "asc" } : { key, dir: "asc" });
3195
+ if (!data.length) {
3196
+ return /* @__PURE__ */ jsx52(YStack41, { padding: "$6", alignItems: "center", children: /* @__PURE__ */ jsx52(SizableText44, { size: "$4", color: "$color9", children: emptyMessage }) });
3197
+ }
3198
+ if (isSmall) {
3199
+ return /* @__PURE__ */ jsx52(YStack41, { gap: "$3", children: sorted.map((row, i) => /* @__PURE__ */ jsx52(CardRow, { row, columns, onPress: onRowPress }, i)) });
3200
+ }
3201
+ return /* @__PURE__ */ jsxs42(YStack41, { borderWidth: 1, borderColor: "$color4", borderRadius: "$4", overflow: "hidden", children: [
3202
+ /* @__PURE__ */ jsx52(XStack37, { backgroundColor: "$color1", borderBottomWidth: 1, borderColor: "$color4", children: columns.map((col) => /* @__PURE__ */ jsx52(HeaderCell, { col, sort, onSort: () => toggleSort(col.key) }, col.key)) }),
3203
+ sorted.map((row, i) => /* @__PURE__ */ jsx52(TableRow, { row, columns, onPress: onRowPress, odd: i % 2 === 1 }, i))
3204
+ ] });
3205
+ }
3206
+
3207
+ // src/patterns/DatePicker.tsx
3208
+ import { useCallback as useCallback7, useMemo as useMemo2, useState as useState15 } from "react";
3209
+ import { SizableText as SizableText45, XStack as XStack38, YStack as YStack42 } from "tamagui";
3210
+ import { jsx as jsx53, jsxs as jsxs43 } from "react/jsx-runtime";
3211
+ var MONTH_NAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3212
+ var DAY_LABELS_SUN = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
3213
+ var DAY_LABELS_MON = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
3214
+ function daysInMonth(year, month) {
3215
+ return new Date(year, month + 1, 0).getDate();
3216
+ }
3217
+ function sameDay(a, b) {
3218
+ return a ? a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate() : false;
3219
+ }
3220
+ function buildGrid(year, month, startDay) {
3221
+ const total = daysInMonth(year, month);
3222
+ const firstWeekday = new Date(year, month, 1).getDay();
3223
+ const offset = (firstWeekday - startDay + 7) % 7;
3224
+ const prevTotal = daysInMonth(year, month - 1);
3225
+ const cells = [];
3226
+ for (let i = offset - 1; i >= 0; i--)
3227
+ cells.push({ day: prevTotal - i, month: month - 1, year: month === 0 ? year - 1 : year, outside: true });
3228
+ for (let d = 1; d <= total; d++)
3229
+ cells.push({ day: d, month, year, outside: false });
3230
+ while (cells.length < 42)
3231
+ cells.push({ day: cells.length - offset - total + 1, month: month + 1, year: month === 11 ? year + 1 : year, outside: true });
3232
+ return cells;
3233
+ }
3234
+ function NavButton({ label, onPress }) {
3235
+ return /* @__PURE__ */ jsx53(
3236
+ XStack38,
3237
+ {
3238
+ width: 36,
3239
+ height: 36,
3240
+ borderRadius: "$10",
3241
+ alignItems: "center",
3242
+ justifyContent: "center",
3243
+ backgroundColor: "$color3",
3244
+ pressStyle: { scale: 0.92, backgroundColor: "$color5" },
3245
+ animation: "quick",
3246
+ onPress,
3247
+ cursor: "pointer",
3248
+ children: /* @__PURE__ */ jsx53(SizableText45, { size: "$5", color: "$color11", fontWeight: "600", children: label })
3249
+ }
3250
+ );
3251
+ }
3252
+ function DatePicker({ value, onDateChange, minDate, maxDate, startDay = 1 }) {
3253
+ const today = useMemo2(() => /* @__PURE__ */ new Date(), []);
3254
+ const [viewMonth, setViewMonth] = useState15(value?.getMonth() ?? today.getMonth());
3255
+ const [viewYear, setViewYear] = useState15(value?.getFullYear() ?? today.getFullYear());
3256
+ const headers = startDay === 1 ? DAY_LABELS_MON : DAY_LABELS_SUN;
3257
+ const grid = useMemo2(() => buildGrid(viewYear, viewMonth, startDay), [viewYear, viewMonth, startDay]);
3258
+ const navigate = useCallback7((dir) => {
3259
+ setViewMonth((m) => {
3260
+ const next = m + dir;
3261
+ if (next < 0) {
3262
+ setViewYear((y) => y - 1);
3263
+ return 11;
3264
+ }
3265
+ if (next > 11) {
3266
+ setViewYear((y) => y + 1);
3267
+ return 0;
3268
+ }
3269
+ return next;
3270
+ });
3271
+ }, []);
3272
+ const isDisabled = useCallback7((d) => {
3273
+ if (minDate && d < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())) return true;
3274
+ if (maxDate && d > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())) return true;
3275
+ return false;
3276
+ }, [minDate, maxDate]);
3277
+ return /* @__PURE__ */ jsxs43(YStack42, { backgroundColor: "$color2", borderRadius: "$4", padding: "$3", gap: "$2", animation: "quick", children: [
3278
+ /* @__PURE__ */ jsxs43(XStack38, { alignItems: "center", justifyContent: "space-between", children: [
3279
+ /* @__PURE__ */ jsx53(NavButton, { label: "\u2039", onPress: () => navigate(-1) }),
3280
+ /* @__PURE__ */ jsxs43(SizableText45, { size: "$4", fontWeight: "700", color: "$color12", children: [
3281
+ MONTH_NAMES[viewMonth],
3282
+ " ",
3283
+ viewYear
3284
+ ] }),
3285
+ /* @__PURE__ */ jsx53(NavButton, { label: "\u203A", onPress: () => navigate(1) })
3286
+ ] }),
3287
+ /* @__PURE__ */ jsx53(XStack38, { children: headers.map((h) => /* @__PURE__ */ jsx53(SizableText45, { size: "$2", color: "$color8", fontWeight: "600", textAlign: "center", flex: 1, children: h }, h)) }),
3288
+ Array.from({ length: Math.ceil(grid.length / 7) }, (_, row) => /* @__PURE__ */ jsx53(XStack38, { children: grid.slice(row * 7, row * 7 + 7).map((cell, i) => {
3289
+ const date = new Date(cell.year, cell.month, cell.day);
3290
+ const selected = sameDay(value, date);
3291
+ const isToday = sameDay(today, date);
3292
+ const disabled = cell.outside || isDisabled(date);
3293
+ return /* @__PURE__ */ jsx53(YStack42, { flex: 1, alignItems: "center", paddingVertical: "$0.5", children: /* @__PURE__ */ jsx53(
3294
+ XStack38,
3295
+ {
3296
+ width: 40,
3297
+ height: 40,
3298
+ borderRadius: "$10",
3299
+ alignItems: "center",
3300
+ justifyContent: "center",
3301
+ backgroundColor: selected ? "$color9" : "transparent",
3302
+ borderWidth: isToday && !selected ? 1.5 : 0,
3303
+ borderColor: "$color9",
3304
+ pressStyle: disabled ? void 0 : { scale: 0.9, backgroundColor: selected ? "$color10" : "$color4" },
3305
+ animation: "quick",
3306
+ opacity: disabled ? 0.35 : 1,
3307
+ cursor: disabled ? "default" : "pointer",
3308
+ onPress: disabled ? void 0 : () => onDateChange?.(date),
3309
+ children: /* @__PURE__ */ jsx53(
3310
+ SizableText45,
3311
+ {
3312
+ size: "$3",
3313
+ fontWeight: selected || isToday ? "700" : "400",
3314
+ color: selected ? "white" : cell.outside ? "$color5" : "$color12",
3315
+ children: cell.day
3316
+ }
3317
+ )
3318
+ }
3319
+ ) }, `${row}-${i}`);
3320
+ }) }, row))
3321
+ ] });
3322
+ }
3323
+
3324
+ // src/patterns/EventCard.tsx
3325
+ import { SizableText as SizableText46, Theme, XStack as XStack39, YStack as YStack43 } from "tamagui";
3326
+ import { jsx as jsx54, jsxs as jsxs44 } from "react/jsx-runtime";
3327
+ var THEME_MAP = {
3328
+ purple: "purple",
3329
+ green: "green",
3330
+ blue: "blue",
3331
+ orange: "orange",
3332
+ red: "red",
3333
+ pink: "pink"
3334
+ };
3335
+ function ParticipantDots({ count, max }) {
3336
+ const dots = Math.min(count, 5);
3337
+ return /* @__PURE__ */ jsxs44(XStack39, { alignItems: "center", gap: "$1.5", children: [
3338
+ /* @__PURE__ */ jsx54(XStack39, { children: Array.from({ length: dots }, (_, i) => /* @__PURE__ */ jsx54(
3339
+ YStack43,
3340
+ {
3341
+ width: 22,
3342
+ height: 22,
3343
+ borderRadius: 11,
3344
+ backgroundColor: "$color7",
3345
+ borderWidth: 2,
3346
+ borderColor: "$color4",
3347
+ marginLeft: i > 0 ? -8 : 0,
3348
+ alignItems: "center",
3349
+ justifyContent: "center",
3350
+ children: /* @__PURE__ */ jsx54(SizableText46, { size: "$1", color: "$color1", fontWeight: "700", children: String.fromCharCode(65 + i) })
3351
+ },
3352
+ i
3353
+ )) }),
3354
+ /* @__PURE__ */ jsxs44(SizableText46, { size: "$2", color: "$color11", fontWeight: "500", children: [
3355
+ count,
3356
+ max ? `/${max}` : ""
3357
+ ] })
3358
+ ] });
3359
+ }
3360
+ function CardInner({ title, subtitle, time, location, label, participants, maxParticipants, onPress, actions }) {
3361
+ return /* @__PURE__ */ jsxs44(
3362
+ YStack43,
3363
+ {
3364
+ backgroundColor: "$color4",
3365
+ borderRadius: "$5",
3366
+ padding: "$4",
3367
+ gap: "$3",
3368
+ borderWidth: 1,
3369
+ borderColor: "$color7",
3370
+ onPress,
3371
+ animation: "quick",
3372
+ pressStyle: onPress ? { scale: 0.97, opacity: 0.9 } : void 0,
3373
+ cursor: onPress ? "pointer" : void 0,
3374
+ children: [
3375
+ /* @__PURE__ */ jsxs44(XStack39, { justifyContent: "space-between", alignItems: "flex-start", children: [
3376
+ /* @__PURE__ */ jsxs44(YStack43, { flex: 1, gap: "$1", children: [
3377
+ /* @__PURE__ */ jsx54(SizableText46, { size: "$6", fontWeight: "700", color: "$color12", children: title }),
3378
+ subtitle && /* @__PURE__ */ jsx54(SizableText46, { size: "$3", color: "$color11", opacity: 0.8, children: subtitle })
3379
+ ] }),
3380
+ time && /* @__PURE__ */ jsx54(YStack43, { backgroundColor: "$color6", paddingHorizontal: "$2.5", paddingVertical: "$1.5", borderRadius: "$3", children: /* @__PURE__ */ jsx54(SizableText46, { size: "$2", fontWeight: "600", color: "$color12", children: time }) })
3381
+ ] }),
3382
+ /* @__PURE__ */ jsxs44(XStack39, { gap: "$4", alignItems: "center", flexWrap: "wrap", children: [
3383
+ location && /* @__PURE__ */ jsxs44(XStack39, { gap: "$1.5", alignItems: "center", children: [
3384
+ /* @__PURE__ */ jsx54(SizableText46, { size: "$3", children: "\u{1F4CD}" }),
3385
+ /* @__PURE__ */ jsx54(SizableText46, { size: "$3", color: "$color11", children: location })
3386
+ ] }),
3387
+ participants !== void 0 && /* @__PURE__ */ jsx54(ParticipantDots, { count: participants, max: maxParticipants })
3388
+ ] }),
3389
+ (label || actions) && /* @__PURE__ */ jsxs44(XStack39, { justifyContent: "space-between", alignItems: "center", children: [
3390
+ label ? /* @__PURE__ */ jsx54(XStack39, { backgroundColor: "$color6", paddingHorizontal: "$2.5", paddingVertical: "$1", borderRadius: "$10", children: /* @__PURE__ */ jsx54(SizableText46, { size: "$2", fontWeight: "600", color: "$color11", children: label }) }) : /* @__PURE__ */ jsx54(YStack43, {}),
3391
+ actions
3392
+ ] })
3393
+ ]
3394
+ }
3395
+ );
3396
+ }
3397
+ function EventCard({ theme = "purple", ...props }) {
3398
+ return /* @__PURE__ */ jsx54(Theme, { name: THEME_MAP[theme], children: /* @__PURE__ */ jsx54(CardInner, { ...props }) });
3399
+ }
3400
+
3401
+ // src/patterns/UserPreferences.tsx
3402
+ import { Separator as Separator6, SizableText as SizableText47, Slider, Switch as Switch2, XStack as XStack40, YStack as YStack44 } from "tamagui";
3403
+ import { jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
3404
+ function ItemLabel({ title, description, color }) {
3405
+ return /* @__PURE__ */ jsxs45(YStack44, { flex: 1, gap: "$1", children: [
3406
+ /* @__PURE__ */ jsx55(SizableText47, { size: "$4", fontWeight: "500", color: color ?? "$color12", children: title }),
3407
+ description && /* @__PURE__ */ jsx55(SizableText47, { size: "$2", color: "$color9", children: description })
3408
+ ] });
3409
+ }
3410
+ function ToggleRow({ item }) {
3411
+ return /* @__PURE__ */ jsxs45(XStack40, { alignItems: "center", gap: "$3", paddingVertical: "$3", paddingHorizontal: "$4", children: [
3412
+ /* @__PURE__ */ jsx55(ItemLabel, { title: item.title, description: item.description }),
3413
+ /* @__PURE__ */ jsx55(Switch2, { size: "$3", checked: item.value, onCheckedChange: item.onValueChange, children: /* @__PURE__ */ jsx55(Switch2.Thumb, { animation: "quick" }) })
3414
+ ] });
3415
+ }
3416
+ function SelectRow({ item }) {
3417
+ const current = item.options.find((o) => o.value === item.value);
3418
+ return /* @__PURE__ */ jsxs45(
3419
+ XStack40,
3420
+ {
3421
+ alignItems: "center",
3422
+ gap: "$3",
3423
+ paddingVertical: "$3",
3424
+ paddingHorizontal: "$4",
3425
+ pressStyle: { backgroundColor: "$color3" },
3426
+ animation: "quick",
3427
+ cursor: "pointer",
3428
+ onPress: () => {
3429
+ const idx = item.options.findIndex((o) => o.value === item.value);
3430
+ const next = item.options[(idx + 1) % item.options.length];
3431
+ if (next) item.onValueChange(next.value);
3432
+ },
3433
+ children: [
3434
+ /* @__PURE__ */ jsx55(ItemLabel, { title: item.title, description: item.description }),
3435
+ /* @__PURE__ */ jsx55(SizableText47, { size: "$3", color: "$color9", fontWeight: "500", children: current?.label ?? item.value }),
3436
+ /* @__PURE__ */ jsx55(SizableText47, { size: "$4", color: "$color8", children: "\u203A" })
3437
+ ]
3438
+ }
3439
+ );
3440
+ }
3441
+ function SliderRow({ item }) {
3442
+ const min = item.min ?? 0;
3443
+ const max = item.max ?? 100;
3444
+ return /* @__PURE__ */ jsxs45(YStack44, { gap: "$2", paddingVertical: "$3", paddingHorizontal: "$4", children: [
3445
+ /* @__PURE__ */ jsxs45(XStack40, { justifyContent: "space-between", alignItems: "center", children: [
3446
+ /* @__PURE__ */ jsx55(ItemLabel, { title: item.title, description: item.description }),
3447
+ /* @__PURE__ */ jsx55(SizableText47, { size: "$3", fontWeight: "600", color: "$color11", children: item.value })
3448
+ ] }),
3449
+ /* @__PURE__ */ jsxs45(
3450
+ Slider,
3451
+ {
3452
+ value: [item.value],
3453
+ min,
3454
+ max,
3455
+ step: 1,
3456
+ onValueChange: ([v]) => {
3457
+ if (v !== void 0) item.onValueChange(v);
3458
+ },
3459
+ children: [
3460
+ /* @__PURE__ */ jsx55(Slider.Track, { backgroundColor: "$color4", height: 4, children: /* @__PURE__ */ jsx55(Slider.TrackActive, { backgroundColor: "$color9" }) }),
3461
+ /* @__PURE__ */ jsx55(Slider.Thumb, { index: 0, size: "$1.5", backgroundColor: "$color9", borderWidth: 0, circular: true })
3462
+ ]
3463
+ }
3464
+ )
3465
+ ] });
3466
+ }
3467
+ function ActionRow({ item }) {
3468
+ return /* @__PURE__ */ jsxs45(
3469
+ XStack40,
3470
+ {
3471
+ alignItems: "center",
3472
+ gap: "$3",
3473
+ paddingVertical: "$3",
3474
+ paddingHorizontal: "$4",
3475
+ pressStyle: { backgroundColor: "$color3" },
3476
+ animation: "quick",
3477
+ cursor: "pointer",
3478
+ onPress: item.onPress,
3479
+ children: [
3480
+ /* @__PURE__ */ jsx55(
3481
+ ItemLabel,
3482
+ {
3483
+ title: item.title,
3484
+ description: item.description,
3485
+ color: item.destructive ? "$red10" : void 0
3486
+ }
3487
+ ),
3488
+ /* @__PURE__ */ jsx55(SizableText47, { size: "$4", color: "$color8", children: "\u203A" })
3489
+ ]
3490
+ }
3491
+ );
3492
+ }
3493
+ function PreferenceRow({ item }) {
3494
+ switch (item.type) {
3495
+ case "toggle":
3496
+ return /* @__PURE__ */ jsx55(ToggleRow, { item });
3497
+ case "select":
3498
+ return /* @__PURE__ */ jsx55(SelectRow, { item });
3499
+ case "slider":
3500
+ return /* @__PURE__ */ jsx55(SliderRow, { item });
3501
+ case "action":
3502
+ return /* @__PURE__ */ jsx55(ActionRow, { item });
3503
+ }
3504
+ }
3505
+ function UserPreferences({ sections }) {
3506
+ return /* @__PURE__ */ jsx55(YStack44, { gap: "$5", children: sections.map((section, si) => /* @__PURE__ */ jsxs45(YStack44, { gap: "$2", children: [
3507
+ /* @__PURE__ */ jsxs45(YStack44, { paddingHorizontal: "$1", gap: "$0.5", children: [
3508
+ /* @__PURE__ */ jsx55(SizableText47, { size: "$2", fontWeight: "600", color: "$color9", textTransform: "uppercase", children: section.title }),
3509
+ section.description && /* @__PURE__ */ jsx55(SizableText47, { size: "$2", color: "$color8", children: section.description })
3510
+ ] }),
3511
+ /* @__PURE__ */ jsx55(
3512
+ YStack44,
3513
+ {
3514
+ backgroundColor: "$color2",
3515
+ borderRadius: "$4",
3516
+ overflow: "hidden",
3517
+ borderWidth: 1,
3518
+ borderColor: "$color4",
3519
+ children: section.items.map((item, ii) => /* @__PURE__ */ jsxs45(YStack44, { children: [
3520
+ /* @__PURE__ */ jsx55(PreferenceRow, { item }),
3521
+ ii < section.items.length - 1 && /* @__PURE__ */ jsx55(Separator6, { borderColor: "$color4" })
3522
+ ] }, item.id))
3523
+ }
3524
+ )
3525
+ ] }, si)) });
3526
+ }
3527
+
3528
+ // src/patterns/BlinkSelect.tsx
3529
+ import { Select, Adapt, Sheet as Sheet3, YStack as YStack45, SizableText as SizableText48 } from "tamagui";
3530
+ import { jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
3531
+ function BlinkSelect({
3532
+ items,
3533
+ value,
3534
+ onValueChange,
3535
+ placeholder = "Select...",
3536
+ label,
3537
+ size = "$4",
3538
+ disabled,
3539
+ width = "100%"
3540
+ }) {
3541
+ return /* @__PURE__ */ jsxs46(YStack45, { gap: "$1.5", width, children: [
3542
+ label ? /* @__PURE__ */ jsx56(SizableText48, { size: "$3", fontWeight: "600", children: label }) : null,
3543
+ /* @__PURE__ */ jsxs46(
3544
+ Select,
3545
+ {
3546
+ value,
3547
+ onValueChange,
3548
+ disablePreventBodyScroll: true,
3549
+ ...disabled ? { disabled: true } : {},
3550
+ children: [
3551
+ /* @__PURE__ */ jsx56(Select.Trigger, { width: "100%", iconAfter: () => /* @__PURE__ */ jsx56(SizableText48, { children: "\u25BC" }), size, children: /* @__PURE__ */ jsx56(Select.Value, { placeholder }) }),
3552
+ /* @__PURE__ */ jsx56(Adapt, { when: "maxMd", platform: "touch", children: /* @__PURE__ */ jsxs46(Sheet3, { modal: true, dismissOnSnapToBottom: true, snapPointsMode: "fit", children: [
3553
+ /* @__PURE__ */ jsx56(Sheet3.Frame, { padding: "$4", children: /* @__PURE__ */ jsx56(Adapt.Contents, {}) }),
3554
+ /* @__PURE__ */ jsx56(Sheet3.Overlay, {})
3555
+ ] }) }),
3556
+ /* @__PURE__ */ jsxs46(Select.Content, { zIndex: 2e5, children: [
3557
+ /* @__PURE__ */ jsx56(Select.ScrollUpButton, { alignItems: "center", justifyContent: "center", height: "$3", children: /* @__PURE__ */ jsx56(SizableText48, { children: "\u25B2" }) }),
3558
+ /* @__PURE__ */ jsx56(Select.Viewport, { minWidth: 200, children: /* @__PURE__ */ jsx56(Select.Group, { children: items.map((item, i) => /* @__PURE__ */ jsxs46(Select.Item, { index: i, value: item.value, children: [
3559
+ /* @__PURE__ */ jsx56(Select.ItemText, { children: item.label }),
3560
+ /* @__PURE__ */ jsx56(Select.ItemIndicator, { marginLeft: "auto", children: /* @__PURE__ */ jsx56(SizableText48, { children: "\u2713" }) })
3561
+ ] }, item.value)) }) }),
3562
+ /* @__PURE__ */ jsx56(Select.ScrollDownButton, { alignItems: "center", justifyContent: "center", height: "$3", children: /* @__PURE__ */ jsx56(SizableText48, { children: "\u25BC" }) })
3563
+ ] })
3564
+ ]
3565
+ }
3566
+ )
3567
+ ] });
3568
+ }
3569
+
3570
+ // src/patterns/BlinkDialog.tsx
3571
+ import { Dialog, Adapt as Adapt2, Sheet as Sheet4, Button as Button11, XStack as XStack41 } from "tamagui";
3572
+ import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
3573
+ function BlinkDialog({
3574
+ open,
3575
+ onOpenChange,
3576
+ trigger,
3577
+ title,
3578
+ description,
3579
+ children,
3580
+ confirmLabel = "Confirm",
3581
+ cancelLabel = "Cancel",
3582
+ onConfirm,
3583
+ onCancel,
3584
+ confirmTheme = "active"
3585
+ }) {
3586
+ return /* @__PURE__ */ jsxs47(Dialog, { modal: true, open, onOpenChange, children: [
3587
+ trigger && /* @__PURE__ */ jsx57(Dialog.Trigger, { asChild: true, children: trigger }),
3588
+ /* @__PURE__ */ jsx57(Adapt2, { when: "maxMd", platform: "touch", children: /* @__PURE__ */ jsxs47(Sheet4, { modal: true, dismissOnSnapToBottom: true, snapPointsMode: "fit", children: [
3589
+ /* @__PURE__ */ jsx57(Sheet4.Frame, { padding: "$4", gap: "$4", children: /* @__PURE__ */ jsx57(Adapt2.Contents, {}) }),
3590
+ /* @__PURE__ */ jsx57(Sheet4.Overlay, {})
3591
+ ] }) }),
3592
+ /* @__PURE__ */ jsxs47(Dialog.Portal, { children: [
3593
+ /* @__PURE__ */ jsx57(
3594
+ Dialog.Overlay,
3595
+ {
3596
+ animation: "quick",
3597
+ opacity: 0.5,
3598
+ enterStyle: { opacity: 0 },
3599
+ exitStyle: { opacity: 0 }
3600
+ },
3601
+ "overlay"
3602
+ ),
3603
+ /* @__PURE__ */ jsxs47(
3604
+ Dialog.Content,
3605
+ {
3606
+ bordered: true,
3607
+ elevate: true,
3608
+ animateOnly: ["transform", "opacity"],
3609
+ animation: ["quick", { opacity: { overshootClamping: true } }],
3610
+ enterStyle: { x: 0, y: -20, opacity: 0, scale: 0.9 },
3611
+ exitStyle: { x: 0, y: 10, opacity: 0, scale: 0.95 },
3612
+ gap: "$4",
3613
+ children: [
3614
+ title && /* @__PURE__ */ jsx57(Dialog.Title, { children: title }),
3615
+ description && /* @__PURE__ */ jsx57(Dialog.Description, { size: "$3", color: "$color10", children: description }),
3616
+ children,
3617
+ (onConfirm || onCancel) && /* @__PURE__ */ jsxs47(XStack41, { justifyContent: "flex-end", gap: "$3", children: [
3618
+ onCancel && /* @__PURE__ */ jsx57(Dialog.Close, { displayWhenAdapted: true, asChild: true, children: /* @__PURE__ */ jsx57(Button11, { variant: "outlined", onPress: onCancel, children: cancelLabel }) }),
3619
+ onConfirm && /* @__PURE__ */ jsx57(Dialog.Close, { displayWhenAdapted: true, asChild: true, children: /* @__PURE__ */ jsx57(Button11, { theme: confirmTheme, onPress: onConfirm, children: confirmLabel }) })
3620
+ ] })
3621
+ ]
3622
+ },
3623
+ "content"
3624
+ )
3625
+ ] })
3626
+ ] });
3627
+ }
3628
+
3629
+ // src/patterns/BlinkPopover.tsx
3630
+ import { Popover as Popover2, Adapt as Adapt3, YStack as YStack46 } from "tamagui";
3631
+ import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
3632
+ function BlinkPopover({
3633
+ trigger,
3634
+ children,
3635
+ placement = "bottom",
3636
+ allowFlip = true,
3637
+ size = "$5"
3638
+ }) {
3639
+ return /* @__PURE__ */ jsxs48(Popover2, { size, allowFlip, placement, children: [
3640
+ /* @__PURE__ */ jsx58(Popover2.Trigger, { asChild: true, children: trigger }),
3641
+ /* @__PURE__ */ jsx58(Adapt3, { when: "maxMd", platform: "touch", children: /* @__PURE__ */ jsxs48(Popover2.Sheet, { modal: true, dismissOnSnapToBottom: true, snapPointsMode: "fit", children: [
3642
+ /* @__PURE__ */ jsx58(Popover2.Sheet.Frame, { padding: "$4", children: /* @__PURE__ */ jsx58(Adapt3.Contents, {}) }),
3643
+ /* @__PURE__ */ jsx58(Popover2.Sheet.Overlay, {})
3644
+ ] }) }),
3645
+ /* @__PURE__ */ jsxs48(
3646
+ Popover2.Content,
3647
+ {
3648
+ borderWidth: 1,
3649
+ borderColor: "$borderColor",
3650
+ enterStyle: { y: -10, opacity: 0 },
3651
+ exitStyle: { y: -10, opacity: 0 },
3652
+ elevate: true,
3653
+ animation: ["quick", { opacity: { overshootClamping: true } }],
3654
+ children: [
3655
+ /* @__PURE__ */ jsx58(Popover2.Arrow, { borderWidth: 1, borderColor: "$borderColor" }),
3656
+ /* @__PURE__ */ jsx58(YStack46, { gap: "$3", padding: "$3", children })
3657
+ ]
3658
+ }
3659
+ )
3660
+ ] });
3661
+ }
3662
+
3663
+ // src/index.ts
3664
+ export * from "@tamagui/lucide-icons";
3665
+
3666
+ // src/patterns/ImmersiveMediaScreen.tsx
3667
+ import { Button as Button12, SizableText as SizableText49, XStack as XStack42, YStack as YStack47 } from "tamagui";
3668
+ import { jsx as jsx59, jsxs as jsxs49 } from "react/jsx-runtime";
3669
+ function ImmersiveMediaScreen({
3670
+ variant = "reel",
3671
+ media,
3672
+ title,
3673
+ subtitle,
3674
+ topLeft,
3675
+ topCenter,
3676
+ topRight,
3677
+ actions = [],
3678
+ bottomMeta,
3679
+ inputPlaceholder,
3680
+ onInputPress,
3681
+ sheetContent
3682
+ }) {
3683
+ const showSheet = variant === "sheet";
3684
+ return /* @__PURE__ */ jsxs49(YStack47, { flex: 1, backgroundColor: "$color1", children: [
3685
+ /* @__PURE__ */ jsxs49(YStack47, { flex: 1, position: "relative", children: [
3686
+ media,
3687
+ /* @__PURE__ */ jsxs49(XStack42, { position: "absolute", top: "$5", left: "$4", right: "$4", justifyContent: "space-between", alignItems: "center", children: [
3688
+ /* @__PURE__ */ jsx59(XStack42, { minWidth: 56, children: topLeft }),
3689
+ /* @__PURE__ */ jsx59(YStack47, { alignItems: "center", flex: 1, children: topCenter }),
3690
+ /* @__PURE__ */ jsx59(XStack42, { minWidth: 56, justifyContent: "flex-end", children: topRight })
3691
+ ] }),
3692
+ actions.length > 0 ? /* @__PURE__ */ jsx59(YStack47, { position: "absolute", right: "$3", bottom: showSheet ? "$20" : "$10", gap: "$3", alignItems: "center", children: actions.map((action) => /* @__PURE__ */ jsxs49(YStack47, { gap: "$1", alignItems: "center", onPress: action.onPress, children: [
3693
+ /* @__PURE__ */ jsx59(
3694
+ YStack47,
3695
+ {
3696
+ width: 44,
3697
+ height: 44,
3698
+ borderRadius: "$10",
3699
+ backgroundColor: "rgba(0,0,0,0.55)",
3700
+ alignItems: "center",
3701
+ justifyContent: "center",
3702
+ children: action.icon ?? /* @__PURE__ */ jsx59(SizableText49, { size: "$5", color: "white", children: "\u2022" })
3703
+ }
3704
+ ),
3705
+ action.value ? /* @__PURE__ */ jsx59(SizableText49, { size: "$2", color: "white", children: action.value }) : null,
3706
+ action.label ? /* @__PURE__ */ jsx59(SizableText49, { size: "$1", color: "rgba(255,255,255,0.8)", children: action.label }) : null
3707
+ ] }, action.id)) }) : null,
3708
+ /* @__PURE__ */ jsxs49(YStack47, { position: "absolute", left: "$4", right: "$4", bottom: showSheet ? "$20" : "$6", gap: "$2", children: [
3709
+ title ? /* @__PURE__ */ jsx59(SizableText49, { size: "$6", fontWeight: "800", color: "white", children: title }) : null,
3710
+ subtitle ? /* @__PURE__ */ jsx59(SizableText49, { size: "$3", color: "rgba(255,255,255,0.82)", children: subtitle }) : null,
3711
+ bottomMeta,
3712
+ variant === "story" && inputPlaceholder ? /* @__PURE__ */ jsx59(
3713
+ XStack42,
3714
+ {
3715
+ onPress: onInputPress,
3716
+ alignItems: "center",
3717
+ paddingHorizontal: "$4",
3718
+ paddingVertical: "$3",
3719
+ borderRadius: "$10",
3720
+ backgroundColor: "rgba(255,255,255,0.14)",
3721
+ borderWidth: 1,
3722
+ borderColor: "rgba(255,255,255,0.25)",
3723
+ children: /* @__PURE__ */ jsx59(SizableText49, { size: "$3", color: "rgba(255,255,255,0.82)", children: inputPlaceholder })
3724
+ }
3725
+ ) : null
3726
+ ] })
3727
+ ] }),
3728
+ showSheet ? /* @__PURE__ */ jsxs49(YStack47, { padding: "$4", gap: "$3", backgroundColor: "$background", borderTopLeftRadius: "$8", borderTopRightRadius: "$8", marginTop: -18, children: [
3729
+ /* @__PURE__ */ jsx59(XStack42, { alignSelf: "center", width: 48, height: 5, borderRadius: "$10", backgroundColor: "$color5" }),
3730
+ sheetContent,
3731
+ inputPlaceholder ? /* @__PURE__ */ jsx59(Button12, { size: "$5", backgroundColor: "$color9", color: "$color1", onPress: onInputPress, children: inputPlaceholder }) : null
3732
+ ] }) : null
3733
+ ] });
3734
+ }
3735
+
3736
+ // src/patterns/FinanceDashboard.tsx
3737
+ import { SizableText as SizableText50, XStack as XStack43, YStack as YStack48 } from "tamagui";
3738
+ import { jsx as jsx60, jsxs as jsxs50 } from "react/jsx-runtime";
3739
+ function FinanceDashboard({
3740
+ title = "Overview",
3741
+ balanceLabel = "Available balance",
3742
+ balance,
3743
+ rangeLabel,
3744
+ metrics = [],
3745
+ quickActions = [],
3746
+ sections = [],
3747
+ chartSlot,
3748
+ topRight
3749
+ }) {
3750
+ return /* @__PURE__ */ jsxs50(YStack48, { flex: 1, backgroundColor: "$background", padding: "$4", gap: "$4", children: [
3751
+ /* @__PURE__ */ jsxs50(XStack43, { justifyContent: "space-between", alignItems: "center", paddingTop: "$4", children: [
3752
+ /* @__PURE__ */ jsxs50(YStack48, { gap: "$1", children: [
3753
+ /* @__PURE__ */ jsx60(SizableText50, { size: "$6", fontWeight: "700", children: title }),
3754
+ rangeLabel ? /* @__PURE__ */ jsx60(SizableText50, { size: "$2", color: "$color9", children: rangeLabel }) : null
3755
+ ] }),
3756
+ topRight
3757
+ ] }),
3758
+ /* @__PURE__ */ jsxs50(YStack48, { backgroundColor: "$color1", borderRadius: "$7", padding: "$4", gap: "$2", borderWidth: 1, borderColor: "$color4", children: [
3759
+ /* @__PURE__ */ jsx60(SizableText50, { size: "$3", color: "$color10", children: balanceLabel }),
3760
+ /* @__PURE__ */ jsx60(SizableText50, { size: "$11", fontWeight: "800", children: balance }),
3761
+ chartSlot ? /* @__PURE__ */ jsx60(YStack48, { marginTop: "$2", children: chartSlot }) : null
3762
+ ] }),
3763
+ metrics.length > 0 ? /* @__PURE__ */ jsx60(XStack43, { gap: "$3", flexWrap: "wrap", children: metrics.map((metric) => /* @__PURE__ */ jsxs50(YStack48, { flex: 1, minWidth: 120, backgroundColor: "$color1", borderRadius: "$6", padding: "$3", gap: "$1", borderWidth: 1, borderColor: "$color4", children: [
3764
+ /* @__PURE__ */ jsx60(SizableText50, { size: "$2", color: "$color10", children: metric.label }),
3765
+ /* @__PURE__ */ jsx60(SizableText50, { size: "$7", fontWeight: "800", children: metric.value }),
3766
+ metric.change ? /* @__PURE__ */ jsx60(SizableText50, { size: "$2", color: "$color9", children: metric.change }) : null
3767
+ ] }, metric.label)) }) : null,
3768
+ quickActions.length > 0 ? /* @__PURE__ */ jsx60(XStack43, { gap: "$3", flexWrap: "wrap", children: quickActions.map((action) => /* @__PURE__ */ jsxs50(
3769
+ YStack48,
3770
+ {
3771
+ flex: 1,
3772
+ minWidth: 88,
3773
+ backgroundColor: "$color1",
3774
+ borderRadius: "$6",
3775
+ padding: "$3",
3776
+ gap: "$2",
3777
+ alignItems: "center",
3778
+ justifyContent: "center",
3779
+ borderWidth: 1,
3780
+ borderColor: "$color4",
3781
+ onPress: action.onPress,
3782
+ children: [
3783
+ /* @__PURE__ */ jsx60(YStack48, { width: 36, height: 36, borderRadius: "$10", backgroundColor: "$color3", alignItems: "center", justifyContent: "center", children: action.icon ?? /* @__PURE__ */ jsx60(SizableText50, { size: "$4", children: "\u2022" }) }),
3784
+ /* @__PURE__ */ jsx60(SizableText50, { size: "$2", textAlign: "center", children: action.label })
3785
+ ]
3786
+ },
3787
+ action.id
3788
+ )) }) : null,
3789
+ /* @__PURE__ */ jsx60(YStack48, { gap: "$3", children: sections.map((section, index) => /* @__PURE__ */ jsxs50(YStack48, { backgroundColor: "$color1", borderRadius: "$6", borderWidth: 1, borderColor: "$color4", overflow: "hidden", children: [
3790
+ /* @__PURE__ */ jsx60(XStack43, { padding: "$3", justifyContent: "space-between", alignItems: "center", children: /* @__PURE__ */ jsx60(SizableText50, { size: "$4", fontWeight: "700", children: section.title }) }),
3791
+ /* @__PURE__ */ jsx60(YStack48, { children: section.rows.map((row, index2) => /* @__PURE__ */ jsxs50(
3792
+ XStack43,
3793
+ {
3794
+ padding: "$3",
3795
+ gap: "$3",
3796
+ alignItems: "center",
3797
+ borderTopWidth: index2 === 0 ? 0 : 1,
3798
+ borderTopColor: "$color4",
3799
+ children: [
3800
+ row.leading ? /* @__PURE__ */ jsx60(YStack48, { width: 32, height: 32, borderRadius: "$8", backgroundColor: "$color3", alignItems: "center", justifyContent: "center", children: row.leading }) : null,
3801
+ /* @__PURE__ */ jsxs50(YStack48, { flex: 1, children: [
3802
+ /* @__PURE__ */ jsx60(SizableText50, { size: "$3", fontWeight: "600", children: row.title }),
3803
+ row.subtitle ? /* @__PURE__ */ jsx60(SizableText50, { size: "$2", color: "$color10", children: row.subtitle }) : null
3804
+ ] }),
3805
+ row.value ? /* @__PURE__ */ jsx60(SizableText50, { size: "$3", color: "$color11", children: row.value }) : null
3806
+ ]
3807
+ },
3808
+ row.id
3809
+ )) })
3810
+ ] }, section.id ?? `${section.title}-${index}`)) })
3811
+ ] });
3812
+ }
1691
3813
  export {
1692
3814
  Accordion,
1693
3815
  ActionSheet,
1694
- Adapt,
1695
- AlertDialog2 as AlertDialog,
3816
+ Adapt4 as Adapt,
3817
+ AlertDialog3 as AlertDialog,
1696
3818
  Anchor,
3819
+ AnimatePresence,
1697
3820
  AppHeader,
3821
+ AppleLogo,
3822
+ Article,
3823
+ Aside,
1698
3824
  Avatar2 as Avatar,
3825
+ AvatarGroup,
3826
+ BLINK_DESIGN_THEMES,
3827
+ BLINK_DESIGN_THEME_IDS,
1699
3828
  Badge,
1700
3829
  BlinkAccordion,
1701
3830
  Avatar as BlinkAvatar,
1702
3831
  Button as BlinkButton,
1703
3832
  Card as BlinkCard,
3833
+ BlinkDialog,
1704
3834
  Input as BlinkInput,
3835
+ BlinkPopover,
1705
3836
  TamaguiProvider2 as BlinkProvider,
3837
+ BlinkSelect,
1706
3838
  BlinkTabs,
1707
3839
  BlinkText,
1708
3840
  BlinkToastProvider,
1709
3841
  BlinkToggleGroup,
1710
3842
  BlinkTooltip,
1711
3843
  BottomSheet,
1712
- Button8 as Button,
3844
+ Button13 as Button,
1713
3845
  Card2 as Card,
1714
3846
  Carousel,
1715
3847
  ChatBubble,
1716
3848
  Checkbox,
1717
- Circle8 as Circle,
3849
+ Chip,
3850
+ ChipGroup,
3851
+ Circle12 as Circle,
3852
+ ConfirmDialog,
1718
3853
  Container,
1719
- Dialog,
3854
+ CountdownBanner,
3855
+ DataTable,
3856
+ DatePicker,
3857
+ Dialog2 as Dialog,
1720
3858
  DialogProvider,
1721
3859
  Divider,
1722
3860
  EmptyState,
3861
+ EnsureFlexed,
3862
+ EventCard,
1723
3863
  Fieldset,
3864
+ FinanceDashboard,
1724
3865
  FloatingActionButton,
3866
+ Footer,
1725
3867
  Form,
1726
3868
  FormField,
3869
+ Frame,
3870
+ GitHubLogo,
3871
+ GlassCard,
3872
+ GoogleLogo,
1727
3873
  Grid,
3874
+ Group,
1728
3875
  H12 as H1,
1729
3876
  H22 as H2,
1730
3877
  H32 as H3,
1731
3878
  H42 as H4,
1732
3879
  H52 as H5,
1733
3880
  H62 as H6,
3881
+ Header,
3882
+ Heading,
1734
3883
  ICONS,
1735
3884
  Icon,
1736
3885
  Image2 as Image,
1737
- Input3 as Input,
3886
+ ImmersiveMediaScreen,
3887
+ Input5 as Input,
1738
3888
  KeyboardStickyFooter,
1739
3889
  Label,
1740
3890
  ListItem,
1741
3891
  LoginScreen,
3892
+ Main,
1742
3893
  MediaCard,
3894
+ MicrosoftLogo,
3895
+ Nav,
1743
3896
  NotificationBanner,
3897
+ OTPInput,
1744
3898
  OnboardingCarousel,
1745
3899
  PageContainer,
1746
3900
  PageMainContainer,
1747
3901
  Paragraph,
3902
+ PasswordInput,
1748
3903
  PaywallScreen,
1749
- Popover2 as Popover,
3904
+ Popover3 as Popover,
3905
+ Portal,
3906
+ PortalHost,
3907
+ PortalItem,
1750
3908
  PortalProvider,
1751
3909
  Pressable,
3910
+ PricingTable,
3911
+ ProductCard,
1752
3912
  ProfileHeader,
1753
3913
  Progress,
1754
3914
  ProgressSteps,
@@ -1756,53 +3916,91 @@ export {
1756
3916
  RadioGroup,
1757
3917
  SafeArea,
1758
3918
  ScreenLayout,
1759
- ScrollView5 as ScrollView,
3919
+ ScrollView6 as ScrollView,
1760
3920
  SearchBar,
1761
3921
  Section,
1762
- Select,
3922
+ Select2 as Select,
1763
3923
  SepHeading,
1764
- Separator5 as Separator,
3924
+ Separator7 as Separator,
1765
3925
  SettingsScreen,
1766
- Sheet3 as Sheet,
1767
- SizableText34 as SizableText,
3926
+ Sheet5 as Sheet,
3927
+ SizableStack,
3928
+ SizableText51 as SizableText,
1768
3929
  Skeleton,
1769
- Slider,
3930
+ Slider2 as Slider,
3931
+ Spacer,
1770
3932
  Spinner2 as Spinner,
1771
3933
  Square,
3934
+ Stack,
3935
+ StatusBadge,
1772
3936
  StepPageLayout,
1773
3937
  SubHeading,
3938
+ SwipeCards,
1774
3939
  SwipeableRow,
1775
- Switch2 as Switch,
3940
+ Switch3 as Switch,
1776
3941
  TabBar,
1777
3942
  Tabs,
1778
- Image6 as TamaguiImage,
3943
+ Image9 as TamaguiImage,
1779
3944
  ListItem2 as TamaguiListItem,
1780
3945
  TamaguiProvider,
3946
+ TestimonialCard2 as TestimonialCard,
1781
3947
  Text,
1782
3948
  TextArea,
1783
- Theme,
3949
+ Theme2 as Theme,
3950
+ ThemeableStack,
1784
3951
  ToggleGroup,
1785
3952
  Tooltip,
1786
3953
  TooltipSimple,
1787
3954
  Unspaced,
1788
- View6 as View,
3955
+ UserPreferences,
3956
+ View7 as View,
1789
3957
  VisuallyHidden,
1790
3958
  XGroup,
1791
- XStack27 as XStack,
3959
+ XStack44 as XStack,
1792
3960
  YGroup,
1793
- YStack32 as YStack,
3961
+ YStack49 as YStack,
1794
3962
  ZStack,
3963
+ addTheme,
1795
3964
  blinkConfig,
3965
+ composeEventHandlers,
3966
+ composeRefs,
3967
+ createFont,
3968
+ createMedia,
3969
+ createStyledContext,
1796
3970
  createTamagui2 as createTamagui,
3971
+ createTheme,
3972
+ createTokens,
3973
+ createVariable,
1797
3974
  dialogConfirm,
3975
+ getBlinkDesignTheme,
3976
+ getBlinkThemePalettes,
3977
+ getConfig,
3978
+ getToken,
3979
+ getTokenValue,
3980
+ getTokens,
3981
+ isClient,
3982
+ isWeb,
3983
+ replaceTheme,
1798
3984
  showError,
1799
- styled12 as styled,
3985
+ styled14 as styled,
1800
3986
  defaultConfig2 as tamaguiDefaultConfig,
1801
3987
  toast,
3988
+ updateTheme,
1802
3989
  useBlinkToast,
1803
- useMedia,
3990
+ useComposedRefs,
3991
+ useControllableState,
3992
+ useDebounce,
3993
+ useDebounceValue,
3994
+ useDidFinishSSR,
3995
+ useEvent,
3996
+ useForceUpdate,
3997
+ useIsPresent,
3998
+ useIsomorphicLayoutEffect,
3999
+ useMedia2 as useMedia,
4000
+ usePresence,
1804
4001
  useTheme,
1805
4002
  useThemeName,
4003
+ useWindowDimensions,
1806
4004
  withStaticProperties2 as withStaticProperties
1807
4005
  };
1808
4006
  //# sourceMappingURL=index.mjs.map