@stackvibe-studio/ui 0.3.0 → 0.3.1

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.cjs CHANGED
@@ -55,11 +55,20 @@ module.exports = __toCommonJS(index_exports);
55
55
  // src/components/accordion.tsx
56
56
  var import_react = require("react");
57
57
  var import_jsx_runtime = require("react/jsx-runtime");
58
+ var radiusClasses = {
59
+ sm: "rounded-lg",
60
+ md: "rounded-xl",
61
+ lg: "rounded-2xl",
62
+ xl: "rounded-3xl"
63
+ };
58
64
  function Accordion({
59
65
  items,
60
66
  type = "single",
67
+ variant = "bordered",
68
+ radius = "lg",
61
69
  defaultOpen = [],
62
- className = ""
70
+ className = "",
71
+ customIcon
63
72
  }) {
64
73
  const [openIds, setOpenIds] = (0, import_react.useState)(defaultOpen);
65
74
  const toggle = (id) => {
@@ -71,54 +80,128 @@ function Accordion({
71
80
  );
72
81
  }
73
82
  };
74
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: ["divide-y divide-white/10 rounded-2xl border border-white/10 bg-slate-900/60 overflow-hidden", className].join(" "), children: items.map((item) => {
75
- const isOpen = openIds.includes(item.id);
76
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "transition duration-150", children: [
77
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
78
- "button",
79
- {
80
- type: "button",
81
- onClick: () => toggle(item.id),
82
- className: "flex w-full items-center justify-between px-5 py-4 text-left font-medium text-white hover:bg-white/5 transition cursor-pointer",
83
- "aria-expanded": isOpen,
84
- children: [
85
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: item.title }),
86
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
87
- "svg",
88
- {
89
- className: `h-4 w-4 transform text-slate-400 transition-transform duration-200 ${isOpen ? "rotate-180 text-violet-400" : ""}`,
90
- fill: "none",
91
- viewBox: "0 0 24 24",
92
- stroke: "currentColor",
93
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
94
- }
95
- )
96
- ]
97
- }
98
- ),
99
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-5 pb-4 pt-1 text-sm text-slate-300 leading-relaxed border-t border-white/5 animate-in fade-in duration-200", children: item.content })
100
- ] }, item.id);
101
- }) });
83
+ const isSeparated = variant === "separated";
84
+ const isGhost = variant === "ghost";
85
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
86
+ "div",
87
+ {
88
+ className: [
89
+ isSeparated ? "space-y-3" : isGhost ? "divide-y divide-white/10" : "divide-y divide-white/10 border border-white/10 bg-slate-900/60 overflow-hidden shadow-lg backdrop-blur-md",
90
+ !isSeparated && !isGhost ? radiusClasses[radius] : "",
91
+ className
92
+ ].filter(Boolean).join(" "),
93
+ children: items.map((item) => {
94
+ const isOpen = openIds.includes(item.id);
95
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
96
+ "div",
97
+ {
98
+ className: [
99
+ "transition duration-200",
100
+ isSeparated ? ["border border-white/10 bg-slate-900/60 overflow-hidden shadow-md backdrop-blur-sm", radiusClasses[radius]].join(" ") : ""
101
+ ].filter(Boolean).join(" "),
102
+ children: [
103
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
104
+ "button",
105
+ {
106
+ type: "button",
107
+ onClick: () => toggle(item.id),
108
+ className: "flex w-full items-center justify-between px-5 py-4 text-left font-medium text-white hover:bg-white/5 transition cursor-pointer select-none",
109
+ "aria-expanded": isOpen,
110
+ children: [
111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-3", children: [
112
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[var(--primary,#8b5cf6)] shrink-0", children: item.icon }),
113
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm font-semibold", children: item.title })
114
+ ] }),
115
+ customIcon ? customIcon(isOpen) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
116
+ "svg",
117
+ {
118
+ className: `h-4 w-4 transform text-slate-400 transition-transform duration-200 ${isOpen ? "rotate-180 text-[var(--primary,#8b5cf6)]" : ""}`,
119
+ fill: "none",
120
+ viewBox: "0 0 24 24",
121
+ stroke: "currentColor",
122
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
123
+ }
124
+ )
125
+ ]
126
+ }
127
+ ),
128
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "border-t border-white/5 px-5 pb-5 pt-3 text-xs leading-relaxed text-slate-300", children: item.content })
129
+ ]
130
+ },
131
+ item.id
132
+ );
133
+ })
134
+ }
135
+ );
102
136
  }
103
137
 
104
138
  // src/components/alert.tsx
139
+ var import_react2 = require("react");
105
140
  var import_jsx_runtime2 = require("react/jsx-runtime");
106
141
  var variantClasses = {
107
- info: "border-cyan-500/40 bg-cyan-500/10 text-cyan-50",
108
- success: "border-emerald-500/40 bg-emerald-500/10 text-emerald-50",
109
- warning: "border-amber-500/40 bg-amber-500/10 text-amber-50",
110
- danger: "border-rose-500/40 bg-rose-500/10 text-rose-50"
142
+ info: "border-cyan-500/30 bg-cyan-500/10 text-cyan-100",
143
+ success: "border-emerald-500/30 bg-emerald-500/10 text-emerald-100",
144
+ warning: "border-amber-500/30 bg-amber-500/10 text-amber-100",
145
+ destructive: "border-rose-500/30 bg-rose-500/10 text-rose-100",
146
+ primary: "border-[var(--primary,#8b5cf6)]/30 bg-[var(--primary,#8b5cf6)]/10 text-slate-100"
111
147
  };
112
- function Alert({ title, variant = "info", className = "", children, ...props }) {
148
+ var defaultIcons = {
149
+ info: "\u2139",
150
+ success: "\u2713",
151
+ warning: "\u26A0",
152
+ destructive: "\u2715",
153
+ primary: "\u26A1"
154
+ };
155
+ var radiusClasses2 = {
156
+ sm: "rounded-lg",
157
+ md: "rounded-xl",
158
+ lg: "rounded-2xl",
159
+ xl: "rounded-3xl"
160
+ };
161
+ function Alert({
162
+ title,
163
+ variant = "info",
164
+ radius = "lg",
165
+ icon,
166
+ dismissible = false,
167
+ onDismiss,
168
+ className = "",
169
+ children,
170
+ ...props
171
+ }) {
172
+ const [visible, setVisible] = (0, import_react2.useState)(true);
173
+ if (!visible) return null;
174
+ const handleDismiss = () => {
175
+ setVisible(false);
176
+ onDismiss?.();
177
+ };
113
178
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
114
179
  "div",
115
180
  {
116
181
  ...props,
117
- className: ["rounded-2xl border p-4 text-sm", variantClasses[variant], className].join(" "),
118
182
  role: "alert",
183
+ className: [
184
+ "relative flex items-start gap-3 border p-4 text-sm shadow-md backdrop-blur-sm transition-all duration-200",
185
+ variantClasses[variant],
186
+ radiusClasses2[radius],
187
+ className
188
+ ].filter(Boolean).join(" "),
119
189
  children: [
120
- title ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mb-1 font-medium", children: title }) : null,
121
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children })
190
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex h-5 w-5 shrink-0 items-center justify-center font-bold", children: icon || defaultIcons[variant] }),
191
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex-1", children: [
192
+ title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mb-1 font-bold tracking-tight", children: title }),
193
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "leading-relaxed opacity-90", children })
194
+ ] }),
195
+ dismissible && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
196
+ "button",
197
+ {
198
+ type: "button",
199
+ onClick: handleDismiss,
200
+ "aria-label": "Dismiss alert",
201
+ className: "shrink-0 rounded-lg p-1 text-current opacity-60 hover:opacity-100 hover:bg-white/10 transition cursor-pointer",
202
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
203
+ }
204
+ )
122
205
  ]
123
206
  }
124
207
  );
@@ -127,41 +210,134 @@ function Alert({ title, variant = "info", className = "", children, ...props })
127
210
  // src/components/avatar.tsx
128
211
  var import_jsx_runtime3 = require("react/jsx-runtime");
129
212
  var sizeClasses = {
130
- sm: "h-9 w-9 text-xs",
131
- md: "h-12 w-12 text-sm",
132
- lg: "h-16 w-16 text-base"
213
+ xs: "h-6 w-6 text-[10px]",
214
+ sm: "h-8 w-8 text-xs",
215
+ md: "h-11 w-11 text-sm",
216
+ lg: "h-14 w-14 text-base",
217
+ xl: "h-18 w-18 text-lg",
218
+ "2xl": "h-24 w-24 text-xl"
219
+ };
220
+ var shapeClasses = {
221
+ circle: "rounded-full",
222
+ rounded: "rounded-2xl",
223
+ square: "rounded-lg"
224
+ };
225
+ var statusColors = {
226
+ online: "bg-emerald-500",
227
+ offline: "bg-slate-500",
228
+ busy: "bg-rose-500",
229
+ away: "bg-amber-500"
133
230
  };
134
- function Avatar({ src, alt = "avatar", fallback = "SV", size = "md", className = "", ...props }) {
135
- return src ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
231
+ function Avatar({
232
+ src,
233
+ alt = "avatar",
234
+ fallback = "SV",
235
+ size = "md",
236
+ shape = "circle",
237
+ status,
238
+ className = "",
239
+ ...props
240
+ }) {
241
+ const commonShape = shapeClasses[shape];
242
+ const content = src ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
136
243
  "img",
137
244
  {
138
245
  ...props,
139
246
  src,
140
247
  alt,
141
- className: ["rounded-full object-cover ring-1 ring-white/10", sizeClasses[size], className].join(" ")
248
+ className: ["object-cover ring-1 ring-white/10 shadow-md", sizeClasses[size], commonShape, className].join(" ")
142
249
  }
143
250
  ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
144
251
  "div",
145
252
  {
146
- className: ["flex items-center justify-center rounded-full bg-violet-500/20 font-semibold text-violet-100 ring-1 ring-violet-400/20", sizeClasses[size], className].join(" "),
253
+ className: [
254
+ "flex items-center justify-center bg-[var(--primary,#8b5cf6)]/20 font-bold text-[var(--primary,#c084fc)] ring-1 ring-[var(--primary,#8b5cf6)]/30 shadow-md",
255
+ sizeClasses[size],
256
+ commonShape,
257
+ className
258
+ ].join(" "),
147
259
  children: fallback
148
260
  }
149
261
  );
262
+ if (!status) return content;
263
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative inline-block", children: [
264
+ content,
265
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
266
+ "span",
267
+ {
268
+ className: [
269
+ "absolute bottom-0 right-0 h-3 w-3 rounded-full ring-2 ring-slate-950",
270
+ statusColors[status]
271
+ ].join(" ")
272
+ }
273
+ )
274
+ ] });
150
275
  }
151
276
 
152
277
  // src/components/badge.tsx
153
278
  var import_jsx_runtime4 = require("react/jsx-runtime");
154
279
  var variants = {
155
- primary: "bg-violet-500/20 text-violet-200 ring-1 ring-violet-400/20",
156
- secondary: "bg-cyan-500/15 text-cyan-200 ring-1 ring-cyan-400/20",
157
- outline: "bg-transparent text-slate-200 ring-1 ring-white/10"
280
+ primary: "bg-[var(--primary,#8b5cf6)]/20 text-[var(--primary,#c084fc)] ring-1 ring-[var(--primary,#8b5cf6)]/30",
281
+ secondary: "bg-[var(--secondary,#22d3ee)]/20 text-[var(--secondary,#22d3ee)] ring-1 ring-[var(--secondary,#22d3ee)]/30",
282
+ outline: "bg-transparent text-slate-200 ring-1 ring-white/15",
283
+ destructive: "bg-rose-500/15 text-rose-300 ring-1 ring-rose-500/30",
284
+ success: "bg-emerald-500/15 text-emerald-300 ring-1 ring-emerald-500/30",
285
+ warning: "bg-amber-500/15 text-amber-300 ring-1 ring-amber-500/30",
286
+ glass: "bg-white/10 text-white backdrop-blur-md ring-1 ring-white/20"
287
+ };
288
+ var dotColors = {
289
+ primary: "bg-[var(--primary,#8b5cf6)]",
290
+ secondary: "bg-[var(--secondary,#22d3ee)]",
291
+ outline: "bg-slate-400",
292
+ destructive: "bg-rose-400",
293
+ success: "bg-emerald-400",
294
+ warning: "bg-amber-400",
295
+ glass: "bg-white"
296
+ };
297
+ var sizes = {
298
+ sm: "px-2 py-0.5 text-[10px] gap-1",
299
+ md: "px-2.5 py-1 text-xs gap-1.5",
300
+ lg: "px-3 py-1.5 text-sm gap-2"
158
301
  };
159
- function Badge({ variant = "primary", className = "", ...props }) {
160
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
302
+ var radiuses = {
303
+ sm: "rounded-md",
304
+ md: "rounded-lg",
305
+ lg: "rounded-xl",
306
+ full: "rounded-full"
307
+ };
308
+ function Badge({
309
+ variant = "primary",
310
+ size = "md",
311
+ radius = "full",
312
+ dot = false,
313
+ leftIcon,
314
+ rightIcon,
315
+ children,
316
+ className = "",
317
+ ...props
318
+ }) {
319
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
161
320
  "span",
162
321
  {
163
322
  ...props,
164
- className: ["inline-flex items-center rounded-full px-2.5 py-1 text-xs font-medium", variants[variant], className].join(" ")
323
+ className: [
324
+ "inline-flex items-center font-medium select-none",
325
+ variants[variant],
326
+ sizes[size],
327
+ radiuses[radius],
328
+ className
329
+ ].filter(Boolean).join(" "),
330
+ children: [
331
+ dot && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
332
+ "span",
333
+ {
334
+ className: ["h-1.5 w-1.5 rounded-full shrink-0 animate-pulse", dotColors[variant]].join(" ")
335
+ }
336
+ ),
337
+ leftIcon && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "shrink-0", children: leftIcon }),
338
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children }),
339
+ rightIcon && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "shrink-0", children: rightIcon })
340
+ ]
165
341
  }
166
342
  );
167
343
  }
@@ -169,43 +345,137 @@ function Badge({ variant = "primary", className = "", ...props }) {
169
345
  // src/components/button.tsx
170
346
  var import_jsx_runtime5 = require("react/jsx-runtime");
171
347
  var variantClasses2 = {
172
- primary: "bg-violet-500 text-white hover:bg-violet-400",
173
- secondary: "bg-cyan-500 text-slate-950 hover:bg-cyan-400",
174
- ghost: "bg-white/5 text-white hover:bg-white/10",
175
- outline: "border border-white/15 bg-transparent text-white hover:bg-white/5"
348
+ primary: "bg-[var(--primary,#8b5cf6)] text-white hover:brightness-110 shadow-lg shadow-[var(--glow,rgba(139,92,246,0.3))]",
349
+ secondary: "bg-[var(--secondary,#22d3ee)] text-slate-950 hover:brightness-110 shadow-md shadow-[var(--secondary,#22d3ee)]/20",
350
+ ghost: "bg-white/5 text-white hover:bg-white/10 hover:text-white",
351
+ outline: "border border-[var(--primary,#8b5cf6)]/40 bg-transparent text-white hover:bg-[var(--primary,#8b5cf6)]/10",
352
+ destructive: "bg-rose-600 text-white hover:bg-rose-500 shadow-md shadow-rose-600/30",
353
+ glass: "border border-white/15 bg-white/10 text-white backdrop-blur-md hover:bg-white/20 shadow-lg",
354
+ gradient: "bg-gradient-to-r from-[var(--primary,#8b5cf6)] via-[var(--accent,#c084fc)] to-[var(--secondary,#22d3ee)] text-white shadow-xl hover:brightness-110"
176
355
  };
177
356
  var sizeClasses2 = {
178
- sm: "px-3 py-1.5 text-sm",
179
- md: "px-4 py-2 text-sm",
180
- lg: "px-5 py-3 text-base"
357
+ xs: "px-2.5 py-1 text-xs gap-1",
358
+ sm: "px-3 py-1.5 text-xs font-medium gap-1.5",
359
+ md: "px-4 py-2 text-sm font-medium gap-2",
360
+ lg: "px-5 py-2.5 text-base font-semibold gap-2.5",
361
+ xl: "px-6 py-3.5 text-lg font-bold gap-3"
362
+ };
363
+ var radiusClasses3 = {
364
+ none: "rounded-none",
365
+ sm: "rounded-md",
366
+ md: "rounded-xl",
367
+ lg: "rounded-2xl",
368
+ xl: "rounded-3xl",
369
+ full: "rounded-full"
181
370
  };
182
371
  function Button(props) {
183
- const { as = "button", variant = "primary", size = "md", className = "", ...rest } = props;
372
+ const {
373
+ as = "button",
374
+ variant = "primary",
375
+ size = "md",
376
+ radius = "md",
377
+ fullWidth = false,
378
+ loading = false,
379
+ loadingText,
380
+ leftIcon,
381
+ rightIcon,
382
+ children,
383
+ className = "",
384
+ disabled,
385
+ ...rest
386
+ } = props;
387
+ const isDisabled = disabled || loading;
184
388
  const commonClassName = [
185
- "inline-flex items-center justify-center rounded-xl font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-400",
389
+ "inline-flex items-center justify-center font-medium transition-all duration-200 cursor-pointer select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--primary,#8b5cf6)] disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none",
186
390
  variantClasses2[variant],
187
391
  sizeClasses2[size],
392
+ radiusClasses3[radius],
393
+ fullWidth ? "w-full" : "",
188
394
  className
189
- ].join(" ");
395
+ ].filter(Boolean).join(" ");
396
+ const content = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
397
+ loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
398
+ "svg",
399
+ {
400
+ className: "animate-spin h-4 w-4 shrink-0 text-current",
401
+ xmlns: "http://www.w3.org/2000/svg",
402
+ fill: "none",
403
+ viewBox: "0 0 24 24",
404
+ children: [
405
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
406
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
407
+ "path",
408
+ {
409
+ className: "opacity-75",
410
+ fill: "currentColor",
411
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
412
+ }
413
+ )
414
+ ]
415
+ }
416
+ ),
417
+ !loading && leftIcon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "shrink-0", children: leftIcon }),
418
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: loading && loadingText ? loadingText : children }),
419
+ !loading && rightIcon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "shrink-0", children: rightIcon })
420
+ ] });
190
421
  if (as === "a") {
191
422
  const { href, ...anchorProps } = rest;
192
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { ...anchorProps, href, className: commonClassName });
423
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { ...anchorProps, href, className: commonClassName, children: content });
193
424
  }
194
- const { type = "button", ...buttonProps } = rest;
195
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { ...buttonProps, type, className: commonClassName });
425
+ const buttonProps = rest;
426
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { ...buttonProps, disabled: isDisabled, className: commonClassName, children: content });
196
427
  }
197
428
 
198
429
  // src/components/card.tsx
199
430
  var import_jsx_runtime6 = require("react/jsx-runtime");
200
- function Card({ as: Component = "div", className = "", ...props }) {
431
+ var variantStyles = {
432
+ default: "border border-white/10 bg-[var(--surface,rgba(15,23,42,0.6))] backdrop-blur-md shadow-lg shadow-black/20",
433
+ glass: "border border-white/15 bg-white/5 backdrop-blur-xl shadow-2xl",
434
+ gradient: "border border-white/10 bg-gradient-to-br from-[var(--surface,rgba(15,23,42,0.8))] to-[var(--background,rgba(2,6,23,0.9))] shadow-xl",
435
+ bordered: "border-2 border-[var(--primary,#8b5cf6)]/30 bg-[var(--surface,rgba(15,23,42,0.5))] shadow-md",
436
+ interactive: "border border-white/10 bg-[var(--surface,rgba(15,23,42,0.6))] backdrop-blur-md shadow-lg transition-all duration-300 hover:-translate-y-1 hover:border-white/20 hover:shadow-2xl cursor-pointer",
437
+ elevated: "border border-white/10 bg-slate-900/90 shadow-2xl shadow-black/40"
438
+ };
439
+ var radiusStyles = {
440
+ none: "rounded-none",
441
+ sm: "rounded-lg",
442
+ md: "rounded-xl",
443
+ lg: "rounded-2xl",
444
+ xl: "rounded-3xl",
445
+ "2xl": "rounded-[2rem]",
446
+ "3xl": "rounded-[2.5rem]"
447
+ };
448
+ var paddingStyles = {
449
+ none: "p-0",
450
+ sm: "p-3",
451
+ md: "p-5",
452
+ lg: "p-7",
453
+ xl: "p-10"
454
+ };
455
+ function Card({
456
+ as: Component = "div",
457
+ variant = "default",
458
+ radius = "lg",
459
+ padding = "md",
460
+ glow = false,
461
+ className = "",
462
+ style,
463
+ ...props
464
+ }) {
201
465
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
202
466
  Component,
203
467
  {
204
468
  ...props,
469
+ style: {
470
+ ...glow ? { boxShadow: "0 0 30px var(--glow, rgba(139, 92, 246, 0.25))" } : {},
471
+ ...style
472
+ },
205
473
  className: [
206
- "rounded-2xl border border-white/10 bg-slate-950/50 p-4 shadow-lg shadow-slate-950/20 backdrop-blur-sm",
474
+ variantStyles[variant],
475
+ radiusStyles[radius],
476
+ paddingStyles[padding],
207
477
  className
208
- ].join(" ")
478
+ ].filter(Boolean).join(" ")
209
479
  }
210
480
  );
211
481
  }
@@ -224,11 +494,16 @@ function Checkbox({ className = "", ...props }) {
224
494
  }
225
495
 
226
496
  // src/components/dialog.tsx
227
- var import_react2 = require("react");
497
+ var import_react3 = require("react");
498
+ var import_react_dom = require("react-dom");
228
499
  var import_jsx_runtime8 = require("react/jsx-runtime");
229
500
  function Dialog({ open, onOpenChange, children, className = "" }) {
230
- const dialogRef = (0, import_react2.useRef)(null);
231
- (0, import_react2.useEffect)(() => {
501
+ const dialogRef = (0, import_react3.useRef)(null);
502
+ const [mounted, setMounted] = (0, import_react3.useState)(false);
503
+ (0, import_react3.useEffect)(() => {
504
+ setMounted(true);
505
+ }, []);
506
+ (0, import_react3.useEffect)(() => {
232
507
  const handleKeyDown = (e) => {
233
508
  if (e.key === "Escape" && open) {
234
509
  onOpenChange(false);
@@ -245,13 +520,13 @@ function Dialog({ open, onOpenChange, children, className = "" }) {
245
520
  window.removeEventListener("keydown", handleKeyDown);
246
521
  };
247
522
  }, [open, onOpenChange]);
248
- if (!open) return null;
249
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
523
+ if (!open || !mounted) return null;
524
+ const content = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
250
525
  "div",
251
526
  {
252
527
  role: "dialog",
253
528
  "aria-modal": "true",
254
- className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-950/80 backdrop-blur-md animate-in fade-in duration-200",
529
+ className: "fixed inset-0 z-[9999] flex items-center justify-center p-4 bg-black/80 backdrop-blur-md transition-opacity duration-200",
255
530
  onClick: (e) => {
256
531
  if (e.target === e.currentTarget) onOpenChange(false);
257
532
  },
@@ -260,7 +535,7 @@ function Dialog({ open, onOpenChange, children, className = "" }) {
260
535
  {
261
536
  ref: dialogRef,
262
537
  className: [
263
- "relative w-full max-w-lg rounded-3xl border border-white/10 bg-slate-900/95 p-6 shadow-2xl shadow-violet-500/10 text-white animate-in zoom-in-95 duration-200",
538
+ "relative w-full max-w-lg rounded-3xl border border-white/10 bg-slate-900/95 p-6 shadow-2xl text-white backdrop-blur-xl transition-transform duration-200",
264
539
  className
265
540
  ].join(" "),
266
541
  children: [
@@ -280,6 +555,7 @@ function Dialog({ open, onOpenChange, children, className = "" }) {
280
555
  )
281
556
  }
282
557
  );
558
+ return typeof document !== "undefined" ? (0, import_react_dom.createPortal)(content, document.body) : null;
283
559
  }
284
560
  function DialogHeader({ children, className = "" }) {
285
561
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: ["mb-4 space-y-1.5", className].join(" "), children });
@@ -295,7 +571,8 @@ function DialogFooter({ children, className = "" }) {
295
571
  }
296
572
 
297
573
  // src/components/drawer.tsx
298
- var import_react3 = require("react");
574
+ var import_react4 = require("react");
575
+ var import_react_dom2 = require("react-dom");
299
576
  var import_jsx_runtime9 = require("react/jsx-runtime");
300
577
  function Drawer({
301
578
  open,
@@ -304,7 +581,11 @@ function Drawer({
304
581
  children,
305
582
  className = ""
306
583
  }) {
307
- (0, import_react3.useEffect)(() => {
584
+ const [mounted, setMounted] = (0, import_react4.useState)(false);
585
+ (0, import_react4.useEffect)(() => {
586
+ setMounted(true);
587
+ }, []);
588
+ (0, import_react4.useEffect)(() => {
308
589
  const handleKeyDown = (e) => {
309
590
  if (e.key === "Escape" && open) onOpenChange(false);
310
591
  };
@@ -319,18 +600,18 @@ function Drawer({
319
600
  window.removeEventListener("keydown", handleKeyDown);
320
601
  };
321
602
  }, [open, onOpenChange]);
322
- if (!open) return null;
603
+ if (!open || !mounted) return null;
323
604
  const positionClasses = {
324
- right: "inset-y-0 right-0 w-full max-w-md border-l border-white/10 animate-in slide-in-from-right duration-300",
325
- left: "inset-y-0 left-0 w-full max-w-md border-r border-white/10 animate-in slide-in-from-left duration-300",
326
- bottom: "inset-x-0 bottom-0 max-h-[85vh] w-full border-t border-white/10 rounded-t-3xl animate-in slide-in-from-bottom duration-300"
605
+ right: "inset-y-0 right-0 w-full max-w-md border-l border-white/10 shadow-2xl",
606
+ left: "inset-y-0 left-0 w-full max-w-md border-r border-white/10 shadow-2xl",
607
+ bottom: "inset-x-0 bottom-0 max-h-[85vh] w-full border-t border-white/10 rounded-t-3xl shadow-2xl"
327
608
  };
328
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
609
+ const content = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
329
610
  "div",
330
611
  {
331
612
  role: "dialog",
332
613
  "aria-modal": "true",
333
- className: "fixed inset-0 z-50 bg-slate-950/80 backdrop-blur-sm animate-in fade-in duration-200",
614
+ className: "fixed inset-0 z-[9999] bg-black/80 backdrop-blur-sm transition-opacity duration-200",
334
615
  onClick: (e) => {
335
616
  if (e.target === e.currentTarget) onOpenChange(false);
336
617
  },
@@ -338,7 +619,7 @@ function Drawer({
338
619
  "div",
339
620
  {
340
621
  className: [
341
- "fixed bg-slate-900/95 p-6 shadow-2xl text-white overflow-y-auto",
622
+ "fixed z-[10000] bg-slate-900/95 p-6 text-white backdrop-blur-xl overflow-y-auto transition-transform duration-300",
342
623
  positionClasses[position],
343
624
  className
344
625
  ].join(" "),
@@ -359,16 +640,17 @@ function Drawer({
359
640
  )
360
641
  }
361
642
  );
643
+ return typeof document !== "undefined" ? (0, import_react_dom2.createPortal)(content, document.body) : null;
362
644
  }
363
645
  function DrawerHeader({ children, className = "" }) {
364
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: ["mb-6 space-y-1.5", className].join(" "), children });
646
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: ["mb-4 space-y-1.5", className].join(" "), children });
365
647
  }
366
648
  function DrawerTitle({ children, className = "" }) {
367
649
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", { className: ["text-xl font-bold tracking-tight text-white", className].join(" "), children });
368
650
  }
369
651
 
370
652
  // src/components/dropdown-menu.tsx
371
- var import_react4 = require("react");
653
+ var import_react5 = require("react");
372
654
  var import_jsx_runtime10 = require("react/jsx-runtime");
373
655
  function DropdownMenu({
374
656
  trigger,
@@ -376,9 +658,9 @@ function DropdownMenu({
376
658
  align = "right",
377
659
  className = ""
378
660
  }) {
379
- const [open, setOpen] = (0, import_react4.useState)(false);
380
- const menuRef = (0, import_react4.useRef)(null);
381
- (0, import_react4.useEffect)(() => {
661
+ const [open, setOpen] = (0, import_react5.useState)(false);
662
+ const menuRef = (0, import_react5.useRef)(null);
663
+ (0, import_react5.useEffect)(() => {
382
664
  const handleClickOutside = (e) => {
383
665
  if (menuRef.current && !menuRef.current.contains(e.target)) {
384
666
  setOpen(false);
@@ -398,7 +680,7 @@ function DropdownMenu({
398
680
  {
399
681
  role: "menu",
400
682
  className: [
401
- "absolute z-50 mt-2 min-w-[12rem] rounded-2xl border border-white/10 bg-slate-900/95 p-1.5 shadow-2xl backdrop-blur-xl animate-in fade-in zoom-in-95 duration-150",
683
+ "absolute z-50 mt-2 min-w-[12rem] rounded-2xl border border-white/10 bg-slate-900/95 p-1.5 shadow-2xl backdrop-blur-xl transition-all duration-150",
402
684
  align === "right" ? "right-0" : "left-0",
403
685
  className
404
686
  ].join(" "),
@@ -432,39 +714,97 @@ function DropdownMenu({
432
714
 
433
715
  // src/components/input.tsx
434
716
  var import_jsx_runtime11 = require("react/jsx-runtime");
435
- function Input({ className = "", ...props }) {
436
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
717
+ var variantStyles2 = {
718
+ default: "border border-white/10 bg-slate-900/80 text-white placeholder:text-slate-500 focus:border-[var(--primary,#8b5cf6)] focus:ring-2 focus:ring-[var(--primary,#8b5cf6)]/25",
719
+ filled: "border border-transparent bg-white/5 text-white placeholder:text-slate-500 hover:bg-white/10 focus:bg-slate-900 focus:border-[var(--primary,#8b5cf6)] focus:ring-2 focus:ring-[var(--primary,#8b5cf6)]/25",
720
+ flushed: "border-0 border-b-2 border-white/15 bg-transparent rounded-none px-0 text-white placeholder:text-slate-500 focus:border-[var(--primary,#8b5cf6)] focus:ring-0"
721
+ };
722
+ var sizeStyles = {
723
+ sm: "px-3 py-1.5 text-xs",
724
+ md: "px-3.5 py-2 text-sm",
725
+ lg: "px-4 py-3 text-base"
726
+ };
727
+ var radiusStyles2 = {
728
+ none: "rounded-none",
729
+ sm: "rounded-lg",
730
+ md: "rounded-xl",
731
+ lg: "rounded-2xl",
732
+ full: "rounded-full"
733
+ };
734
+ function Input({
735
+ variant = "default",
736
+ size = "md",
737
+ radius = "md",
738
+ leftElement,
739
+ rightElement,
740
+ error,
741
+ fullWidth = true,
742
+ className = "",
743
+ disabled,
744
+ ...props
745
+ }) {
746
+ const isFlushed = variant === "flushed";
747
+ const inputElement = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
437
748
  "input",
438
749
  {
439
750
  ...props,
751
+ disabled,
440
752
  className: [
441
- "w-full rounded-xl border border-white/10 bg-slate-900 px-3 py-2 text-sm text-white placeholder:text-slate-400 focus:border-violet-400 focus:outline-none focus:ring-2 focus:ring-violet-400/30",
753
+ "w-full transition-all duration-200 outline-none disabled:opacity-50 disabled:cursor-not-allowed",
754
+ variantStyles2[variant],
755
+ sizeStyles[size],
756
+ !isFlushed ? radiusStyles2[radius] : "",
757
+ leftElement ? "pl-9" : "",
758
+ rightElement ? "pr-9" : "",
759
+ error ? "!border-rose-500 !ring-rose-500/30" : "",
442
760
  className
443
- ].join(" ")
761
+ ].filter(Boolean).join(" ")
444
762
  }
445
763
  );
764
+ if (!leftElement && !rightElement && !error) {
765
+ return inputElement;
766
+ }
767
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: ["relative", fullWidth ? "w-full" : "inline-block"].join(" "), children: [
768
+ leftElement && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none flex items-center justify-center", children: leftElement }),
769
+ inputElement,
770
+ rightElement && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 flex items-center justify-center", children: rightElement }),
771
+ typeof error === "string" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "mt-1 text-xs text-rose-400", children: error })
772
+ ] });
446
773
  }
447
774
 
448
775
  // src/components/progress.tsx
449
776
  var import_jsx_runtime12 = require("react/jsx-runtime");
450
777
  var variantGradients = {
451
- primary: "from-violet-600 to-indigo-500",
452
- secondary: "from-cyan-500 to-blue-500",
778
+ primary: "from-[var(--primary,#8b5cf6)] to-[var(--accent,#c084fc)]",
779
+ secondary: "from-[var(--secondary,#22d3ee)] to-blue-500",
453
780
  success: "from-emerald-500 to-teal-400",
454
- warning: "from-amber-500 to-orange-400"
781
+ warning: "from-amber-500 to-orange-400",
782
+ destructive: "from-rose-500 to-red-600",
783
+ gradient: "from-[var(--primary,#8b5cf6)] via-[var(--secondary,#22d3ee)] to-emerald-400"
784
+ };
785
+ var sizeStyles2 = {
786
+ xs: "h-1",
787
+ sm: "h-1.5",
788
+ md: "h-2.5",
789
+ lg: "h-4",
790
+ xl: "h-6"
455
791
  };
456
792
  function Progress({
457
793
  value = 0,
458
794
  max = 100,
459
795
  variant = "primary",
796
+ size = "md",
797
+ striped = false,
798
+ animated = false,
460
799
  showLabel = false,
800
+ label = "Progress",
461
801
  className = "",
462
802
  ...props
463
803
  }) {
464
804
  const percentage = Math.min(Math.max(value / max * 100, 0), 100);
465
805
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: ["w-full space-y-1.5", className].join(" "), ...props, children: [
466
806
  showLabel && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex justify-between text-xs font-semibold text-slate-300", children: [
467
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "Progress" }),
807
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: label }),
468
808
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "font-mono", children: [
469
809
  Math.round(percentage),
470
810
  "%"
@@ -477,14 +817,19 @@ function Progress({
477
817
  "aria-valuenow": value,
478
818
  "aria-valuemin": 0,
479
819
  "aria-valuemax": max,
480
- className: "relative h-2.5 w-full overflow-hidden rounded-full bg-slate-800 ring-1 ring-white/10",
820
+ className: [
821
+ "relative w-full overflow-hidden rounded-full bg-slate-800 ring-1 ring-white/10 shadow-inner",
822
+ sizeStyles2[size]
823
+ ].join(" "),
481
824
  children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
482
825
  "div",
483
826
  {
484
827
  className: [
485
828
  "h-full rounded-full bg-gradient-to-r transition-all duration-300 ease-out shadow-sm",
486
- variantGradients[variant]
487
- ].join(" "),
829
+ variantGradients[variant],
830
+ striped ? "bg-[length:1rem_1rem] bg-[linear-gradient(45deg,rgba(255,255,255,0.15)_25%,transparent_25%,transparent_50%,rgba(255,255,255,0.15)_50%,rgba(255,255,255,0.15)_75%,transparent_75%,transparent)]" : "",
831
+ animated ? "animate-pulse" : ""
832
+ ].filter(Boolean).join(" "),
488
833
  style: { width: `${percentage}%` }
489
834
  }
490
835
  )
@@ -495,34 +840,86 @@ function Progress({
495
840
 
496
841
  // src/components/select.tsx
497
842
  var import_jsx_runtime13 = require("react/jsx-runtime");
498
- function Select({ className = "", children, ...props }) {
499
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
500
- "select",
501
- {
502
- ...props,
503
- className: [
504
- "w-full rounded-xl border border-white/10 bg-slate-900 px-3 py-2 text-sm text-white focus:border-violet-400 focus:outline-none focus:ring-2 focus:ring-violet-400/30",
505
- className
506
- ].join(" "),
507
- children
508
- }
509
- );
843
+ var variantStyles3 = {
844
+ default: "border border-white/10 bg-slate-900/80 text-white focus:border-[var(--primary,#8b5cf6)] focus:ring-2 focus:ring-[var(--primary,#8b5cf6)]/25",
845
+ filled: "border border-transparent bg-white/5 text-white hover:bg-white/10 focus:bg-slate-900 focus:border-[var(--primary,#8b5cf6)] focus:ring-2 focus:ring-[var(--primary,#8b5cf6)]/25"
846
+ };
847
+ var sizeStyles3 = {
848
+ sm: "px-3 py-1.5 text-xs",
849
+ md: "px-3.5 py-2 text-sm",
850
+ lg: "px-4 py-3 text-base"
851
+ };
852
+ var radiusStyles3 = {
853
+ none: "rounded-none",
854
+ sm: "rounded-lg",
855
+ md: "rounded-xl",
856
+ lg: "rounded-2xl",
857
+ full: "rounded-full"
858
+ };
859
+ function Select({
860
+ variant = "default",
861
+ size = "md",
862
+ radius = "md",
863
+ error,
864
+ icon,
865
+ className = "",
866
+ children,
867
+ disabled,
868
+ ...props
869
+ }) {
870
+ const selectElement = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "relative w-full", children: [
871
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
872
+ "select",
873
+ {
874
+ ...props,
875
+ disabled,
876
+ className: [
877
+ "w-full appearance-none transition-all duration-200 outline-none pr-9 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed",
878
+ variantStyles3[variant],
879
+ sizeStyles3[size],
880
+ radiusStyles3[radius],
881
+ error ? "!border-rose-500 !ring-rose-500/30" : "",
882
+ className
883
+ ].filter(Boolean).join(" "),
884
+ children
885
+ }
886
+ ),
887
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none text-slate-400", children: icon || /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "h-4 w-4 fill-none stroke-current", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) }) })
888
+ ] });
889
+ if (!error) return selectElement;
890
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "w-full", children: [
891
+ selectElement,
892
+ typeof error === "string" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "mt-1 text-xs text-rose-400", children: error })
893
+ ] });
510
894
  }
511
895
 
512
896
  // src/components/skeleton.tsx
513
897
  var import_jsx_runtime14 = require("react/jsx-runtime");
514
898
  var roundedClasses = {
899
+ none: "rounded-none",
515
900
  sm: "rounded-md",
516
901
  md: "rounded-xl",
517
902
  lg: "rounded-2xl",
903
+ xl: "rounded-3xl",
518
904
  full: "rounded-full"
519
905
  };
520
- function Skeleton({ className = "", rounded = "md", ...props }) {
906
+ function Skeleton({
907
+ className = "",
908
+ rounded = "md",
909
+ animation = "pulse",
910
+ ...props
911
+ }) {
521
912
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
522
913
  "div",
523
914
  {
524
915
  ...props,
525
- className: ["animate-pulse bg-slate-700/70", roundedClasses[rounded], className].join(" "),
916
+ className: [
917
+ "bg-slate-800/80 ring-1 ring-white/5",
918
+ animation === "pulse" ? "animate-pulse" : "",
919
+ animation === "shimmer" ? "relative overflow-hidden before:absolute before:inset-0 before:-translate-x-full before:animate-[shimmer_2s_infinite] before:bg-gradient-to-r before:from-transparent before:via-white/10 before:to-transparent" : "",
920
+ roundedClasses[rounded],
921
+ className
922
+ ].filter(Boolean).join(" "),
526
923
  "aria-hidden": "true"
527
924
  }
528
925
  );
@@ -530,15 +927,35 @@ function Skeleton({ className = "", rounded = "md", ...props }) {
530
927
 
531
928
  // src/components/switch.tsx
532
929
  var import_jsx_runtime15 = require("react/jsx-runtime");
930
+ var sizeTrackStyles = {
931
+ sm: "h-5 w-9",
932
+ md: "h-6 w-11",
933
+ lg: "h-7 w-14"
934
+ };
935
+ var sizeThumbStyles = {
936
+ sm: "h-4 w-4",
937
+ md: "h-5 w-5",
938
+ lg: "h-6 w-6"
939
+ };
940
+ var sizeTranslateStyles = {
941
+ sm: "translate-x-4",
942
+ md: "translate-x-5",
943
+ lg: "translate-x-7"
944
+ };
533
945
  function Switch({
534
946
  checked,
535
947
  defaultChecked = false,
536
948
  onCheckedChange,
949
+ size = "md",
950
+ color,
951
+ checkedIcon,
952
+ uncheckedIcon,
537
953
  disabled = false,
538
954
  className = "",
539
955
  id,
540
956
  "aria-label": ariaLabel
541
957
  }) {
958
+ const isChecked = checked ?? defaultChecked;
542
959
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
543
960
  "button",
544
961
  {
@@ -546,21 +963,25 @@ function Switch({
546
963
  role: "switch",
547
964
  id,
548
965
  "aria-label": ariaLabel,
549
- "aria-checked": checked ?? defaultChecked,
966
+ "aria-checked": isChecked,
550
967
  disabled,
551
- onClick: () => onCheckedChange?.(!checked),
968
+ onClick: () => onCheckedChange?.(!isChecked),
969
+ style: isChecked ? { backgroundColor: color || "var(--primary, #8b5cf6)" } : void 0,
552
970
  className: [
553
- "relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-400 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-950 disabled:cursor-not-allowed disabled:opacity-50",
554
- checked ?? defaultChecked ? "bg-violet-600" : "bg-slate-800",
971
+ "relative inline-flex shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--primary,#8b5cf6)] focus-visible:ring-offset-2 focus-visible:ring-offset-slate-950 disabled:cursor-not-allowed disabled:opacity-50",
972
+ sizeTrackStyles[size],
973
+ isChecked ? "" : "bg-slate-800",
555
974
  className
556
- ].join(" "),
975
+ ].filter(Boolean).join(" "),
557
976
  children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
558
977
  "span",
559
978
  {
560
979
  className: [
561
- "pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out",
562
- checked ?? defaultChecked ? "translate-x-5" : "translate-x-0"
563
- ].join(" ")
980
+ "pointer-events-none flex items-center justify-center transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out text-slate-900",
981
+ sizeThumbStyles[size],
982
+ isChecked ? sizeTranslateStyles[size] : "translate-x-0"
983
+ ].join(" "),
984
+ children: isChecked ? checkedIcon : uncheckedIcon
564
985
  }
565
986
  )
566
987
  }
@@ -568,47 +989,149 @@ function Switch({
568
989
  }
569
990
 
570
991
  // src/components/tabs.tsx
571
- var import_react5 = require("react");
992
+ var import_react6 = require("react");
572
993
  var import_jsx_runtime16 = require("react/jsx-runtime");
573
- function Tabs({ items, defaultTab, className = "" }) {
994
+ var sizeStyles4 = {
995
+ sm: "px-3 py-1 text-xs gap-1.5",
996
+ md: "px-4 py-2 text-sm gap-2",
997
+ lg: "px-5 py-2.5 text-base gap-2.5"
998
+ };
999
+ function Tabs({
1000
+ items,
1001
+ defaultTab,
1002
+ variant = "pills",
1003
+ size = "md",
1004
+ fullWidth = false,
1005
+ className = ""
1006
+ }) {
574
1007
  const initialTab = defaultTab ?? items[0]?.id ?? "";
575
- const [activeTab, setActiveTab] = (0, import_react5.useState)(initialTab);
1008
+ const [activeTab, setActiveTab] = (0, import_react6.useState)(initialTab);
576
1009
  const activeItem = items.find((item) => item.id === activeTab) ?? items[0];
577
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className, children: [
578
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "mb-4 flex flex-wrap gap-2", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
579
- "button",
1010
+ const getTabButtonClass = (isActive) => {
1011
+ switch (variant) {
1012
+ case "underline":
1013
+ return [
1014
+ "border-b-2 font-medium transition cursor-pointer flex items-center justify-center",
1015
+ isActive ? "border-[var(--primary,#8b5cf6)] text-white font-bold" : "border-transparent text-slate-400 hover:text-white hover:border-white/20",
1016
+ sizeStyles4[size],
1017
+ fullWidth ? "flex-1" : ""
1018
+ ].join(" ");
1019
+ case "bordered":
1020
+ return [
1021
+ "rounded-xl border font-medium transition cursor-pointer flex items-center justify-center",
1022
+ isActive ? "border-[var(--primary,#8b5cf6)] bg-[var(--primary,#8b5cf6)]/15 text-white shadow-md" : "border-white/10 bg-slate-900/40 text-slate-400 hover:bg-white/5 hover:text-white",
1023
+ sizeStyles4[size],
1024
+ fullWidth ? "flex-1" : ""
1025
+ ].join(" ");
1026
+ case "segmented":
1027
+ return [
1028
+ "rounded-xl font-medium transition cursor-pointer flex items-center justify-center",
1029
+ isActive ? "bg-slate-900 text-white shadow-lg shadow-black/40 font-bold" : "text-slate-400 hover:text-white",
1030
+ sizeStyles4[size],
1031
+ fullWidth ? "flex-1" : ""
1032
+ ].join(" ");
1033
+ case "pills":
1034
+ default:
1035
+ return [
1036
+ "rounded-full font-medium transition cursor-pointer flex items-center justify-center",
1037
+ isActive ? "bg-[var(--primary,#8b5cf6)] text-white shadow-lg shadow-[var(--glow,rgba(139,92,246,0.25))] font-bold" : "bg-white/5 text-slate-300 hover:bg-white/10 hover:text-white",
1038
+ sizeStyles4[size],
1039
+ fullWidth ? "flex-1" : ""
1040
+ ].join(" ");
1041
+ }
1042
+ };
1043
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: ["w-full space-y-4", className].join(" "), children: [
1044
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1045
+ "div",
580
1046
  {
581
- type: "button",
582
- onClick: () => setActiveTab(item.id),
583
1047
  className: [
584
- "rounded-full px-3 py-1.5 text-sm transition",
585
- item.id === activeItem?.id ? "bg-violet-500 text-white shadow-lg shadow-violet-500/20" : "bg-slate-800 text-slate-300 hover:bg-slate-700 hover:text-white"
1048
+ "flex flex-wrap gap-2 select-none",
1049
+ variant === "underline" ? "border-b border-white/10 gap-4" : "",
1050
+ variant === "segmented" ? "rounded-2xl border border-white/10 bg-slate-950/80 p-1.5" : ""
586
1051
  ].join(" "),
587
- children: item.label
588
- },
589
- item.id
590
- )) }),
591
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "rounded-2xl border border-white/10 bg-slate-950/60 p-4 text-sm text-slate-200", children: activeItem?.content })
1052
+ children: items.map((item) => {
1053
+ const isActive = item.id === activeItem?.id;
1054
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1055
+ "button",
1056
+ {
1057
+ type: "button",
1058
+ onClick: () => setActiveTab(item.id),
1059
+ className: getTabButtonClass(isActive),
1060
+ children: [
1061
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "shrink-0", children: item.icon }),
1062
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: item.label }),
1063
+ item.badge && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "shrink-0", children: item.badge })
1064
+ ]
1065
+ },
1066
+ item.id
1067
+ );
1068
+ })
1069
+ }
1070
+ ),
1071
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "rounded-2xl border border-white/10 bg-[var(--surface,rgba(15,23,42,0.6))] p-5 text-sm text-slate-200 shadow-xl backdrop-blur-md", children: activeItem?.content })
592
1072
  ] });
593
1073
  }
594
1074
 
595
1075
  // src/components/textarea.tsx
596
1076
  var import_jsx_runtime17 = require("react/jsx-runtime");
597
- function Textarea({ className = "", ...props }) {
598
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1077
+ var variantStyles4 = {
1078
+ default: "border border-white/10 bg-slate-900/80 text-white placeholder:text-slate-500 focus:border-[var(--primary,#8b5cf6)] focus:ring-2 focus:ring-[var(--primary,#8b5cf6)]/25",
1079
+ filled: "border border-transparent bg-white/5 text-white placeholder:text-slate-500 hover:bg-white/10 focus:bg-slate-900 focus:border-[var(--primary,#8b5cf6)] focus:ring-2 focus:ring-[var(--primary,#8b5cf6)]/25"
1080
+ };
1081
+ var sizeStyles5 = {
1082
+ sm: "px-3 py-1.5 text-xs",
1083
+ md: "px-3.5 py-2.5 text-sm",
1084
+ lg: "px-4 py-3 text-base"
1085
+ };
1086
+ var radiusStyles4 = {
1087
+ none: "rounded-none",
1088
+ sm: "rounded-lg",
1089
+ md: "rounded-xl",
1090
+ lg: "rounded-2xl",
1091
+ xl: "rounded-3xl"
1092
+ };
1093
+ var resizeStyles = {
1094
+ none: "resize-none",
1095
+ vertical: "resize-y",
1096
+ horizontal: "resize-x",
1097
+ both: "resize"
1098
+ };
1099
+ function Textarea({
1100
+ variant = "default",
1101
+ size = "md",
1102
+ radius = "md",
1103
+ resize = "vertical",
1104
+ error,
1105
+ className = "",
1106
+ disabled,
1107
+ ...props
1108
+ }) {
1109
+ const textareaElement = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
599
1110
  "textarea",
600
1111
  {
601
1112
  ...props,
1113
+ disabled,
602
1114
  className: [
603
- "w-full rounded-xl border border-white/10 bg-slate-900 px-3 py-2 text-sm text-white placeholder:text-slate-400 focus:border-violet-400 focus:outline-none focus:ring-2 focus:ring-violet-400/30",
1115
+ "w-full transition-all duration-200 outline-none disabled:opacity-50 disabled:cursor-not-allowed",
1116
+ variantStyles4[variant],
1117
+ sizeStyles5[size],
1118
+ radiusStyles4[radius],
1119
+ resizeStyles[resize],
1120
+ error ? "!border-rose-500 !ring-rose-500/30" : "",
604
1121
  className
605
- ].join(" ")
1122
+ ].filter(Boolean).join(" ")
606
1123
  }
607
1124
  );
1125
+ if (!error) return textareaElement;
1126
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "w-full", children: [
1127
+ textareaElement,
1128
+ typeof error === "string" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "mt-1 text-xs text-rose-400", children: error })
1129
+ ] });
608
1130
  }
609
1131
 
610
1132
  // src/components/toast.tsx
611
- var import_react6 = require("react");
1133
+ var import_react7 = require("react");
1134
+ var import_react_dom3 = require("react-dom");
612
1135
  var import_jsx_runtime18 = require("react/jsx-runtime");
613
1136
  var toasts = [];
614
1137
  var listeners = /* @__PURE__ */ new Set();
@@ -641,77 +1164,119 @@ var toast = {
641
1164
  info(message, title) {
642
1165
  return toast.show(message, { type: "info", title });
643
1166
  },
1167
+ warning(message, title) {
1168
+ return toast.show(message, { type: "warning", title });
1169
+ },
644
1170
  dismiss(id) {
645
1171
  toasts = toasts.filter((t) => t.id !== id);
646
1172
  notify();
647
1173
  }
648
1174
  };
649
- function Toaster() {
650
- const [activeToasts, setActiveToasts] = (0, import_react6.useState)([]);
651
- (0, import_react6.useEffect)(() => {
1175
+ var positionStyles = {
1176
+ "bottom-right": "bottom-5 right-5 items-end",
1177
+ "bottom-left": "bottom-5 left-5 items-start",
1178
+ "top-right": "top-5 right-5 items-end",
1179
+ "top-left": "top-5 left-5 items-start",
1180
+ "top-center": "top-5 left-1/2 -translate-x-1/2 items-center",
1181
+ "bottom-center": "bottom-5 left-1/2 -translate-x-1/2 items-center"
1182
+ };
1183
+ function Toaster({ position = "bottom-right" }) {
1184
+ const [activeToasts, setActiveToasts] = (0, import_react7.useState)([]);
1185
+ const [mounted, setMounted] = (0, import_react7.useState)(false);
1186
+ (0, import_react7.useEffect)(() => {
1187
+ setMounted(true);
652
1188
  listeners.add(setActiveToasts);
653
1189
  return () => {
654
1190
  listeners.delete(setActiveToasts);
655
1191
  };
656
1192
  }, []);
657
- if (activeToasts.length === 0) return null;
1193
+ if (!mounted || activeToasts.length === 0) return null;
658
1194
  const typeStyles = {
659
- success: "border-emerald-500/40 bg-slate-900/95 text-emerald-100 shadow-emerald-500/10",
660
- error: "border-rose-500/40 bg-slate-900/95 text-rose-100 shadow-rose-500/10",
661
- info: "border-cyan-500/40 bg-slate-900/95 text-cyan-100 shadow-cyan-500/10",
662
- warning: "border-amber-500/40 bg-slate-900/95 text-amber-100 shadow-amber-500/10"
1195
+ success: "border-emerald-500/40 bg-slate-900/95 text-emerald-100 shadow-emerald-500/15",
1196
+ error: "border-rose-500/40 bg-slate-900/95 text-rose-100 shadow-rose-500/15",
1197
+ info: "border-[var(--primary,#8b5cf6)]/40 bg-slate-900/95 text-slate-100 shadow-[var(--glow,rgba(139,92,246,0.15))]",
1198
+ warning: "border-amber-500/40 bg-slate-900/95 text-amber-100 shadow-amber-500/15"
663
1199
  };
664
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "fixed bottom-5 right-5 z-50 flex flex-col gap-2.5 max-w-sm w-full pointer-events-none", children: activeToasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1200
+ const content = /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
665
1201
  "div",
666
1202
  {
667
1203
  className: [
668
- "pointer-events-auto flex items-start justify-between rounded-2xl border p-4 shadow-xl backdrop-blur-md animate-in slide-in-from-bottom-5 duration-200",
669
- typeStyles[t.type || "info"]
1204
+ "fixed z-[99999] flex flex-col gap-2.5 max-w-sm w-full pointer-events-none transition-all duration-300",
1205
+ positionStyles[position]
670
1206
  ].join(" "),
671
- children: [
672
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-1", children: [
673
- t.title && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "font-semibold text-xs tracking-wide uppercase text-white", children: t.title }),
674
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm font-medium", children: t.message })
675
- ] }),
676
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
677
- "button",
678
- {
679
- type: "button",
680
- onClick: () => toast.dismiss(t.id),
681
- className: "ml-3 text-slate-400 hover:text-white transition cursor-pointer",
682
- children: "\xD7"
683
- }
684
- )
685
- ]
686
- },
687
- t.id
688
- )) });
1207
+ children: activeToasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1208
+ "div",
1209
+ {
1210
+ className: [
1211
+ "pointer-events-auto flex items-start justify-between rounded-2xl border p-4 shadow-2xl backdrop-blur-xl transition-all duration-200",
1212
+ typeStyles[t.type || "info"]
1213
+ ].join(" "),
1214
+ children: [
1215
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-1", children: [
1216
+ t.title && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "font-bold text-xs tracking-wide uppercase text-white", children: t.title }),
1217
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm font-medium leading-relaxed", children: t.message })
1218
+ ] }),
1219
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1220
+ "button",
1221
+ {
1222
+ type: "button",
1223
+ onClick: () => toast.dismiss(t.id),
1224
+ "aria-label": "Close notification",
1225
+ className: "ml-3 text-slate-400 hover:text-white transition cursor-pointer text-lg leading-none",
1226
+ children: "\xD7"
1227
+ }
1228
+ )
1229
+ ]
1230
+ },
1231
+ t.id
1232
+ ))
1233
+ }
1234
+ );
1235
+ return typeof document !== "undefined" ? (0, import_react_dom3.createPortal)(content, document.body) : null;
689
1236
  }
690
1237
 
691
1238
  // src/components/tooltip.tsx
692
- var import_react7 = require("react");
1239
+ var import_react8 = require("react");
693
1240
  var import_jsx_runtime19 = require("react/jsx-runtime");
1241
+ var sideClasses = {
1242
+ top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
1243
+ bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
1244
+ left: "right-full top-1/2 -translate-y-1/2 mr-2",
1245
+ right: "left-full top-1/2 -translate-y-1/2 ml-2"
1246
+ };
1247
+ var themeClasses = {
1248
+ dark: "border border-white/10 bg-slate-900/95 text-slate-100 shadow-xl",
1249
+ light: "border border-slate-200 bg-white text-slate-900 shadow-xl font-semibold",
1250
+ primary: "border border-[var(--primary,#8b5cf6)]/40 bg-[var(--primary,#8b5cf6)] text-white shadow-lg shadow-[var(--glow,rgba(139,92,246,0.3))]"
1251
+ };
694
1252
  function Tooltip({
695
1253
  content,
696
1254
  children,
697
- side = "top",
1255
+ side,
1256
+ position = "top",
1257
+ theme = "dark",
1258
+ arrow = true,
1259
+ delay = 100,
698
1260
  className = ""
699
1261
  }) {
700
- const [isVisible, setIsVisible] = (0, import_react7.useState)(false);
701
- const sideClasses = {
702
- top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
703
- bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
704
- left: "right-full top-1/2 -translate-y-1/2 mr-2",
705
- right: "left-full top-1/2 -translate-y-1/2 ml-2"
1262
+ const activeSide = side || position;
1263
+ const [isVisible, setIsVisible] = (0, import_react8.useState)(false);
1264
+ const timeoutRef = (0, import_react8.useRef)(null);
1265
+ const show = () => {
1266
+ timeoutRef.current = setTimeout(() => setIsVisible(true), delay);
1267
+ };
1268
+ const hide = () => {
1269
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
1270
+ setIsVisible(false);
706
1271
  };
707
1272
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
708
1273
  "div",
709
1274
  {
710
1275
  className: "relative inline-flex",
711
- onMouseEnter: () => setIsVisible(true),
712
- onMouseLeave: () => setIsVisible(false),
713
- onFocus: () => setIsVisible(true),
714
- onBlur: () => setIsVisible(false),
1276
+ onMouseEnter: show,
1277
+ onMouseLeave: hide,
1278
+ onFocus: show,
1279
+ onBlur: hide,
715
1280
  children: [
716
1281
  children,
717
1282
  isVisible && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
@@ -719,8 +1284,9 @@ function Tooltip({
719
1284
  {
720
1285
  role: "tooltip",
721
1286
  className: [
722
- "absolute z-50 whitespace-nowrap rounded-lg border border-white/10 bg-slate-900/95 px-2.5 py-1 text-xs font-medium text-slate-200 shadow-xl backdrop-blur-md animate-in fade-in zoom-in-95 duration-150 pointer-events-none",
723
- sideClasses[side],
1287
+ "absolute z-50 whitespace-nowrap rounded-lg px-2.5 py-1 text-xs font-medium shadow-2xl backdrop-blur-md transition-all duration-150 pointer-events-none",
1288
+ sideClasses[activeSide],
1289
+ themeClasses[theme],
724
1290
  className
725
1291
  ].join(" "),
726
1292
  children: content