@nebutra/ui 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +21 -676
  2. package/README.md +81 -86
  3. package/dist/agent/index.d.ts +119 -0
  4. package/dist/agent/index.js +135 -0
  5. package/dist/agent/index.js.map +1 -0
  6. package/dist/canonical-CrO71UPO.d.ts +4058 -0
  7. package/dist/components/index.d.ts +51 -56
  8. package/dist/components/index.js +1467 -1160
  9. package/dist/components/index.js.map +1 -1
  10. package/dist/hooks/index.d.ts +62 -15
  11. package/dist/hooks/index.js +56 -34
  12. package/dist/hooks/index.js.map +1 -1
  13. package/dist/index-CKLIGfiU.d.ts +19 -0
  14. package/dist/index-Dg4jRJV2.d.ts +57 -0
  15. package/dist/layout/index.d.ts +5 -1
  16. package/dist/layout/index.js +427 -533
  17. package/dist/layout/index.js.map +1 -1
  18. package/dist/layouts/index.js +11 -9
  19. package/dist/layouts/index.js.map +1 -1
  20. package/dist/patterns/index.d.ts +128 -2
  21. package/dist/patterns/index.js +1478 -786
  22. package/dist/patterns/index.js.map +1 -1
  23. package/dist/primitives/canonical.d.ts +25 -0
  24. package/dist/primitives/canonical.js +11903 -0
  25. package/dist/primitives/canonical.js.map +1 -0
  26. package/dist/primitives/index.d.ts +577 -3545
  27. package/dist/primitives/index.js +8002 -6159
  28. package/dist/primitives/index.js.map +1 -1
  29. package/dist/shared/animation/css/index.d.ts +1 -0
  30. package/dist/shared/animation/css/index.js +14 -0
  31. package/dist/shared/animation/css/index.js.map +1 -0
  32. package/dist/shared/animation/index.d.ts +6 -0
  33. package/dist/shared/animation/index.js +272 -0
  34. package/dist/shared/animation/index.js.map +1 -0
  35. package/dist/shared/animation/motion/index.d.ts +4 -0
  36. package/dist/shared/animation/motion/index.js +205 -0
  37. package/dist/shared/animation/motion/index.js.map +1 -0
  38. package/dist/styles/brand-override.css +11 -11
  39. package/dist/tailwind.preset.d.ts +10 -10
  40. package/dist/tailwind.preset.js +7 -4
  41. package/dist/tailwind.preset.js.map +1 -1
  42. package/dist/theme/index.d.ts +2 -2
  43. package/dist/tokens-EAC6uPem.d.ts +302 -0
  44. package/dist/typography/fonts.css +31 -12
  45. package/dist/typography/index.d.ts +27 -27
  46. package/dist/typography/index.js +24 -4
  47. package/dist/typography/index.js.map +1 -1
  48. package/dist/utils/index.d.ts +36 -14
  49. package/dist/utils/index.js +44 -10
  50. package/dist/utils/index.js.map +1 -1
  51. package/package.json +38 -12
  52. package/src/styles/brand-override.css +61 -0
  53. package/src/styles/preset.css +29 -0
  54. package/src/styles/sources.css +27 -0
  55. package/src/typography/fonts.css +129 -0
@@ -1,26 +1,135 @@
1
1
  "use client";
2
- import * as React14 from 'react';
3
- import { useState, useRef, useCallback, useMemo, Fragment as Fragment$1 } from 'react';
4
2
  import { clsx } from 'clsx';
5
3
  import { twMerge } from 'tailwind-merge';
6
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
- import { ChevronRight, Check, Status, ChevronUpDown, Pencil, FileText, TextBold, TextItalic, Code, Hash, ListUnordered, Link, Image, ChevronUp, ChevronDown, Calendar, Eye, Bookmark, StarFill, Share, Flag, Pin, MoreHorizontal } from '@nebutra/icons';
4
+ import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
5
+ import * as React from 'react';
6
+ import { useState, useRef, useCallback, useMemo, Fragment, isValidElement } from 'react';
7
+ import { Check, Copy, Pencil, FileText, TextBold, TextItalic, Code, Hash, ListUnordered, Link, Image, ChevronUp, ChevronDown, Calendar, Eye, Bookmark, StarFill, Share, Flag, ChevronUpDown, Pin, ChevronRight, MoreHorizontal } from '@nebutra/icons';
8
8
  import { cva } from 'class-variance-authority';
9
9
  import { Menu } from '@base-ui/react/menu';
10
- import { Tabs as Tabs$1 } from '@base-ui/react/tabs';
11
10
  import { colors } from '@nebutra/brand';
11
+ import { Tabs as Tabs$1 } from '@base-ui/react/tabs';
12
12
  import { Tooltip as Tooltip$1 } from '@base-ui/react/tooltip';
13
13
  import ReactMarkdown from 'react-markdown';
14
14
  import remarkGfm from 'remark-gfm';
15
15
  import { Separator as Separator$1 } from '@base-ui/react/separator';
16
16
  import { Avatar as Avatar$1 } from '@base-ui/react/avatar';
17
- import { AnimatePresence, motion } from 'framer-motion';
17
+ import { useReducedMotion, AnimatePresence, motion } from 'framer-motion';
18
18
 
19
- // src/patterns/Card/Card.tsx
19
+ // src/utils/cn.ts
20
20
  function cn(...inputs) {
21
21
  return twMerge(clsx(inputs));
22
22
  }
23
- var CardContext = React14.createContext(null);
23
+ function ArtifactShiftCard({
24
+ className,
25
+ contentClassName,
26
+ children,
27
+ ...props
28
+ }) {
29
+ return /* @__PURE__ */ jsxs(
30
+ "div",
31
+ {
32
+ className: cn(
33
+ "group/card relative flex h-full min-h-[560px] flex-col overflow-hidden rounded-[var(--radius-panel)] border bg-background/90 transition-[transform,border-color,box-shadow] duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] hover:-translate-y-1 hover:border-foreground/25 hover:shadow-[0_28px_90px_-64px_var(--foreground)] focus-within:-translate-y-1 focus-within:border-foreground/25",
34
+ className
35
+ ),
36
+ "data-taste": "nebutra-shift-card",
37
+ ...props,
38
+ children: [
39
+ /* @__PURE__ */ jsx(
40
+ "div",
41
+ {
42
+ "aria-hidden": "true",
43
+ className: "pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_1px_1px,var(--neutral-8)_1px,transparent_0)] bg-[length:22px_22px] opacity-[0.09]"
44
+ }
45
+ ),
46
+ /* @__PURE__ */ jsx(
47
+ "div",
48
+ {
49
+ "aria-hidden": "true",
50
+ className: "pointer-events-none absolute inset-x-0 top-0 h-32 bg-gradient-to-b from-primary/10 via-primary/5 to-transparent opacity-80"
51
+ }
52
+ ),
53
+ /* @__PURE__ */ jsx("div", { className: cn("relative flex h-full flex-col p-4 sm:p-5", contentClassName), children })
54
+ ]
55
+ }
56
+ );
57
+ }
58
+ function ArtifactShiftCardPreview({
59
+ filename,
60
+ language,
61
+ code,
62
+ label,
63
+ maxLines = 8,
64
+ signals = ["typed", "scoped", "ready"],
65
+ className,
66
+ ...props
67
+ }) {
68
+ const lines = code.split("\n").slice(0, maxLines);
69
+ return /* @__PURE__ */ jsxs(
70
+ "section",
71
+ {
72
+ "aria-label": label,
73
+ className: cn(
74
+ "relative min-h-[260px] overflow-hidden rounded-[var(--radius-xl)] border border-border/60 bg-background/80 p-3 shadow-[0_18px_60px_-46px_var(--foreground)] transition-[transform,border-color,box-shadow] duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] group-hover/card:-translate-y-1 group-hover/card:border-foreground/20 group-hover/card:shadow-[0_24px_80px_-52px_var(--foreground)] group-focus-within/card:-translate-y-1 group-focus-within/card:border-foreground/20 sm:p-4",
75
+ className
76
+ ),
77
+ ...props,
78
+ children: [
79
+ /* @__PURE__ */ jsx(
80
+ "div",
81
+ {
82
+ "aria-hidden": "true",
83
+ className: "pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_1px_1px,var(--neutral-7)_1px,transparent_0)] bg-[length:18px_18px] opacity-[0.16]"
84
+ }
85
+ ),
86
+ /* @__PURE__ */ jsx(
87
+ "div",
88
+ {
89
+ "aria-hidden": "true",
90
+ className: "pointer-events-none absolute inset-x-0 top-0 h-24 bg-gradient-to-b from-primary/10 to-transparent opacity-80"
91
+ }
92
+ ),
93
+ /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-between gap-3 rounded-[var(--radius-md)] border border-border/60 bg-background/85 px-3 py-2", children: [
94
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate font-mono text-[11px] text-foreground/80", translate: "no", children: filename }),
95
+ /* @__PURE__ */ jsx(
96
+ "span",
97
+ {
98
+ className: "rounded-full border border-border/70 bg-muted/40 px-2 py-0.5 font-mono text-[10px] text-muted-foreground uppercase",
99
+ translate: "no",
100
+ children: language
101
+ }
102
+ )
103
+ ] }),
104
+ /* @__PURE__ */ jsx("div", { className: "relative mt-3 space-y-1.5 rounded-[var(--radius-lg)] border border-border/50 bg-muted/25 p-3 font-mono text-[11px] leading-5", children: lines.map((line, index) => /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 gap-3", children: [
105
+ /* @__PURE__ */ jsx("span", { className: "w-5 shrink-0 text-right text-muted-foreground/55 tabular-nums", children: index + 1 }),
106
+ /* @__PURE__ */ jsx("code", { className: "min-w-0 truncate text-foreground/75", translate: "no", children: line || " " })
107
+ ] }, `${line}-${index}`)) }),
108
+ /* @__PURE__ */ jsx("div", { className: "relative mt-3 grid grid-cols-3 gap-2", children: signals.map((signal) => /* @__PURE__ */ jsx(
109
+ "span",
110
+ {
111
+ className: "rounded-[var(--radius-md)] border border-border/55 bg-background/75 px-2 py-1.5 text-center font-mono text-[10px] text-muted-foreground uppercase tracking-[0.14em]",
112
+ children: signal
113
+ },
114
+ signal
115
+ )) })
116
+ ]
117
+ }
118
+ );
119
+ }
120
+ function ArtifactShiftCardFooter({ className, ...props }) {
121
+ return /* @__PURE__ */ jsx(
122
+ "footer",
123
+ {
124
+ className: cn(
125
+ "relative mt-4 flex flex-wrap items-center justify-between gap-3 rounded-[var(--radius-xl)] border border-border/60 bg-background/85 px-4 py-3 shadow-[0_14px_48px_-42px_var(--foreground)] backdrop-blur-xl transition-[transform,border-color,box-shadow] duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] group-hover/card:-translate-y-2 group-hover/card:border-foreground/20 group-hover/card:shadow-[0_22px_70px_-50px_var(--foreground)] group-focus-within/card:-translate-y-2 group-focus-within/card:border-foreground/20",
126
+ className
127
+ ),
128
+ ...props
129
+ }
130
+ );
131
+ }
132
+ var CardContext = React.createContext(null);
24
133
  var paddingMap = {
25
134
  none: "",
26
135
  sm: "p-4",
@@ -34,14 +143,14 @@ var variantStyles = {
34
143
  ghost: "bg-transparent",
35
144
  gradient: "bg-gradient-to-br from-card to-muted border border-border"
36
145
  };
37
- var CardRoot = React14.forwardRef(
146
+ var CardRoot = React.forwardRef(
38
147
  ({ className, variant = "default", padding = "md", children, ...props }, ref) => {
39
148
  return /* @__PURE__ */ jsx(CardContext.Provider, { value: { variant }, children: /* @__PURE__ */ jsx(
40
149
  "div",
41
150
  {
42
151
  ref,
43
152
  className: cn(
44
- "rounded-[var(--radius-xl)] transition-all duration-200",
153
+ "rounded-[var(--radius-xl)] transition-[background-color,border-color,box-shadow,color] duration-200",
45
154
  variantStyles[variant],
46
155
  paddingMap[padding],
47
156
  className
@@ -53,26 +162,26 @@ var CardRoot = React14.forwardRef(
53
162
  }
54
163
  );
55
164
  CardRoot.displayName = "Card";
56
- var CardHeader = React14.forwardRef(
165
+ var CardHeader = React.forwardRef(
57
166
  ({ className, spacing: gap = "md", children, ...props }, ref) => {
58
167
  const gapMap = { sm: "gap-2", md: "gap-3", lg: "gap-4" };
59
168
  return /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-start", gapMap[gap], className), ...props, children });
60
169
  }
61
170
  );
62
171
  CardHeader.displayName = "Card.Header";
63
- var CardBody = React14.forwardRef(
172
+ var CardBody = React.forwardRef(
64
173
  ({ className, children, ...props }, ref) => {
65
174
  return /* @__PURE__ */ jsx("div", { ref, className: cn("mt-4", className), ...props, children });
66
175
  }
67
176
  );
68
177
  CardBody.displayName = "Card.Body";
69
- var CardFooter = React14.forwardRef(
178
+ var CardFooter = React.forwardRef(
70
179
  ({ className, children, ...props }, ref) => {
71
180
  return /* @__PURE__ */ jsx("div", { ref, className: cn("mt-6 pt-4 border-t border-border/50", className), ...props, children });
72
181
  }
73
182
  );
74
183
  CardFooter.displayName = "Card.Footer";
75
- var CardIcon = React14.forwardRef(
184
+ var CardIcon = React.forwardRef(
76
185
  ({ className, size = "md", children, ...props }, ref) => {
77
186
  const sizeMap = {
78
187
  sm: "w-8 h-8",
@@ -95,14 +204,14 @@ var CardIcon = React14.forwardRef(
95
204
  }
96
205
  );
97
206
  CardIcon.displayName = "Card.Icon";
98
- var CardTitle = React14.forwardRef(
207
+ var CardTitle = React.forwardRef(
99
208
  ({ className, as: Tag = "h3", children, ...props }, ref) => {
100
209
  return /* @__PURE__ */ jsx(Tag, { ref, className: cn("text-lg font-semibold text-foreground", className), ...props, children });
101
210
  }
102
211
  );
103
212
  CardTitle.displayName = "Card.Title";
104
- var CardDescription = React14.forwardRef(({ className, as: Tag = "p", children, ...props }, ref) => {
105
- return React14.createElement(
213
+ var CardDescription = React.forwardRef(({ className, as: Tag = "p", children, ...props }, ref) => {
214
+ return React.createElement(
106
215
  Tag,
107
216
  {
108
217
  ref,
@@ -121,7 +230,7 @@ var Card = Object.assign(CardRoot, {
121
230
  Title: CardTitle,
122
231
  Description: CardDescription
123
232
  });
124
- var CommandBox = React14.forwardRef(
233
+ var CommandBox = React.forwardRef(
125
234
  ({
126
235
  className,
127
236
  command,
@@ -131,20 +240,23 @@ var CommandBox = React14.forwardRef(
131
240
  onCopy,
132
241
  ...props
133
242
  }, ref) => {
134
- const [copied, setCopied] = React14.useState(false);
135
- const handleCopy = React14.useCallback(async () => {
243
+ const [copied, setCopied] = React.useState(false);
244
+ const handleCopy = React.useCallback(async () => {
136
245
  try {
137
246
  await navigator.clipboard.writeText(command);
138
247
  setCopied(true);
139
248
  onCopy?.();
140
249
  setTimeout(() => setCopied(false), 2e3);
141
- } catch (_err) {
250
+ } catch (err) {
251
+ if (process.env.NODE_ENV !== "production") {
252
+ console.error("[CommandBox] clipboard write failed:", err);
253
+ }
142
254
  }
143
255
  }, [command, onCopy]);
144
256
  const variantStyles3 = {
145
- default: "bg-[var(--neutral-2)] border border-[var(--neutral-7)] rounded-[var(--radius-lg)]",
146
- minimal: "bg-[var(--neutral-1)] border border-[var(--neutral-7)] rounded-[var(--radius-md)]",
147
- pill: "bg-[var(--neutral-2)] border border-[var(--neutral-7)] rounded-full"
257
+ default: "bg-muted border border-border rounded-[var(--radius-lg)]",
258
+ minimal: "bg-background border border-border rounded-[var(--radius-md)]",
259
+ pill: "bg-muted border border-border rounded-full"
148
260
  };
149
261
  return (
150
262
  // biome-ignore lint/a11y/useSemanticElements: ARIA pattern
@@ -153,7 +265,7 @@ var CommandBox = React14.forwardRef(
153
265
  {
154
266
  ref,
155
267
  className: cn(
156
- "group relative flex items-center gap-3 px-4 py-2.5 font-mono text-sm cursor-pointer transition-all hover:bg-[var(--neutral-3)]",
268
+ "group relative flex items-center gap-3 px-4 py-2.5 font-mono text-sm cursor-pointer transition-colors hover:bg-muted",
157
269
  variantStyles3[variant],
158
270
  className
159
271
  ),
@@ -170,13 +282,13 @@ var CommandBox = React14.forwardRef(
170
282
  ...props,
171
283
  children: [
172
284
  /* @__PURE__ */ jsx("span", { className: "text-emerald-400 shrink-0 select-none", children: prefix }),
173
- /* @__PURE__ */ jsx("span", { className: "flex-1 text-[var(--neutral-11)] truncate", children: command }),
285
+ /* @__PURE__ */ jsx("span", { className: "flex-1 text-muted-foreground truncate", children: command }),
174
286
  showCopyButton && /* @__PURE__ */ jsx(
175
287
  "span",
176
288
  {
177
289
  className: cn(
178
290
  "shrink-0 text-xs transition-colors",
179
- copied ? "text-emerald-400" : "text-[var(--neutral-9)] group-hover:text-[var(--neutral-11)]"
291
+ copied ? "text-emerald-400" : "text-muted-foreground group-hover:text-muted-foreground"
180
292
  ),
181
293
  children: copied ? /* @__PURE__ */ jsx(CopiedIcon, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx(CopyIcon, { className: "w-4 h-4" })
182
294
  }
@@ -185,7 +297,7 @@ var CommandBox = React14.forwardRef(
185
297
  "span",
186
298
  {
187
299
  className: cn(
188
- "absolute -top-8 left-1/2 -translate-x-1/2 px-2 py-1 text-xs rounded bg-zinc-700 text-[var(--neutral-11)] opacity-0 transition-opacity pointer-events-none",
300
+ "absolute -top-8 left-1/2 -translate-x-1/2 px-2 py-1 text-xs rounded bg-zinc-700 text-muted-foreground opacity-0 transition-opacity pointer-events-none",
189
301
  "group-hover:opacity-100",
190
302
  copied && "opacity-100"
191
303
  ),
@@ -236,13 +348,139 @@ function CopiedIcon({ className }) {
236
348
  }
237
349
  );
238
350
  }
351
+ var metricToneClasses = {
352
+ neutral: "bg-muted/70 text-muted-foreground ring-border",
353
+ blue: "bg-info/10 text-info ring-info/20",
354
+ green: "bg-success/10 text-success ring-success/20",
355
+ amber: "bg-warning/10 text-warning ring-warning/20"
356
+ };
357
+ function DashboardCommandSurface({
358
+ status,
359
+ title,
360
+ description,
361
+ actions,
362
+ children,
363
+ className
364
+ }) {
365
+ return /* @__PURE__ */ jsxs(
366
+ "section",
367
+ {
368
+ "data-pattern": "nebutra-dashboard-command",
369
+ className: cn(
370
+ "relative overflow-hidden rounded-[var(--radius-lg)] border border-border bg-card p-4 text-card-foreground shadow-sm",
371
+ "before:pointer-events-none before:absolute before:inset-x-0 before:top-0 before:h-px before:bg-[linear-gradient(90deg,transparent,hsl(var(--primary)/0.58),transparent)]",
372
+ "after:pointer-events-none after:absolute after:inset-0 after:bg-[radial-gradient(circle_at_top_left,hsl(var(--primary)/0.08),transparent_42%)]",
373
+ "sm:p-5",
374
+ className
375
+ ),
376
+ children: [
377
+ /* @__PURE__ */ jsxs("div", { className: "relative z-10 flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between", children: [
378
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
379
+ status ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
380
+ /* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-green-9 shadow-[0_0_0_3px_var(--green-3)]" }),
381
+ /* @__PURE__ */ jsx("p", { className: "text-[11px] font-medium uppercase text-muted-foreground", children: status })
382
+ ] }) : null,
383
+ /* @__PURE__ */ jsx("h1", { className: "mt-2 text-2xl font-semibold tracking-normal text-card-foreground sm:text-[28px]", children: title }),
384
+ description ? /* @__PURE__ */ jsx("p", { className: "mt-2 max-w-2xl text-[13px] leading-5 text-muted-foreground", children: description }) : null
385
+ ] }),
386
+ actions ? /* @__PURE__ */ jsx("div", { className: "flex shrink-0 flex-wrap items-center gap-1.5", children: actions }) : null
387
+ ] }),
388
+ children ? /* @__PURE__ */ jsx("div", { className: "relative z-10 mt-4", children }) : null
389
+ ]
390
+ }
391
+ );
392
+ }
393
+ function DashboardPanel({
394
+ title,
395
+ description,
396
+ meta,
397
+ action,
398
+ children,
399
+ className,
400
+ headerClassName
401
+ }) {
402
+ return /* @__PURE__ */ jsxs(
403
+ "section",
404
+ {
405
+ "data-pattern": "nebutra-dashboard-panel",
406
+ className: cn(
407
+ "rounded-[var(--radius-lg)] border border-border bg-card p-3.5 text-card-foreground shadow-sm sm:p-4",
408
+ className
409
+ ),
410
+ children: [
411
+ /* @__PURE__ */ jsxs(
412
+ "div",
413
+ {
414
+ className: cn(
415
+ "mb-3 flex flex-col gap-2.5 border-b border-border pb-3 lg:flex-row lg:items-start lg:justify-between",
416
+ headerClassName
417
+ ),
418
+ children: [
419
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
420
+ /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold tracking-normal text-card-foreground", children: title }),
421
+ description ? /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs leading-5 text-muted-foreground", children: description }) : null
422
+ ] }),
423
+ (meta || action) && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2 lg:justify-end", children: [
424
+ meta,
425
+ action
426
+ ] })
427
+ ]
428
+ }
429
+ ),
430
+ children
431
+ ]
432
+ }
433
+ );
434
+ }
435
+ function DashboardMetricTile({
436
+ label,
437
+ value,
438
+ detail,
439
+ source,
440
+ icon: Icon,
441
+ tone = "neutral",
442
+ className
443
+ }) {
444
+ return /* @__PURE__ */ jsxs(
445
+ "div",
446
+ {
447
+ "data-pattern": "nebutra-dashboard-metric",
448
+ className: cn(
449
+ "group h-full rounded-[var(--radius-lg)] border border-border bg-muted/40 p-3 transition-colors duration-150",
450
+ "hover:border-muted-foreground/30 hover:bg-muted/65",
451
+ className
452
+ ),
453
+ children: [
454
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
455
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-xs font-medium text-muted-foreground", children: label }),
456
+ Icon ? /* @__PURE__ */ jsx(
457
+ "span",
458
+ {
459
+ className: cn(
460
+ "inline-flex size-6 shrink-0 items-center justify-center rounded-[var(--radius-sm)] ring-1",
461
+ metricToneClasses[tone]
462
+ ),
463
+ children: /* @__PURE__ */ jsx(Icon, { className: "size-3.5", "aria-hidden": true })
464
+ }
465
+ ) : null
466
+ ] }),
467
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-2xl font-semibold tabular-nums tracking-normal text-card-foreground", children: value }),
468
+ (detail || source) && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 space-y-0.5 text-xs leading-5 text-muted-foreground", children: [
469
+ detail ? /* @__PURE__ */ jsx("span", { className: "block", children: detail }) : null,
470
+ source ? /* @__PURE__ */ jsx("span", { className: "block text-[11px] text-muted-foreground/70", children: source }) : null
471
+ ] })
472
+ ]
473
+ }
474
+ );
475
+ }
239
476
  var badgeVariants = cva(
240
477
  "inline-flex justify-center items-center align-middle shrink-0 rounded-full font-sans font-medium whitespace-nowrap tabular-nums transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 border border-transparent",
241
478
  {
242
479
  variants: {
243
480
  variant: {
244
481
  // ─── Semantic / brand variants ────────────────────────────────────────
245
- default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
482
+ // Recipe-driven default (solid | outline | … via --badge-default-*)
483
+ default: "badge-brand-default border",
246
484
  secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
247
485
  destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
248
486
  outline: "border-border text-foreground",
@@ -250,32 +488,32 @@ var badgeVariants = cva(
250
488
  warning: "border-transparent bg-warning text-warning-foreground hover:bg-warning/80",
251
489
  info: "border-transparent bg-info text-info-foreground hover:bg-info/80",
252
490
  error: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
253
- // ─── Geist-style color palette ────────────────────────────────────────
254
- gray: "bg-geist-gray-700 text-white fill-white",
255
- "gray-subtle": "bg-geist-gray-200 text-geist-gray-1000 fill-geist-gray-1000 border-transparent",
256
- blue: "bg-blue-700 text-white fill-white",
257
- "blue-subtle": "bg-blue-200 text-blue-900 fill-blue-900 border-transparent",
258
- purple: "bg-purple-700 text-white fill-white",
259
- "purple-subtle": "bg-purple-200 text-purple-900 fill-purple-900 border-transparent",
260
- amber: "bg-amber-700 text-black fill-black",
261
- "amber-subtle": "bg-amber-200 text-amber-900 fill-amber-900 border-transparent",
262
- red: "bg-red-700 text-white fill-white",
263
- "red-subtle": "bg-red-200 text-red-900 fill-red-900 border-transparent",
264
- pink: "bg-pink-700 text-white fill-white",
265
- "pink-subtle": "bg-pink-300 text-pink-900 fill-pink-900 border-transparent",
266
- green: "bg-green-700 text-white fill-white",
267
- "green-subtle": "bg-green-200 text-green-900 fill-green-900 border-transparent",
268
- teal: "bg-teal-700 text-white fill-white",
269
- "teal-subtle": "bg-teal-300 text-teal-900 fill-teal-900 border-transparent",
270
- inverted: "bg-geist-gray-1000 text-geist-gray-100 fill-geist-gray-100",
271
- trial: "bg-gradient-to-br from-trial-start to-trial-end text-white fill-white",
272
- turbo: "bg-gradient-to-br from-turbo-start to-turbo-end text-white fill-white",
273
- pill: "bg-background text-foreground fill-foreground !border-gray-alpha-400 hover:bg-muted/50 focus-visible:bg-muted/50 dark:!border-border",
274
- // ─── Semantic tone variants (nav badges, ownership, featured) ─────────
491
+ // ─── Palette accents (decorative scale — not product chrome CTAs) ────
492
+ gray: "bg-muted text-muted-foreground fill-current",
493
+ "gray-subtle": "bg-muted/60 text-muted-foreground fill-current border-transparent",
494
+ blue: "bg-primary text-primary-foreground fill-current",
495
+ "blue-subtle": "bg-primary/10 text-primary fill-current border-transparent",
496
+ purple: "bg-secondary text-secondary-foreground fill-current",
497
+ "purple-subtle": "bg-secondary/40 text-secondary-foreground fill-current border-transparent",
498
+ amber: "bg-warning text-warning-foreground fill-current",
499
+ "amber-subtle": "bg-warning/15 text-warning fill-current border-transparent",
500
+ red: "bg-destructive text-destructive-foreground fill-current",
501
+ "red-subtle": "bg-destructive/15 text-destructive fill-current border-transparent",
502
+ pink: "bg-accent text-accent-foreground fill-current",
503
+ "pink-subtle": "bg-accent/40 text-accent-foreground fill-current border-transparent",
504
+ green: "bg-success text-success-foreground fill-current",
505
+ "green-subtle": "bg-success/15 text-success fill-current border-transparent",
506
+ teal: "bg-info text-info-foreground fill-current",
507
+ "teal-subtle": "bg-info/15 text-info fill-current border-transparent",
508
+ inverted: "bg-foreground text-background fill-current",
509
+ // Special visual treatments (intentional product design, not brand hex)
510
+ trial: "bg-gradient-to-br from-trial-start to-trial-end text-primary-foreground fill-current",
511
+ turbo: "bg-gradient-to-br from-turbo-start to-turbo-end text-primary-foreground fill-current",
512
+ pill: "bg-background text-foreground fill-foreground border-border hover:bg-muted/50 focus-visible:bg-muted/50",
275
513
  beta: "border-transparent bg-muted text-muted-foreground",
276
- new: "border-transparent bg-blue-100 text-blue-700 dark:bg-blue-950/50 dark:text-blue-300",
514
+ new: "border-transparent bg-primary/10 text-primary",
277
515
  owner: "border-border bg-transparent text-foreground",
278
- featured: "border-transparent text-white bg-[image:var(--brand-gradient)] [text-shadow:0_0_1px_rgba(0,0,0,0.2)]",
516
+ featured: "badge-brand-default border [text-shadow:0_0_1px_hsl(var(--background)/0.2)]",
279
517
  "coming-soon": "border-transparent bg-muted/60 text-muted-foreground italic"
280
518
  },
281
519
  size: {
@@ -296,15 +534,16 @@ var dotColorMap = {
296
534
  info: "bg-info-foreground",
297
535
  error: "bg-destructive-foreground",
298
536
  destructive: "bg-destructive-foreground",
299
- "gray-subtle": "bg-geist-gray-500",
300
- "green-subtle": "bg-green-500",
301
- "amber-subtle": "bg-amber-500",
302
- "red-subtle": "bg-red-500",
303
- "blue-subtle": "bg-blue-500",
304
- "purple-subtle": "bg-purple-500",
305
- "pink-subtle": "bg-pink-500",
306
- "teal-subtle": "bg-teal-500",
307
- default: "bg-primary-foreground",
537
+ "gray-subtle": "bg-muted-foreground",
538
+ "green-subtle": "bg-success",
539
+ "amber-subtle": "bg-warning",
540
+ "red-subtle": "bg-destructive",
541
+ "blue-subtle": "bg-primary",
542
+ "purple-subtle": "bg-secondary-foreground",
543
+ "pink-subtle": "bg-accent-foreground",
544
+ "teal-subtle": "bg-info",
545
+ default: "bg-brand-mark-foreground",
546
+ featured: "bg-brand-mark-foreground",
308
547
  secondary: "bg-secondary-foreground",
309
548
  outline: "bg-muted-foreground"
310
549
  };
@@ -319,7 +558,7 @@ function Badge({
319
558
  ...props
320
559
  }) {
321
560
  const badgeClassName = cn(badgeVariants({ variant, size }), className);
322
- const renderContent = (label) => /* @__PURE__ */ jsxs(Fragment, { children: [
561
+ const renderContent = (label) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
323
562
  dot && /* @__PURE__ */ jsx(
324
563
  "span",
325
564
  {
@@ -334,11 +573,11 @@ function Badge({
334
573
  label
335
574
  ] });
336
575
  if (asChild) {
337
- const childArray = React14.Children.toArray(children);
576
+ const childArray = React.Children.toArray(children);
338
577
  const child = childArray.length === 1 ? childArray[0] : null;
339
- if (React14.isValidElement(child)) {
578
+ if (React.isValidElement(child)) {
340
579
  const childProps = child.props;
341
- return React14.cloneElement(child, {
580
+ return React.cloneElement(child, {
342
581
  ...props,
343
582
  ...childProps,
344
583
  "data-slot": "badge",
@@ -350,133 +589,244 @@ function Badge({
350
589
  }
351
590
  return /* @__PURE__ */ jsx("span", { "data-slot": "badge", className: badgeClassName, ...props, children: renderContent(children) });
352
591
  }
353
- var DropdownMenu = Menu.Root;
354
- var DropdownMenuTrigger = React14.forwardRef(
355
- ({ asChild, children, render, ...props }, ref) => {
356
- const renderElement = asChild && React14.isValidElement(children) ? children : render;
357
- return /* @__PURE__ */ jsx(
358
- Menu.Trigger,
359
- {
360
- ref,
361
- render: renderElement,
362
- ...renderElement ? props : { ...props, children }
363
- }
364
- );
592
+ ({
593
+ // Nebutra Blue (云毓蓝) — technology & trust — VI: #0033FE
594
+ blue50: colors.primary[50],
595
+ blue100: colors.primary[100],
596
+ blue200: colors.primary[200],
597
+ blue300: colors.primary[300],
598
+ blue400: colors.primary[400],
599
+ blue500: colors.primary[500],
600
+ // brand primary
601
+ blue600: colors.primary[600],
602
+ blue700: colors.primary[700],
603
+ blue800: colors.primary[800],
604
+ blue900: colors.primary[900],
605
+ blue950: colors.primary[950],
606
+ // Nebutra Cyan (云毓青) — data flow & intelligence — VI: #0BF1C3
607
+ cyan50: colors.accent[50],
608
+ cyan100: colors.accent[100],
609
+ cyan200: colors.accent[200],
610
+ cyan300: colors.accent[300],
611
+ cyan400: colors.accent[400],
612
+ cyan500: colors.accent[500],
613
+ // brand secondary
614
+ cyan600: colors.accent[600],
615
+ cyan700: colors.accent[700],
616
+ cyan800: colors.accent[800],
617
+ cyan900: colors.accent[900],
618
+ cyan950: colors.accent[950],
619
+ // Neutral (blue-undertone gray scale)
620
+ neutral50: colors.neutral[50],
621
+ neutral100: colors.neutral[100],
622
+ neutral200: colors.neutral[200],
623
+ neutral300: colors.neutral[300],
624
+ neutral400: colors.neutral[400],
625
+ neutral500: colors.neutral[500],
626
+ neutral600: colors.neutral[600],
627
+ neutral700: colors.neutral[700],
628
+ neutral800: colors.neutral[800],
629
+ neutral900: colors.neutral[900],
630
+ neutral950: colors.neutral[950],
631
+ white: colors.white,
632
+ black: colors.black
633
+ });
634
+ ({
635
+ /** Hero sections, primary CTA buttons, logo fills — VI signature gradient */
636
+ primary: colors.gradient.primary,
637
+ /** Hover states, secondary gradient elements */
638
+ reverse: colors.gradient.primaryReverse,
639
+ /** Vertical layout dividers, page section separators */
640
+ vertical: colors.gradient.primaryVertical,
641
+ /** Background halos, focus glow effects, radial emphasis */
642
+ radial: colors.gradient.primaryRadial});
643
+ var primitiveSpacing = {
644
+ 1: 4,
645
+ 2: 8,
646
+ 3: 12,
647
+ 4: 16,
648
+ 5: 20,
649
+ 20: 80,
650
+ 24: 96
651
+ };
652
+ var primitiveSizing = {
653
+ /** Geist button-specific size (24px). Larger than xs by design. */
654
+ tiny: 24,
655
+ sm: 32,
656
+ md: 40,
657
+ lg: 48};
658
+ var primitiveRadius = {
659
+ md: 6,
660
+ // Geist default — slightly more rounded than 4px
661
+ lg: 8,
662
+ full: 9999
663
+ };
664
+ var primitiveFontSize = {
665
+ xs: 12,
666
+ sm: 14,
667
+ base: 16,
668
+ lg: 18};
669
+ var primitiveTransition = {
670
+ duration: {
671
+ // hover, focus, small state changes
672
+ flow: 200},
673
+ easing: {
674
+ inOut: "cubic-bezier(0.4, 0, 0.2, 1)"
365
675
  }
366
- );
676
+ };
677
+ var primitiveFocusRing = {
678
+ width: 2,
679
+ // px
680
+ offset: 2
681
+ // px — gap between element and ring
682
+ };
683
+
684
+ // src/tokens/shadows.ts
685
+ var shadowClasses = {
686
+ md: "shadow-md",
687
+ xl: "shadow-xl"};
688
+ var overlayZIndex = {
689
+ popover: 1060,
690
+ tooltip: 1070
691
+ };
692
+ var overlayClassNames = {
693
+ menuSurface: [
694
+ "min-w-32 overflow-hidden rounded-[var(--radius-lg)] border border-border/70 bg-popover/95 p-1 text-popover-foreground backdrop-blur-md",
695
+ shadowClasses.xl,
696
+ "outline-none transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-out)]",
697
+ "data-[starting-style]:scale-95 data-[starting-style]:opacity-0 data-[ending-style]:scale-95 data-[ending-style]:opacity-0",
698
+ "motion-reduce:transition-none motion-reduce:data-[starting-style]:transform-none motion-reduce:data-[ending-style]:transform-none"
699
+ ].join(" "),
700
+ tooltipSurface: [
701
+ "overflow-hidden rounded-[var(--radius-md)] border border-border/70 bg-popover/95 px-3 py-1.5 text-sm text-popover-foreground backdrop-blur-md",
702
+ shadowClasses.md,
703
+ "transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-out)]",
704
+ "data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0",
705
+ "motion-reduce:transition-none motion-reduce:data-starting-style:transform-none motion-reduce:data-ending-style:transform-none"
706
+ ].join(" ")};
707
+
708
+ // src/primitives/overlay.ts
709
+ var menuItemBaseClassName = [
710
+ "relative flex cursor-default select-none items-center rounded-[var(--radius-sm)] px-2 py-1.5 text-sm",
711
+ "outline-none transition-colors duration-micro ease-out",
712
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-60"
713
+ ].join(" ");
714
+ var menuHighlightedClassName = "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground";
715
+ var overlayPrimitiveClassNames = {
716
+ menuSurface: "rounded-[var(--radius-md)] border-border/70 bg-popover/95 shadow-md",
717
+ menuItem: [menuItemBaseClassName, menuHighlightedClassName].join(" ")};
718
+ var DropdownMenuContext = React.createContext(null);
719
+ function DropdownMenu({
720
+ open: controlledOpen,
721
+ defaultOpen = false,
722
+ onOpenChange,
723
+ children,
724
+ ...props
725
+ }) {
726
+ const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);
727
+ const open = controlledOpen ?? uncontrolledOpen;
728
+ function setOpen(nextOpen, eventDetails) {
729
+ if (controlledOpen === void 0) {
730
+ setUncontrolledOpen(nextOpen);
731
+ }
732
+ onOpenChange?.(nextOpen, eventDetails);
733
+ }
734
+ const contextValue = { setOpen };
735
+ return /* @__PURE__ */ jsx(DropdownMenuContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(Menu.Root, { open, onOpenChange: setOpen, ...props, children }) });
736
+ }
737
+ DropdownMenu.displayName = "DropdownMenu";
738
+ var DropdownMenuTrigger = ({
739
+ asChild,
740
+ children,
741
+ render,
742
+ ref,
743
+ ...props
744
+ }) => {
745
+ const context = React.use(DropdownMenuContext);
746
+ function openFromTrigger() {
747
+ context?.setOpen(true);
748
+ }
749
+ const childRenderElement = asChild && React.isValidElement(children) ? React.cloneElement(children, {
750
+ onMouseDown: (event) => {
751
+ children.props.onMouseDown?.(event);
752
+ if (!event.defaultPrevented) {
753
+ openFromTrigger();
754
+ }
755
+ },
756
+ onKeyDown: (event) => {
757
+ children.props.onKeyDown?.(event);
758
+ if (!event.defaultPrevented && (event.key === "Enter" || event.key === " ")) {
759
+ openFromTrigger();
760
+ }
761
+ }
762
+ }) : null;
763
+ const renderElement = childRenderElement ?? render;
764
+ return /* @__PURE__ */ jsx(
765
+ Menu.Trigger,
766
+ {
767
+ ref,
768
+ render: renderElement,
769
+ ...renderElement ? props : { ...props, children }
770
+ }
771
+ );
772
+ };
367
773
  DropdownMenuTrigger.displayName = "DropdownMenuTrigger";
368
774
  Menu.Group;
369
775
  Menu.Portal;
370
776
  Menu.SubmenuRoot;
371
777
  Menu.RadioGroup;
372
- var DropdownMenuSubTrigger = React14.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
373
- Menu.SubmenuTrigger,
374
- {
375
- ref,
376
- className: cn(
377
- "flex cursor-default select-none items-center rounded-[var(--radius-md)] px-2 py-1.5 text-sm outline-none focus:bg-accent data-[popup-open]:bg-accent",
378
- inset && "pl-8",
379
- className
380
- ),
381
- ...props,
382
- children: [
383
- children,
384
- /* @__PURE__ */ jsx(ChevronRight, { className: "ml-auto size-4" })
385
- ]
386
- }
387
- ));
388
- DropdownMenuSubTrigger.displayName = "DropdownMenuSubTrigger";
389
- var DropdownMenuSubContent = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, { children: /* @__PURE__ */ jsx(
390
- Menu.Popup,
778
+ var DropdownMenuContent = ({
779
+ className,
780
+ style,
781
+ sideOffset = 4,
782
+ align = "center",
783
+ alignOffset = 0,
784
+ side = "bottom",
785
+ ref,
786
+ ...props
787
+ }) => /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(
788
+ Menu.Positioner,
391
789
  {
392
- ref,
393
- className: cn(
394
- "z-50 min-w-32 overflow-hidden rounded-xl border bg-background/90 backdrop-blur-md p-1 text-popover-foreground shadow-xl transition-[opacity,transform,display] duration-flow ease-out data-[starting-style]:zoom-out-95 data-[ending-style]:zoom-out-95 data-[starting-style]:fade-out-0 data-[ending-style]:fade-out-0",
395
- className
396
- ),
397
- ...props
790
+ sideOffset,
791
+ align,
792
+ alignOffset,
793
+ side,
794
+ children: /* @__PURE__ */ jsx(
795
+ Menu.Popup,
796
+ {
797
+ ref,
798
+ className: cn(
799
+ overlayClassNames.menuSurface,
800
+ overlayPrimitiveClassNames.menuSurface,
801
+ className
802
+ ),
803
+ style: { zIndex: overlayZIndex.popover, ...style },
804
+ ...props
805
+ }
806
+ )
398
807
  }
399
- ) }) }));
400
- DropdownMenuSubContent.displayName = "DropdownMenuSubContent";
401
- var DropdownMenuContent = React14.forwardRef(
402
- ({ className, sideOffset = 4, align = "center", alignOffset = 0, side = "bottom", ...props }, ref) => /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(
403
- Menu.Positioner,
404
- {
405
- sideOffset,
406
- align,
407
- alignOffset,
408
- side,
409
- children: /* @__PURE__ */ jsx(
410
- Menu.Popup,
411
- {
412
- ref,
413
- className: cn(
414
- "z-50 min-w-32 overflow-hidden rounded-xl border bg-background/90 backdrop-blur-md p-1 text-popover-foreground shadow-xl transition-[opacity,transform,display] duration-flow ease-out outline-none data-[starting-style]:zoom-out-95 data-[ending-style]:zoom-out-95 data-[starting-style]:fade-out-0 data-[ending-style]:fade-out-0",
415
- className
416
- ),
417
- ...props
418
- }
419
- )
420
- }
421
- ) })
422
- );
808
+ ) });
423
809
  DropdownMenuContent.displayName = "DropdownMenuContent";
424
- var DropdownMenuItem = React14.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
810
+ var DropdownMenuItem = ({
811
+ className,
812
+ inset,
813
+ ref,
814
+ ...props
815
+ }) => /* @__PURE__ */ jsx(
425
816
  Menu.Item,
426
817
  {
427
818
  ref,
428
- className: cn(
429
- "relative flex cursor-default select-none items-center rounded-[var(--radius-md)] px-2 py-1.5 text-sm outline-none transition-colors data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
430
- inset && "pl-8",
431
- className
432
- ),
819
+ className: cn(overlayPrimitiveClassNames.menuItem, inset && "pl-8", className),
433
820
  ...props
434
821
  }
435
- ));
822
+ );
436
823
  DropdownMenuItem.displayName = "DropdownMenuItem";
437
- var DropdownMenuCheckboxItem = React14.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
438
- Menu.CheckboxItem,
439
- {
440
- ref,
441
- className: cn(
442
- "relative flex cursor-default select-none items-center rounded-[var(--radius-md)] py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
443
- className
444
- ),
445
- ...checked !== void 0 && { checked },
446
- ...props,
447
- children: [
448
- /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "size-4" }) }) }),
449
- children
450
- ]
451
- }
452
- ));
453
- DropdownMenuCheckboxItem.displayName = "DropdownMenuCheckboxItem";
454
- var DropdownMenuRadioItem = React14.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
455
- Menu.RadioItem,
456
- {
457
- ref,
458
- className: cn(
459
- "relative flex cursor-default select-none items-center rounded-[var(--radius-md)] py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
460
- className
461
- ),
462
- ...props,
463
- children: [
464
- /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(Menu.RadioItemIndicator, { children: /* @__PURE__ */ jsx(Status, { className: "size-2 fill-current" }) }) }),
465
- children
466
- ]
467
- }
468
- ));
469
- DropdownMenuRadioItem.displayName = "DropdownMenuRadioItem";
470
- var DropdownMenuLabel = React14.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
471
- Menu.GroupLabel,
472
- {
473
- ref,
474
- className: cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className),
475
- ...props
476
- }
477
- ));
478
- DropdownMenuLabel.displayName = "DropdownMenuLabel";
479
- var DropdownMenuSeparator = React14.forwardRef(({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx(
824
+ var DropdownMenuSeparator = ({
825
+ className,
826
+ orientation = "horizontal",
827
+ ref,
828
+ ...props
829
+ }) => /* @__PURE__ */ jsx(
480
830
  Menu.Separator,
481
831
  {
482
832
  ref,
@@ -484,7 +834,7 @@ var DropdownMenuSeparator = React14.forwardRef(({ className, orientation = "hori
484
834
  className: cn("-mx-1 my-1 h-px bg-muted", className),
485
835
  ...props
486
836
  }
487
- ));
837
+ );
488
838
  DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
489
839
  var iconToneStyles = {
490
840
  neutral: "bg-muted text-muted-foreground",
@@ -503,15 +853,15 @@ var badgeToneToVariant = {
503
853
  "coming-soon": "coming-soon"
504
854
  };
505
855
  var cardClassName = cn(
506
- "group relative block rounded-xl border border-border bg-card text-card-foreground p-5 text-left",
507
- "transition-all duration-150",
508
- "hover:border-neutral-7 hover:shadow-sm hover:-translate-y-px",
856
+ "group relative block rounded-[var(--radius-xl)] border border-border bg-card text-card-foreground p-5 text-left",
857
+ "transition-[border-color,box-shadow,transform] duration-150 motion-reduce:transition-none motion-reduce:transform-none",
858
+ "hover:border-neutral-7 hover:shadow-sm hover:-translate-y-px motion-reduce:hover:translate-y-0",
509
859
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
510
860
  );
511
861
  function GalleryCardActionsMenu({ actions, title }) {
512
- const stop = React14.useCallback((event) => {
862
+ function stop(event) {
513
863
  event.stopPropagation();
514
- }, []);
864
+ }
515
865
  return /* @__PURE__ */ jsx("div", { onClickCapture: stop, onPointerDownCapture: stop, children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
516
866
  /* @__PURE__ */ jsx(
517
867
  DropdownMenuTrigger,
@@ -522,7 +872,7 @@ function GalleryCardActionsMenu({ actions, title }) {
522
872
  type: "button",
523
873
  "aria-label": `Actions for ${title}`,
524
874
  className: cn(
525
- "inline-flex h-7 w-7 items-center justify-center rounded-md",
875
+ "inline-flex h-7 w-7 items-center justify-center rounded-[var(--radius-md)]",
526
876
  "text-muted-foreground transition-colors",
527
877
  "hover:bg-accent hover:text-accent-foreground",
528
878
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1"
@@ -560,13 +910,13 @@ function GalleryCardBody({
560
910
  }) {
561
911
  const hasActions = Boolean(actions && actions.length > 0);
562
912
  const hasMetadataStrip = Boolean(metadata?.author || metadata?.metric || metadata?.trailing);
563
- return /* @__PURE__ */ jsxs(Fragment, { children: [
913
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
564
914
  /* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-start justify-between gap-2", children: [
565
915
  icon ? /* @__PURE__ */ jsx(
566
916
  "div",
567
917
  {
568
918
  className: cn(
569
- "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg text-base",
919
+ "flex h-10 w-10 shrink-0 items-center justify-center rounded-[var(--radius-lg)] text-base",
570
920
  iconToneStyles[iconTone]
571
921
  ),
572
922
  "aria-hidden": "true",
@@ -620,36 +970,418 @@ function GalleryCard(props) {
620
970
  actions
621
971
  }
622
972
  );
623
- const composedClassName = cn(cardClassName, "cursor-pointer", className);
624
- if (href) {
625
- if (renderLink) {
626
- return renderLink({
627
- href,
628
- className: composedClassName,
629
- "aria-label": title,
630
- children: body
631
- });
973
+ const composedClassName = cn(cardClassName, "cursor-pointer", className);
974
+ if (href) {
975
+ if (renderLink) {
976
+ return renderLink({
977
+ href,
978
+ className: composedClassName,
979
+ "aria-label": title,
980
+ children: body
981
+ });
982
+ }
983
+ return /* @__PURE__ */ jsx("a", { href, "aria-label": title, className: composedClassName, onClick, children: body });
984
+ }
985
+ if (onClick) {
986
+ return /* @__PURE__ */ jsx("button", { type: "button", "aria-label": title, className: composedClassName, onClick, children: body });
987
+ }
988
+ return /* @__PURE__ */ jsx("div", { className: cn(cardClassName, "cursor-default", className), children: body });
989
+ }
990
+ GalleryCard.displayName = "GalleryCard";
991
+ function lineTone(line) {
992
+ const trimmed = line.trim();
993
+ if (trimmed.startsWith("//") || trimmed.startsWith("--")) {
994
+ return "text-muted-foreground/55 italic";
995
+ }
996
+ if (/\b(await|const|export|return|CREATE|ALTER|POLICY|USING|ENABLE|TABLE)\b/.test(trimmed)) {
997
+ return "text-primary font-medium";
998
+ }
999
+ if (trimmed.includes(":")) {
1000
+ return "text-emerald-600 dark:text-emerald-400";
1001
+ }
1002
+ return "text-foreground/78";
1003
+ }
1004
+ function renderIcon(icon) {
1005
+ if (!icon) {
1006
+ return null;
1007
+ }
1008
+ if (typeof icon === "function") {
1009
+ const Icon = icon;
1010
+ return /* @__PURE__ */ jsx(Icon, { "aria-hidden": true, className: "size-7 text-primary" });
1011
+ }
1012
+ if (isValidElement(icon)) {
1013
+ return /* @__PURE__ */ jsx(
1014
+ "span",
1015
+ {
1016
+ "aria-hidden": true,
1017
+ className: "inline-grid place-items-center text-primary [&_svg]:size-7 [&_svg]:text-primary",
1018
+ children: icon
1019
+ }
1020
+ );
1021
+ }
1022
+ return icon;
1023
+ }
1024
+ function KineticFeatureCard({
1025
+ icon,
1026
+ eyebrow,
1027
+ title,
1028
+ description,
1029
+ children,
1030
+ className,
1031
+ ...props
1032
+ }) {
1033
+ const renderedIcon = renderIcon(icon);
1034
+ return /* @__PURE__ */ jsxs(
1035
+ "article",
1036
+ {
1037
+ className: cn(
1038
+ "group/kinetic relative flex h-full min-h-[540px] flex-col overflow-hidden rounded-[var(--radius-panel)] border border-border/65 bg-background/82 p-6 shadow-[inset_0_1px_0_rgb(255_255_255/0.45),0_24px_90px_-70px_var(--foreground)] backdrop-blur-2xl transition-[transform,border-color,box-shadow,background-color] duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] hover:-translate-y-1 hover:border-foreground/25 hover:bg-background/94 hover:shadow-[inset_0_1px_0_rgb(255_255_255/0.55),0_34px_110px_-74px_var(--foreground)] focus-within:-translate-y-1 focus-within:border-foreground/25 sm:p-7",
1039
+ className
1040
+ ),
1041
+ "data-taste": "nebutra-texture-cutout-card",
1042
+ ...props,
1043
+ children: [
1044
+ /* @__PURE__ */ jsx(
1045
+ "div",
1046
+ {
1047
+ "aria-hidden": "true",
1048
+ className: "pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_1px_1px,var(--neutral-8)_1px,transparent_0)] bg-[length:18px_18px] opacity-[0.12]"
1049
+ }
1050
+ ),
1051
+ /* @__PURE__ */ jsx(
1052
+ "div",
1053
+ {
1054
+ "aria-hidden": "true",
1055
+ className: "pointer-events-none absolute inset-x-0 top-0 h-40 bg-gradient-to-b from-primary/12 via-primary/5 to-transparent",
1056
+ style: { maskImage: "linear-gradient(to bottom, black 45%, transparent 100%)" }
1057
+ }
1058
+ ),
1059
+ /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-0 z-10 rounded-bl-[2rem] border-b border-l border-border/60 bg-muted/55 px-4 py-2 backdrop-blur-xl", children: /* @__PURE__ */ jsx("span", { className: "font-mono text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: eyebrow }) }),
1060
+ /* @__PURE__ */ jsxs("div", { className: "relative z-10 flex h-full flex-col", children: [
1061
+ /* @__PURE__ */ jsx("div", { className: "mb-8 flex items-start justify-between gap-4 pr-16", children: renderedIcon && /* @__PURE__ */ jsx("div", { className: "grid size-14 place-items-center rounded-[var(--radius-xl)] border border-border/65 bg-background/75 shadow-[inset_0_1px_0_rgb(255_255_255/0.55),0_16px_42px_-34px_var(--foreground)] transition-transform duration-500 group-hover/kinetic:-translate-y-1", children: renderedIcon }) }),
1062
+ /* @__PURE__ */ jsx(
1063
+ "h3",
1064
+ {
1065
+ className: "text-2xl font-semibold text-foreground text-balance",
1066
+ style: { letterSpacing: "var(--tracking-heading)", lineHeight: "var(--leading-heading)" },
1067
+ children: title
1068
+ }
1069
+ ),
1070
+ /* @__PURE__ */ jsx("p", { className: "mt-4 text-base font-medium leading-7 text-muted-foreground text-balance", children: description }),
1071
+ /* @__PURE__ */ jsx("div", { className: "mt-auto pt-8", children })
1072
+ ] })
1073
+ ]
1074
+ }
1075
+ );
1076
+ }
1077
+ function KineticCodePreview({
1078
+ filename = "artifact.ts",
1079
+ language = "ts",
1080
+ lines,
1081
+ className,
1082
+ ...props
1083
+ }) {
1084
+ return /* @__PURE__ */ jsxs(
1085
+ "div",
1086
+ {
1087
+ className: cn(
1088
+ "relative overflow-hidden rounded-[var(--radius-xl)] border border-border/60 bg-muted/30 shadow-[0_18px_70px_-56px_var(--foreground)] transition-[transform,border-color,box-shadow] duration-500 group-hover/kinetic:-translate-y-2 group-hover/kinetic:border-foreground/20 group-hover/kinetic:shadow-[0_26px_90px_-62px_var(--foreground)]",
1089
+ className
1090
+ ),
1091
+ ...props,
1092
+ children: [
1093
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b border-border/60 bg-background/70 px-4 py-3 backdrop-blur-xl", children: [
1094
+ /* @__PURE__ */ jsx("span", { className: "size-2.5 rounded-full bg-border/90", "aria-hidden": true }),
1095
+ /* @__PURE__ */ jsx("span", { className: "size-2.5 rounded-full bg-border/80", "aria-hidden": true }),
1096
+ /* @__PURE__ */ jsx("span", { className: "size-2.5 rounded-full bg-border/70", "aria-hidden": true }),
1097
+ /* @__PURE__ */ jsx(
1098
+ "span",
1099
+ {
1100
+ className: "ml-3 min-w-0 truncate font-mono text-[11px] text-muted-foreground",
1101
+ translate: "no",
1102
+ children: filename
1103
+ }
1104
+ ),
1105
+ /* @__PURE__ */ jsx("span", { className: "ml-auto rounded-full border border-border/60 bg-background/60 px-2 py-0.5 font-mono text-[10px] uppercase text-muted-foreground", children: language })
1106
+ ] }),
1107
+ /* @__PURE__ */ jsx("pre", { className: "relative max-h-[190px] overflow-hidden p-4 font-mono text-[12px] leading-5", children: lines.map((line, index) => /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 gap-3", children: [
1108
+ /* @__PURE__ */ jsx("span", { className: "w-5 shrink-0 text-right text-muted-foreground/45 tabular-nums", children: index + 1 }),
1109
+ /* @__PURE__ */ jsx("code", { className: cn("min-w-0 truncate", lineTone(line)), translate: "no", children: line || " " })
1110
+ ] }, `${line}-${index}`)) })
1111
+ ]
1112
+ }
1113
+ );
1114
+ }
1115
+ function KineticConsoleFrame({
1116
+ title = "operator@nebutra-sailor: ~",
1117
+ status,
1118
+ children,
1119
+ className,
1120
+ ...props
1121
+ }) {
1122
+ return /* @__PURE__ */ jsxs(
1123
+ "div",
1124
+ {
1125
+ className: cn(
1126
+ "group/kinetic relative flex h-full min-h-[460px] w-full flex-col overflow-hidden rounded-[2rem] border border-border/65 bg-background/84 shadow-[inset_0_1px_0_rgb(255_255_255/0.45),0_32px_120px_-88px_var(--foreground)] backdrop-blur-3xl transition-[transform,border-color,box-shadow] duration-500 hover:-translate-y-1 hover:border-foreground/25 hover:shadow-[inset_0_1px_0_rgb(255_255_255/0.55),0_44px_140px_-90px_var(--foreground)]",
1127
+ className
1128
+ ),
1129
+ "data-taste": "nebutra-terminal-animation",
1130
+ ...props,
1131
+ children: [
1132
+ /* @__PURE__ */ jsxs("div", { className: "flex h-14 flex-none items-center gap-4 border-b border-border/60 bg-background/70 px-5 backdrop-blur-xl", children: [
1133
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", "aria-hidden": true, children: [
1134
+ /* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-red-400/80" }),
1135
+ /* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-amber-400/80" }),
1136
+ /* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-emerald-400/80" })
1137
+ ] }),
1138
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1 text-center", children: /* @__PURE__ */ jsx("span", { className: "inline-flex max-w-full items-center rounded-[var(--radius-md)] border border-border/50 bg-muted/35 px-4 py-1 font-mono text-[10px] font-semibold uppercase tracking-[0.16em] text-muted-foreground", children: /* @__PURE__ */ jsx("span", { className: "truncate", translate: "no", children: title }) }) }),
1139
+ /* @__PURE__ */ jsx("div", { className: "hidden min-w-20 justify-end sm:flex", children: status && /* @__PURE__ */ jsx("span", { className: "rounded-full border border-border/55 bg-background/65 px-2 py-0.5 font-mono text-[10px] uppercase text-muted-foreground", children: status }) })
1140
+ ] }),
1141
+ /* @__PURE__ */ jsxs("div", { className: "relative flex-1 overflow-hidden bg-gradient-to-br from-background/55 via-background/25 to-muted/28 p-6 sm:p-8", children: [
1142
+ /* @__PURE__ */ jsx(
1143
+ "div",
1144
+ {
1145
+ "aria-hidden": "true",
1146
+ className: "pointer-events-none absolute inset-0 bg-[linear-gradient(to_right,var(--neutral-6)_1px,transparent_1px),linear-gradient(to_bottom,var(--neutral-6)_1px,transparent_1px)] bg-[size:16px_24px] opacity-45"
1147
+ }
1148
+ ),
1149
+ /* @__PURE__ */ jsx(
1150
+ "div",
1151
+ {
1152
+ "aria-hidden": "true",
1153
+ className: "pointer-events-none absolute inset-x-0 bottom-0 h-28 bg-gradient-to-t from-background/80 to-transparent"
1154
+ }
1155
+ ),
1156
+ /* @__PURE__ */ jsx("div", { className: "relative z-10 h-full w-full", children })
1157
+ ] })
1158
+ ]
1159
+ }
1160
+ );
1161
+ }
1162
+ function KineticMorphSurface({
1163
+ activeKey,
1164
+ className,
1165
+ children,
1166
+ ...props
1167
+ }) {
1168
+ return /* @__PURE__ */ jsxs(
1169
+ "div",
1170
+ {
1171
+ className: cn(
1172
+ "group/kinetic relative overflow-hidden rounded-[var(--radius-panel)] border border-border/65 bg-background/80 p-3 shadow-[inset_0_1px_0_rgb(255_255_255/0.45),0_28px_110px_-82px_var(--foreground)] backdrop-blur-2xl transition-[border-color,box-shadow,background-color] duration-500 hover:border-foreground/20 hover:bg-background/92 hover:shadow-[inset_0_1px_0_rgb(255_255_255/0.55),0_36px_130px_-88px_var(--foreground)] sm:p-4 lg:p-5",
1173
+ className
1174
+ ),
1175
+ "data-active-key": activeKey,
1176
+ "data-taste": "nebutra-morph-surface",
1177
+ ...props,
1178
+ children: [
1179
+ /* @__PURE__ */ jsx(
1180
+ "div",
1181
+ {
1182
+ "aria-hidden": "true",
1183
+ className: "pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_1px_1px,var(--neutral-8)_1px,transparent_0)] bg-[length:20px_20px] opacity-[0.10]"
1184
+ }
1185
+ ),
1186
+ /* @__PURE__ */ jsx(
1187
+ "div",
1188
+ {
1189
+ "aria-hidden": "true",
1190
+ className: "pointer-events-none absolute inset-x-0 top-0 h-36 bg-gradient-to-b from-primary/12 via-primary/4 to-transparent",
1191
+ style: { maskImage: "linear-gradient(to bottom, black 45%, transparent 100%)" }
1192
+ }
1193
+ ),
1194
+ /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
1195
+ ]
1196
+ }
1197
+ );
1198
+ }
1199
+ function KineticSignalMarquee({
1200
+ eyebrow,
1201
+ className,
1202
+ children,
1203
+ ...props
1204
+ }) {
1205
+ return /* @__PURE__ */ jsxs(
1206
+ "div",
1207
+ {
1208
+ className: cn(
1209
+ "group/kinetic relative mx-auto overflow-hidden rounded-[var(--radius-panel)] border border-border/55 bg-background/72 px-3 py-8 shadow-[inset_0_1px_0_rgb(255_255_255/0.45),0_22px_90px_-76px_var(--foreground)] backdrop-blur-2xl sm:px-5",
1210
+ className
1211
+ ),
1212
+ "data-taste": "nebutra-provider-grid",
1213
+ ...props,
1214
+ children: [
1215
+ /* @__PURE__ */ jsx(
1216
+ "div",
1217
+ {
1218
+ "aria-hidden": "true",
1219
+ className: "pointer-events-none absolute inset-0 bg-[linear-gradient(to_right,var(--neutral-6)_1px,transparent_1px),linear-gradient(to_bottom,var(--neutral-6)_1px,transparent_1px)] bg-[size:32px_32px] opacity-25"
1220
+ }
1221
+ ),
1222
+ /* @__PURE__ */ jsx(
1223
+ "div",
1224
+ {
1225
+ "aria-hidden": "true",
1226
+ className: "pointer-events-none absolute inset-y-0 left-0 w-28 bg-gradient-to-r from-background via-background/90 to-transparent z-20"
1227
+ }
1228
+ ),
1229
+ /* @__PURE__ */ jsx(
1230
+ "div",
1231
+ {
1232
+ "aria-hidden": "true",
1233
+ className: "pointer-events-none absolute inset-y-0 right-0 w-28 bg-gradient-to-l from-background via-background/90 to-transparent z-20"
1234
+ }
1235
+ ),
1236
+ eyebrow && /* @__PURE__ */ jsx("div", { className: "relative z-30 mb-6 text-center font-mono text-[10px] font-semibold uppercase tracking-[0.2em] text-muted-foreground", children: eyebrow }),
1237
+ /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
1238
+ ]
1239
+ }
1240
+ );
1241
+ }
1242
+ function KineticCommandBox({
1243
+ command,
1244
+ copyLabel,
1245
+ copiedLabel,
1246
+ className,
1247
+ ...props
1248
+ }) {
1249
+ const [copied, setCopied] = useState(false);
1250
+ const handleCopy = async () => {
1251
+ await navigator.clipboard.writeText(command);
1252
+ setCopied(true);
1253
+ window.setTimeout(() => setCopied(false), 2e3);
1254
+ };
1255
+ return /* @__PURE__ */ jsxs(
1256
+ "div",
1257
+ {
1258
+ className: cn(
1259
+ "group/kinetic relative flex flex-col items-stretch overflow-hidden rounded-[var(--radius-xl)] border border-border/65 bg-background/82 p-1.5 shadow-[inset_0_1px_0_rgb(255_255_255/0.5),0_20px_70px_-58px_var(--foreground)] backdrop-blur-2xl transition-[transform,border-color,box-shadow,background-color] duration-500 hover:-translate-y-1 hover:border-foreground/25 hover:bg-background/92 hover:shadow-[inset_0_1px_0_rgb(255_255_255/0.6),0_28px_90px_-62px_var(--foreground)] sm:flex-row sm:items-center",
1260
+ className
1261
+ ),
1262
+ "data-taste": "nebutra-texture-command",
1263
+ ...props,
1264
+ children: [
1265
+ /* @__PURE__ */ jsx(
1266
+ "div",
1267
+ {
1268
+ "aria-hidden": "true",
1269
+ className: "pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_1px_1px,var(--neutral-8)_1px,transparent_0)] bg-[length:16px_16px] opacity-[0.10]"
1270
+ }
1271
+ ),
1272
+ /* @__PURE__ */ jsxs("code", { className: "relative z-10 flex-1 overflow-x-auto whitespace-nowrap px-4 py-3.5 font-mono text-xs text-foreground sm:px-5 sm:text-sm md:text-base", children: [
1273
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "$" }),
1274
+ " ",
1275
+ command
1276
+ ] }),
1277
+ /* @__PURE__ */ jsxs(
1278
+ "button",
1279
+ {
1280
+ type: "button",
1281
+ onClick: handleCopy,
1282
+ className: "relative z-10 mt-2 flex shrink-0 cursor-pointer items-center justify-center gap-2 rounded-[var(--radius-lg)] border border-primary/20 bg-foreground px-5 py-2.5 text-sm font-medium text-background shadow-[inset_0_1px_0_rgb(255_255_255/0.2)] transition-[transform,opacity] hover:-translate-y-px hover:opacity-90 sm:mt-0",
1283
+ children: [
1284
+ copied ? /* @__PURE__ */ jsx(Check, { className: "size-4" }) : /* @__PURE__ */ jsx(Copy, { className: "size-4" }),
1285
+ copied ? copiedLabel : copyLabel
1286
+ ]
1287
+ }
1288
+ )
1289
+ ]
1290
+ }
1291
+ );
1292
+ }
1293
+ function KineticStepRail({ className, children, ...props }) {
1294
+ return /* @__PURE__ */ jsxs(
1295
+ "div",
1296
+ {
1297
+ className: cn(
1298
+ "relative overflow-hidden rounded-[var(--radius-panel)] border border-border/65 bg-background/78 p-6 shadow-[inset_0_1px_0_rgb(255_255_255/0.45),0_24px_100px_-78px_var(--foreground)] backdrop-blur-2xl md:p-10",
1299
+ className
1300
+ ),
1301
+ "data-taste": "nebutra-grid-beam",
1302
+ ...props,
1303
+ children: [
1304
+ /* @__PURE__ */ jsx(
1305
+ "div",
1306
+ {
1307
+ "aria-hidden": "true",
1308
+ className: "pointer-events-none absolute inset-0 bg-[linear-gradient(to_right,var(--neutral-6)_1px,transparent_1px),linear-gradient(to_bottom,var(--neutral-6)_1px,transparent_1px)] bg-[size:36px_36px] opacity-30"
1309
+ }
1310
+ ),
1311
+ /* @__PURE__ */ jsx(
1312
+ "div",
1313
+ {
1314
+ "aria-hidden": "true",
1315
+ className: "pointer-events-none absolute left-8 right-8 top-[5.7rem] hidden h-px bg-gradient-to-r from-transparent via-primary/45 to-transparent md:block"
1316
+ }
1317
+ ),
1318
+ /* @__PURE__ */ jsx(
1319
+ "div",
1320
+ {
1321
+ "aria-hidden": "true",
1322
+ className: "pointer-events-none absolute left-1/2 top-8 bottom-8 w-px -translate-x-1/2 bg-gradient-to-b from-transparent via-primary/35 to-transparent md:hidden"
1323
+ }
1324
+ ),
1325
+ /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
1326
+ ]
1327
+ }
1328
+ );
1329
+ }
1330
+ function KineticStep({
1331
+ icon: Icon,
1332
+ index,
1333
+ title,
1334
+ description,
1335
+ phaseLabel,
1336
+ className,
1337
+ ...props
1338
+ }) {
1339
+ const formatted = String(index).padStart(2, "0");
1340
+ return /* @__PURE__ */ jsxs(
1341
+ "article",
1342
+ {
1343
+ className: cn(
1344
+ "group/kinetic relative flex h-full flex-col items-center rounded-[var(--radius-xl)] border border-border/60 bg-background/82 p-5 text-center shadow-[0_18px_70px_-58px_var(--foreground)] backdrop-blur-xl transition-[transform,border-color,box-shadow] duration-500 hover:-translate-y-1 hover:border-foreground/25 hover:shadow-[0_28px_90px_-62px_var(--foreground)]",
1345
+ className
1346
+ ),
1347
+ ...props,
1348
+ children: [
1349
+ /* @__PURE__ */ jsxs("div", { className: "relative mb-6 grid size-16 place-items-center rounded-[var(--radius-xl)] border border-border/65 bg-background shadow-[inset_0_1px_0_rgb(255_255_255/0.55),0_18px_56px_-42px_var(--foreground)]", children: [
1350
+ /* @__PURE__ */ jsx(
1351
+ "span",
1352
+ {
1353
+ className: "absolute -right-2 -top-2 rounded-full border border-border/60 bg-muted px-2 py-0.5 font-mono text-[10px] text-muted-foreground",
1354
+ "aria-hidden": true,
1355
+ children: formatted
1356
+ }
1357
+ ),
1358
+ Icon && /* @__PURE__ */ jsx(
1359
+ Icon,
1360
+ {
1361
+ "aria-hidden": true,
1362
+ className: "size-7 text-primary transition-colors group-hover/kinetic:text-foreground"
1363
+ }
1364
+ )
1365
+ ] }),
1366
+ /* @__PURE__ */ jsx("span", { className: "mb-4 rounded-full border border-primary/20 bg-primary/7 px-3 py-1 font-mono text-[10px] font-semibold uppercase tracking-[0.16em] text-primary", children: phaseLabel ?? `Phase ${formatted}` }),
1367
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-foreground", children: title }),
1368
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-sm leading-6 text-muted-foreground text-balance", children: description })
1369
+ ]
632
1370
  }
633
- return /* @__PURE__ */ jsx("a", { href, "aria-label": title, className: composedClassName, onClick, children: body });
634
- }
635
- if (onClick) {
636
- return /* @__PURE__ */ jsx("button", { type: "button", "aria-label": title, className: composedClassName, onClick, children: body });
637
- }
638
- return /* @__PURE__ */ jsx("div", { className: cn(cardClassName, "cursor-default", className), children: body });
1371
+ );
639
1372
  }
640
- GalleryCard.displayName = "GalleryCard";
641
- var Slot = React14.forwardRef(
1373
+ var Slot = React.forwardRef(
642
1374
  ({ children, className, style, ...props }, ref) => {
643
- const childArray = React14.Children.toArray(children);
1375
+ const childArray = React.Children.toArray(children);
644
1376
  const child = childArray.length === 1 ? childArray[0] : null;
645
- if (child == null || !React14.isValidElement(child)) {
1377
+ if (child == null || !React.isValidElement(child)) {
646
1378
  return /* @__PURE__ */ jsx("span", { ref, className, style, ...props, children });
647
1379
  }
648
1380
  const childProps = child.props;
649
1381
  const mergedRef = (node) => {
650
1382
  if (typeof ref === "function") ref(node);
651
1383
  else if (ref) ref.current = node;
652
- const childRef = child.ref;
1384
+ const childRef = childProps.ref;
653
1385
  if (typeof childRef === "function") childRef(node);
654
1386
  else if (childRef && "current" in childRef) {
655
1387
  childRef.current = node;
@@ -663,7 +1395,7 @@ var Slot = React14.forwardRef(
663
1395
  className: mergedClass,
664
1396
  style: { ...childProps.style, ...style }
665
1397
  };
666
- return React14.cloneElement(
1398
+ return React.cloneElement(
667
1399
  child,
668
1400
  merged
669
1401
  );
@@ -673,8 +1405,9 @@ Slot.displayName = "Slot";
673
1405
  var buttonVariants = cva(
674
1406
  [
675
1407
  "inline-flex items-center justify-center gap-2 whitespace-nowrap",
676
- "rounded-[var(--radius-md)] text-sm font-medium",
677
- "transition-colors duration-150 ease-out",
1408
+ "rounded-[var(--btn-default-radius,var(--radius-md))]",
1409
+ "text-[length:var(--control-font-size-md,0.875rem)] font-[number:var(--font-weight-medium,500)]",
1410
+ "transition-colors duration-micro ease-out",
678
1411
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
679
1412
  "disabled:pointer-events-none disabled:opacity-50",
680
1413
  "aria-busy:cursor-wait"
@@ -682,8 +1415,9 @@ var buttonVariants = cva(
682
1415
  {
683
1416
  variants: {
684
1417
  variant: {
685
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
686
- ink: "bg-[var(--neutral-12)] text-[var(--neutral-1)] ring-1 ring-inset ring-white/[0.04] hover:bg-[var(--neutral-11)] hover:-translate-y-px active:translate-y-0 transition-[transform,background-color] duration-150",
1418
+ // Recipe-driven via packages/design/tokens/recipe.css (.btn-brand-default)
1419
+ default: "btn-brand-default",
1420
+ ink: "bg-[var(--neutral-12)] text-[var(--neutral-1)] ring-1 ring-inset ring-[color:var(--neutral-1)]/5 hover:bg-[var(--neutral-11)] hover:-translate-y-px active:translate-y-0 transition-[transform,background-color] duration-micro",
687
1421
  destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
688
1422
  outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
689
1423
  secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
@@ -693,16 +1427,11 @@ var buttonVariants = cva(
693
1427
  warning: "bg-warning text-warning-foreground hover:bg-warning/90"
694
1428
  },
695
1429
  size: {
696
- tiny: "h-6 rounded-[var(--radius-sm)] px-2 text-[11px]",
697
- // 24px
698
- sm: "h-8 rounded-[var(--radius-sm)] px-3 text-xs",
699
- // 32px
700
- default: "h-10 px-4 py-2",
701
- // 40px
702
- lg: "h-12 rounded-[var(--radius-lg)] px-5 text-base",
703
- // 48px
704
- icon: "h-10 w-10"
705
- // 40×40px (kept for backward compat)
1430
+ tiny: "h-[var(--control-height-tiny,1.5rem)] rounded-[var(--radius-sm)] px-2 text-[length:var(--control-font-size-tiny,0.6875rem)]",
1431
+ sm: "h-[var(--control-height-sm,2rem)] rounded-[var(--radius-sm)] px-3 text-[length:var(--control-font-size-sm,0.75rem)]",
1432
+ default: "h-[var(--control-height-md,2.5rem)] px-[var(--btn-default-padding-x,1rem)] py-[var(--btn-default-padding-y,0.5rem)]",
1433
+ lg: "h-[var(--control-height-lg,3rem)] rounded-[var(--radius-lg)] px-5 text-[length:var(--control-font-size-lg,1rem)]",
1434
+ icon: "h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)]"
706
1435
  },
707
1436
  shape: {
708
1437
  default: "",
@@ -711,16 +1440,30 @@ var buttonVariants = cva(
711
1440
  }
712
1441
  },
713
1442
  compoundVariants: [
714
- // shape="square" — width = height, no horizontal padding
715
- { shape: "square", size: "tiny", className: "w-6 px-0" },
716
- { shape: "square", size: "sm", className: "w-8 px-0" },
717
- { shape: "square", size: "default", className: "w-10 px-0" },
718
- { shape: "square", size: "lg", className: "w-12 px-0" },
719
- // shape="circle" — width = height + rounded-full
720
- { shape: "circle", size: "tiny", className: "w-6 px-0 rounded-full" },
721
- { shape: "circle", size: "sm", className: "w-8 px-0 rounded-full" },
722
- { shape: "circle", size: "default", className: "w-10 px-0 rounded-full" },
723
- { shape: "circle", size: "lg", className: "w-12 px-0 rounded-full" }
1443
+ { shape: "square", size: "tiny", className: "w-[var(--control-height-tiny,1.5rem)] px-0" },
1444
+ { shape: "square", size: "sm", className: "w-[var(--control-height-sm,2rem)] px-0" },
1445
+ { shape: "square", size: "default", className: "w-[var(--control-height-md,2.5rem)] px-0" },
1446
+ { shape: "square", size: "lg", className: "w-[var(--control-height-lg,3rem)] px-0" },
1447
+ {
1448
+ shape: "circle",
1449
+ size: "tiny",
1450
+ className: "w-[var(--control-height-tiny,1.5rem)] px-0 rounded-full"
1451
+ },
1452
+ {
1453
+ shape: "circle",
1454
+ size: "sm",
1455
+ className: "w-[var(--control-height-sm,2rem)] px-0 rounded-full"
1456
+ },
1457
+ {
1458
+ shape: "circle",
1459
+ size: "default",
1460
+ className: "w-[var(--control-height-md,2.5rem)] px-0 rounded-full"
1461
+ },
1462
+ {
1463
+ shape: "circle",
1464
+ size: "lg",
1465
+ className: "w-[var(--control-height-lg,3rem)] px-0 rounded-full"
1466
+ }
724
1467
  ],
725
1468
  defaultVariants: {
726
1469
  variant: "default",
@@ -774,7 +1517,7 @@ function getSpinnerSizeClass(size) {
774
1517
  var SHADOW_CLASSES = {
775
1518
  sm: "shadow-sm",
776
1519
  md: "shadow-md",
777
- lg: "shadow-lg"
1520
+ lg: "shadow-md"
778
1521
  };
779
1522
  function resolveShadowClass(shadow) {
780
1523
  if (!shadow) return void 0;
@@ -783,173 +1526,44 @@ function resolveShadowClass(shadow) {
783
1526
  }
784
1527
  function ButtonContent({ loading, prefix, suffix, size, children }) {
785
1528
  const iconSizeClass = getIconSizeClass(size);
786
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1529
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
787
1530
  loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size) }),
788
1531
  prefix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: prefix }),
789
1532
  children,
790
1533
  suffix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: suffix })
791
1534
  ] });
792
1535
  }
793
- var Button = React14.forwardRef(
794
- ({
795
- className,
796
- variant,
797
- size,
798
- shape,
799
- asChild = false,
800
- loading = false,
801
- disabled,
802
- prefix,
803
- suffix,
804
- shadow,
805
- children,
806
- ...props
807
- }, ref) => {
808
- const Comp = asChild ? Slot : "button";
809
- const isDisabled = disabled ?? loading;
810
- const shadowClass = resolveShadowClass(shadow);
811
- return /* @__PURE__ */ jsx(
812
- Comp,
813
- {
814
- ref,
815
- className: cn(buttonVariants({ variant, size, shape }), shadowClass, className),
816
- disabled: isDisabled,
817
- "aria-busy": loading || void 0,
818
- ...props,
819
- children: asChild ? children : /* @__PURE__ */ jsx(ButtonContent, { loading, prefix, suffix, size, children })
820
- }
821
- );
822
- }
823
- );
824
- Button.displayName = "Button";
825
- var ButtonLink = React14.forwardRef(
826
- ({
827
- className,
828
- variant,
829
- size,
830
- shape,
831
- prefix,
832
- suffix,
833
- shadow,
834
- loading = false,
835
- children,
836
- ...props
837
- }, ref) => {
838
- const shadowClass = resolveShadowClass(shadow);
839
- const loadingProps = loading ? {
840
- "aria-busy": "true",
841
- "aria-disabled": "true",
842
- tabIndex: -1
843
- } : {};
844
- return /* @__PURE__ */ jsx(
845
- "a",
846
- {
847
- ref,
848
- className: cn(
849
- buttonVariants({ variant, size, shape }),
850
- shadowClass,
851
- loading && "pointer-events-none opacity-50",
852
- className
853
- ),
854
- ...loadingProps,
855
- ...props,
856
- children: /* @__PURE__ */ jsx(ButtonContent, { loading, prefix, suffix, size, children })
857
- }
858
- );
859
- }
860
- );
861
- ButtonLink.displayName = "ButtonLink";
862
- ({
863
- // Nebutra Blue (云毓蓝) — technology & trust — VI: #0033FE
864
- blue50: colors.primary[50],
865
- blue100: colors.primary[100],
866
- blue200: colors.primary[200],
867
- blue300: colors.primary[300],
868
- blue400: colors.primary[400],
869
- blue500: colors.primary[500],
870
- // brand primary
871
- blue600: colors.primary[600],
872
- blue700: colors.primary[700],
873
- blue800: colors.primary[800],
874
- blue900: colors.primary[900],
875
- blue950: colors.primary[950],
876
- // Nebutra Cyan (云毓青) — data flow & intelligence — VI: #0BF1C3
877
- cyan50: colors.accent[50],
878
- cyan100: colors.accent[100],
879
- cyan200: colors.accent[200],
880
- cyan300: colors.accent[300],
881
- cyan400: colors.accent[400],
882
- cyan500: colors.accent[500],
883
- // brand secondary
884
- cyan600: colors.accent[600],
885
- cyan700: colors.accent[700],
886
- cyan800: colors.accent[800],
887
- cyan900: colors.accent[900],
888
- cyan950: colors.accent[950],
889
- // Neutral (blue-undertone gray scale)
890
- neutral50: colors.neutral[50],
891
- neutral100: colors.neutral[100],
892
- neutral200: colors.neutral[200],
893
- neutral300: colors.neutral[300],
894
- neutral400: colors.neutral[400],
895
- neutral500: colors.neutral[500],
896
- neutral600: colors.neutral[600],
897
- neutral700: colors.neutral[700],
898
- neutral800: colors.neutral[800],
899
- neutral900: colors.neutral[900],
900
- neutral950: colors.neutral[950],
901
- white: colors.white,
902
- black: colors.black
903
- });
904
- ({
905
- /** Hero sections, primary CTA buttons, logo fills — VI signature gradient */
906
- primary: colors.gradient.primary,
907
- /** Hover states, secondary gradient elements */
908
- reverse: colors.gradient.primaryReverse,
909
- /** Vertical layout dividers, page section separators */
910
- vertical: colors.gradient.primaryVertical,
911
- /** Background halos, focus glow effects, radial emphasis */
912
- radial: colors.gradient.primaryRadial});
913
- var primitiveSpacing = {
914
- 1: 4,
915
- 2: 8,
916
- 3: 12,
917
- 4: 16,
918
- 5: 20,
919
- 20: 80,
920
- 24: 96
921
- };
922
- var primitiveSizing = {
923
- /** Geist button-specific size (24px). Larger than xs by design. */
924
- tiny: 24,
925
- sm: 32,
926
- md: 40,
927
- lg: 48};
928
- var primitiveRadius = {
929
- md: 6,
930
- // Geist default — slightly more rounded than 4px
931
- lg: 8,
932
- full: 9999
933
- };
934
- var primitiveFontSize = {
935
- xs: 12,
936
- sm: 14,
937
- base: 16,
938
- lg: 18};
939
- var primitiveTransition = {
940
- duration: {
941
- // hover, focus, small state changes
942
- flow: 200},
943
- easing: {
944
- inOut: "cubic-bezier(0.4, 0, 0.2, 1)"
945
- }
946
- };
947
- var primitiveFocusRing = {
948
- width: 2,
949
- // px
950
- offset: 2
951
- // px — gap between element and ring
1536
+ var Button = ({
1537
+ className,
1538
+ variant,
1539
+ size,
1540
+ shape,
1541
+ asChild = false,
1542
+ loading = false,
1543
+ disabled,
1544
+ prefix,
1545
+ suffix,
1546
+ shadow,
1547
+ children,
1548
+ ref,
1549
+ ...props
1550
+ }) => {
1551
+ const Comp = asChild ? Slot : "button";
1552
+ const isDisabled = Boolean(disabled || loading);
1553
+ const shadowClass = resolveShadowClass(shadow);
1554
+ return /* @__PURE__ */ jsx(
1555
+ Comp,
1556
+ {
1557
+ ref,
1558
+ className: cn(buttonVariants({ variant, size, shape }), shadowClass, className),
1559
+ disabled: isDisabled,
1560
+ "aria-busy": loading || void 0,
1561
+ ...props,
1562
+ children: asChild ? children : /* @__PURE__ */ jsx(ButtonContent, { loading, prefix, suffix, size, children })
1563
+ }
1564
+ );
952
1565
  };
1566
+ Button.displayName = "Button";
953
1567
 
954
1568
  // src/tokens/components/tabs.ts
955
1569
  var tabsSizes = {
@@ -1030,8 +1644,13 @@ var Tooltip = ({
1030
1644
  const delay = delayDuration ?? DEFAULT_TOOLTIP_DELAY_MS;
1031
1645
  return /* @__PURE__ */ jsx(Tooltip$1.Provider, { delay, children: /* @__PURE__ */ jsx(Tooltip$1.Root, { ...props, children }) });
1032
1646
  };
1033
- var TooltipTrigger = React14.forwardRef(({ asChild, children, ...props }, ref) => {
1034
- if (asChild && React14.isValidElement(children)) {
1647
+ var TooltipTrigger = ({
1648
+ asChild,
1649
+ children,
1650
+ ref,
1651
+ ...props
1652
+ }) => {
1653
+ if (asChild && React.isValidElement(children)) {
1035
1654
  return /* @__PURE__ */ jsx(
1036
1655
  Tooltip$1.Trigger,
1037
1656
  {
@@ -1042,31 +1661,36 @@ var TooltipTrigger = React14.forwardRef(({ asChild, children, ...props }, ref) =
1042
1661
  );
1043
1662
  }
1044
1663
  return /* @__PURE__ */ jsx(Tooltip$1.Trigger, { ref, ...props, children });
1045
- });
1664
+ };
1046
1665
  TooltipTrigger.displayName = "TooltipTrigger";
1047
- var TooltipContent = React14.forwardRef(
1048
- ({ className, side = "top", align = "center", sideOffset = 4, alignOffset = 0, ...props }, ref) => /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(
1049
- Tooltip$1.Positioner,
1050
- {
1051
- side,
1052
- align,
1053
- sideOffset,
1054
- alignOffset,
1055
- className: "z-50",
1056
- children: /* @__PURE__ */ jsx(
1057
- Tooltip$1.Popup,
1058
- {
1059
- ref,
1060
- className: cn(
1061
- "z-50 overflow-hidden rounded-xl border bg-background/90 backdrop-blur-md px-3 py-1.5 text-sm text-popover-foreground shadow-xl transition-[opacity,transform,display] duration-200 data-starting-style:animate-in data-starting-style:fade-in-0 data-starting-style:zoom-in-95 data-ending-style:animate-out data-ending-style:fade-out-0 data-ending-style:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
1062
- className
1063
- ),
1064
- ...props
1065
- }
1066
- )
1067
- }
1068
- ) })
1069
- );
1666
+ var TooltipContent = ({
1667
+ className,
1668
+ style,
1669
+ side = "top",
1670
+ align = "center",
1671
+ sideOffset = 4,
1672
+ alignOffset = 0,
1673
+ ref,
1674
+ ...props
1675
+ }) => /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(
1676
+ Tooltip$1.Positioner,
1677
+ {
1678
+ side,
1679
+ align,
1680
+ sideOffset,
1681
+ alignOffset,
1682
+ style: { zIndex: overlayZIndex.tooltip },
1683
+ children: /* @__PURE__ */ jsx(
1684
+ Tooltip$1.Popup,
1685
+ {
1686
+ ref,
1687
+ className: cn(overlayClassNames.tooltipSurface, className),
1688
+ style: { zIndex: overlayZIndex.tooltip, ...style },
1689
+ ...props
1690
+ }
1691
+ )
1692
+ }
1693
+ ) });
1070
1694
  TooltipContent.displayName = "TooltipContent";
1071
1695
  var BaseRoot = withHtmlProps(Tabs$1.Root);
1072
1696
  var BaseList = withHtmlProps(Tabs$1.List);
@@ -1117,7 +1741,7 @@ var tabsTriggerVariants = cva(
1117
1741
  variants: {
1118
1742
  variant: {
1119
1743
  default: "hover:text-foreground data-[active]:text-foreground",
1120
- button: "border border-border bg-background text-muted-foreground shadow-[var(--shadow-xs)] hover:border-ring/40 hover:text-foreground data-[active]:border-ring/40 data-[active]:text-foreground",
1744
+ button: "border border-border bg-background text-muted-foreground shadow-xs hover:border-ring/40 hover:text-foreground data-[active]:border-ring/40 data-[active]:text-foreground",
1121
1745
  line: "min-w-0 rounded-none px-0 hover:text-foreground data-[active]:text-foreground",
1122
1746
  secondary: "hover:bg-muted hover:text-foreground data-[active]:bg-muted data-[active]:text-foreground"
1123
1747
  }
@@ -1132,7 +1756,7 @@ var tabsIndicatorVariants = cva(
1132
1756
  {
1133
1757
  variants: {
1134
1758
  variant: {
1135
- default: "z-[-1] rounded-[var(--tabs-trigger-radius)] bg-background shadow-[var(--shadow-xs)]",
1759
+ default: "z-[-1] rounded-[var(--tabs-trigger-radius)] bg-background shadow-xs",
1136
1760
  button: "z-[-1] rounded-[var(--tabs-trigger-radius)] bg-muted",
1137
1761
  line: "bottom-0 h-[var(--tabs-line-thickness)] rounded-[var(--tabs-pill-radius)] bg-foreground",
1138
1762
  secondary: "z-[-1] rounded-[var(--tabs-trigger-radius)] bg-muted"
@@ -1161,7 +1785,7 @@ var tabsContentVariants = cva(
1161
1785
  }
1162
1786
  }
1163
1787
  );
1164
- var TabsContext = React14.createContext({
1788
+ var TabsContext = React.createContext({
1165
1789
  activationMode: "manual",
1166
1790
  disabled: false,
1167
1791
  shape: "default",
@@ -1219,7 +1843,7 @@ function Tabs({
1219
1843
  }) {
1220
1844
  const rootValue = selected ?? value;
1221
1845
  const rootDefaultValue = defaultValue ?? getFirstEnabledValue(tabs);
1222
- const context = React14.useMemo(
1846
+ const context = React.useMemo(
1223
1847
  () => ({ activationMode, disabled, shape, size, variant }),
1224
1848
  [activationMode, disabled, shape, size, variant]
1225
1849
  );
@@ -1272,7 +1896,7 @@ function TabsCollection({
1272
1896
  children: tabs.map((tab) => /* @__PURE__ */ jsx(TabsCollectionTrigger, { disabled, tab }, tab.value))
1273
1897
  }
1274
1898
  );
1275
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1899
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1276
1900
  hasTooltip ? /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 150, children: list }) : list,
1277
1901
  tabs.map(
1278
1902
  (tab) => tab.content === void 0 ? null : /* @__PURE__ */ jsx(TabsContent, { value: tab.value, children: tab.content }, tab.value)
@@ -1305,11 +1929,11 @@ function TabsList({
1305
1929
  children,
1306
1930
  ...props
1307
1931
  }) {
1308
- const context = React14.useContext(TabsContext);
1932
+ const context = React.use(TabsContext);
1309
1933
  const resolvedVariant = variant ?? context.variant;
1310
1934
  const resolvedShape = shape ?? context.shape;
1311
1935
  const resolvedActivateOnFocus = activateOnFocus ?? context.activationMode === "automatic";
1312
- const listContext = React14.useMemo(
1936
+ const listContext = React.useMemo(
1313
1937
  () => ({ ...context, shape: resolvedShape, variant: resolvedVariant }),
1314
1938
  [context, resolvedShape, resolvedVariant]
1315
1939
  );
@@ -1346,7 +1970,7 @@ function TabsList({
1346
1970
  ) });
1347
1971
  }
1348
1972
  function TabsTrigger({ badge, children, className, disabled, icon, ...props }) {
1349
- const context = React14.useContext(TabsContext);
1973
+ const context = React.use(TabsContext);
1350
1974
  const isDisabled = disabled ?? context.disabled;
1351
1975
  return /* @__PURE__ */ jsxs(
1352
1976
  BaseTrigger,
@@ -1403,6 +2027,12 @@ var textareaTokens = {
1403
2027
  labelSize: primitiveFontSize.sm,
1404
2028
  focusRingWidth: 3,
1405
2029
  fieldGap: primitiveSpacing[2] - primitiveSpacing[1] / 2};
2030
+
2031
+ // src/primitives/form-control.ts
2032
+ var formControlFocusClassNames = {
2033
+ textarea: "outline-none focus:border-ring focus:ring-[length:var(--textarea-focus-ring-width)] focus:ring-ring/30"};
2034
+ var formControlInvalidClassNames = {
2035
+ textarea: "aria-invalid:border-destructive/60 aria-invalid:focus:border-destructive aria-invalid:focus:ring-destructive/20"};
1406
2036
  var fieldMessageClassName = "text-xs text-muted-foreground";
1407
2037
  var fieldErrorClassName = "text-xs font-medium text-destructive";
1408
2038
  function getTextareaStyle(size, style) {
@@ -1422,91 +2052,90 @@ function getTextareaStyle(size, style) {
1422
2052
  function getTextareaFieldStyle() {
1423
2053
  return {
1424
2054
  "--textarea-field-gap": `${textareaTokens.fieldGap}px`,
1425
- "--textarea-label-size": `${textareaTokens.labelSize}px`
1426
- };
1427
- }
1428
- function joinDescriptionIds(...ids) {
1429
- return ids.filter(Boolean).join(" ") || void 0;
1430
- }
1431
- function isInvalid(error, ariaInvalid) {
1432
- return error === true || typeof error === "string" || ariaInvalid === true || ariaInvalid === "true";
1433
- }
1434
- var Textarea = React14.forwardRef(
1435
- ({
1436
- className,
1437
- style,
1438
- size = "md",
1439
- label,
1440
- description,
1441
- error,
1442
- fieldClassName,
1443
- id,
1444
- onChange,
1445
- onValueChange,
1446
- "aria-describedby": ariaDescribedBy,
1447
- "aria-invalid": ariaInvalid,
1448
- ...props
1449
- }, ref) => {
1450
- const baseId = React14.useId();
1451
- const textareaId = id ?? (label || description || typeof error === "string" ? baseId : void 0);
1452
- const resolvedInvalid = isInvalid(error, ariaInvalid);
1453
- const descriptionId = description && textareaId ? `${textareaId}-description` : void 0;
1454
- const errorId = typeof error === "string" && textareaId ? `${textareaId}-error` : void 0;
1455
- const describedBy = joinDescriptionIds(ariaDescribedBy, descriptionId, errorId);
1456
- const handleChange = React14.useCallback(
1457
- (event) => {
1458
- onValueChange?.(event.currentTarget.value);
1459
- onChange?.(event);
1460
- },
1461
- [onChange, onValueChange]
1462
- );
1463
- const control = /* @__PURE__ */ jsx(
1464
- "textarea",
1465
- {
1466
- className: cn(
1467
- "flex min-h-[var(--textarea-min-height)] w-full resize-y rounded-[var(--textarea-radius)] border border-input bg-background",
1468
- "px-[var(--textarea-padding-x)] py-[var(--textarea-padding-y)] text-[length:var(--textarea-font-size)] text-foreground shadow-[var(--shadow-xs)]",
1469
- "transition-[background-color,border-color,box-shadow,color] duration-micro ease-out placeholder:text-muted-foreground",
1470
- "outline-none focus:border-ring focus:ring-[length:var(--textarea-focus-ring-width)] focus:ring-ring/30",
1471
- "disabled:cursor-not-allowed disabled:opacity-50 read-only:cursor-default read-only:bg-muted/70",
1472
- "aria-invalid:border-destructive/60 aria-invalid:focus:border-destructive aria-invalid:focus:ring-destructive/20",
1473
- className
1474
- ),
1475
- ref,
1476
- id: textareaId,
1477
- "aria-invalid": resolvedInvalid || void 0,
1478
- "aria-describedby": describedBy,
1479
- style: getTextareaStyle(size, style),
1480
- onChange: handleChange,
1481
- ...props
1482
- }
1483
- );
1484
- if (!label && !description && typeof error !== "string" && !fieldClassName) {
1485
- return control;
2055
+ "--textarea-label-size": `${textareaTokens.labelSize}px`
2056
+ };
2057
+ }
2058
+ function joinDescriptionIds(...ids) {
2059
+ return ids.filter(Boolean).join(" ") || void 0;
2060
+ }
2061
+ function isInvalid(error, ariaInvalid) {
2062
+ return error === true || typeof error === "string" || ariaInvalid === true || ariaInvalid === "true";
2063
+ }
2064
+ var Textarea = ({
2065
+ className,
2066
+ style,
2067
+ size = "md",
2068
+ label,
2069
+ description,
2070
+ error,
2071
+ fieldClassName,
2072
+ id,
2073
+ onChange,
2074
+ onValueChange,
2075
+ "aria-describedby": ariaDescribedBy,
2076
+ "aria-invalid": ariaInvalid,
2077
+ ref,
2078
+ ...props
2079
+ }) => {
2080
+ const baseId = React.useId();
2081
+ const textareaId = id ?? (label || description || typeof error === "string" ? baseId : void 0);
2082
+ const resolvedInvalid = isInvalid(error, ariaInvalid);
2083
+ const descriptionId = description && textareaId ? `${textareaId}-description` : void 0;
2084
+ const errorId = typeof error === "string" && textareaId ? `${textareaId}-error` : void 0;
2085
+ const describedBy = joinDescriptionIds(ariaDescribedBy, descriptionId, errorId);
2086
+ const handleChange = React.useCallback(
2087
+ (event) => {
2088
+ onValueChange?.(event.currentTarget.value);
2089
+ onChange?.(event);
2090
+ },
2091
+ [onChange, onValueChange]
2092
+ );
2093
+ const control = /* @__PURE__ */ jsx(
2094
+ "textarea",
2095
+ {
2096
+ className: cn(
2097
+ "flex min-h-[var(--textarea-min-height)] w-full resize-y rounded-[var(--textarea-radius)] border border-input bg-background",
2098
+ "px-[var(--textarea-padding-x)] py-[var(--textarea-padding-y)] text-[length:var(--textarea-font-size)] text-foreground shadow-xs",
2099
+ "transition-[background-color,border-color,box-shadow,color] duration-micro ease-out placeholder:text-muted-foreground",
2100
+ formControlFocusClassNames.textarea,
2101
+ "disabled:cursor-not-allowed disabled:opacity-50 read-only:cursor-default read-only:bg-muted/70",
2102
+ formControlInvalidClassNames.textarea,
2103
+ className
2104
+ ),
2105
+ ref,
2106
+ id: textareaId,
2107
+ "aria-invalid": resolvedInvalid || void 0,
2108
+ "aria-describedby": describedBy,
2109
+ style: getTextareaStyle(size, style),
2110
+ onChange: handleChange,
2111
+ ...props
1486
2112
  }
1487
- return /* @__PURE__ */ jsxs(
1488
- "div",
1489
- {
1490
- "data-slot": "textarea-field",
1491
- className: cn("grid gap-[var(--textarea-field-gap)]", fieldClassName),
1492
- style: getTextareaFieldStyle(),
1493
- children: [
1494
- label && /* @__PURE__ */ jsx(
1495
- "label",
1496
- {
1497
- htmlFor: textareaId,
1498
- className: "text-[length:var(--textarea-label-size)] font-medium text-foreground",
1499
- children: label
1500
- }
1501
- ),
1502
- control,
1503
- description && !error && /* @__PURE__ */ jsx("p", { id: descriptionId, className: fieldMessageClassName, children: description }),
1504
- typeof error === "string" && /* @__PURE__ */ jsx("p", { id: errorId, role: "alert", className: fieldErrorClassName, children: error })
1505
- ]
1506
- }
1507
- );
2113
+ );
2114
+ if (!label && !description && typeof error !== "string" && !fieldClassName) {
2115
+ return control;
1508
2116
  }
1509
- );
2117
+ return /* @__PURE__ */ jsxs(
2118
+ "div",
2119
+ {
2120
+ "data-slot": "textarea-field",
2121
+ className: cn("grid gap-[var(--textarea-field-gap)]", fieldClassName),
2122
+ style: getTextareaFieldStyle(),
2123
+ children: [
2124
+ label && /* @__PURE__ */ jsx(
2125
+ "label",
2126
+ {
2127
+ htmlFor: textareaId,
2128
+ className: "text-[length:var(--textarea-label-size)] font-medium text-foreground",
2129
+ children: label
2130
+ }
2131
+ ),
2132
+ control,
2133
+ description && !error && /* @__PURE__ */ jsx("p", { id: descriptionId, className: fieldMessageClassName, children: description }),
2134
+ typeof error === "string" && /* @__PURE__ */ jsx("p", { id: errorId, role: "alert", className: fieldErrorClassName, children: error })
2135
+ ]
2136
+ }
2137
+ );
2138
+ };
1510
2139
  Textarea.displayName = "Textarea";
1511
2140
  function MarkdownRenderer({ content, className }) {
1512
2141
  return /* @__PURE__ */ jsx("div", { className: cn("prose prose-sm dark:prose-invert max-w-none", className), children: /* @__PURE__ */ jsx(
@@ -1700,53 +2329,41 @@ function ToolbarButton({
1700
2329
  }
1701
2330
  );
1702
2331
  }
1703
- var Card2 = React14.forwardRef(
1704
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1705
- "div",
1706
- {
1707
- ref,
1708
- className: cn(
1709
- "rounded-[var(--radius-lg)] border border-border bg-card text-card-foreground shadow-sm",
1710
- className
1711
- ),
1712
- ...props
1713
- }
1714
- )
1715
- );
1716
- Card2.displayName = "Card";
1717
- var CardHeader2 = React14.forwardRef(
1718
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })
1719
- );
1720
- CardHeader2.displayName = "CardHeader";
1721
- var CardTitle2 = React14.forwardRef(
1722
- ({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
1723
- "h3",
1724
- {
1725
- ref,
1726
- className: cn("text-2xl font-semibold leading-none tracking-tight", className),
1727
- ...props,
1728
- children
1729
- }
1730
- )
1731
- );
1732
- CardTitle2.displayName = "CardTitle";
1733
- var CardDescription2 = React14.forwardRef(({ className, as: Tag = "p", ...props }, ref) => {
1734
- return React14.createElement(Tag, {
2332
+ var Card2 = ({
2333
+ className,
2334
+ ref,
2335
+ ...props
2336
+ }) => /* @__PURE__ */ jsx(
2337
+ "div",
2338
+ {
1735
2339
  ref,
1736
- className: cn("text-sm text-muted-foreground", className),
2340
+ className: cn(
2341
+ "rounded-[var(--radius-lg)] border border-border bg-card text-card-foreground shadow-sm",
2342
+ className
2343
+ ),
1737
2344
  ...props
1738
- });
1739
- });
1740
- CardDescription2.displayName = "CardDescription";
1741
- var CardContent = React14.forwardRef(
1742
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props })
2345
+ }
1743
2346
  );
2347
+ Card2.displayName = "Card";
2348
+ var CardHeader2 = ({
2349
+ className,
2350
+ ref,
2351
+ ...props
2352
+ }) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props });
2353
+ CardHeader2.displayName = "CardHeader";
2354
+ var CardContent = ({
2355
+ className,
2356
+ ref,
2357
+ ...props
2358
+ }) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props });
1744
2359
  CardContent.displayName = "CardContent";
1745
- var CardFooter2 = React14.forwardRef(
1746
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center p-6 pt-0", className), ...props })
1747
- );
1748
- CardFooter2.displayName = "CardFooter";
1749
- var Separator = React14.forwardRef(({ className, orientation = "horizontal", decorative: _decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
2360
+ var Separator = ({
2361
+ className,
2362
+ orientation = "horizontal",
2363
+ decorative: _decorative = true,
2364
+ ref,
2365
+ ...props
2366
+ }) => /* @__PURE__ */ jsx(
1750
2367
  Separator$1,
1751
2368
  {
1752
2369
  ref,
@@ -1758,7 +2375,7 @@ var Separator = React14.forwardRef(({ className, orientation = "horizontal", dec
1758
2375
  ),
1759
2376
  ...props
1760
2377
  }
1761
- ));
2378
+ );
1762
2379
  Separator.displayName = "Separator";
1763
2380
  var sizeClasses = {
1764
2381
  xs: { root: "h-5 w-5", fallback: "text-[8px]" },
@@ -1768,7 +2385,7 @@ var sizeClasses = {
1768
2385
  xl: { root: "h-20 w-20", fallback: "text-2xl" }
1769
2386
  };
1770
2387
  var numericAvatarClass = "h-[var(--avatar-size)] w-[var(--avatar-size)]";
1771
- var AvatarContext = React14.createContext(null);
2388
+ var AvatarContext = React.createContext(null);
1772
2389
  function isPresetSize(size) {
1773
2390
  return typeof size === "string";
1774
2391
  }
@@ -1800,77 +2417,86 @@ function normalizeAvatarLabel({
1800
2417
  }) {
1801
2418
  return title ?? alt ?? username ?? "Avatar";
1802
2419
  }
1803
- var Avatar = React14.forwardRef(
1804
- ({
1805
- className,
1806
- size = "md",
1807
- src,
1808
- alt,
1809
- title,
1810
- letter,
1811
- username,
1812
- placeholder,
1813
- fallbackDelayMs,
1814
- children,
1815
- style,
1816
- ...props
1817
- }, ref) => {
1818
- const label = normalizeAvatarLabel({ alt, title, username });
1819
- const fallback = letter ?? getAvatarInitials(title ?? username ?? alt ?? "");
1820
- const contextTitle = title ?? alt ?? username;
1821
- const contextValue = contextTitle === void 0 ? { size } : { size, title: contextTitle };
1822
- const shouldRenderConvenienceContent = children === void 0 && (src !== void 0 || placeholder === true || fallback.length > 0);
1823
- return /* @__PURE__ */ jsx(AvatarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
1824
- Avatar$1.Root,
1825
- {
1826
- ref,
1827
- className: cn(
1828
- "relative flex shrink-0 overflow-hidden rounded-full bg-muted",
1829
- getAvatarRootClass(size),
1830
- className
1831
- ),
1832
- style: getAvatarStyle(size, style),
1833
- ...props,
1834
- children: shouldRenderConvenienceContent ? /* @__PURE__ */ jsxs(Fragment, { children: [
1835
- src && /* @__PURE__ */ jsx(AvatarImage, { src, alt: label }),
1836
- /* @__PURE__ */ jsx(AvatarFallback, { size, delay: fallbackDelayMs, children: placeholder ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading avatar" }) : fallback })
1837
- ] }) : children
1838
- }
1839
- ) });
1840
- }
1841
- );
2420
+ var Avatar = ({
2421
+ className,
2422
+ size = "md",
2423
+ src,
2424
+ alt,
2425
+ title,
2426
+ letter,
2427
+ username,
2428
+ placeholder,
2429
+ fallbackDelayMs,
2430
+ children,
2431
+ style,
2432
+ ref,
2433
+ ...props
2434
+ }) => {
2435
+ const label = normalizeAvatarLabel({ alt, title, username });
2436
+ const fallback = letter ?? getAvatarInitials(title ?? username ?? alt ?? "");
2437
+ const contextTitle = title ?? alt ?? username;
2438
+ const contextValue = contextTitle === void 0 ? { size } : { size, title: contextTitle };
2439
+ const shouldRenderConvenienceContent = children === void 0 && (src !== void 0 || placeholder === true || fallback.length > 0);
2440
+ return /* @__PURE__ */ jsx(AvatarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
2441
+ Avatar$1.Root,
2442
+ {
2443
+ ref,
2444
+ className: cn(
2445
+ "relative flex shrink-0 overflow-hidden rounded-full bg-muted",
2446
+ getAvatarRootClass(size),
2447
+ className
2448
+ ),
2449
+ style: getAvatarStyle(size, style),
2450
+ ...props,
2451
+ children: shouldRenderConvenienceContent ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
2452
+ src && /* @__PURE__ */ jsx(AvatarImage, { src, alt: label }),
2453
+ /* @__PURE__ */ jsx(AvatarFallback, { size, delay: fallbackDelayMs, children: placeholder ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading avatar" }) : fallback })
2454
+ ] }) : children
2455
+ }
2456
+ ) });
2457
+ };
1842
2458
  Avatar.displayName = "Avatar";
1843
- var AvatarImage = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2459
+ var AvatarImage = ({
2460
+ className,
2461
+ ref,
2462
+ ...props
2463
+ }) => /* @__PURE__ */ jsx(
1844
2464
  Avatar$1.Image,
1845
2465
  {
1846
2466
  ref,
1847
2467
  className: cn("aspect-square h-full w-full object-cover", className),
1848
2468
  ...props
1849
2469
  }
1850
- ));
1851
- AvatarImage.displayName = "AvatarImage";
1852
- var AvatarFallback = React14.forwardRef(
1853
- ({ className, size, children, "aria-label": ariaLabel, style, ...props }, ref) => {
1854
- const context = React14.useContext(AvatarContext);
1855
- const resolvedSize = size ?? context?.size ?? "md";
1856
- const fallbackLabel = ariaLabel ?? (typeof children === "string" && children.trim().length > 0 ? `Avatar with initials: ${children}` : context?.title);
1857
- return /* @__PURE__ */ jsx(
1858
- Avatar$1.Fallback,
1859
- {
1860
- ref,
1861
- "aria-label": fallbackLabel,
1862
- className: cn(
1863
- "flex h-full w-full items-center justify-center rounded-full bg-muted font-medium text-muted-foreground",
1864
- getAvatarFallbackClass(resolvedSize),
1865
- className
1866
- ),
1867
- style: getAvatarStyle(resolvedSize, style),
1868
- ...props,
1869
- children
1870
- }
1871
- );
1872
- }
1873
2470
  );
2471
+ AvatarImage.displayName = "AvatarImage";
2472
+ var AvatarFallback = ({
2473
+ className,
2474
+ size,
2475
+ children,
2476
+ "aria-label": ariaLabel,
2477
+ style,
2478
+ ref,
2479
+ ...props
2480
+ }) => {
2481
+ const context = React.use(AvatarContext);
2482
+ const resolvedSize = size ?? context?.size ?? "md";
2483
+ const fallbackLabel = ariaLabel ?? (typeof children === "string" && children.trim().length > 0 ? `Avatar with initials: ${children}` : context?.title);
2484
+ return /* @__PURE__ */ jsx(
2485
+ Avatar$1.Fallback,
2486
+ {
2487
+ ref,
2488
+ "aria-label": fallbackLabel,
2489
+ className: cn(
2490
+ "flex h-full w-full items-center justify-center rounded-full bg-muted font-medium text-muted-foreground",
2491
+ getAvatarFallbackClass(resolvedSize),
2492
+ className
2493
+ ),
2494
+ style: getAvatarStyle(resolvedSize, style),
2495
+ ...props,
2496
+ children
2497
+ }
2498
+ );
2499
+ };
1874
2500
  AvatarFallback.displayName = "AvatarFallback";
1875
2501
  function initials(name) {
1876
2502
  return name.split(/\s+/).map((part) => part.charAt(0).toUpperCase()).join("").slice(0, 2);
@@ -2113,7 +2739,7 @@ function QAPage({
2113
2739
  " ",
2114
2740
  answers.length === 1 ? "Answer" : "Answers"
2115
2741
  ] }) }),
2116
- /* @__PURE__ */ jsx("div", { className: "mb-8", children: sortedAnswers.map((answer, index) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
2742
+ /* @__PURE__ */ jsx("div", { className: "mb-8", children: sortedAnswers.map((answer, index) => /* @__PURE__ */ jsxs(Fragment, { children: [
2117
2743
  /* @__PURE__ */ jsx(Card2, { className: cn("mb-6", answer.isAccepted && "ring-2 ring-success/40"), children: /* @__PURE__ */ jsxs(CardContent, { className: "flex gap-6 p-6", children: [
2118
2744
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4", children: [
2119
2745
  /* @__PURE__ */ jsx(
@@ -2213,12 +2839,21 @@ function PostActions({
2213
2839
  /* @__PURE__ */ jsx(UserInfo, { author, timestamp, verb })
2214
2840
  ] });
2215
2841
  }
2216
- var CollapsibleContext = React14.createContext({});
2217
- var Collapsible = React14.forwardRef(({ className, open: openProp, defaultOpen, onOpenChange, disabled, children, ...props }, ref) => {
2218
- const [uncontrolledOpen, setUncontrolledOpen] = React14.useState(defaultOpen || false);
2842
+ var CollapsibleContext = React.createContext({});
2843
+ var Collapsible = ({
2844
+ className,
2845
+ open: openProp,
2846
+ defaultOpen,
2847
+ onOpenChange,
2848
+ disabled,
2849
+ children,
2850
+ ref,
2851
+ ...props
2852
+ }) => {
2853
+ const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen || false);
2219
2854
  const isControlled = openProp !== void 0;
2220
2855
  const open = isControlled ? openProp : uncontrolledOpen;
2221
- const handleOpenChange = React14.useCallback(
2856
+ const handleOpenChange = React.useCallback(
2222
2857
  (nextOpen) => {
2223
2858
  if (!isControlled) {
2224
2859
  setUncontrolledOpen(nextOpen);
@@ -2238,11 +2873,17 @@ var Collapsible = React14.forwardRef(({ className, open: openProp, defaultOpen,
2238
2873
  children
2239
2874
  }
2240
2875
  ) });
2241
- });
2876
+ };
2242
2877
  Collapsible.displayName = "Collapsible";
2243
- var CollapsibleTrigger = React14.forwardRef(({ className, asChild, children, ...props }, ref) => {
2244
- const { open, onOpenChange, disabled } = React14.useContext(CollapsibleContext);
2245
- const handleClick = React14.useCallback(
2878
+ var CollapsibleTrigger = ({
2879
+ className,
2880
+ asChild,
2881
+ children,
2882
+ ref,
2883
+ ...props
2884
+ }) => {
2885
+ const { open, onOpenChange, disabled } = React.use(CollapsibleContext);
2886
+ const handleClick = React.useCallback(
2246
2887
  (e) => {
2247
2888
  if (disabled) return;
2248
2889
  onOpenChange?.(!open);
@@ -2250,8 +2891,8 @@ var CollapsibleTrigger = React14.forwardRef(({ className, asChild, children, ...
2250
2891
  },
2251
2892
  [disabled, open, onOpenChange, props.onClick]
2252
2893
  );
2253
- if (asChild && React14.isValidElement(children)) {
2254
- return React14.cloneElement(children, {
2894
+ if (asChild && React.isValidElement(children)) {
2895
+ return React.cloneElement(children, {
2255
2896
  ref,
2256
2897
  onClick: handleClick,
2257
2898
  "data-state": open ? "open" : "closed",
@@ -2277,36 +2918,40 @@ var CollapsibleTrigger = React14.forwardRef(({ className, asChild, children, ...
2277
2918
  children
2278
2919
  }
2279
2920
  );
2280
- });
2921
+ };
2281
2922
  CollapsibleTrigger.displayName = "CollapsibleTrigger";
2282
- var CollapsibleContent = React14.forwardRef(
2283
- ({ className, children, ...props }, ref) => {
2284
- const { open } = React14.useContext(CollapsibleContext);
2285
- return /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: open && /* @__PURE__ */ jsx(
2286
- motion.div,
2287
- {
2288
- initial: "collapsed",
2289
- animate: "open",
2290
- exit: "collapsed",
2291
- variants: {
2292
- open: { opacity: 1, height: "auto" },
2293
- collapsed: { opacity: 0, height: 0 }
2294
- },
2295
- transition: { duration: 0.3, ease: [0.04, 0.62, 0.23, 0.98] },
2296
- className: "overflow-hidden",
2297
- children: /* @__PURE__ */ jsx("div", { ref, "data-state": "open", className: cn("", className), ...props, children })
2923
+ var CollapsibleContent = ({
2924
+ className,
2925
+ children,
2926
+ ref,
2927
+ ...props
2928
+ }) => {
2929
+ const { open } = React.use(CollapsibleContext);
2930
+ const shouldReduceMotion = useReducedMotion();
2931
+ return /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: open && /* @__PURE__ */ jsx(
2932
+ motion.div,
2933
+ {
2934
+ initial: "collapsed",
2935
+ animate: "open",
2936
+ exit: "collapsed",
2937
+ variants: {
2938
+ open: { opacity: 1, height: "auto" },
2939
+ collapsed: { opacity: 0, height: 0 }
2298
2940
  },
2299
- "content"
2300
- ) });
2301
- }
2302
- );
2941
+ transition: shouldReduceMotion ? { duration: 0 } : { duration: 0.3, ease: [0.04, 0.62, 0.23, 0.98] },
2942
+ className: "overflow-hidden",
2943
+ children: /* @__PURE__ */ jsx("div", { ref, "data-state": "open", className: cn("", className), ...props, children })
2944
+ },
2945
+ "content"
2946
+ ) });
2947
+ };
2303
2948
  CollapsibleContent.displayName = "CollapsibleContent";
2304
- var ITEM_BASE_CLASSES = "flex items-center gap-2 rounded-md px-2.5 py-1.5 text-[13px] leading-5 transition-colors";
2305
- var ITEM_DEFAULT_CLASSES = "text-foreground hover:bg-accent hover:text-accent-foreground";
2306
- var ITEM_ACTIVE_CLASSES = "bg-accent text-accent-foreground font-medium";
2949
+ var ITEM_BASE_CLASSES = "group flex min-h-8 items-center gap-2 rounded-[var(--radius-md)] px-2.5 py-1.5 text-[13px] leading-5 transition-[background-color,color,box-shadow,transform]";
2950
+ var ITEM_DEFAULT_CLASSES = "text-sidebar-foreground/72 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground";
2951
+ var ITEM_ACTIVE_CLASSES = "bg-sidebar-primary text-sidebar-primary-foreground font-medium shadow-sm shadow-sidebar-primary/10 hover:bg-sidebar-primary hover:text-sidebar-primary-foreground";
2307
2952
  var ITEM_DISABLED_CLASSES = "opacity-50 pointer-events-none";
2308
2953
  var ITEM_COLLAPSED_CLASSES = "justify-center px-0 size-8 mx-auto";
2309
- var ICON_CLASSES = "size-3.5 shrink-0";
2954
+ var ICON_CLASSES = "size-4 shrink-0";
2310
2955
  function defaultRenderLink({
2311
2956
  href,
2312
2957
  children,
@@ -2335,12 +2980,12 @@ function ItemContent({
2335
2980
  }) {
2336
2981
  const Icon = item.icon;
2337
2982
  if (collapsed) {
2338
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2983
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
2339
2984
  Icon ? /* @__PURE__ */ jsx(Icon, { className: ICON_CLASSES }) : null,
2340
2985
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: item.label })
2341
2986
  ] });
2342
2987
  }
2343
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2988
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
2344
2989
  Icon ? /* @__PURE__ */ jsx(Icon, { className: ICON_CLASSES }) : null,
2345
2990
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: item.label }),
2346
2991
  item.badge ? /* @__PURE__ */ jsx(Badge, { variant: item.badge.tone, size: "sm", children: item.badge.label }) : null,
@@ -2348,7 +2993,7 @@ function ItemContent({
2348
2993
  ChevronRight,
2349
2994
  {
2350
2995
  className: cn(
2351
- "h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform",
2996
+ "size-3.5 shrink-0 text-muted-foreground transition-transform",
2352
2997
  chevronOpen && "rotate-90"
2353
2998
  ),
2354
2999
  "aria-hidden": "true"
@@ -2431,11 +3076,22 @@ function ParentItem({
2431
3076
  itemClassName,
2432
3077
  renderLink
2433
3078
  }) {
2434
- const hasActiveChild = React14.useMemo(
2435
- () => item.children?.some((c) => c.isActive === true) ?? false,
2436
- [item.children]
3079
+ const hasActiveChild = item.children?.some((c) => c.isActive === true) ?? false;
3080
+ const [uncontrolledOpen, setUncontrolledOpen] = React.useState(
3081
+ item.isActive === true || hasActiveChild
3082
+ );
3083
+ const isControlled = item.expanded !== void 0 && item.onExpandedChange !== void 0;
3084
+ const open = isControlled ? item.expanded : uncontrolledOpen;
3085
+ const setOpen = React.useCallback(
3086
+ (next) => {
3087
+ if (isControlled) {
3088
+ item.onExpandedChange?.(next);
3089
+ } else {
3090
+ setUncontrolledOpen(next);
3091
+ }
3092
+ },
3093
+ [isControlled, item.onExpandedChange]
2437
3094
  );
2438
- const [open, setOpen] = React14.useState(item.isActive === true || hasActiveChild);
2439
3095
  if (collapsed) {
2440
3096
  return /* @__PURE__ */ jsx(
2441
3097
  InteractiveItem,
@@ -2491,48 +3147,69 @@ function SidebarNav({
2491
3147
  "nav",
2492
3148
  {
2493
3149
  "aria-label": "Sidebar",
3150
+ "data-ui": "nebutra-sidebar-nav",
2494
3151
  className: cn(
2495
- "flex h-full flex-col gap-4",
2496
- collapsed ? "px-2 py-2.5" : "px-2.5 py-3",
3152
+ "flex h-full flex-col",
3153
+ collapsed ? "gap-3 px-2 py-3" : "gap-5 px-3 py-4",
2497
3154
  className
2498
3155
  ),
2499
3156
  children: [
2500
3157
  header ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: header }) : null,
2501
- /* @__PURE__ */ jsx("div", { className: "flex-1 space-y-4 overflow-y-auto", children: sections.map((section) => /* @__PURE__ */ jsxs("div", { children: [
2502
- section.label && !collapsed ? /* @__PURE__ */ jsx("div", { className: "mb-1.5 px-2.5 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: section.label }) : null,
2503
- /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-0.5", children: section.items.map((item) => {
2504
- const hasChildren = Array.isArray(item.children) && item.children.length > 0;
2505
- return /* @__PURE__ */ jsx("li", { children: hasChildren ? /* @__PURE__ */ jsx(
2506
- ParentItem,
2507
- {
2508
- item,
2509
- collapsed,
2510
- itemClassName,
2511
- renderLink
2512
- }
2513
- ) : /* @__PURE__ */ jsx(
2514
- InteractiveItem,
2515
- {
2516
- item,
2517
- collapsed,
2518
- itemClassName,
2519
- renderLink
2520
- }
2521
- ) }, item.id);
2522
- }) })
2523
- ] }, section.id)) }),
2524
- footer ? /* @__PURE__ */ jsx("div", { className: "shrink-0 border-t border-border pt-3", children: footer }) : null
3158
+ /* @__PURE__ */ jsx("div", { className: "flex-1 space-y-4 overflow-y-auto", children: sections.map((section) => {
3159
+ const visibleActions = !collapsed && section.actions && section.actions.length > 0 ? section.actions.slice(0, 3) : null;
3160
+ return /* @__PURE__ */ jsxs("section", { className: "group/section", children: [
3161
+ section.label && !collapsed ? /* @__PURE__ */ jsxs("div", { className: "mb-1.5 flex items-center justify-between px-2.5", children: [
3162
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-sidebar-foreground/45", children: section.label }),
3163
+ visibleActions ? /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 opacity-0 transition-opacity duration-150 group-hover/section:opacity-100 focus-within:opacity-100", children: visibleActions.map((action) => {
3164
+ const ActionIcon = action.icon;
3165
+ const defaultButton = /* @__PURE__ */ jsx(
3166
+ "button",
3167
+ {
3168
+ type: "button",
3169
+ "aria-label": action.label,
3170
+ title: action.label,
3171
+ onClick: action.onClick,
3172
+ className: "inline-flex size-4 items-center justify-center rounded text-sidebar-foreground/50 transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3173
+ children: /* @__PURE__ */ jsx(ActionIcon, { className: "size-3" })
3174
+ }
3175
+ );
3176
+ return /* @__PURE__ */ jsx("span", { className: "contents", children: action.render ? action.render(defaultButton) : defaultButton }, action.id);
3177
+ }) }) : null
3178
+ ] }) : null,
3179
+ /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-0.5", children: section.items.map((item) => {
3180
+ const hasChildren = Array.isArray(item.children) && item.children.length > 0;
3181
+ return /* @__PURE__ */ jsx("li", { children: hasChildren ? /* @__PURE__ */ jsx(
3182
+ ParentItem,
3183
+ {
3184
+ item,
3185
+ collapsed,
3186
+ itemClassName,
3187
+ renderLink
3188
+ }
3189
+ ) : /* @__PURE__ */ jsx(
3190
+ InteractiveItem,
3191
+ {
3192
+ item,
3193
+ collapsed,
3194
+ itemClassName,
3195
+ renderLink
3196
+ }
3197
+ ) }, item.id);
3198
+ }) })
3199
+ ] }, section.id);
3200
+ }) }),
3201
+ footer ? /* @__PURE__ */ jsx("div", { className: "shrink-0 border-t border-sidebar-border pt-3", children: footer }) : null
2525
3202
  ]
2526
3203
  }
2527
3204
  ) });
2528
3205
  }
2529
- var TerminalContext = React14.createContext(null);
3206
+ var TerminalContext = React.createContext(null);
2530
3207
  var variantStyles2 = {
2531
- default: "bg-[var(--neutral-2)] border border-[var(--neutral-7)]",
2532
- minimal: "bg-[var(--neutral-1)] border border-[var(--neutral-7)]",
2533
- glass: "bg-[var(--neutral-2)] backdrop-blur-md border border-[var(--neutral-7)]"
3208
+ default: "bg-muted border border-border",
3209
+ minimal: "bg-background border border-border",
3210
+ glass: "bg-muted backdrop-blur-md border border-border"
2534
3211
  };
2535
- var TerminalRoot = React14.forwardRef(
3212
+ var TerminalRoot = React.forwardRef(
2536
3213
  ({ className, variant = "default", children, ...props }, ref) => {
2537
3214
  return /* @__PURE__ */ jsx(TerminalContext.Provider, { value: { variant }, children: /* @__PURE__ */ jsx(
2538
3215
  "div",
@@ -2550,14 +3227,14 @@ var TerminalRoot = React14.forwardRef(
2550
3227
  }
2551
3228
  );
2552
3229
  TerminalRoot.displayName = "Terminal";
2553
- var TerminalHeader = React14.forwardRef(
3230
+ var TerminalHeader = React.forwardRef(
2554
3231
  ({ className, title, showControls = true, children, ...props }, ref) => {
2555
3232
  return /* @__PURE__ */ jsxs(
2556
3233
  "div",
2557
3234
  {
2558
3235
  ref,
2559
3236
  className: cn(
2560
- "flex items-center gap-2 px-4 py-3 border-b border-[var(--neutral-7)] bg-[var(--neutral-3)]",
3237
+ "flex items-center gap-2 px-4 py-3 border-b border-border bg-muted",
2561
3238
  className
2562
3239
  ),
2563
3240
  ...props,
@@ -2567,7 +3244,7 @@ var TerminalHeader = React14.forwardRef(
2567
3244
  /* @__PURE__ */ jsx("span", { className: "w-3 h-3 rounded-full bg-yellow-500/80", "aria-hidden": true }),
2568
3245
  /* @__PURE__ */ jsx("span", { className: "w-3 h-3 rounded-full bg-green-500/80", "aria-hidden": true })
2569
3246
  ] }),
2570
- title && /* @__PURE__ */ jsx("span", { className: "ml-2 text-xs text-[var(--neutral-9)]", children: title }),
3247
+ title && /* @__PURE__ */ jsx("span", { className: "ml-2 text-xs text-muted-foreground", children: title }),
2571
3248
  children
2572
3249
  ]
2573
3250
  }
@@ -2575,13 +3252,13 @@ var TerminalHeader = React14.forwardRef(
2575
3252
  }
2576
3253
  );
2577
3254
  TerminalHeader.displayName = "Terminal.Header";
2578
- var TerminalBody = React14.forwardRef(
3255
+ var TerminalBody = React.forwardRef(
2579
3256
  ({ className, children, ...props }, ref) => {
2580
3257
  return /* @__PURE__ */ jsx("div", { ref, className: cn("p-4 space-y-1", className), ...props, children });
2581
3258
  }
2582
3259
  );
2583
3260
  TerminalBody.displayName = "Terminal.Body";
2584
- var TerminalLine = React14.forwardRef(
3261
+ var TerminalLine = React.forwardRef(
2585
3262
  ({ className, prompt = "$", output = false, highlight = false, children, ...props }, ref) => {
2586
3263
  return /* @__PURE__ */ jsxs(
2587
3264
  "div",
@@ -2589,19 +3266,13 @@ var TerminalLine = React14.forwardRef(
2589
3266
  ref,
2590
3267
  className: cn(
2591
3268
  "flex items-start gap-2",
2592
- highlight && "bg-[var(--neutral-3)] -mx-2 px-2 py-0.5 rounded",
3269
+ highlight && "bg-muted -mx-2 px-2 py-0.5 rounded",
2593
3270
  className
2594
3271
  ),
2595
3272
  ...props,
2596
3273
  children: [
2597
3274
  !output && /* @__PURE__ */ jsx("span", { className: "text-emerald-400 shrink-0 select-none", children: prompt }),
2598
- /* @__PURE__ */ jsx(
2599
- "span",
2600
- {
2601
- className: cn("flex-1", output ? "text-[var(--neutral-9)]" : "text-[var(--neutral-11)]"),
2602
- children
2603
- }
2604
- )
3275
+ /* @__PURE__ */ jsx("span", { className: cn("flex-1", output ? "text-muted-foreground" : "text-muted-foreground"), children })
2605
3276
  ]
2606
3277
  }
2607
3278
  );
@@ -2642,7 +3313,7 @@ function subscribePlatform() {
2642
3313
  return () => void 0;
2643
3314
  }
2644
3315
  function usePlatform() {
2645
- return React14.useSyncExternalStore(subscribePlatform, getClientPlatform, () => "apple");
3316
+ return React.useSyncExternalStore(subscribePlatform, getClientPlatform, () => "apple");
2646
3317
  }
2647
3318
  function normalizeKey(children) {
2648
3319
  if (typeof children !== "string") {
@@ -2657,41 +3328,50 @@ function normalizeKey(children) {
2657
3328
  function getModifierSymbols(platform) {
2658
3329
  return platform === "apple" ? appleModifierSymbols : otherModifierSymbols;
2659
3330
  }
2660
- var Kbd = React14.forwardRef(
2661
- ({ meta, shift, alt, ctrl, small, children, className, "aria-label": ariaLabel, ...props }, ref) => {
2662
- const platform = usePlatform();
2663
- const symbols = getModifierSymbols(platform);
2664
- const activeModifiers = modifierOrder.filter((modifier) => {
2665
- if (modifier === "meta") return meta;
2666
- if (modifier === "shift") return shift;
2667
- if (modifier === "alt") return alt;
2668
- return ctrl;
2669
- });
2670
- const normalizedKey = normalizeKey(children);
2671
- const visualParts = [
2672
- ...activeModifiers.map((modifier) => symbols[modifier]),
2673
- normalizedKey
2674
- ].filter(Boolean);
2675
- const accessibleName = ariaLabel ?? [
2676
- ...activeModifiers.map((modifier) => modifierLabels[modifier]),
2677
- typeof normalizedKey === "string" ? normalizedKey : void 0
2678
- ].filter(Boolean).join(" ");
2679
- return /* @__PURE__ */ jsx(
2680
- "kbd",
2681
- {
2682
- ref,
2683
- "aria-label": accessibleName || void 0,
2684
- className: cn(
2685
- "inline-flex select-none items-center justify-center gap-0.5 rounded-[var(--radius-sm)] border border-border bg-muted font-mono font-medium leading-none text-muted-foreground tabular-nums",
2686
- small ? "min-h-4 min-w-4 px-1 py-0 text-xs" : "min-h-5 min-w-5 px-1.5 py-0.5 text-xs",
2687
- className
2688
- ),
2689
- ...props,
2690
- children: visualParts.join("")
2691
- }
2692
- );
2693
- }
2694
- );
3331
+ var Kbd = ({
3332
+ meta,
3333
+ shift,
3334
+ alt,
3335
+ ctrl,
3336
+ small,
3337
+ children,
3338
+ className,
3339
+ "aria-label": ariaLabel,
3340
+ ref,
3341
+ ...props
3342
+ }) => {
3343
+ const platform = usePlatform();
3344
+ const symbols = getModifierSymbols(platform);
3345
+ const activeModifiers = modifierOrder.filter((modifier) => {
3346
+ if (modifier === "meta") return meta;
3347
+ if (modifier === "shift") return shift;
3348
+ if (modifier === "alt") return alt;
3349
+ return ctrl;
3350
+ });
3351
+ const normalizedKey = normalizeKey(children);
3352
+ const visualParts = [
3353
+ ...activeModifiers.map((modifier) => symbols[modifier]),
3354
+ normalizedKey
3355
+ ].filter(Boolean);
3356
+ const accessibleName = ariaLabel ?? [
3357
+ ...activeModifiers.map((modifier) => modifierLabels[modifier]),
3358
+ typeof normalizedKey === "string" ? normalizedKey : void 0
3359
+ ].filter(Boolean).join(" ");
3360
+ return /* @__PURE__ */ jsx(
3361
+ "kbd",
3362
+ {
3363
+ ref,
3364
+ "aria-label": accessibleName || void 0,
3365
+ className: cn(
3366
+ "inline-flex select-none items-center justify-center gap-0.5 rounded-[var(--radius-sm)] border border-border bg-muted font-mono font-medium leading-none text-muted-foreground tabular-nums",
3367
+ small ? "min-h-4 min-w-4 px-1 py-0 text-xs" : "min-h-5 min-w-5 px-1.5 py-0.5 text-xs",
3368
+ className
3369
+ ),
3370
+ ...props,
3371
+ children: visualParts.join("")
3372
+ }
3373
+ );
3374
+ };
2695
3375
  Kbd.displayName = "Kbd";
2696
3376
  function computeInitials(user) {
2697
3377
  if (user.initials && user.initials.trim().length > 0) {
@@ -2716,20 +3396,20 @@ function DefaultTrigger({ user }) {
2716
3396
  "aria-label": "Open user menu",
2717
3397
  className: cn(
2718
3398
  "inline-flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full",
2719
- "outline-none transition-all hover:opacity-90",
3399
+ "outline-none transition-[box-shadow,opacity] hover:opacity-90",
2720
3400
  "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
2721
3401
  "hover:ring-1 hover:ring-border"
2722
3402
  ),
2723
3403
  children: /* @__PURE__ */ jsxs(Avatar, { size: "sm", children: [
2724
3404
  user.avatarUrl ? /* @__PURE__ */ jsx(AvatarImage, { src: user.avatarUrl, alt: user.name }) : null,
2725
- /* @__PURE__ */ jsx(AvatarFallback, { size: "sm", className: "bg-[image:var(--brand-gradient)] text-white", children: initials2 })
3405
+ /* @__PURE__ */ jsx(AvatarFallback, { size: "sm", className: "bg-primary text-white", children: initials2 })
2726
3406
  ] })
2727
3407
  }
2728
3408
  );
2729
3409
  }
2730
3410
  function UserMenuItemContent({ item }) {
2731
3411
  const Icon = item.icon;
2732
- return /* @__PURE__ */ jsxs(Fragment, { children: [
3412
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
2733
3413
  Icon ? /* @__PURE__ */ jsx(Icon, { className: "mr-2 h-4 w-4 shrink-0", "aria-hidden": true }) : null,
2734
3414
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: item.label }),
2735
3415
  item.shortcut ? /* @__PURE__ */ jsx(Kbd, { className: "ml-2", small: true, children: item.shortcut }) : null
@@ -2752,7 +3432,7 @@ function UserMenu(props) {
2752
3432
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 p-3", children: [
2753
3433
  /* @__PURE__ */ jsxs(Avatar, { size: "md", children: [
2754
3434
  user.avatarUrl ? /* @__PURE__ */ jsx(AvatarImage, { src: user.avatarUrl, alt: user.name }) : null,
2755
- /* @__PURE__ */ jsx(AvatarFallback, { size: "md", className: "bg-[image:var(--brand-gradient)] text-white", children: initials2 })
3435
+ /* @__PURE__ */ jsx(AvatarFallback, { size: "md", className: "bg-primary text-white", children: initials2 })
2756
3436
  ] }),
2757
3437
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
2758
3438
  /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-medium text-foreground", children: user.name }),
@@ -2760,13 +3440,13 @@ function UserMenu(props) {
2760
3440
  ] })
2761
3441
  ] }),
2762
3442
  /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
2763
- workspaceSlot ? /* @__PURE__ */ jsxs(Fragment, { children: [
3443
+ workspaceSlot ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
2764
3444
  /* @__PURE__ */ jsx("div", { className: "px-1 py-1", children: workspaceSlot }),
2765
3445
  /* @__PURE__ */ jsx(DropdownMenuSeparator, {})
2766
3446
  ] }) : null,
2767
3447
  groups.map((group, groupIndex) => {
2768
3448
  const isLastGroup = groupIndex === groups.length - 1;
2769
- return /* @__PURE__ */ jsxs(React14.Fragment, { children: [
3449
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
2770
3450
  group.label ? /* @__PURE__ */ jsx("div", { className: "px-2 py-1 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: group.label }) : null,
2771
3451
  group.items.map((item) => {
2772
3452
  const itemClassName = cn(
@@ -2830,43 +3510,35 @@ function roleLabel(role) {
2830
3510
  }
2831
3511
  function WorkspaceAvatar({ workspace, size = "sm", className }) {
2832
3512
  const initials2 = getInitials(workspace);
2833
- return /* @__PURE__ */ jsxs(Avatar, { size, className: cn("rounded-md", className), children: [
2834
- workspace.avatarUrl && /* @__PURE__ */ jsx(AvatarImage, { src: workspace.avatarUrl, alt: workspace.name, className: "rounded-md" }),
3513
+ return /* @__PURE__ */ jsxs(Avatar, { size, className: cn("rounded-[var(--radius-md)]", className), children: [
3514
+ workspace.avatarUrl && /* @__PURE__ */ jsx(
3515
+ AvatarImage,
3516
+ {
3517
+ src: workspace.avatarUrl,
3518
+ alt: workspace.name,
3519
+ className: "rounded-[var(--radius-md)]"
3520
+ }
3521
+ ),
2835
3522
  /* @__PURE__ */ jsx(
2836
3523
  AvatarFallback,
2837
3524
  {
2838
3525
  size,
2839
- className: "rounded-md bg-[image:var(--brand-gradient)] text-white font-semibold",
3526
+ className: "rounded-[var(--radius-md)] bg-primary text-white font-semibold",
2840
3527
  children: initials2
2841
3528
  }
2842
3529
  )
2843
3530
  ] });
2844
3531
  }
2845
- var TriggerButton = React14.forwardRef(
2846
- ({ activeWorkspace, variant, showRoleBadge, disabled, className }, ref) => {
2847
- const isOwner = activeWorkspace.role === "owner";
2848
- if (variant === "compact") {
2849
- return /* @__PURE__ */ jsxs(
2850
- "button",
2851
- {
2852
- ref,
2853
- type: "button",
2854
- "aria-label": "Switch workspace",
2855
- disabled,
2856
- className: cn(
2857
- "inline-flex items-center gap-1 rounded-md p-1 outline-none transition-colors",
2858
- "hover:bg-accent hover:text-accent-foreground",
2859
- "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
2860
- "disabled:cursor-not-allowed disabled:opacity-50",
2861
- className
2862
- ),
2863
- children: [
2864
- /* @__PURE__ */ jsx(WorkspaceAvatar, { workspace: activeWorkspace, size: "sm" }),
2865
- /* @__PURE__ */ jsx(ChevronUpDown, { "aria-hidden": "true", className: "h-3.5 w-3.5 text-muted-foreground" })
2866
- ]
2867
- }
2868
- );
2869
- }
3532
+ function TriggerButton({
3533
+ activeWorkspace,
3534
+ variant,
3535
+ showRoleBadge,
3536
+ disabled,
3537
+ className,
3538
+ ref
3539
+ }) {
3540
+ const isOwner = activeWorkspace.role === "owner";
3541
+ if (variant === "compact") {
2870
3542
  return /* @__PURE__ */ jsxs(
2871
3543
  "button",
2872
3544
  {
@@ -2875,7 +3547,7 @@ var TriggerButton = React14.forwardRef(
2875
3547
  "aria-label": "Switch workspace",
2876
3548
  disabled,
2877
3549
  className: cn(
2878
- "inline-flex w-full items-center gap-2 rounded-md border border-border bg-background px-2 py-1 text-left outline-none transition-colors",
3550
+ "inline-flex items-center gap-1 rounded-[var(--radius-md)] p-1 outline-none transition-colors",
2879
3551
  "hover:bg-accent hover:text-accent-foreground",
2880
3552
  "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
2881
3553
  "disabled:cursor-not-allowed disabled:opacity-50",
@@ -2883,16 +3555,36 @@ var TriggerButton = React14.forwardRef(
2883
3555
  ),
2884
3556
  children: [
2885
3557
  /* @__PURE__ */ jsx(WorkspaceAvatar, { workspace: activeWorkspace, size: "sm" }),
2886
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
2887
- /* @__PURE__ */ jsx("span", { className: "truncate font-medium text-[13px] text-foreground", children: activeWorkspace.name }),
2888
- showRoleBadge && isOwner && /* @__PURE__ */ jsx(Badge, { variant: "owner", size: "sm", children: "Owner" })
2889
- ] }),
2890
- /* @__PURE__ */ jsx(ChevronUpDown, { "aria-hidden": "true", className: "size-3.5 shrink-0 text-muted-foreground" })
3558
+ /* @__PURE__ */ jsx(ChevronUpDown, { "aria-hidden": "true", className: "h-3.5 w-3.5 text-muted-foreground" })
2891
3559
  ]
2892
3560
  }
2893
3561
  );
2894
3562
  }
2895
- );
3563
+ return /* @__PURE__ */ jsxs(
3564
+ "button",
3565
+ {
3566
+ ref,
3567
+ type: "button",
3568
+ "aria-label": "Switch workspace",
3569
+ disabled,
3570
+ className: cn(
3571
+ "inline-flex w-full items-center gap-2 rounded-[var(--radius-md)] border border-border bg-background px-2 py-1 text-left outline-none transition-colors",
3572
+ "hover:bg-accent hover:text-accent-foreground",
3573
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
3574
+ "disabled:cursor-not-allowed disabled:opacity-50",
3575
+ className
3576
+ ),
3577
+ children: [
3578
+ /* @__PURE__ */ jsx(WorkspaceAvatar, { workspace: activeWorkspace, size: "sm" }),
3579
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
3580
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium text-[13px] text-foreground", children: activeWorkspace.name }),
3581
+ showRoleBadge && isOwner && /* @__PURE__ */ jsx(Badge, { variant: "owner", size: "sm", children: "Owner" })
3582
+ ] }),
3583
+ /* @__PURE__ */ jsx(ChevronUpDown, { "aria-hidden": "true", className: "size-3.5 shrink-0 text-muted-foreground" })
3584
+ ]
3585
+ }
3586
+ );
3587
+ }
2896
3588
  TriggerButton.displayName = "WorkspaceSwitcherTrigger";
2897
3589
  function WorkspaceItem({ workspace, isActive, onSelect }) {
2898
3590
  return /* @__PURE__ */ jsxs(
@@ -2950,7 +3642,7 @@ function WorkspaceSwitcher({
2950
3642
  "div",
2951
3643
  {
2952
3644
  className: cn(
2953
- "inline-flex items-center gap-2 rounded-md border border-dashed border-border px-2 py-1.5 text-sm text-muted-foreground",
3645
+ "inline-flex items-center gap-2 rounded-[var(--radius-md)] border border-dashed border-border px-2 py-1.5 text-sm text-muted-foreground",
2954
3646
  className
2955
3647
  ),
2956
3648
  children: "No workspaces"
@@ -2975,7 +3667,7 @@ function WorkspaceSwitcher({
2975
3667
  sideOffset: 6,
2976
3668
  className: "w-[min(20rem,calc(100vw-2rem))] p-1",
2977
3669
  children: [
2978
- headerSlot && /* @__PURE__ */ jsxs(Fragment, { children: [
3670
+ headerSlot && /* @__PURE__ */ jsxs(Fragment$1, { children: [
2979
3671
  /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5", children: headerSlot }),
2980
3672
  /* @__PURE__ */ jsx(DropdownMenuSeparator, {})
2981
3673
  ] }),
@@ -2989,7 +3681,7 @@ function WorkspaceSwitcher({
2989
3681
  },
2990
3682
  ws.id
2991
3683
  )) }),
2992
- footerSlot && /* @__PURE__ */ jsxs(Fragment, { children: [
3684
+ footerSlot && /* @__PURE__ */ jsxs(Fragment$1, { children: [
2993
3685
  /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
2994
3686
  /* @__PURE__ */ jsx("div", { className: "px-1 py-0.5", children: footerSlot })
2995
3687
  ] })
@@ -2999,6 +3691,6 @@ function WorkspaceSwitcher({
2999
3691
  ] });
3000
3692
  }
3001
3693
 
3002
- export { Card, CardBody, CardDescription, CardFooter, CardHeader, CardIcon, CardRoot, CardTitle, CommandBox, GalleryCard, MarkdownEditor, MarkdownRenderer, QAPage, SidebarNav, Terminal, TerminalBody, TerminalHeader, TerminalLine, TerminalRoot, UserInfo, UserMenu, VoteButtons, WorkspaceSwitcher };
3694
+ export { ArtifactShiftCard, ArtifactShiftCardFooter, ArtifactShiftCardPreview, Card, CardBody, CardDescription, CardFooter, CardHeader, CardIcon, CardRoot, CardTitle, CommandBox, DashboardCommandSurface, DashboardMetricTile, DashboardPanel, GalleryCard, KineticCodePreview, KineticCommandBox, KineticConsoleFrame, KineticFeatureCard, KineticMorphSurface, KineticSignalMarquee, KineticStep, KineticStepRail, MarkdownEditor, MarkdownRenderer, QAPage, SidebarNav, Terminal, TerminalBody, TerminalHeader, TerminalLine, TerminalRoot, UserInfo, UserMenu, VoteButtons, WorkspaceSwitcher };
3003
3695
  //# sourceMappingURL=index.js.map
3004
3696
  //# sourceMappingURL=index.js.map