kaleido-ui 0.1.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.
@@ -0,0 +1,1276 @@
1
+ "use client";
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/web/index.ts
32
+ var web_exports = {};
33
+ __export(web_exports, {
34
+ AlertBanner: () => AlertBanner,
35
+ AssetCard: () => AssetCard,
36
+ AssetIcon: () => AssetIcon,
37
+ Button: () => Button,
38
+ Card: () => Card,
39
+ CardContent: () => CardContent,
40
+ CardDescription: () => CardDescription,
41
+ CardFooter: () => CardFooter,
42
+ CardHeader: () => CardHeader,
43
+ CardTitle: () => CardTitle,
44
+ Dialog: () => Dialog,
45
+ DialogClose: () => DialogClose,
46
+ DialogContent: () => DialogContent,
47
+ DialogDescription: () => DialogDescription,
48
+ DialogFooter: () => DialogFooter,
49
+ DialogHeader: () => DialogHeader,
50
+ DialogOverlay: () => DialogOverlay,
51
+ DialogPortal: () => DialogPortal,
52
+ DialogTitle: () => DialogTitle,
53
+ DialogTrigger: () => DialogTrigger,
54
+ ErrorBoundary: () => ErrorBoundary,
55
+ Icon: () => Icon,
56
+ Icons: () => Icons,
57
+ Input: () => Input,
58
+ Label: () => Label,
59
+ NetworkBadge: () => NetworkBadge,
60
+ PageHeader: () => PageHeader,
61
+ SectionLabel: () => SectionLabel,
62
+ SettingItem: () => SettingItem,
63
+ StatusBadge: () => StatusBadge,
64
+ Tabs: () => Tabs,
65
+ TabsContent: () => TabsContent,
66
+ TabsList: () => TabsList,
67
+ TabsTrigger: () => TabsTrigger,
68
+ Toast: () => Toast,
69
+ ToastAction: () => ToastAction,
70
+ ToastClose: () => ToastClose,
71
+ ToastDescription: () => ToastDescription,
72
+ ToastProvider: () => ToastProvider,
73
+ ToastTitle: () => ToastTitle,
74
+ ToastViewport: () => ToastViewport,
75
+ Toaster: () => Toaster,
76
+ TransactionCard: () => TransactionCard,
77
+ buttonVariants: () => buttonVariants,
78
+ cn: () => cn,
79
+ getAssetIconUrl: () => getAssetIconUrl,
80
+ getFallbackAssetIconUrl: () => getFallbackAssetIconUrl,
81
+ toast: () => toast,
82
+ useAssetIcon: () => useAssetIcon,
83
+ useToast: () => useToast
84
+ });
85
+ module.exports = __toCommonJS(web_exports);
86
+
87
+ // src/web/utils/cn.ts
88
+ var import_clsx = require("clsx");
89
+ var import_tailwind_merge = require("tailwind-merge");
90
+ function cn(...inputs) {
91
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
92
+ }
93
+
94
+ // src/web/primitives/button.tsx
95
+ var React = __toESM(require("react"), 1);
96
+ var import_react_slot = require("@radix-ui/react-slot");
97
+ var import_class_variance_authority = require("class-variance-authority");
98
+ var import_jsx_runtime = require("react/jsx-runtime");
99
+ var buttonVariants = (0, import_class_variance_authority.cva)(
100
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-xl text-sm font-semibold ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 active:scale-[0.98]",
101
+ {
102
+ variants: {
103
+ variant: {
104
+ default: "bg-primary text-primary-foreground hover:bg-primary/90 shadow-glow-subtle hover:shadow-glow",
105
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
106
+ outline: "border border-border bg-transparent hover:bg-accent hover:text-accent-foreground hover:border-primary/30",
107
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
108
+ ghost: "hover:bg-white/5 hover:text-foreground",
109
+ link: "text-primary underline-offset-4 hover:underline",
110
+ glow: "bg-primary text-primary-foreground shadow-glow hover:shadow-glow-strong animate-pulse-glow",
111
+ surface: "bg-card text-card-foreground border border-border hover:bg-accent hover:border-primary/30",
112
+ cta: "w-full bg-primary hover:bg-primary-dark text-primary-foreground font-bold rounded-2xl shadow-glow-accent disabled:opacity-50 disabled:cursor-not-allowed disabled:shadow-none",
113
+ "cta-gradient": "w-full bg-gradient-to-r from-primary to-primary-dark text-primary-foreground font-extrabold rounded-2xl shadow-[0_8px_30px_rgba(43,238,121,0.35)] hover:opacity-90 hover:-translate-y-0.5 active:translate-y-0 active:opacity-100 disabled:opacity-40 disabled:shadow-none disabled:cursor-not-allowed disabled:bg-surface-highlight disabled:text-white/50",
114
+ "danger-subtle": "w-full bg-red-500/10 border border-red-500/20 text-red-400 font-bold rounded-xl hover:bg-red-500/20"
115
+ },
116
+ size: {
117
+ default: "h-11 px-5 py-2",
118
+ sm: "h-9 rounded-lg px-3 text-xs",
119
+ lg: "h-14 rounded-xl px-8 text-base font-bold",
120
+ xl: "h-16 rounded-2xl px-10 text-lg font-bold",
121
+ cta: "h-14 py-4 px-6 text-lg",
122
+ "cta-lg": "h-[60px] py-5 px-6 text-lg",
123
+ icon: "h-10 w-10 rounded-full",
124
+ "icon-lg": "h-12 w-12 rounded-full",
125
+ "icon-xl": "h-14 w-14 rounded-full"
126
+ }
127
+ },
128
+ defaultVariants: {
129
+ variant: "default",
130
+ size: "default"
131
+ }
132
+ }
133
+ );
134
+ var Button = React.forwardRef(
135
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
136
+ const Comp = asChild ? import_react_slot.Slot : "button";
137
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
138
+ Comp,
139
+ {
140
+ className: cn(buttonVariants({ variant, size, className })),
141
+ ref,
142
+ ...props
143
+ }
144
+ );
145
+ }
146
+ );
147
+ Button.displayName = "Button";
148
+
149
+ // src/web/primitives/card.tsx
150
+ var React2 = __toESM(require("react"), 1);
151
+ var import_jsx_runtime2 = require("react/jsx-runtime");
152
+ var Card = React2.forwardRef(
153
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
154
+ "div",
155
+ {
156
+ ref,
157
+ className: cn(
158
+ "rounded-2xl border border-border/50 bg-card text-card-foreground shadow-sm transition-colors",
159
+ className
160
+ ),
161
+ ...props
162
+ }
163
+ )
164
+ );
165
+ Card.displayName = "Card";
166
+ var CardHeader = React2.forwardRef(
167
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })
168
+ );
169
+ CardHeader.displayName = "CardHeader";
170
+ var CardTitle = React2.forwardRef(
171
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
172
+ "h3",
173
+ {
174
+ ref,
175
+ className: cn("text-2xl font-semibold leading-none tracking-tight", className),
176
+ ...props
177
+ }
178
+ )
179
+ );
180
+ CardTitle.displayName = "CardTitle";
181
+ var CardDescription = React2.forwardRef(
182
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props })
183
+ );
184
+ CardDescription.displayName = "CardDescription";
185
+ var CardContent = React2.forwardRef(
186
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref, className: cn("p-6 pt-0", className), ...props })
187
+ );
188
+ CardContent.displayName = "CardContent";
189
+ var CardFooter = React2.forwardRef(
190
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref, className: cn("flex items-center p-6 pt-0", className), ...props })
191
+ );
192
+ CardFooter.displayName = "CardFooter";
193
+
194
+ // src/web/primitives/input.tsx
195
+ var React3 = __toESM(require("react"), 1);
196
+ var import_jsx_runtime3 = require("react/jsx-runtime");
197
+ var Input = React3.forwardRef(
198
+ ({ className, type, ...props }, ref) => {
199
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
200
+ "input",
201
+ {
202
+ type,
203
+ className: cn(
204
+ "flex h-12 w-full rounded-xl border border-border bg-card px-4 py-3 text-base ring-offset-background transition-all file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:border-primary disabled:cursor-not-allowed disabled:opacity-50",
205
+ className
206
+ ),
207
+ ref,
208
+ ...props
209
+ }
210
+ );
211
+ }
212
+ );
213
+ Input.displayName = "Input";
214
+
215
+ // src/web/primitives/dialog.tsx
216
+ var React4 = __toESM(require("react"), 1);
217
+ var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
218
+
219
+ // src/web/primitives/icon.tsx
220
+ var import_jsx_runtime4 = require("react/jsx-runtime");
221
+ var sizeClasses = {
222
+ xs: "text-[14px]",
223
+ sm: "text-[16px]",
224
+ md: "text-[20px]",
225
+ lg: "text-[24px]",
226
+ xl: "text-[32px]",
227
+ "2xl": "text-[48px]"
228
+ };
229
+ function Icon({
230
+ name,
231
+ filled = false,
232
+ size = "lg",
233
+ className,
234
+ ...props
235
+ }) {
236
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
237
+ "span",
238
+ {
239
+ className: cn(
240
+ "material-symbols-outlined",
241
+ filled && "filled",
242
+ sizeClasses[size],
243
+ className
244
+ ),
245
+ ...props,
246
+ children: name
247
+ }
248
+ );
249
+ }
250
+ var Icons = {
251
+ // Navigation
252
+ ArrowBack: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "arrow_back", ...props }),
253
+ ArrowForward: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "arrow_forward", ...props }),
254
+ Close: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "close", ...props }),
255
+ Menu: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "menu", ...props }),
256
+ // Actions
257
+ Send: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "arrow_upward", ...props }),
258
+ Receive: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "arrow_downward", ...props }),
259
+ Swap: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "swap_horiz", ...props }),
260
+ Copy: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "content_copy", ...props }),
261
+ Paste: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "content_paste", ...props }),
262
+ Refresh: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "refresh", ...props }),
263
+ Share: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "ios_share", ...props }),
264
+ QrCode: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "qr_code_2", ...props }),
265
+ QrScanner: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "qr_code_scanner", ...props }),
266
+ // Status
267
+ Check: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "check", ...props }),
268
+ CheckCircle: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "check_circle", ...props }),
269
+ Error: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "error", ...props }),
270
+ Warning: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "warning", ...props }),
271
+ Info: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "info", ...props }),
272
+ Pending: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "hourglass_top", ...props }),
273
+ // Navigation tabs
274
+ Wallet: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "account_balance_wallet", ...props }),
275
+ Activity: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "history", ...props }),
276
+ Settings: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "settings", ...props }),
277
+ // Networks
278
+ Lightning: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "bolt", ...props }),
279
+ Bitcoin: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "currency_bitcoin", ...props }),
280
+ Ark: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "hexagon", ...props }),
281
+ // Security
282
+ Lock: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "lock", ...props }),
283
+ Unlock: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "lock_open", ...props }),
284
+ Shield: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "shield", ...props }),
285
+ Key: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "key", ...props }),
286
+ Fingerprint: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "fingerprint", ...props }),
287
+ Visibility: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "visibility", ...props }),
288
+ VisibilityOff: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "visibility_off", ...props }),
289
+ // Misc
290
+ ExpandMore: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "expand_more", ...props }),
291
+ ExpandLess: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "expand_less", ...props }),
292
+ ChevronRight: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "chevron_right", ...props }),
293
+ OpenInNew: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "open_in_new", ...props }),
294
+ Search: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "search", ...props }),
295
+ Add: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "add", ...props }),
296
+ Download: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "download", ...props }),
297
+ Upload: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "upload", ...props }),
298
+ Edit: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "edit", ...props }),
299
+ Delete: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "delete", ...props }),
300
+ Timer: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "timer", ...props }),
301
+ Person: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "person", ...props }),
302
+ Hub: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "hub", ...props }),
303
+ Verified: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "verified", ...props }),
304
+ // Agent / AI
305
+ SmartToy: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "smart_toy", ...props }),
306
+ Psychology: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "psychology", ...props }),
307
+ Event: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "event", ...props }),
308
+ PlayArrow: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "play_arrow", ...props }),
309
+ ChatBubble: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "chat_bubble", ...props }),
310
+ Progress: (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "progress_activity", ...props })
311
+ };
312
+
313
+ // src/web/primitives/dialog.tsx
314
+ var import_jsx_runtime5 = require("react/jsx-runtime");
315
+ var Dialog = DialogPrimitive.Root;
316
+ var DialogTrigger = DialogPrimitive.Trigger;
317
+ var DialogPortal = DialogPrimitive.Portal;
318
+ var DialogClose = DialogPrimitive.Close;
319
+ var DialogOverlay = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
320
+ DialogPrimitive.Overlay,
321
+ {
322
+ ref,
323
+ className: cn(
324
+ "fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
325
+ className
326
+ ),
327
+ ...props
328
+ }
329
+ ));
330
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
331
+ var DialogContent = React4.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(DialogPortal, { children: [
332
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogOverlay, {}),
333
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
334
+ DialogPrimitive.Content,
335
+ {
336
+ ref,
337
+ className: cn(
338
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] rounded-lg",
339
+ className
340
+ ),
341
+ ...props,
342
+ children: [
343
+ children,
344
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
345
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "close", size: "sm" }),
346
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "sr-only", children: "Close" })
347
+ ] })
348
+ ]
349
+ }
350
+ )
351
+ ] }));
352
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
353
+ var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
354
+ DialogHeader.displayName = "DialogHeader";
355
+ var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props });
356
+ DialogFooter.displayName = "DialogFooter";
357
+ var DialogTitle = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
358
+ DialogPrimitive.Title,
359
+ {
360
+ ref,
361
+ className: cn("text-lg font-semibold leading-none tracking-tight", className),
362
+ ...props
363
+ }
364
+ ));
365
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
366
+ var DialogDescription = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
367
+ DialogPrimitive.Description,
368
+ {
369
+ ref,
370
+ className: cn("text-sm text-muted-foreground", className),
371
+ ...props
372
+ }
373
+ ));
374
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
375
+
376
+ // src/web/primitives/tabs.tsx
377
+ var React5 = __toESM(require("react"), 1);
378
+ var TabsPrimitive = __toESM(require("@radix-ui/react-tabs"), 1);
379
+ var import_jsx_runtime6 = require("react/jsx-runtime");
380
+ var Tabs = TabsPrimitive.Root;
381
+ var TabsList = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
382
+ TabsPrimitive.List,
383
+ {
384
+ ref,
385
+ className: cn(
386
+ "inline-flex h-12 items-center justify-center gap-2 rounded-xl bg-card p-1.5 text-muted-foreground border border-border/50",
387
+ className
388
+ ),
389
+ ...props
390
+ }
391
+ ));
392
+ TabsList.displayName = TabsPrimitive.List.displayName;
393
+ var TabsTrigger = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
394
+ TabsPrimitive.Trigger,
395
+ {
396
+ ref,
397
+ className: cn(
398
+ "inline-flex items-center justify-center whitespace-nowrap rounded-lg px-4 py-2 text-sm font-semibold ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
399
+ "hover:text-foreground hover:bg-white/5",
400
+ "data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-glow-subtle",
401
+ className
402
+ ),
403
+ ...props
404
+ }
405
+ ));
406
+ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
407
+ var TabsContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
408
+ TabsPrimitive.Content,
409
+ {
410
+ ref,
411
+ className: cn(
412
+ "mt-4 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 animate-fade-in",
413
+ className
414
+ ),
415
+ ...props
416
+ }
417
+ ));
418
+ TabsContent.displayName = TabsPrimitive.Content.displayName;
419
+
420
+ // src/web/primitives/label.tsx
421
+ var React6 = __toESM(require("react"), 1);
422
+ var LabelPrimitive = __toESM(require("@radix-ui/react-label"), 1);
423
+ var import_class_variance_authority2 = require("class-variance-authority");
424
+ var import_jsx_runtime7 = require("react/jsx-runtime");
425
+ var labelVariants = (0, import_class_variance_authority2.cva)(
426
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
427
+ );
428
+ var Label = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
429
+ LabelPrimitive.Root,
430
+ {
431
+ ref,
432
+ className: cn(labelVariants(), className),
433
+ ...props
434
+ }
435
+ ));
436
+ Label.displayName = LabelPrimitive.Root.displayName;
437
+
438
+ // src/web/primitives/toast.tsx
439
+ var React7 = __toESM(require("react"), 1);
440
+ var ToastPrimitives = __toESM(require("@radix-ui/react-toast"), 1);
441
+ var import_class_variance_authority3 = require("class-variance-authority");
442
+ var import_jsx_runtime8 = require("react/jsx-runtime");
443
+ var ToastProvider = ToastPrimitives.Provider;
444
+ var ToastViewport = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
445
+ ToastPrimitives.Viewport,
446
+ {
447
+ ref,
448
+ className: cn(
449
+ "fixed bottom-20 left-0 right-0 z-[100] flex max-h-screen w-full flex-col items-center p-4 gap-2",
450
+ className
451
+ ),
452
+ ...props
453
+ }
454
+ ));
455
+ ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
456
+ var toastVariants = (0, import_class_variance_authority3.cva)(
457
+ "group pointer-events-auto relative flex w-full max-w-md items-center justify-between space-x-3 overflow-hidden rounded-xl border backdrop-blur-xl p-4 pr-10 shadow-[0_0_30px_rgba(0,0,0,0.3)] transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-bottom-full data-[state=open]:slide-in-from-bottom-full",
458
+ {
459
+ variants: {
460
+ variant: {
461
+ default: "border-white/10 bg-surface-dark/95 text-white",
462
+ destructive: "border-red-500/20 bg-red-500/10 text-red-400"
463
+ }
464
+ },
465
+ defaultVariants: {
466
+ variant: "default"
467
+ }
468
+ }
469
+ );
470
+ var Toast = React7.forwardRef(({ className, variant, ...props }, ref) => {
471
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
472
+ ToastPrimitives.Root,
473
+ {
474
+ ref,
475
+ className: cn(toastVariants({ variant }), className),
476
+ ...props
477
+ }
478
+ );
479
+ });
480
+ Toast.displayName = ToastPrimitives.Root.displayName;
481
+ var ToastAction = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
482
+ ToastPrimitives.Action,
483
+ {
484
+ ref,
485
+ className: cn(
486
+ "inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",
487
+ className
488
+ ),
489
+ ...props
490
+ }
491
+ ));
492
+ ToastAction.displayName = ToastPrimitives.Action.displayName;
493
+ var ToastClose = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
494
+ ToastPrimitives.Close,
495
+ {
496
+ ref,
497
+ className: cn(
498
+ "absolute right-2 top-2 rounded-full p-1 text-white/50 opacity-100 transition-all hover:text-white hover:bg-white/10 focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-primary group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:hover:bg-red-500/20 group-[.destructive]:focus:ring-red-400",
499
+ className
500
+ ),
501
+ "toast-close": "",
502
+ ...props,
503
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "close", size: "sm" })
504
+ }
505
+ ));
506
+ ToastClose.displayName = ToastPrimitives.Close.displayName;
507
+ var ToastTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
508
+ ToastPrimitives.Title,
509
+ {
510
+ ref,
511
+ className: cn("text-sm font-semibold text-white", className),
512
+ ...props
513
+ }
514
+ ));
515
+ ToastTitle.displayName = ToastPrimitives.Title.displayName;
516
+ var ToastDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
517
+ ToastPrimitives.Description,
518
+ {
519
+ ref,
520
+ className: cn("text-xs text-white/70", className),
521
+ ...props
522
+ }
523
+ ));
524
+ ToastDescription.displayName = ToastPrimitives.Description.displayName;
525
+
526
+ // src/web/primitives/toaster.tsx
527
+ var import_react = require("react");
528
+
529
+ // src/web/hooks/use-toast.ts
530
+ var React8 = __toESM(require("react"), 1);
531
+ var TOAST_LIMIT = 1;
532
+ var TOAST_REMOVE_DELAY = 1e3;
533
+ var count = 0;
534
+ function genId() {
535
+ count = (count + 1) % Number.MAX_SAFE_INTEGER;
536
+ return count.toString();
537
+ }
538
+ var toastTimeouts = /* @__PURE__ */ new Map();
539
+ var addToRemoveQueue = (toastId) => {
540
+ if (toastTimeouts.has(toastId)) return;
541
+ const timeout = setTimeout(() => {
542
+ toastTimeouts.delete(toastId);
543
+ dispatch({ type: "REMOVE_TOAST", toastId });
544
+ }, TOAST_REMOVE_DELAY);
545
+ toastTimeouts.set(toastId, timeout);
546
+ };
547
+ var reducer = (state, action) => {
548
+ switch (action.type) {
549
+ case "ADD_TOAST":
550
+ return {
551
+ ...state,
552
+ toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT)
553
+ };
554
+ case "UPDATE_TOAST":
555
+ return {
556
+ ...state,
557
+ toasts: state.toasts.map(
558
+ (t) => t.id === action.toast.id ? { ...t, ...action.toast } : t
559
+ )
560
+ };
561
+ case "DISMISS_TOAST": {
562
+ const { toastId } = action;
563
+ if (toastId) {
564
+ addToRemoveQueue(toastId);
565
+ } else {
566
+ state.toasts.forEach((toast2) => addToRemoveQueue(toast2.id));
567
+ }
568
+ return {
569
+ ...state,
570
+ toasts: state.toasts.map(
571
+ (t) => t.id === toastId || toastId === void 0 ? { ...t, open: false } : t
572
+ )
573
+ };
574
+ }
575
+ case "REMOVE_TOAST":
576
+ if (action.toastId === void 0) return { ...state, toasts: [] };
577
+ return {
578
+ ...state,
579
+ toasts: state.toasts.filter((t) => t.id !== action.toastId)
580
+ };
581
+ }
582
+ };
583
+ var listeners = [];
584
+ var memoryState = { toasts: [] };
585
+ function dispatch(action) {
586
+ memoryState = reducer(memoryState, action);
587
+ listeners.forEach((listener) => listener(memoryState));
588
+ }
589
+ function toast({ duration = 4e3, ...props }) {
590
+ const id = genId();
591
+ const update = (props2) => dispatch({ type: "UPDATE_TOAST", toast: { ...props2, id } });
592
+ const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id });
593
+ dispatch({
594
+ type: "ADD_TOAST",
595
+ toast: {
596
+ ...props,
597
+ id,
598
+ open: true,
599
+ duration,
600
+ onOpenChange: (open) => {
601
+ if (!open) dismiss();
602
+ }
603
+ }
604
+ });
605
+ if (duration > 0) {
606
+ setTimeout(() => dismiss(), duration);
607
+ }
608
+ return { id, dismiss, update };
609
+ }
610
+ function useToast() {
611
+ const [state, setState] = React8.useState(memoryState);
612
+ React8.useEffect(() => {
613
+ listeners.push(setState);
614
+ return () => {
615
+ const index = listeners.indexOf(setState);
616
+ if (index > -1) listeners.splice(index, 1);
617
+ };
618
+ }, [state]);
619
+ return {
620
+ ...state,
621
+ toast,
622
+ dismiss: (toastId) => dispatch({ type: "DISMISS_TOAST", toastId })
623
+ };
624
+ }
625
+
626
+ // src/web/primitives/toaster.tsx
627
+ var import_jsx_runtime9 = require("react/jsx-runtime");
628
+ function ToastWithProgress({ id, title, description, action, duration = 4e3, variant, ...props }) {
629
+ const [progress, setProgress] = (0, import_react.useState)(100);
630
+ (0, import_react.useEffect)(() => {
631
+ const interval = 50;
632
+ const decrement = interval / duration * 100;
633
+ const timer = setInterval(() => {
634
+ setProgress((prev) => {
635
+ const next = prev - decrement;
636
+ return next <= 0 ? 0 : next;
637
+ });
638
+ }, interval);
639
+ return () => clearInterval(timer);
640
+ }, [duration]);
641
+ const getIcon = () => {
642
+ if (variant === "destructive") {
643
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { name: "error", size: "md", className: "text-red-400" });
644
+ }
645
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { name: "check_circle", size: "md", className: "text-primary" });
646
+ };
647
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Toast, { ...props, variant, children: [
648
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-start gap-3 flex-1", children: [
649
+ getIcon(),
650
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "grid gap-1 flex-1", children: [
651
+ title && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToastTitle, { children: title }),
652
+ description && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToastDescription, { children: description })
653
+ ] })
654
+ ] }),
655
+ action,
656
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToastClose, {}),
657
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "absolute bottom-0 left-0 right-0 h-1 bg-white/10 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
658
+ "div",
659
+ {
660
+ className: `h-full transition-all ease-linear ${variant === "destructive" ? "bg-red-500" : "bg-primary"}`,
661
+ style: { width: `${progress}%` }
662
+ }
663
+ ) })
664
+ ] });
665
+ }
666
+ function Toaster() {
667
+ const { toasts } = useToast();
668
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ToastProvider, { children: [
669
+ toasts.map(function({ id, title, description, action, duration, ...props }) {
670
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
671
+ ToastWithProgress,
672
+ {
673
+ id,
674
+ title,
675
+ description,
676
+ action,
677
+ duration,
678
+ ...props
679
+ },
680
+ id
681
+ );
682
+ }),
683
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToastViewport, {})
684
+ ] });
685
+ }
686
+
687
+ // src/web/components/status-badge.tsx
688
+ var import_jsx_runtime10 = require("react/jsx-runtime");
689
+ function StatusBadge({ status, className }) {
690
+ const config = {
691
+ success: {
692
+ color: "text-primary",
693
+ bg: "bg-primary/10",
694
+ border: "border-primary/20",
695
+ icon: "check_circle",
696
+ label: "Success"
697
+ },
698
+ completed: {
699
+ color: "text-primary",
700
+ bg: "bg-primary/10",
701
+ border: "border-primary/20",
702
+ icon: "check_circle",
703
+ label: "Completed"
704
+ },
705
+ pending: {
706
+ color: "text-yellow-500",
707
+ bg: "bg-yellow-500/10",
708
+ border: "border-yellow-500/20",
709
+ icon: "schedule",
710
+ label: "Pending"
711
+ },
712
+ failed: {
713
+ color: "text-red-500",
714
+ bg: "bg-red-500/10",
715
+ border: "border-red-500/20",
716
+ icon: "error",
717
+ label: "Failed"
718
+ },
719
+ error: {
720
+ color: "text-red-500",
721
+ bg: "bg-red-500/10",
722
+ border: "border-red-500/20",
723
+ icon: "error",
724
+ label: "Error"
725
+ }
726
+ };
727
+ const { color, bg, border, icon, label } = config[status];
728
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
729
+ "div",
730
+ {
731
+ className: cn(
732
+ "inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full border font-medium text-xs",
733
+ bg,
734
+ border,
735
+ color,
736
+ className
737
+ ),
738
+ children: [
739
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: icon }),
740
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: label })
741
+ ]
742
+ }
743
+ );
744
+ }
745
+
746
+ // src/web/components/network-badge.tsx
747
+ var import_jsx_runtime11 = require("react/jsx-runtime");
748
+ var networkConfig = {
749
+ L1: {
750
+ color: "text-network-bitcoin",
751
+ bg: "bg-network-bitcoin/10 backdrop-blur-md",
752
+ border: "border-network-bitcoin/20",
753
+ label: "L1",
754
+ iconSuffix: "bitcoin/bitcoin-logo.svg"
755
+ },
756
+ LN: {
757
+ color: "text-purple-400",
758
+ bg: "bg-purple-500/10 backdrop-blur-md",
759
+ border: "border-purple-500/20",
760
+ label: "LN",
761
+ iconSuffix: "lightning/lightning.svg"
762
+ },
763
+ RGB20: {
764
+ color: "text-network-rgb",
765
+ bg: "bg-network-rgb/10 backdrop-blur-md",
766
+ border: "border-network-rgb/20",
767
+ label: "RGB",
768
+ iconSuffix: "rgb/rgb-logo.svg"
769
+ },
770
+ RGB21: {
771
+ color: "text-network-rgb",
772
+ bg: "bg-network-rgb/10 backdrop-blur-md",
773
+ border: "border-network-rgb/20",
774
+ label: "RGB21",
775
+ iconSuffix: "rgb/rgb-logo.svg"
776
+ },
777
+ "RGB-L1": {
778
+ color: "text-network-rgb",
779
+ bg: "bg-network-rgb/10 backdrop-blur-md",
780
+ border: "border-network-rgb/20",
781
+ label: "RGB L1",
782
+ iconSuffix: "rgb/rgb-logo.svg"
783
+ },
784
+ "RGB-LN": {
785
+ color: "text-network-rgb",
786
+ bg: "bg-network-rgb/10 backdrop-blur-md",
787
+ border: "border-network-rgb/20",
788
+ label: "RGB LN",
789
+ iconSuffix: "rgb/rgb-logo.svg"
790
+ },
791
+ Spark: {
792
+ color: "text-network-spark",
793
+ bg: "bg-network-spark/10 backdrop-blur-md",
794
+ border: "border-network-spark/20",
795
+ label: "Spark",
796
+ iconSuffix: "spark/Asterisk/Spark Asterisk White.svg"
797
+ },
798
+ Arkade: {
799
+ color: "text-network-arkade",
800
+ bg: "bg-network-arkade/10 backdrop-blur-md",
801
+ border: "border-network-arkade/20",
802
+ label: "Arkade",
803
+ iconSuffix: "arkade/arkade-icon.svg"
804
+ }
805
+ };
806
+ function NetworkBadge({ network, iconBasePath = "/icons", className }) {
807
+ const { color, bg, border, label, iconSuffix } = networkConfig[network];
808
+ const icon = `${iconBasePath}/${iconSuffix}`;
809
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
810
+ "span",
811
+ {
812
+ className: cn(
813
+ "text-xxs px-2 py-0.5 rounded-full font-bold border shadow-inner flex items-center justify-center gap-1 w-max transition-all",
814
+ bg,
815
+ border,
816
+ color,
817
+ className
818
+ ),
819
+ children: [
820
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
821
+ "img",
822
+ {
823
+ src: icon,
824
+ alt: network,
825
+ className: cn("size-3 object-contain", network === "Spark" && "opacity-80")
826
+ }
827
+ ),
828
+ label
829
+ ]
830
+ }
831
+ );
832
+ }
833
+
834
+ // src/web/components/asset-icon.tsx
835
+ var import_react3 = require("react");
836
+
837
+ // src/web/hooks/use-asset-icon.ts
838
+ var import_react2 = require("react");
839
+ var DEFAULT_ICON_CDN_BASE_URL = "https://raw.githubusercontent.com/kaleidoswap/coinmarketcap-icons-cryptos/refs/heads/main/icons/";
840
+ var DICEBEAR_SHAPES_BASE_URL = "https://api.dicebear.com/9.x/shapes/svg";
841
+ var TICKER_MAPPINGS = {
842
+ SAT: "BTC",
843
+ None: ""
844
+ };
845
+ var VALID_ICON_TICKER_REGEX = /^[A-Z0-9-]{1,12}$/;
846
+ function getAssetIconUrl(ticker, cdnBaseUrl = DEFAULT_ICON_CDN_BASE_URL) {
847
+ if (!ticker || ticker.trim() === "") return "";
848
+ const normalized = ticker.toUpperCase().trim();
849
+ if (!VALID_ICON_TICKER_REGEX.test(normalized)) return "";
850
+ if (TICKER_MAPPINGS[normalized] !== void 0) {
851
+ const mapped = TICKER_MAPPINGS[normalized];
852
+ if (mapped === "") return "";
853
+ return getAssetIconUrl(mapped, cdnBaseUrl);
854
+ }
855
+ return `${cdnBaseUrl}${normalized.toLowerCase()}.png`;
856
+ }
857
+ function getFallbackAssetIconUrl(seed) {
858
+ const normalized = seed.trim();
859
+ if (!normalized) return "";
860
+ const params = new URLSearchParams({
861
+ seed: normalized,
862
+ backgroundType: "gradientLinear",
863
+ radius: "50"
864
+ });
865
+ return `${DICEBEAR_SHAPES_BASE_URL}?${params.toString()}`;
866
+ }
867
+ function useAssetIcon(ticker, cdnBaseUrl) {
868
+ const [url, setUrl] = (0, import_react2.useState)(() => getAssetIconUrl(ticker, cdnBaseUrl));
869
+ (0, import_react2.useEffect)(() => {
870
+ setUrl(getAssetIconUrl(ticker, cdnBaseUrl));
871
+ }, [ticker, cdnBaseUrl]);
872
+ return url;
873
+ }
874
+
875
+ // src/web/components/asset-icon.tsx
876
+ var import_jsx_runtime12 = require("react/jsx-runtime");
877
+ var ASSET_COLORS = {
878
+ BTC: "bg-transparent",
879
+ ETH: "bg-[#627EEA]",
880
+ USDT: "bg-[#26A17B]",
881
+ USDC: "bg-[#2775CA]"
882
+ };
883
+ var LOCAL_ICONS = {
884
+ BTC: "/icons/bitcoin/bitcoin-logo.svg",
885
+ ARKADE: "/icons/arkade/arkade-icon.svg",
886
+ RGB: "/icons/rgb/rgb-logo.svg",
887
+ SPARK: "/icons/spark/Asterisk/Spark Asterisk White.svg"
888
+ };
889
+ function AssetIcon({ ticker, logoUri, cdnBaseUrl, size = 40, className }) {
890
+ const normTicker = ticker.toUpperCase();
891
+ const localIcon = LOCAL_ICONS[normTicker];
892
+ const cdnUrl = useAssetIcon(ticker, cdnBaseUrl);
893
+ const fallbackUrl = getFallbackAssetIconUrl(ticker);
894
+ const [useFallback, setUseFallback] = (0, import_react3.useState)(!logoUri && !localIcon && !cdnUrl && !!fallbackUrl);
895
+ const [failed, setFailed] = (0, import_react3.useState)(false);
896
+ (0, import_react3.useEffect)(() => {
897
+ setFailed(false);
898
+ setUseFallback(!logoUri && !localIcon && !cdnUrl && !!fallbackUrl);
899
+ }, [logoUri, localIcon, cdnUrl, fallbackUrl]);
900
+ const iconUrl = logoUri ? logoUri : localIcon ? localIcon : failed ? null : useFallback || !cdnUrl ? fallbackUrl || null : cdnUrl || fallbackUrl || null;
901
+ const bgColor = ASSET_COLORS[normTicker] || "bg-slate-600";
902
+ if (iconUrl) {
903
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
904
+ "div",
905
+ {
906
+ className: cn(
907
+ "rounded-full overflow-hidden flex items-center justify-center shadow-inner",
908
+ !localIcon && bgColor,
909
+ className
910
+ ),
911
+ style: { width: size, height: size },
912
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
913
+ "img",
914
+ {
915
+ src: iconUrl,
916
+ alt: `${ticker} icon`,
917
+ width: size,
918
+ height: size,
919
+ className: "object-cover w-full h-full",
920
+ onError: () => {
921
+ if (logoUri) {
922
+ setFailed(false);
923
+ setUseFallback(!localIcon && !!fallbackUrl);
924
+ return;
925
+ }
926
+ if (localIcon) return;
927
+ if (!useFallback && fallbackUrl) {
928
+ setUseFallback(true);
929
+ return;
930
+ }
931
+ setFailed(true);
932
+ }
933
+ }
934
+ )
935
+ }
936
+ );
937
+ }
938
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
939
+ "div",
940
+ {
941
+ className: cn(
942
+ "rounded-full flex items-center justify-center font-bold text-white shadow-inner border border-white/10",
943
+ bgColor,
944
+ className
945
+ ),
946
+ style: { width: size, height: size, fontSize: size * 0.4 },
947
+ children: ticker.charAt(0).toUpperCase()
948
+ }
949
+ );
950
+ }
951
+
952
+ // src/web/components/asset-card.tsx
953
+ var import_jsx_runtime13 = require("react/jsx-runtime");
954
+ function AssetCard({
955
+ ticker,
956
+ name,
957
+ displayBalance,
958
+ networks = [],
959
+ logoUri,
960
+ balanceVisible = true,
961
+ onClick,
962
+ className
963
+ }) {
964
+ const shown = balanceVisible ? displayBalance : "\u2022\u2022\u2022\u2022\u2022\u2022";
965
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
966
+ "div",
967
+ {
968
+ className: cn(
969
+ "p-4 rounded-card bg-background-dark/40 backdrop-blur-xl border border-white/5 transition-all shadow-sm relative overflow-hidden group",
970
+ onClick && "cursor-pointer hover:border-primary/40 hover:shadow-glow-subtle active:scale-[0.98]",
971
+ className
972
+ ),
973
+ onClick,
974
+ children: [
975
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "absolute inset-0 bg-gradient-to-br from-white/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" }),
976
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between relative z-10", children: [
977
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-3", children: [
978
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
979
+ AssetIcon,
980
+ {
981
+ ticker,
982
+ logoUri,
983
+ size: 44,
984
+ className: "group-hover:scale-105 transition-transform"
985
+ }
986
+ ),
987
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col", children: [
988
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
989
+ "span",
990
+ {
991
+ className: cn(
992
+ "font-bold text-base leading-tight tracking-wide text-white",
993
+ onClick && "group-hover:text-primary transition-colors"
994
+ ),
995
+ children: name
996
+ }
997
+ ),
998
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex flex-wrap gap-1 mt-1", children: networks.map((network) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NetworkBadge, { network }, network)) })
999
+ ] })
1000
+ ] }),
1001
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "text-right", children: [
1002
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "font-bold text-base tracking-tight text-white group-hover:text-white/90 transition-colors", children: shown }),
1003
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-tiny text-slate-400 font-medium tracking-wide uppercase mt-0.5", children: ticker })
1004
+ ] })
1005
+ ] })
1006
+ ]
1007
+ }
1008
+ );
1009
+ }
1010
+
1011
+ // src/web/components/transaction-card.tsx
1012
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1013
+ function TransactionCard({
1014
+ direction,
1015
+ status,
1016
+ displayAmount,
1017
+ unit = "sats",
1018
+ timestamp,
1019
+ onClick,
1020
+ className
1021
+ }) {
1022
+ const isInbound = direction === "inbound";
1023
+ const formatDate = (ts) => new Date(ts * 1e3).toLocaleDateString();
1024
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1025
+ "div",
1026
+ {
1027
+ className: cn(
1028
+ "p-4 rounded-card bg-background-dark/40 backdrop-blur-xl border border-white/5 flex items-center justify-between transition-all shadow-sm relative overflow-hidden group",
1029
+ onClick && "cursor-pointer hover:border-primary/40 hover:shadow-glow-subtle active:scale-[0.98]",
1030
+ className
1031
+ ),
1032
+ onClick,
1033
+ children: [
1034
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "absolute inset-0 bg-gradient-to-br from-white/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" }),
1035
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-3 relative z-10", children: [
1036
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1037
+ "div",
1038
+ {
1039
+ className: cn(
1040
+ "size-11 rounded-full flex items-center justify-center shadow-inner group-hover:scale-105 transition-transform",
1041
+ isInbound ? "bg-primary/20 text-primary border border-primary/20" : "bg-white/5 text-slate-300 border border-white/10"
1042
+ ),
1043
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: isInbound ? "arrow_downward" : "arrow_outward" })
1044
+ }
1045
+ ),
1046
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col", children: [
1047
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1048
+ "span",
1049
+ {
1050
+ className: cn(
1051
+ "font-bold text-sm text-white tracking-wide",
1052
+ onClick && "group-hover:text-primary transition-colors"
1053
+ ),
1054
+ children: isInbound ? "Received" : "Sent"
1055
+ }
1056
+ ),
1057
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2 mt-1", children: [
1058
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StatusBadge, { status, className: "text-xxs px-1.5 py-0.5" }),
1059
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-tiny text-slate-400 font-medium tracking-wide", children: formatDate(timestamp) })
1060
+ ] })
1061
+ ] })
1062
+ ] }),
1063
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "text-right relative z-10", children: [
1064
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1065
+ "p",
1066
+ {
1067
+ className: cn(
1068
+ "font-bold text-base tracking-tight group-hover:opacity-90 transition-opacity",
1069
+ isInbound ? "text-primary" : "text-white"
1070
+ ),
1071
+ children: [
1072
+ isInbound ? "+" : "-",
1073
+ displayAmount
1074
+ ]
1075
+ }
1076
+ ),
1077
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-tiny text-slate-400 font-medium tracking-wide uppercase mt-0.5", children: unit })
1078
+ ] })
1079
+ ]
1080
+ }
1081
+ );
1082
+ }
1083
+
1084
+ // src/web/components/page-header.tsx
1085
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1086
+ function PageHeader({ left, title, right, borderClassName = "border-border" }) {
1087
+ if (!title) {
1088
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("header", { className: `sticky top-0 z-20 flex items-center border-b bg-background-dark/95 px-4 py-3.5 backdrop-blur ${borderClassName}`, children: [
1089
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex shrink-0 items-center", children: left }),
1090
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "ml-auto flex min-w-0 items-center justify-end gap-2", children: right })
1091
+ ] });
1092
+ }
1093
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("header", { className: `sticky top-0 z-20 flex items-center border-b bg-background-dark/95 px-4 py-3.5 backdrop-blur ${borderClassName}`, children: [
1094
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex min-w-0 flex-1 items-center", children: left }),
1095
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "font-bold text-body text-white shrink-0", children: title }),
1096
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex min-w-0 flex-1 items-center justify-end gap-2", children: right })
1097
+ ] });
1098
+ }
1099
+
1100
+ // src/web/components/setting-item.tsx
1101
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1102
+ function SettingItem({
1103
+ icon,
1104
+ iconSrc,
1105
+ iconAlt,
1106
+ title,
1107
+ description,
1108
+ value,
1109
+ onClick,
1110
+ showChevron = true,
1111
+ className,
1112
+ iconColor = "text-primary"
1113
+ }) {
1114
+ const isClickable = !!onClick;
1115
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1116
+ "div",
1117
+ {
1118
+ className: cn(
1119
+ "p-5 rounded-2xl glass-panel border border-white/10 shadow-inner transition-all duration-200",
1120
+ isClickable && "cursor-pointer hover:bg-white/5 active:scale-[0.98]",
1121
+ className
1122
+ ),
1123
+ onClick,
1124
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
1125
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [
1126
+ (icon || iconSrc) && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1127
+ "div",
1128
+ {
1129
+ className: cn(
1130
+ "flex-shrink-0 size-10 rounded-xl flex items-center justify-center bg-black/20 shadow-inner border border-white/5",
1131
+ iconColor
1132
+ ),
1133
+ children: iconSrc ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("img", { src: iconSrc, alt: iconAlt ?? title, className: "size-5 object-contain" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: icon })
1134
+ }
1135
+ ),
1136
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col flex-1 min-w-0", children: [
1137
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-bold text-body text-white tracking-wide", children: title }),
1138
+ description && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-sm text-slate-400 mt-0.5 font-medium", children: description })
1139
+ ] })
1140
+ ] }),
1141
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2 flex-shrink-0", children: [
1142
+ value && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-xs text-slate-400 font-mono", children: value }),
1143
+ showChevron && isClickable && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "material-symbols-outlined text-[16px] text-slate-500", children: "chevron_right" })
1144
+ ] })
1145
+ ] })
1146
+ }
1147
+ );
1148
+ }
1149
+
1150
+ // src/web/components/section-label.tsx
1151
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1152
+ function SectionLabel({ children, className }) {
1153
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: cn("text-xxs font-black uppercase tracking-[0.22em] text-white/30", className), children });
1154
+ }
1155
+
1156
+ // src/web/components/alert-banner.tsx
1157
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1158
+ var variantStyles = {
1159
+ error: {
1160
+ container: "bg-red-500/10 border-red-500/20",
1161
+ icon: "text-red-400",
1162
+ iconName: "error"
1163
+ },
1164
+ warning: {
1165
+ container: "bg-amber-500/10 border-amber-500/20",
1166
+ icon: "text-amber-400",
1167
+ iconName: "warning"
1168
+ },
1169
+ info: {
1170
+ container: "bg-blue-500/10 border-blue-500/20",
1171
+ icon: "text-blue-400",
1172
+ iconName: "info"
1173
+ },
1174
+ success: {
1175
+ container: "bg-primary/10 border-primary/20",
1176
+ icon: "text-primary",
1177
+ iconName: "check_circle"
1178
+ }
1179
+ };
1180
+ function AlertBanner({ variant = "info", icon, children, className }) {
1181
+ const styles = variantStyles[variant];
1182
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cn("rounded-xl border p-3 flex items-start gap-2", styles.container, className), children: [
1183
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: icon ?? styles.iconName, size: "md", className: cn("shrink-0 mt-0.5", styles.icon) }),
1184
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "text-sm", children })
1185
+ ] });
1186
+ }
1187
+
1188
+ // src/web/components/error-boundary.tsx
1189
+ var import_react4 = require("react");
1190
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1191
+ var ErrorBoundary = class extends import_react4.Component {
1192
+ constructor(props) {
1193
+ super(props);
1194
+ this.state = { hasError: false, error: null };
1195
+ }
1196
+ static getDerivedStateFromError(error) {
1197
+ return { hasError: true, error };
1198
+ }
1199
+ componentDidCatch(error, info) {
1200
+ console.error("[ErrorBoundary] Render crash:", error, info);
1201
+ }
1202
+ render() {
1203
+ if (this.state.hasError) {
1204
+ return this.props.fallback ?? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "min-h-screen bg-background-dark text-white font-display flex flex-col items-center justify-center p-6 gap-4", children: [
1205
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "material-symbols-outlined text-red-400 text-[48px]", children: "error" }),
1206
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h2", { className: "text-lg font-bold", children: "Something went wrong" }),
1207
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm text-white/50 text-center", children: this.state.error?.message ?? "An unexpected error occurred." }),
1208
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1209
+ "button",
1210
+ {
1211
+ onClick: () => {
1212
+ this.setState({ hasError: false, error: null });
1213
+ this.props.onReset?.();
1214
+ },
1215
+ className: "px-6 py-3 rounded-xl bg-primary text-black font-bold hover:bg-primary/90 transition-all",
1216
+ children: "Try Again"
1217
+ }
1218
+ )
1219
+ ] });
1220
+ }
1221
+ return this.props.children;
1222
+ }
1223
+ };
1224
+ // Annotate the CommonJS export names for ESM import in node:
1225
+ 0 && (module.exports = {
1226
+ AlertBanner,
1227
+ AssetCard,
1228
+ AssetIcon,
1229
+ Button,
1230
+ Card,
1231
+ CardContent,
1232
+ CardDescription,
1233
+ CardFooter,
1234
+ CardHeader,
1235
+ CardTitle,
1236
+ Dialog,
1237
+ DialogClose,
1238
+ DialogContent,
1239
+ DialogDescription,
1240
+ DialogFooter,
1241
+ DialogHeader,
1242
+ DialogOverlay,
1243
+ DialogPortal,
1244
+ DialogTitle,
1245
+ DialogTrigger,
1246
+ ErrorBoundary,
1247
+ Icon,
1248
+ Icons,
1249
+ Input,
1250
+ Label,
1251
+ NetworkBadge,
1252
+ PageHeader,
1253
+ SectionLabel,
1254
+ SettingItem,
1255
+ StatusBadge,
1256
+ Tabs,
1257
+ TabsContent,
1258
+ TabsList,
1259
+ TabsTrigger,
1260
+ Toast,
1261
+ ToastAction,
1262
+ ToastClose,
1263
+ ToastDescription,
1264
+ ToastProvider,
1265
+ ToastTitle,
1266
+ ToastViewport,
1267
+ Toaster,
1268
+ TransactionCard,
1269
+ buttonVariants,
1270
+ cn,
1271
+ getAssetIconUrl,
1272
+ getFallbackAssetIconUrl,
1273
+ toast,
1274
+ useAssetIcon,
1275
+ useToast
1276
+ });