@nebutra/ui 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/{canonical-Bf4czR2u.d.ts → canonical-DEhT4VfS.d.ts} +71 -120
  2. package/dist/card-DunB1gKE.d.ts +105 -0
  3. package/dist/components/index.d.ts +33 -4
  4. package/dist/components/index.js +225 -89
  5. package/dist/components/index.js.map +1 -1
  6. package/dist/editorial/index.d.ts +2 -2
  7. package/dist/editorial/index.js +75 -1
  8. package/dist/editorial/index.js.map +1 -1
  9. package/dist/empty-state-bmfHCOuN.d.ts +86 -0
  10. package/dist/hooks/index.d.ts +18 -1
  11. package/dist/hooks/index.js +120 -5
  12. package/dist/hooks/index.js.map +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/layout/index.d.ts +17 -58
  15. package/dist/layout/index.js +366 -126
  16. package/dist/layout/index.js.map +1 -1
  17. package/dist/layouts/index.d.ts +1 -1
  18. package/dist/layouts/index.js +89 -15
  19. package/dist/layouts/index.js.map +1 -1
  20. package/dist/patterns/index.d.ts +38 -44
  21. package/dist/patterns/index.js +470 -278
  22. package/dist/patterns/index.js.map +1 -1
  23. package/dist/primitives/canonical.d.ts +3 -1
  24. package/dist/primitives/canonical.js +495 -231
  25. package/dist/primitives/canonical.js.map +1 -1
  26. package/dist/primitives/index.d.ts +90 -62
  27. package/dist/primitives/index.js +1129 -1185
  28. package/dist/primitives/index.js.map +1 -1
  29. package/dist/tailwind.preset.d.ts +32 -32
  30. package/dist/tailwind.preset.js +24 -20
  31. package/dist/tailwind.preset.js.map +1 -1
  32. package/dist/theme/index.d.ts +1 -110
  33. package/dist/typography/fonts.css +8 -16
  34. package/dist/typography/index.d.ts +29 -45
  35. package/dist/typography/index.js +26 -14
  36. package/dist/typography/index.js.map +1 -1
  37. package/dist/utils/index.d.ts +18 -12
  38. package/dist/utils/index.js +94 -18
  39. package/dist/utils/index.js.map +1 -1
  40. package/package.json +6 -10
  41. package/src/typography/fonts.css +8 -16
  42. package/dist/styles/brand-override.css +0 -61
  43. package/src/styles/brand-override.css +0 -61
@@ -1,13 +1,14 @@
1
1
  "use client";
2
2
  import { clsx } from 'clsx';
3
- import { twMerge } from 'tailwind-merge';
4
- import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
5
- import * as React from 'react';
3
+ import { extendTailwindMerge } from 'tailwind-merge';
4
+ import { jsxs, jsx, Fragment as Fragment$1 } from 'react/jsx-runtime';
5
+ import { cva } from 'class-variance-authority';
6
+ import * as React10 from 'react';
6
7
  import { useState, useRef, useCallback, useMemo, Fragment, isValidElement } from 'react';
7
8
  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
- import { cva } from 'class-variance-authority';
9
9
  import { Menu } from '@base-ui/react/menu';
10
10
  import { colors } from '@nebutra/brand';
11
+ import { tokenColor, fontStack } from '@nebutra/tokens/values';
11
12
  import { Tabs as Tabs$1 } from '@base-ui/react/tabs';
12
13
  import { Tooltip as Tooltip$1 } from '@base-ui/react/tooltip';
13
14
  import ReactMarkdown from 'react-markdown';
@@ -17,6 +18,80 @@ import { Avatar as Avatar$1 } from '@base-ui/react/avatar';
17
18
  import { useReducedMotion, AnimatePresence, motion } from 'framer-motion';
18
19
 
19
20
  // src/utils/cn.ts
21
+
22
+ // src/utils/tw-merge-theme.generated.ts
23
+ var TW_MERGE_THEME = {
24
+ breakpoint: ["3xl", "shell", "tight", "xs"],
25
+ container: ["content", "text", "wide"],
26
+ ease: ["brand", "in", "in-out", "out", "spring"],
27
+ font: ["cn", "display", "heading", "mono", "sans"],
28
+ leading: ["display", "heading"],
29
+ radius: ["2xl", "3xl", "button", "card", "full", "lg", "md", "none", "panel", "sm", "xl", "xs"],
30
+ shadow: [
31
+ "2xl",
32
+ "ambient-glow",
33
+ "ambient-lg",
34
+ "ambient-md",
35
+ "ambient-sm",
36
+ "brand",
37
+ "brand-lg",
38
+ "glass-lg",
39
+ "glass-md",
40
+ "glass-sm",
41
+ "glow-accent",
42
+ "glow-accent-lg",
43
+ "glow-accent-sm",
44
+ "glow-primary",
45
+ "lg",
46
+ "md",
47
+ "sheen",
48
+ "sm",
49
+ "xl",
50
+ "xs"
51
+ ],
52
+ text: [
53
+ "2xl",
54
+ "2xs",
55
+ "3xl",
56
+ "4xl",
57
+ "5xl",
58
+ "6xl",
59
+ "7xl",
60
+ "8xl",
61
+ "9xl",
62
+ "base",
63
+ "body",
64
+ "display",
65
+ "label",
66
+ "lg",
67
+ "meta",
68
+ "sm",
69
+ "ui",
70
+ "xl",
71
+ "xs"
72
+ ],
73
+ tracking: ["display", "heading", "label", "tight"]
74
+ };
75
+ var TW_MERGE_CLASS_GROUPS = {
76
+ duration: [{ duration: ["cinematic", "flow", "micro", "reveal"] }]
77
+ };
78
+
79
+ // src/utils/cn.ts
80
+ var twMerge = extendTailwindMerge({
81
+ extend: {
82
+ theme: Object.fromEntries(
83
+ Object.entries(TW_MERGE_THEME).map(([key, values]) => [key, [...values]])
84
+ ),
85
+ classGroups: Object.fromEntries(
86
+ Object.entries(TW_MERGE_CLASS_GROUPS).map(([key, groups]) => [
87
+ key,
88
+ groups.map(
89
+ (group) => Object.fromEntries(Object.entries(group).map(([k, v]) => [k, [...v]]))
90
+ )
91
+ ])
92
+ )
93
+ }
94
+ });
20
95
  function cn(...inputs) {
21
96
  return twMerge(clsx(inputs));
22
97
  }
@@ -129,108 +204,120 @@ function ArtifactShiftCardFooter({ className, ...props }) {
129
204
  }
130
205
  );
131
206
  }
132
- var CardContext = React.createContext(null);
133
- var paddingMap = {
134
- none: "",
135
- sm: "p-4",
136
- md: "p-6",
137
- lg: "p-8"
138
- };
139
- var variantStyles = {
140
- default: "bg-card border border-border",
141
- elevated: "bg-card border border-border shadow-lg",
142
- bordered: "bg-transparent border-2 border-border",
143
- ghost: "bg-transparent",
144
- gradient: "bg-gradient-to-br from-card to-muted border border-border"
145
- };
146
- var CardRoot = React.forwardRef(
147
- ({ className, variant = "default", padding = "md", children, ...props }, ref) => {
148
- return /* @__PURE__ */ jsx(CardContext.Provider, { value: { variant }, children: /* @__PURE__ */ jsx(
149
- "div",
150
- {
151
- ref,
152
- className: cn(
153
- "rounded-[var(--radius-xl)] transition-[background-color,border-color,box-shadow,color] duration-micro",
154
- variantStyles[variant],
155
- paddingMap[padding],
156
- className
157
- ),
158
- ...props,
159
- children
207
+ var cardVariants = cva(
208
+ "rounded-[var(--radius-card,var(--radius-lg))] text-card-foreground transition-[box-shadow,background-color] duration-micro",
209
+ {
210
+ variants: {
211
+ variant: {
212
+ default: "bg-card shadow-[var(--elevation-card)] ring-1 ring-[var(--edge-soft)]",
213
+ elevated: "bg-card shadow-ambient-md ring-1 ring-[var(--edge-soft)]",
214
+ outline: "bg-transparent ring-1 ring-border",
215
+ ghost: "bg-transparent"
216
+ },
217
+ padding: {
218
+ none: "",
219
+ sm: "p-4",
220
+ md: "p-6",
221
+ lg: "p-8"
222
+ },
223
+ interactive: {
224
+ true: "cursor-pointer hover:shadow-ambient-md",
225
+ false: ""
160
226
  }
161
- ) });
162
- }
163
- );
164
- CardRoot.displayName = "Card";
165
- var CardHeader = React.forwardRef(
166
- ({ className, spacing: gap = "md", children, ...props }, ref) => {
167
- const gapMap = { sm: "gap-2", md: "gap-3", lg: "gap-4" };
168
- return /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-start", gapMap[gap], className), ...props, children });
169
- }
170
- );
171
- CardHeader.displayName = "Card.Header";
172
- var CardBody = React.forwardRef(
173
- ({ className, children, ...props }, ref) => {
174
- return /* @__PURE__ */ jsx("div", { ref, className: cn("mt-4", className), ...props, children });
175
- }
176
- );
177
- CardBody.displayName = "Card.Body";
178
- var CardFooter = React.forwardRef(
179
- ({ className, children, ...props }, ref) => {
180
- return /* @__PURE__ */ jsx("div", { ref, className: cn("mt-6 pt-4 border-t border-border/50", className), ...props, children });
227
+ },
228
+ defaultVariants: { variant: "default", padding: "none", interactive: false }
181
229
  }
182
230
  );
183
- CardFooter.displayName = "Card.Footer";
184
- var CardIcon = React.forwardRef(
185
- ({ className, size = "md", children, ...props }, ref) => {
186
- const sizeMap = {
187
- sm: "w-8 h-8",
188
- md: "w-10 h-10",
189
- lg: "w-12 h-12"
190
- };
191
- return /* @__PURE__ */ jsx(
192
- "div",
193
- {
194
- ref,
195
- className: cn(
196
- "flex items-center justify-center rounded-[var(--radius-lg)] bg-muted/50 shrink-0",
197
- sizeMap[size],
198
- className
199
- ),
200
- ...props,
201
- children
202
- }
203
- );
231
+ var CardPaddedContext = React10.createContext(false);
232
+ var CardRoot = ({
233
+ className,
234
+ variant,
235
+ padding = "none",
236
+ interactive,
237
+ ref,
238
+ ...props
239
+ }) => /* @__PURE__ */ jsx(CardPaddedContext.Provider, { value: padding !== "none", children: /* @__PURE__ */ jsx(
240
+ "div",
241
+ {
242
+ ref,
243
+ className: cn(cardVariants({ variant, padding, interactive }), className),
244
+ ...props
204
245
  }
205
- );
206
- CardIcon.displayName = "Card.Icon";
207
- var CardTitle = React.forwardRef(
208
- ({ className, as: Tag = "h3", children, ...props }, ref) => {
209
- return /* @__PURE__ */ jsx(Tag, { ref, className: cn("text-lg font-semibold text-foreground", className), ...props, children });
246
+ ) });
247
+ CardRoot.displayName = "Card";
248
+ var CardHeader = ({ className, ref, ...props }) => {
249
+ const padded = React10.use(CardPaddedContext);
250
+ return /* @__PURE__ */ jsx(
251
+ "div",
252
+ {
253
+ ref,
254
+ className: cn("flex flex-col gap-1.5", !padded && "p-6", className),
255
+ ...props
256
+ }
257
+ );
258
+ };
259
+ CardHeader.displayName = "CardHeader";
260
+ var CardTitle = ({ className, as: Tag = "h3", ref, ...props }) => /* @__PURE__ */ jsx(
261
+ Tag,
262
+ {
263
+ ref,
264
+ className: cn("text-lg font-semibold leading-tight tracking-tight text-foreground", className),
265
+ ...props
210
266
  }
211
267
  );
212
- CardTitle.displayName = "Card.Title";
213
- var CardDescription = React.forwardRef(({ className, as: Tag = "p", children, ...props }, ref) => {
214
- return React.createElement(
215
- Tag,
268
+ CardTitle.displayName = "CardTitle";
269
+ var CardDescription = ({ className, as: Tag = "p", ref, ...props }) => React10.createElement(Tag, {
270
+ ref,
271
+ className: cn("text-sm leading-relaxed text-muted-foreground", className),
272
+ ...props
273
+ });
274
+ CardDescription.displayName = "CardDescription";
275
+ var CardContent = ({ className, ref, ...props }) => {
276
+ const padded = React10.use(CardPaddedContext);
277
+ return /* @__PURE__ */ jsx("div", { ref, className: cn(padded ? "mt-4 first:mt-0" : "p-6 pt-0", className), ...props });
278
+ };
279
+ CardContent.displayName = "CardContent";
280
+ var CardFooter = ({ className, ref, ...props }) => {
281
+ const padded = React10.use(CardPaddedContext);
282
+ return /* @__PURE__ */ jsx(
283
+ "div",
216
284
  {
217
285
  ref,
218
- className: cn("text-sm text-muted-foreground leading-relaxed", className),
286
+ className: cn(
287
+ "flex items-center",
288
+ padded ? "mt-6 border-t border-border/50 pt-4 first:mt-0" : "p-6 pt-0",
289
+ className
290
+ ),
219
291
  ...props
220
- },
221
- children
292
+ }
222
293
  );
223
- });
224
- CardDescription.displayName = "Card.Description";
294
+ };
295
+ CardFooter.displayName = "CardFooter";
296
+ var iconSize = { sm: "size-8", md: "size-10", lg: "size-12" };
297
+ var CardIcon = ({ className, size = "md", ref, ...props }) => /* @__PURE__ */ jsx(
298
+ "div",
299
+ {
300
+ ref,
301
+ className: cn(
302
+ "flex shrink-0 items-center justify-center rounded-[var(--radius-lg)] bg-muted/50",
303
+ iconSize[size],
304
+ className
305
+ ),
306
+ ...props
307
+ }
308
+ );
309
+ CardIcon.displayName = "CardIcon";
225
310
  var Card = Object.assign(CardRoot, {
226
311
  Header: CardHeader,
227
- Body: CardBody,
228
- Footer: CardFooter,
229
- Icon: CardIcon,
230
312
  Title: CardTitle,
231
- Description: CardDescription
313
+ Description: CardDescription,
314
+ Content: CardContent,
315
+ Body: CardContent,
316
+ Footer: CardFooter,
317
+ Icon: CardIcon
232
318
  });
233
- var CommandBox = React.forwardRef(
319
+ var CardBody = CardContent;
320
+ var CommandBox = React10.forwardRef(
234
321
  ({
235
322
  className,
236
323
  command,
@@ -240,8 +327,8 @@ var CommandBox = React.forwardRef(
240
327
  onCopy,
241
328
  ...props
242
329
  }, ref) => {
243
- const [copied, setCopied] = React.useState(false);
244
- const handleCopy = React.useCallback(async () => {
330
+ const [copied, setCopied] = React10.useState(false);
331
+ const handleCopy = React10.useCallback(async () => {
245
332
  try {
246
333
  await navigator.clipboard.writeText(command);
247
334
  setCopied(true);
@@ -253,7 +340,7 @@ var CommandBox = React.forwardRef(
253
340
  }
254
341
  }
255
342
  }, [command, onCopy]);
256
- const variantStyles3 = {
343
+ const variantStyles2 = {
257
344
  default: "bg-muted border border-border rounded-[var(--radius-lg)]",
258
345
  minimal: "bg-background border border-border rounded-[var(--radius-md)]",
259
346
  pill: "bg-muted border border-border rounded-full"
@@ -266,7 +353,7 @@ var CommandBox = React.forwardRef(
266
353
  ref,
267
354
  className: cn(
268
355
  "group relative flex items-center gap-3 px-4 py-2.5 font-mono text-sm cursor-pointer transition-colors hover:bg-muted",
269
- variantStyles3[variant],
356
+ variantStyles2[variant],
270
357
  className
271
358
  ),
272
359
  onClick: handleCopy,
@@ -281,14 +368,14 @@ var CommandBox = React.forwardRef(
281
368
  "aria-label": `Copy command: ${command}`,
282
369
  ...props,
283
370
  children: [
284
- /* @__PURE__ */ jsx("span", { className: "text-emerald-400 shrink-0 select-none", children: prefix }),
371
+ /* @__PURE__ */ jsx("span", { className: "text-success-strong shrink-0 select-none", children: prefix }),
285
372
  /* @__PURE__ */ jsx("span", { className: "flex-1 text-muted-foreground truncate", children: command }),
286
373
  showCopyButton && /* @__PURE__ */ jsx(
287
374
  "span",
288
375
  {
289
376
  className: cn(
290
377
  "shrink-0 text-xs transition-colors",
291
- copied ? "text-emerald-400" : "text-muted-foreground group-hover:text-muted-foreground"
378
+ copied ? "text-success-strong" : "text-muted-foreground group-hover:text-muted-foreground"
292
379
  ),
293
380
  children: copied ? /* @__PURE__ */ jsx(CopiedIcon, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx(CopyIcon, { className: "w-4 h-4" })
294
381
  }
@@ -297,7 +384,7 @@ var CommandBox = React.forwardRef(
297
384
  "span",
298
385
  {
299
386
  className: cn(
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",
387
+ "absolute -top-8 left-1/2 -translate-x-1/2 px-2 py-1 text-xs rounded bg-popover text-popover-foreground opacity-0 transition-opacity pointer-events-none",
301
388
  "group-hover:opacity-100",
302
389
  copied && "opacity-100"
303
390
  ),
@@ -351,8 +438,8 @@ function CopiedIcon({ className }) {
351
438
  var metricToneClasses = {
352
439
  neutral: "bg-muted/70 text-muted-foreground ring-border",
353
440
  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"
441
+ green: "bg-success/10 text-success-strong ring-success/20",
442
+ amber: "bg-warning/10 text-warning-strong ring-warning/20"
356
443
  };
357
444
  function DashboardCommandSurface({
358
445
  status,
@@ -367,25 +454,27 @@ function DashboardCommandSurface({
367
454
  {
368
455
  "data-pattern": "nebutra-dashboard-command",
369
456
  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%)]",
457
+ // Same surface rails as Card: --radius-card, --edge-soft hairline and
458
+ // --elevation-card, so a Brand Package retargets a command header and a
459
+ // card together. The gradient hairline + radial wash that used to sit
460
+ // here were decoration no language could retarget.
461
+ "rounded-[var(--radius-card)] bg-card p-4 text-card-foreground shadow-[0_0_0_1px_var(--edge-soft),var(--elevation-card)]",
373
462
  "sm:p-5",
374
463
  className
375
464
  ),
376
465
  children: [
377
- /* @__PURE__ */ jsxs("div", { className: "relative z-10 flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between", children: [
466
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between", children: [
378
467
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
379
468
  status ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
380
- /* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-success shadow-[0_0_0_3px_hsl(var(--success)/0.18)]" }),
381
- /* @__PURE__ */ jsx("p", { className: "text-[11px] font-medium uppercase text-muted-foreground", children: status })
469
+ /* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-success" }),
470
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase tracking-label text-muted-foreground", children: status })
382
471
  ] }) : 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
472
+ /* @__PURE__ */ jsx("h1", { className: "mt-2 text-2xl font-semibold tracking-heading text-card-foreground sm:text-3xl", children: title }),
473
+ description ? /* @__PURE__ */ jsx("p", { className: "mt-2 max-w-2xl text-sm leading-5 text-muted-foreground", children: description }) : null
385
474
  ] }),
386
475
  actions ? /* @__PURE__ */ jsx("div", { className: "flex shrink-0 flex-wrap items-center gap-1.5", children: actions }) : null
387
476
  ] }),
388
- children ? /* @__PURE__ */ jsx("div", { className: "relative z-10 mt-4", children }) : null
477
+ children ? /* @__PURE__ */ jsx("div", { className: "mt-4", children }) : null
389
478
  ]
390
479
  }
391
480
  );
@@ -404,7 +493,7 @@ function DashboardPanel({
404
493
  {
405
494
  "data-pattern": "nebutra-dashboard-panel",
406
495
  className: cn(
407
- "rounded-[var(--radius-lg)] border border-border bg-card p-3.5 text-card-foreground shadow-sm sm:p-4",
496
+ "rounded-[var(--radius-card)] bg-card p-3.5 text-card-foreground shadow-[0_0_0_1px_var(--edge-soft),var(--elevation-card)] sm:p-4",
408
497
  className
409
498
  ),
410
499
  children: [
@@ -417,7 +506,7 @@ function DashboardPanel({
417
506
  ),
418
507
  children: [
419
508
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
420
- /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold tracking-normal text-card-foreground", children: title }),
509
+ /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold text-card-foreground", children: title }),
421
510
  description ? /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs leading-5 text-muted-foreground", children: description }) : null
422
511
  ] }),
423
512
  (meta || action) && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2 lg:justify-end", children: [
@@ -446,8 +535,8 @@ function DashboardMetricTile({
446
535
  {
447
536
  "data-pattern": "nebutra-dashboard-metric",
448
537
  className: cn(
449
- "group h-full rounded-[var(--radius-lg)] border border-border bg-muted/40 p-3 transition-colors duration-micro",
450
- "hover:border-muted-foreground/30 hover:bg-muted/65",
538
+ "group h-full rounded-[var(--radius-card)] bg-muted/40 p-3 shadow-[0_0_0_1px_var(--edge-soft)] transition-[background-color,box-shadow] duration-micro",
539
+ "hover:bg-muted/65 hover:shadow-[0_0_0_1px_var(--edge-medium)]",
451
540
  className
452
541
  ),
453
542
  children: [
@@ -464,10 +553,10 @@ function DashboardMetricTile({
464
553
  }
465
554
  ) : null
466
555
  ] }),
467
- /* @__PURE__ */ jsx("p", { className: "mt-2 text-2xl font-semibold tabular-nums tracking-normal text-card-foreground", children: value }),
556
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-2xl font-semibold tabular-nums text-card-foreground", children: value }),
468
557
  (detail || source) && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 space-y-0.5 text-xs leading-5 text-muted-foreground", children: [
469
558
  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
559
+ source ? /* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground/70", children: source }) : null
471
560
  ] })
472
561
  ]
473
562
  }
@@ -518,8 +607,14 @@ var badgeVariants = cva(
518
607
  "teal-subtle": "bg-info/10 text-info fill-current border-transparent",
519
608
  inverted: "bg-foreground text-background fill-current",
520
609
  // Special visual treatments (intentional product design, not brand hex)
521
- trial: "bg-gradient-to-br from-trial-start to-trial-end text-primary-foreground fill-current",
522
- turbo: "bg-gradient-to-br from-turbo-start to-turbo-end text-primary-foreground fill-current",
610
+ trial: (
611
+ // allow-palette: the trial gradient is fixed and vivid in both themes, so its ink is fixed white
612
+ "bg-gradient-to-br from-trial-start to-trial-end text-white fill-current"
613
+ ),
614
+ turbo: (
615
+ // allow-palette: the turbo gradient is fixed and vivid in both themes, so its ink is fixed white
616
+ "bg-gradient-to-br from-turbo-start to-turbo-end text-white fill-current"
617
+ ),
523
618
  pill: "bg-background text-foreground fill-foreground border-border hover:bg-muted/50 focus-visible:bg-muted/50",
524
619
  beta: "border-transparent bg-muted text-muted-foreground",
525
620
  new: "border-transparent bg-primary/10 text-primary",
@@ -584,11 +679,11 @@ function Badge({
584
679
  label
585
680
  ] });
586
681
  if (asChild) {
587
- const childArray = React.Children.toArray(children);
682
+ const childArray = React10.Children.toArray(children);
588
683
  const child = childArray.length === 1 ? childArray[0] : null;
589
- if (React.isValidElement(child)) {
684
+ if (React10.isValidElement(child)) {
590
685
  const childProps = child.props;
591
- return React.cloneElement(child, {
686
+ return React10.cloneElement(child, {
592
687
  ...props,
593
688
  ...childProps,
594
689
  "data-slot": "badge",
@@ -601,7 +696,7 @@ function Badge({
601
696
  return /* @__PURE__ */ jsx("span", { "data-slot": "badge", className: badgeClassName, ...props, children: renderContent(children) });
602
697
  }
603
698
  ({
604
- // Nebutra Blue (云毓蓝) — technology & trust — VI: #0033FE
699
+ // Nebutra Blue (云毓蓝) — technology & trust
605
700
  blue50: colors.primary[50],
606
701
  blue100: colors.primary[100],
607
702
  blue200: colors.primary[200],
@@ -614,7 +709,7 @@ function Badge({
614
709
  blue800: colors.primary[800],
615
710
  blue900: colors.primary[900],
616
711
  blue950: colors.primary[950],
617
- // Nebutra Cyan (云毓青) — data flow & intelligence — VI: #0BF1C3
712
+ // Nebutra Cyan (云毓青) — data flow & intelligence
618
713
  cyan50: colors.accent[50],
619
714
  cyan100: colors.accent[100],
620
715
  cyan200: colors.accent[200],
@@ -639,6 +734,13 @@ function Badge({
639
734
  neutral800: colors.neutral[800],
640
735
  neutral900: colors.neutral[900],
641
736
  neutral950: colors.neutral[950],
737
+ // deepest — used as dark background
738
+ // Semantic raw colors — VI §Color Specifications. The 500s are the status
739
+ // tokens; the 600 hover steps have no token of their own.
740
+ // NOTE: info = brand blue, not sky/teal
741
+ red500: tokenColor("--status-danger"),
742
+ green500: tokenColor("--status-success"),
743
+ amber500: tokenColor("--status-warning"),
642
744
  white: colors.white,
643
745
  black: colors.black
644
746
  });
@@ -677,6 +779,18 @@ var primitiveFontSize = {
677
779
  sm: 14,
678
780
  base: 16,
679
781
  lg: 18};
782
+ ({
783
+ /** Default body/UI stack — Geist with CJK falling through to MiSans */
784
+ sans: fontStack("--font-sans"),
785
+ /** CJK-locale stack (same order as sans, minus Latin-only system faces) */
786
+ cnSans: fontStack("--font-cn"),
787
+ /** Display / hero headlines */
788
+ display: fontStack("--font-display"),
789
+ /** Headings */
790
+ heading: fontStack("--font-heading"),
791
+ /** Code / monospace */
792
+ mono: fontStack("--font-mono")
793
+ });
680
794
  var primitiveTransition = {
681
795
  duration: {
682
796
  // hover, focus, small state changes
@@ -704,15 +818,15 @@ var overlayClassNames = {
704
818
  menuSurface: [
705
819
  "min-w-32 origin-[var(--transform-origin)] overflow-hidden rounded-[var(--radius-lg)] border border-border/70 bg-popover/95 p-1 text-popover-foreground backdrop-blur-md",
706
820
  shadowClasses.xl,
707
- "outline-none transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-brand)]",
708
- "data-[starting-style]:scale-[0.97] data-[starting-style]:opacity-0 data-[ending-style]:scale-[0.97] data-[ending-style]:opacity-0",
821
+ "outline-none transition-[opacity,transform] duration-[var(--motion-duration-flow)] ease-[var(--ease-brand)]",
822
+ "data-[starting-style]:scale-[0.97] data-[starting-style]:opacity-0 data-ending-style:scale-[0.97] data-ending-style:opacity-0 data-ending-style:duration-[var(--motion-duration-micro)]",
709
823
  "motion-reduce:transition-none motion-reduce:data-[starting-style]:transform-none motion-reduce:data-[ending-style]:transform-none"
710
824
  ].join(" "),
711
825
  tooltipSurface: [
712
826
  "origin-[var(--transform-origin)] 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",
713
827
  shadowClasses.md,
714
- "transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-brand)]",
715
- "data-starting-style:scale-[0.97] data-starting-style:opacity-0 data-ending-style:scale-[0.97] data-ending-style:opacity-0",
828
+ "transition-[opacity,transform] duration-[var(--motion-duration-flow)] ease-[var(--ease-brand)]",
829
+ "data-starting-style:scale-[0.97] data-starting-style:opacity-0 data-ending-style:scale-[0.97] data-ending-style:opacity-0 data-ending-style:duration-[var(--motion-duration-micro)]",
716
830
  "data-[instant]:duration-0",
717
831
  "motion-reduce:transition-none motion-reduce:data-starting-style:transform-none motion-reduce:data-ending-style:transform-none"
718
832
  ].join(" ")};
@@ -727,7 +841,7 @@ var menuHighlightedClassName = "data-[highlighted]:bg-accent data-[highlighted]:
727
841
  var overlayPrimitiveClassNames = {
728
842
  menuSurface: "rounded-[var(--radius-md)] border-border/70 bg-popover/95 shadow-md",
729
843
  menuItem: [menuItemBaseClassName, menuHighlightedClassName].join(" ")};
730
- var DropdownMenuContext = React.createContext(null);
844
+ var DropdownMenuContext = React10.createContext(null);
731
845
  function DropdownMenu({
732
846
  open: controlledOpen,
733
847
  defaultOpen = false,
@@ -735,7 +849,7 @@ function DropdownMenu({
735
849
  children,
736
850
  ...props
737
851
  }) {
738
- const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);
852
+ const [uncontrolledOpen, setUncontrolledOpen] = React10.useState(defaultOpen);
739
853
  const open = controlledOpen ?? uncontrolledOpen;
740
854
  function setOpen(nextOpen, eventDetails) {
741
855
  if (controlledOpen === void 0) {
@@ -754,11 +868,11 @@ var DropdownMenuTrigger = ({
754
868
  ref,
755
869
  ...props
756
870
  }) => {
757
- const context = React.use(DropdownMenuContext);
871
+ const context = React10.use(DropdownMenuContext);
758
872
  function openFromTrigger() {
759
873
  context?.setOpen(true);
760
874
  }
761
- const childRenderElement = asChild && React.isValidElement(children) ? React.cloneElement(children, {
875
+ const childRenderElement = asChild && React10.isValidElement(children) ? React10.cloneElement(children, {
762
876
  onMouseDown: (event) => {
763
877
  children.props.onMouseDown?.(event);
764
878
  if (!event.defaultPrevented) {
@@ -851,11 +965,13 @@ var DropdownMenuSeparator = ({
851
965
  DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
852
966
  var iconToneStyles = {
853
967
  neutral: "bg-muted text-muted-foreground",
854
- blue: "bg-blue-50 text-blue-700 dark:bg-blue-950/40 dark:text-blue-300",
855
- cyan: "bg-cyan-50 text-cyan-700 dark:bg-cyan-950/40 dark:text-cyan-300",
968
+ blue: "bg-blue-3 text-blue-11",
969
+ cyan: "bg-cyan-3 text-cyan-11",
970
+ // allow-palette: categorical hue with no token equivalent (purple/violet has no semantic slot)
856
971
  purple: "bg-purple-50 text-purple-700 dark:bg-purple-950/40 dark:text-purple-300",
857
- amber: "bg-amber-50 text-amber-700 dark:bg-amber-950/40 dark:text-amber-300",
858
- green: "bg-green-50 text-green-700 dark:bg-green-950/40 dark:text-green-300",
972
+ amber: "bg-warning/15 text-warning-strong",
973
+ green: "bg-success/15 text-success-strong",
974
+ // allow-palette: categorical hue with no token equivalent (pink has no semantic slot)
859
975
  pink: "bg-pink-50 text-pink-700 dark:bg-pink-950/40 dark:text-pink-300"
860
976
  };
861
977
  var badgeToneToVariant = {
@@ -903,7 +1019,7 @@ function GalleryCardActionsMenu({ actions, title }) {
903
1019
  action.onSelect();
904
1020
  },
905
1021
  className: cn(
906
- action.destructive && "text-destructive data-[highlighted]:bg-destructive/10 data-[highlighted]:text-destructive"
1022
+ action.destructive && "text-destructive-strong data-[highlighted]:bg-destructive/10 data-[highlighted]:text-destructive-strong"
907
1023
  ),
908
1024
  children: action.label
909
1025
  },
@@ -918,6 +1034,7 @@ function GalleryCardBody({
918
1034
  iconTone,
919
1035
  badge,
920
1036
  pinned,
1037
+ pinnedLabel = "Pinned",
921
1038
  metadata,
922
1039
  actions
923
1040
  }) {
@@ -937,7 +1054,13 @@ function GalleryCardBody({
937
1054
  }
938
1055
  ) : /* @__PURE__ */ jsx("span", { className: "h-10 w-10 shrink-0", "aria-hidden": "true" }),
939
1056
  (pinned || hasActions) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
940
- pinned && /* @__PURE__ */ jsx(Pin, { className: "h-3.5 w-3.5 fill-amber-400 text-amber-500", "aria-label": "Pinned" }),
1057
+ pinned && /* @__PURE__ */ jsx(
1058
+ Pin,
1059
+ {
1060
+ className: "h-3.5 w-3.5 fill-warning-strong text-warning-strong",
1061
+ "aria-label": pinnedLabel
1062
+ }
1063
+ ),
941
1064
  hasActions && actions ? /* @__PURE__ */ jsx(GalleryCardActionsMenu, { actions, title }) : null
942
1065
  ] })
943
1066
  ] }),
@@ -963,6 +1086,7 @@ function GalleryCard(props) {
963
1086
  iconTone = "neutral",
964
1087
  badge,
965
1088
  pinned,
1089
+ pinnedLabel,
966
1090
  metadata,
967
1091
  actions,
968
1092
  onClick,
@@ -979,6 +1103,7 @@ function GalleryCard(props) {
979
1103
  iconTone,
980
1104
  badge,
981
1105
  pinned,
1106
+ ...pinnedLabel !== void 0 ? { pinnedLabel } : {},
982
1107
  metadata,
983
1108
  actions
984
1109
  }
@@ -1010,7 +1135,7 @@ function lineTone(line) {
1010
1135
  return "text-primary font-medium";
1011
1136
  }
1012
1137
  if (trimmed.includes(":")) {
1013
- return "text-emerald-600 dark:text-emerald-400";
1138
+ return "text-success-strong";
1014
1139
  }
1015
1140
  return "text-foreground/78";
1016
1141
  }
@@ -1135,9 +1260,9 @@ function KineticConsoleFrame({
1135
1260
  children: [
1136
1261
  /* @__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: [
1137
1262
  /* @__PURE__ */ jsxs("div", { className: "flex gap-2", "aria-hidden": true, children: [
1138
- /* @__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" }),
1139
- /* @__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" }),
1140
- /* @__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" })
1263
+ /* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-destructive/80" }),
1264
+ /* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-warning/80" }),
1265
+ /* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-success/80" })
1141
1266
  ] }),
1142
1267
  /* @__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 }) }) }),
1143
1268
  /* @__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 }) })
@@ -1360,11 +1485,11 @@ function KineticStep({
1360
1485
  }
1361
1486
  );
1362
1487
  }
1363
- var Slot = React.forwardRef(
1488
+ var Slot = React10.forwardRef(
1364
1489
  ({ children, className, style, ...props }, ref) => {
1365
- const childArray = React.Children.toArray(children);
1490
+ const childArray = React10.Children.toArray(children);
1366
1491
  const child = childArray.length === 1 ? childArray[0] : null;
1367
- if (child == null || !React.isValidElement(child)) {
1492
+ if (child == null || !React10.isValidElement(child)) {
1368
1493
  return /* @__PURE__ */ jsx("span", { ref, className, style, ...props, children });
1369
1494
  }
1370
1495
  const childProps = child.props;
@@ -1385,7 +1510,7 @@ var Slot = React.forwardRef(
1385
1510
  className: mergedClass,
1386
1511
  style: { ...childProps.style, ...style }
1387
1512
  };
1388
- return React.cloneElement(
1513
+ return React10.cloneElement(
1389
1514
  child,
1390
1515
  merged
1391
1516
  );
@@ -1397,7 +1522,11 @@ var buttonVariants = cva(
1397
1522
  "inline-flex items-center justify-center gap-2 whitespace-nowrap",
1398
1523
  "rounded-[var(--btn-default-radius,var(--radius-md))]",
1399
1524
  "text-[length:var(--control-font-size-md,0.875rem)] font-[number:var(--font-weight-medium,500)]",
1400
- "transition-[color,background-color,border-color,transform] duration-flow ease-[var(--ease-brand)]",
1525
+ // `transform` is in the property list on purpose: without it the
1526
+ // active:scale-[0.97] press snapped instantly and the button felt dead
1527
+ // under the finger. Duration/ease stay on the flow rail — motion
1528
+ // governance pins them (primitives/__tests__/motion-governance.test.ts).
1529
+ "transition-[color,background-color,border-color,box-shadow,transform] duration-flow ease-[var(--ease-brand)]",
1401
1530
  "active:scale-[0.97] motion-reduce:active:scale-100 motion-reduce:transition-none",
1402
1531
  "disabled:pointer-events-none disabled:opacity-50",
1403
1532
  "aria-busy:cursor-wait"
@@ -1407,7 +1536,7 @@ var buttonVariants = cva(
1407
1536
  variant: {
1408
1537
  // Recipe-driven via packages/design/tokens/recipe.css (.btn-brand-default)
1409
1538
  default: "btn-brand-default",
1410
- 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",
1539
+ ink: "bg-neutral-12 text-neutral-1 ring-1 ring-inset ring-neutral-1/5 hover:bg-neutral-11 hover:-translate-y-px active:translate-y-0 transition-[transform,background-color] duration-micro",
1411
1540
  destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
1412
1541
  outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
1413
1542
  secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
@@ -1530,10 +1659,10 @@ function Spinner({ className }) {
1530
1659
  }
1531
1660
  );
1532
1661
  }
1533
- function getIconSizeClass(size, iconSize) {
1534
- if (iconSize === "sm") return "[&>svg]:size-3.5";
1535
- if (iconSize === "md") return "[&>svg]:size-3.5";
1536
- if (iconSize === "lg") return "[&>svg]:size-4";
1662
+ function getIconSizeClass(size, iconSize2) {
1663
+ if (iconSize2 === "sm") return "[&>svg]:size-3.5";
1664
+ if (iconSize2 === "md") return "[&>svg]:size-3.5";
1665
+ if (iconSize2 === "lg") return "[&>svg]:size-4";
1537
1666
  switch (size) {
1538
1667
  case "tiny":
1539
1668
  return "[&>svg]:size-3";
@@ -1548,10 +1677,10 @@ function getIconSizeClass(size, iconSize) {
1548
1677
  return "[&>svg]:size-4";
1549
1678
  }
1550
1679
  }
1551
- function getSpinnerSizeClass(size, iconSize) {
1552
- if (iconSize === "sm") return "size-3.5";
1553
- if (iconSize === "md") return "size-3.5";
1554
- if (iconSize === "lg") return "size-4";
1680
+ function getSpinnerSizeClass(size, iconSize2) {
1681
+ if (iconSize2 === "sm") return "size-3.5";
1682
+ if (iconSize2 === "md") return "size-3.5";
1683
+ if (iconSize2 === "lg") return "size-4";
1555
1684
  switch (size) {
1556
1685
  case "tiny":
1557
1686
  return "size-3";
@@ -1576,10 +1705,10 @@ function resolveShadowClass(shadow) {
1576
1705
  const level = shadow === true ? "md" : shadow;
1577
1706
  return SHADOW_CLASSES[level];
1578
1707
  }
1579
- function ButtonContent({ loading, prefix, suffix, size, iconSize, children }) {
1580
- const iconSizeClass = getIconSizeClass(size, iconSize);
1708
+ function ButtonContent({ loading, prefix, suffix, size, iconSize: iconSize2, children }) {
1709
+ const iconSizeClass = getIconSizeClass(size, iconSize2);
1581
1710
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1582
- loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size, iconSize) }),
1711
+ loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size, iconSize2) }),
1583
1712
  prefix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: prefix }),
1584
1713
  children,
1585
1714
  suffix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: suffix })
@@ -1590,7 +1719,7 @@ var Button = ({
1590
1719
  variant,
1591
1720
  size,
1592
1721
  shape,
1593
- iconSize,
1722
+ iconSize: iconSize2,
1594
1723
  asChild = false,
1595
1724
  loading = false,
1596
1725
  disabled,
@@ -1608,7 +1737,7 @@ var Button = ({
1608
1737
  Comp,
1609
1738
  {
1610
1739
  ref,
1611
- className: cn(buttonVariants({ variant, size, shape, iconSize }), shadowClass, className),
1740
+ className: cn(buttonVariants({ variant, size, shape, iconSize: iconSize2 }), shadowClass, className),
1612
1741
  disabled: isDisabled,
1613
1742
  "aria-busy": loading || void 0,
1614
1743
  ...props,
@@ -1619,7 +1748,7 @@ var Button = ({
1619
1748
  prefix,
1620
1749
  suffix,
1621
1750
  size,
1622
- iconSize,
1751
+ iconSize: iconSize2,
1623
1752
  children
1624
1753
  }
1625
1754
  )
@@ -1696,8 +1825,18 @@ function asPlainStyle(style) {
1696
1825
  function withHtmlProps(Component) {
1697
1826
  return Component;
1698
1827
  }
1699
- var DEFAULT_TOOLTIP_DELAY_MS = 150;
1700
- var SKIP_DELAY_WINDOW_MS = 400;
1828
+
1829
+ // src/tokens/components/interaction.ts
1830
+ var interaction = {
1831
+ /**
1832
+ * Tooltips. The first one waits so a sweeping pointer does not strobe;
1833
+ * once one is open, its neighbours open instantly if the pointer arrives
1834
+ * within the skip window. Radix Tooltip defaults: delayDuration 700,
1835
+ * skipDelayDuration 300. Vercel/Kowalski: "delay the first tooltip only".
1836
+ */
1837
+ tooltip: { delayMs: 700, skipWindowMs: 300 }};
1838
+ var DEFAULT_TOOLTIP_DELAY_MS = interaction.tooltip.delayMs;
1839
+ var SKIP_DELAY_WINDOW_MS = interaction.tooltip.skipWindowMs;
1701
1840
  var lastTooltipOpenAt = 0;
1702
1841
  var skipDelayListeners = /* @__PURE__ */ new Set();
1703
1842
  function markTooltipOpened() {
@@ -1708,8 +1847,8 @@ function shouldSkipDelay() {
1708
1847
  return Date.now() - lastTooltipOpenAt < SKIP_DELAY_WINDOW_MS;
1709
1848
  }
1710
1849
  function useSkipDelay() {
1711
- const [, tick] = React.useReducer((count) => count + 1, 0);
1712
- React.useEffect(() => {
1850
+ const [, tick] = React10.useReducer((count) => count + 1, 0);
1851
+ React10.useEffect(() => {
1713
1852
  skipDelayListeners.add(tick);
1714
1853
  return () => {
1715
1854
  skipDelayListeners.delete(tick);
@@ -1717,7 +1856,7 @@ function useSkipDelay() {
1717
1856
  }, []);
1718
1857
  return shouldSkipDelay();
1719
1858
  }
1720
- var TooltipInstantContext = React.createContext(false);
1859
+ var TooltipInstantContext = React10.createContext(false);
1721
1860
  var TooltipProvider = ({
1722
1861
  children,
1723
1862
  delayDuration = DEFAULT_TOOLTIP_DELAY_MS
@@ -1752,7 +1891,7 @@ var TooltipTrigger = ({
1752
1891
  ref,
1753
1892
  ...props
1754
1893
  }) => {
1755
- if (asChild && React.isValidElement(children)) {
1894
+ if (asChild && React10.isValidElement(children)) {
1756
1895
  return /* @__PURE__ */ jsx(
1757
1896
  Tooltip$1.Trigger,
1758
1897
  {
@@ -1775,7 +1914,7 @@ var TooltipContent = ({
1775
1914
  ref,
1776
1915
  ...props
1777
1916
  }) => {
1778
- const instant = React.use(TooltipInstantContext);
1917
+ const instant = React10.use(TooltipInstantContext);
1779
1918
  return /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(
1780
1919
  Tooltip$1.Positioner,
1781
1920
  {
@@ -1891,7 +2030,7 @@ var tabsContentVariants = cva(
1891
2030
  }
1892
2031
  }
1893
2032
  );
1894
- var TabsContext = React.createContext({
2033
+ var TabsContext = React10.createContext({
1895
2034
  activationMode: "manual",
1896
2035
  disabled: false,
1897
2036
  shape: "default",
@@ -1949,7 +2088,7 @@ function Tabs({
1949
2088
  }) {
1950
2089
  const rootValue = selected ?? value;
1951
2090
  const rootDefaultValue = defaultValue ?? getFirstEnabledValue(tabs);
1952
- const context = React.useMemo(
2091
+ const context = React10.useMemo(
1953
2092
  () => ({ activationMode, disabled, shape, size, variant }),
1954
2093
  [activationMode, disabled, shape, size, variant]
1955
2094
  );
@@ -2035,11 +2174,11 @@ function TabsList({
2035
2174
  children,
2036
2175
  ...props
2037
2176
  }) {
2038
- const context = React.use(TabsContext);
2177
+ const context = React10.use(TabsContext);
2039
2178
  const resolvedVariant = variant ?? context.variant;
2040
2179
  const resolvedShape = shape ?? context.shape;
2041
2180
  const resolvedActivateOnFocus = activateOnFocus ?? context.activationMode === "automatic";
2042
- const listContext = React.useMemo(
2181
+ const listContext = React10.useMemo(
2043
2182
  () => ({ ...context, shape: resolvedShape, variant: resolvedVariant }),
2044
2183
  [context, resolvedShape, resolvedVariant]
2045
2184
  );
@@ -2076,7 +2215,7 @@ function TabsList({
2076
2215
  ) });
2077
2216
  }
2078
2217
  function TabsTrigger({ badge, children, className, disabled, icon, ...props }) {
2079
- const context = React.use(TabsContext);
2218
+ const context = React10.use(TabsContext);
2080
2219
  const isDisabled = disabled ?? context.disabled;
2081
2220
  return /* @__PURE__ */ jsxs(
2082
2221
  BaseTrigger,
@@ -2140,7 +2279,7 @@ var formControlFocusClassNames = {
2140
2279
  var formControlInvalidClassNames = {
2141
2280
  textarea: "aria-invalid:border-destructive/60 aria-invalid:focus:border-destructive aria-invalid:focus:ring-destructive/20"};
2142
2281
  var fieldMessageClassName = "text-xs text-muted-foreground";
2143
- var fieldErrorClassName = "text-xs font-medium text-destructive";
2282
+ var fieldErrorClassName = "text-xs font-medium text-destructive-strong";
2144
2283
  function getTextareaStyle(size, style) {
2145
2284
  const token = textareaTokens.sizes[size];
2146
2285
  return {
@@ -2175,6 +2314,7 @@ var Textarea = ({
2175
2314
  description,
2176
2315
  error,
2177
2316
  fieldClassName,
2317
+ tone = "bordered",
2178
2318
  id,
2179
2319
  onChange,
2180
2320
  onValueChange,
@@ -2183,13 +2323,13 @@ var Textarea = ({
2183
2323
  ref,
2184
2324
  ...props
2185
2325
  }) => {
2186
- const baseId = React.useId();
2326
+ const baseId = React10.useId();
2187
2327
  const textareaId = id ?? (label || description || typeof error === "string" ? baseId : void 0);
2188
2328
  const resolvedInvalid = isInvalid(error, ariaInvalid);
2189
2329
  const descriptionId = description && textareaId ? `${textareaId}-description` : void 0;
2190
2330
  const errorId = typeof error === "string" && textareaId ? `${textareaId}-error` : void 0;
2191
2331
  const describedBy = joinDescriptionIds(ariaDescribedBy, descriptionId, errorId);
2192
- const handleChange = React.useCallback(
2332
+ const handleChange = React10.useCallback(
2193
2333
  (event) => {
2194
2334
  onValueChange?.(event.currentTarget.value);
2195
2335
  onChange?.(event);
@@ -2200,10 +2340,10 @@ var Textarea = ({
2200
2340
  "textarea",
2201
2341
  {
2202
2342
  className: cn(
2203
- "flex min-h-[var(--textarea-min-height)] w-full resize-y rounded-[var(--textarea-radius)] border border-input bg-background",
2204
- "px-[var(--textarea-padding-x)] py-[var(--textarea-padding-y)] text-[length:var(--textarea-font-size)] text-foreground shadow-xs",
2343
+ "flex min-h-[var(--textarea-min-height)] w-full resize-y rounded-[var(--textarea-radius)]",
2344
+ "px-[var(--textarea-padding-x)] py-[var(--textarea-padding-y)] text-[length:var(--textarea-font-size)] text-foreground",
2205
2345
  "transition-[background-color,border-color,box-shadow,color] duration-micro ease-out placeholder:text-muted-foreground",
2206
- formControlFocusClassNames.textarea,
2346
+ tone === "bordered" ? `border border-input bg-background ${formControlFocusClassNames.textarea}` : "border-0 bg-transparent shadow-none",
2207
2347
  "disabled:cursor-not-allowed disabled:opacity-50 read-only:cursor-default read-only:bg-muted/70",
2208
2348
  formControlInvalidClassNames.textarea,
2209
2349
  className
@@ -2309,6 +2449,17 @@ function MarkdownRenderer({ content, className }) {
2309
2449
  }
2310
2450
  ) });
2311
2451
  }
2452
+ var DEFAULT_MARKDOWN_EDITOR_LABELS = {
2453
+ bold: "Bold (Ctrl+B)",
2454
+ italic: "Italic (Ctrl+I)",
2455
+ inlineCode: "Inline code",
2456
+ heading: "Heading",
2457
+ blockQuote: "Block quote",
2458
+ bulletList: "Bullet list",
2459
+ link: "Link",
2460
+ image: "Image",
2461
+ fencedCodeBlock: "Fenced code block"
2462
+ };
2312
2463
  function QuoteGlyph(props) {
2313
2464
  return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": "true", className: props.className, children: [
2314
2465
  /* @__PURE__ */ jsx("title", { children: "Block quote" }),
@@ -2317,11 +2468,15 @@ function QuoteGlyph(props) {
2317
2468
  }
2318
2469
  function MarkdownEditor({
2319
2470
  value,
2320
- onChange,
2471
+ onValueChange,
2472
+ onChange: legacyOnChange,
2321
2473
  placeholder = "Write your answer here\u2026",
2322
2474
  minHeight = 250,
2323
- className
2475
+ className,
2476
+ labels
2324
2477
  }) {
2478
+ const onChange = onValueChange ?? legacyOnChange;
2479
+ const mergedLabels = { ...DEFAULT_MARKDOWN_EDITOR_LABELS, ...labels };
2325
2480
  const [tab, setTab] = useState("write");
2326
2481
  const textareaRef = useRef(null);
2327
2482
  const insertMarkdown = useCallback(
@@ -2361,14 +2516,42 @@ function MarkdownEditor({
2361
2516
  ] })
2362
2517
  ] }),
2363
2518
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1", children: [
2364
- /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Bold (Ctrl+B)", onClick: () => insertMarkdown("**", "**"), children: /* @__PURE__ */ jsx(TextBold, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
2365
- /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Italic (Ctrl+I)", onClick: () => insertMarkdown("*", "*"), children: /* @__PURE__ */ jsx(TextItalic, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
2366
- /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Inline code", onClick: () => insertMarkdown("`", "`"), children: /* @__PURE__ */ jsx(Code, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
2367
- /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Heading", onClick: () => insertMarkdown("\n## ", "", true), children: /* @__PURE__ */ jsx(Hash, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
2368
2519
  /* @__PURE__ */ jsx(
2369
2520
  ToolbarButton,
2370
2521
  {
2371
- "aria-label": "Block quote",
2522
+ "aria-label": mergedLabels.bold,
2523
+ onClick: () => insertMarkdown("**", "**"),
2524
+ children: /* @__PURE__ */ jsx(TextBold, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
2525
+ }
2526
+ ),
2527
+ /* @__PURE__ */ jsx(
2528
+ ToolbarButton,
2529
+ {
2530
+ "aria-label": mergedLabels.italic,
2531
+ onClick: () => insertMarkdown("*", "*"),
2532
+ children: /* @__PURE__ */ jsx(TextItalic, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
2533
+ }
2534
+ ),
2535
+ /* @__PURE__ */ jsx(
2536
+ ToolbarButton,
2537
+ {
2538
+ "aria-label": mergedLabels.inlineCode,
2539
+ onClick: () => insertMarkdown("`", "`"),
2540
+ children: /* @__PURE__ */ jsx(Code, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
2541
+ }
2542
+ ),
2543
+ /* @__PURE__ */ jsx(
2544
+ ToolbarButton,
2545
+ {
2546
+ "aria-label": mergedLabels.heading,
2547
+ onClick: () => insertMarkdown("\n## ", "", true),
2548
+ children: /* @__PURE__ */ jsx(Hash, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
2549
+ }
2550
+ ),
2551
+ /* @__PURE__ */ jsx(
2552
+ ToolbarButton,
2553
+ {
2554
+ "aria-label": mergedLabels.blockQuote,
2372
2555
  onClick: () => insertMarkdown("\n> ", "", true),
2373
2556
  children: /* @__PURE__ */ jsx(QuoteGlyph, { className: "h-3.5 w-3.5" })
2374
2557
  }
@@ -2376,17 +2559,31 @@ function MarkdownEditor({
2376
2559
  /* @__PURE__ */ jsx(
2377
2560
  ToolbarButton,
2378
2561
  {
2379
- "aria-label": "Bullet list",
2562
+ "aria-label": mergedLabels.bulletList,
2380
2563
  onClick: () => insertMarkdown("\n- ", "", true),
2381
2564
  children: /* @__PURE__ */ jsx(ListUnordered, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
2382
2565
  }
2383
2566
  ),
2384
- /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Link", onClick: () => insertMarkdown("[", "](url)"), children: /* @__PURE__ */ jsx(Link, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
2385
- /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Image", onClick: () => insertMarkdown("![alt text](", ")"), children: /* @__PURE__ */ jsx(Image, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
2386
2567
  /* @__PURE__ */ jsx(
2387
2568
  ToolbarButton,
2388
2569
  {
2389
- "aria-label": "Fenced code block",
2570
+ "aria-label": mergedLabels.link,
2571
+ onClick: () => insertMarkdown("[", "](url)"),
2572
+ children: /* @__PURE__ */ jsx(Link, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
2573
+ }
2574
+ ),
2575
+ /* @__PURE__ */ jsx(
2576
+ ToolbarButton,
2577
+ {
2578
+ "aria-label": mergedLabels.image,
2579
+ onClick: () => insertMarkdown("![alt text](", ")"),
2580
+ children: /* @__PURE__ */ jsx(Image, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
2581
+ }
2582
+ ),
2583
+ /* @__PURE__ */ jsx(
2584
+ ToolbarButton,
2585
+ {
2586
+ "aria-label": mergedLabels.fencedCodeBlock,
2390
2587
  onClick: () => insertMarkdown("\n```javascript\n", "\n```\n", true),
2391
2588
  children: /* @__PURE__ */ jsx(FileText, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
2392
2589
  }
@@ -2400,7 +2597,8 @@ function MarkdownEditor({
2400
2597
  value,
2401
2598
  onChange: (e) => onChange(e.target.value),
2402
2599
  placeholder,
2403
- className: "resize-none rounded-none border-0 font-mono text-sm shadow-none",
2600
+ tone: "bare",
2601
+ className: "resize-none rounded-none font-mono text-sm",
2404
2602
  style: { minHeight }
2405
2603
  }
2406
2604
  ) }),
@@ -2435,34 +2633,6 @@ function ToolbarButton({
2435
2633
  }
2436
2634
  );
2437
2635
  }
2438
- var Card2 = ({
2439
- className,
2440
- ref,
2441
- ...props
2442
- }) => /* @__PURE__ */ jsx(
2443
- "div",
2444
- {
2445
- ref,
2446
- className: cn(
2447
- "rounded-[var(--radius-lg)] border border-border bg-card text-card-foreground shadow-sm",
2448
- className
2449
- ),
2450
- ...props
2451
- }
2452
- );
2453
- Card2.displayName = "Card";
2454
- var CardHeader2 = ({
2455
- className,
2456
- ref,
2457
- ...props
2458
- }) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props });
2459
- CardHeader2.displayName = "CardHeader";
2460
- var CardContent = ({
2461
- className,
2462
- ref,
2463
- ...props
2464
- }) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props });
2465
- CardContent.displayName = "CardContent";
2466
2636
  var Separator = ({
2467
2637
  className,
2468
2638
  orientation = "horizontal",
@@ -2491,7 +2661,7 @@ var sizeClasses = {
2491
2661
  xl: { root: "h-20 w-20", fallback: "text-2xl" }
2492
2662
  };
2493
2663
  var numericAvatarClass = "h-[var(--avatar-size)] w-[var(--avatar-size)]";
2494
- var AvatarContext = React.createContext(null);
2664
+ var AvatarContext = React10.createContext(null);
2495
2665
  function isPresetSize(size) {
2496
2666
  return typeof size === "string";
2497
2667
  }
@@ -2593,7 +2763,7 @@ var AvatarFallback = ({
2593
2763
  ref,
2594
2764
  ...props
2595
2765
  }) => {
2596
- const context = React.use(AvatarContext);
2766
+ const context = React10.use(AvatarContext);
2597
2767
  const resolvedSize = size ?? context?.size ?? "md";
2598
2768
  const fallbackLabel = ariaLabel ?? (typeof children === "string" && children.trim().length > 0 ? `Avatar with initials: ${children}` : context?.title);
2599
2769
  return /* @__PURE__ */ jsx(
@@ -2635,9 +2805,10 @@ function UserInfo({ author, timestamp, verb = "asked", className }) {
2635
2805
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
2636
2806
  /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground text-sm", children: author.name }),
2637
2807
  /* @__PURE__ */ jsx("span", { className: "font-bold text-muted-foreground text-xs tabular-nums", children: author.reputation.toLocaleString() }),
2638
- author.badges.gold > 0 && /* @__PURE__ */ jsx(Badge2, { color: "bg-yellow-500", count: author.badges.gold, label: "gold" }),
2639
- author.badges.silver > 0 && /* @__PURE__ */ jsx(Badge2, { color: "bg-gray-400", count: author.badges.silver, label: "silver" }),
2640
- author.badges.bronze > 0 && /* @__PURE__ */ jsx(Badge2, { color: "bg-amber-600", count: author.badges.bronze, label: "bronze" })
2808
+ author.badges.gold > 0 && /* @__PURE__ */ jsx(Badge2, { color: "bg-warning", count: author.badges.gold, label: "gold" }),
2809
+ author.badges.silver > 0 && /* @__PURE__ */ jsx(Badge2, { color: "bg-neutral-9", count: author.badges.silver, label: "silver" }),
2810
+ author.badges.bronze > 0 && // allow-palette: bronze medal tier has no design-system equivalent; amber-600 is the closest fixed hue and is distinct from the gold (warning) dot above
2811
+ /* @__PURE__ */ jsx(Badge2, { color: "bg-amber-600", count: author.badges.bronze, label: "bronze" })
2641
2812
  ] })
2642
2813
  ] })
2643
2814
  ]
@@ -2668,7 +2839,7 @@ function VoteButtons({
2668
2839
  size = "default",
2669
2840
  label = "post"
2670
2841
  }) {
2671
- const iconSize = size === "large" ? "h-5 w-5" : "h-4 w-4";
2842
+ const iconSize2 = size === "large" ? "h-5 w-5" : "h-4 w-4";
2672
2843
  const scoreSize = size === "large" ? "text-lg" : "text-base";
2673
2844
  const score = votes + voteDelta(userVote);
2674
2845
  return /* @__PURE__ */ jsxs("fieldset", { className: "flex flex-col items-center gap-2", children: [
@@ -2686,7 +2857,7 @@ function VoteButtons({
2686
2857
  "aria-pressed": userVote === "up",
2687
2858
  onClick: () => onVote("up"),
2688
2859
  className: cn("p-2", userVote === "up" && "bg-primary/10 text-primary hover:bg-primary/15"),
2689
- children: /* @__PURE__ */ jsx(ChevronUp, { className: iconSize, "aria-hidden": "true" })
2860
+ children: /* @__PURE__ */ jsx(ChevronUp, { className: iconSize2, "aria-hidden": "true" })
2690
2861
  }
2691
2862
  ),
2692
2863
  /* @__PURE__ */ jsx(
@@ -2716,7 +2887,7 @@ function VoteButtons({
2716
2887
  "p-2",
2717
2888
  userVote === "down" && "bg-muted text-muted-foreground hover:bg-muted"
2718
2889
  ),
2719
- children: /* @__PURE__ */ jsx(ChevronDown, { className: iconSize, "aria-hidden": "true" })
2890
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: iconSize2, "aria-hidden": "true" })
2720
2891
  }
2721
2892
  )
2722
2893
  ] });
@@ -2807,7 +2978,7 @@ function QAPage({
2807
2978
  ] }),
2808
2979
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: question.tags.map((tag) => /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: tag }, tag)) })
2809
2980
  ] }),
2810
- /* @__PURE__ */ jsx(Card2, { className: "mb-8", children: /* @__PURE__ */ jsxs(CardContent, { className: "flex gap-6 p-6", children: [
2981
+ /* @__PURE__ */ jsx(Card, { className: "mb-8", children: /* @__PURE__ */ jsxs(CardContent, { className: "flex gap-6 p-6", children: [
2811
2982
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4", children: [
2812
2983
  /* @__PURE__ */ jsx(
2813
2984
  VoteButtons,
@@ -2828,7 +2999,7 @@ function QAPage({
2828
2999
  "aria-label": question.bookmarked ? "Remove bookmark" : "Bookmark question",
2829
3000
  "aria-pressed": question.bookmarked,
2830
3001
  onClick: handleBookmarkToggle,
2831
- className: cn("p-2", question.bookmarked && "bg-warning/10 text-warning"),
3002
+ className: cn("p-2", question.bookmarked && "bg-warning/10 text-warning-strong"),
2832
3003
  children: /* @__PURE__ */ jsx(Bookmark, { className: "h-4 w-4", "aria-hidden": "true" })
2833
3004
  }
2834
3005
  )
@@ -2855,7 +3026,7 @@ function QAPage({
2855
3026
  answers.length === 1 ? "Answer" : "Answers"
2856
3027
  ] }) }),
2857
3028
  /* @__PURE__ */ jsx("div", { className: "mb-8", children: sortedAnswers.map((answer, index) => /* @__PURE__ */ jsxs(Fragment, { children: [
2858
- /* @__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: [
3029
+ /* @__PURE__ */ jsx(Card, { className: cn("mb-6", answer.isAccepted && "ring-2 ring-success/40"), children: /* @__PURE__ */ jsxs(CardContent, { className: "flex gap-6 p-6", children: [
2859
3030
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4", children: [
2860
3031
  /* @__PURE__ */ jsx(
2861
3032
  VoteButtons,
@@ -2876,13 +3047,19 @@ function QAPage({
2876
3047
  "aria-label": answer.isAccepted ? "Unaccept this answer" : "Accept this answer",
2877
3048
  "aria-pressed": answer.isAccepted,
2878
3049
  onClick: () => handleAccept(answer.id),
2879
- className: cn("p-2", answer.isAccepted && "bg-success/10 text-success"),
3050
+ className: cn("p-2", answer.isAccepted && "bg-success/10 text-success-strong"),
2880
3051
  children: /* @__PURE__ */ jsx(Check, { className: "h-5 w-5", "aria-hidden": "true" })
2881
3052
  }
2882
3053
  ),
2883
3054
  answer.isAccepted && /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
2884
- /* @__PURE__ */ jsx(StarFill, { "aria-hidden": "true", className: "mx-auto mb-1 h-4 w-4 text-success" }),
2885
- /* @__PURE__ */ jsx("span", { className: "font-medium text-success text-xs", children: "Accepted" })
3055
+ /* @__PURE__ */ jsx(
3056
+ StarFill,
3057
+ {
3058
+ "aria-hidden": "true",
3059
+ className: "mx-auto mb-1 h-4 w-4 text-success-strong"
3060
+ }
3061
+ ),
3062
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-success-strong text-xs", children: "Accepted" })
2886
3063
  ] })
2887
3064
  ] }),
2888
3065
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
@@ -2903,10 +3080,17 @@ function QAPage({
2903
3080
  ] }) }),
2904
3081
  index < sortedAnswers.length - 1 && /* @__PURE__ */ jsx(Separator, { className: "mb-6" })
2905
3082
  ] }, answer.id)) }),
2906
- /* @__PURE__ */ jsxs(Card2, { children: [
2907
- /* @__PURE__ */ jsx(CardHeader2, { children: /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground text-lg", children: "Your Answer" }) }),
3083
+ /* @__PURE__ */ jsxs(Card, { children: [
3084
+ /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground text-lg", children: "Your Answer" }) }),
2908
3085
  /* @__PURE__ */ jsxs(CardContent, { className: "space-y-4", children: [
2909
- /* @__PURE__ */ jsx(MarkdownEditor, { value: draft, onChange: setDraft, placeholder: "Write your answer here\u2026" }),
3086
+ /* @__PURE__ */ jsx(
3087
+ MarkdownEditor,
3088
+ {
3089
+ value: draft,
3090
+ onValueChange: setDraft,
3091
+ placeholder: "Write your answer here\u2026"
3092
+ }
3093
+ ),
2910
3094
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
2911
3095
  /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-xs", children: "Thanks for contributing an answer!" }),
2912
3096
  /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
@@ -2954,7 +3138,7 @@ function PostActions({
2954
3138
  /* @__PURE__ */ jsx(UserInfo, { author, timestamp, verb })
2955
3139
  ] });
2956
3140
  }
2957
- var CollapsibleContext = React.createContext({});
3141
+ var CollapsibleContext = React10.createContext({});
2958
3142
  var Collapsible = ({
2959
3143
  className,
2960
3144
  open: openProp,
@@ -2965,10 +3149,10 @@ var Collapsible = ({
2965
3149
  ref,
2966
3150
  ...props
2967
3151
  }) => {
2968
- const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen || false);
3152
+ const [uncontrolledOpen, setUncontrolledOpen] = React10.useState(defaultOpen || false);
2969
3153
  const isControlled = openProp !== void 0;
2970
3154
  const open = isControlled ? openProp : uncontrolledOpen;
2971
- const handleOpenChange = React.useCallback(
3155
+ const handleOpenChange = React10.useCallback(
2972
3156
  (nextOpen) => {
2973
3157
  if (!isControlled) {
2974
3158
  setUncontrolledOpen(nextOpen);
@@ -2997,8 +3181,8 @@ var CollapsibleTrigger = ({
2997
3181
  ref,
2998
3182
  ...props
2999
3183
  }) => {
3000
- const { open, onOpenChange, disabled } = React.use(CollapsibleContext);
3001
- const handleClick = React.useCallback(
3184
+ const { open, onOpenChange, disabled } = React10.use(CollapsibleContext);
3185
+ const handleClick = React10.useCallback(
3002
3186
  (e) => {
3003
3187
  if (disabled) return;
3004
3188
  onOpenChange?.(!open);
@@ -3006,8 +3190,8 @@ var CollapsibleTrigger = ({
3006
3190
  },
3007
3191
  [disabled, open, onOpenChange, props.onClick]
3008
3192
  );
3009
- if (asChild && React.isValidElement(children)) {
3010
- return React.cloneElement(children, {
3193
+ if (asChild && React10.isValidElement(children)) {
3194
+ return React10.cloneElement(children, {
3011
3195
  ref,
3012
3196
  onClick: handleClick,
3013
3197
  "data-state": open ? "open" : "closed",
@@ -3041,7 +3225,7 @@ var CollapsibleContent = ({
3041
3225
  ref,
3042
3226
  ...props
3043
3227
  }) => {
3044
- const { open } = React.use(CollapsibleContext);
3228
+ const { open } = React10.use(CollapsibleContext);
3045
3229
  const shouldReduceMotion = useReducedMotion();
3046
3230
  return /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: open && /* @__PURE__ */ jsx(
3047
3231
  motion.div,
@@ -3061,9 +3245,9 @@ var CollapsibleContent = ({
3061
3245
  ) });
3062
3246
  };
3063
3247
  CollapsibleContent.displayName = "CollapsibleContent";
3064
- 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]";
3065
- var ITEM_DEFAULT_CLASSES = "text-sidebar-foreground/72 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground";
3066
- 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";
3248
+ 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] duration-micro ease-brand";
3249
+ var ITEM_DEFAULT_CLASSES = "text-sidebar-foreground/72 hover:bg-sidebar-accent/55 hover:text-sidebar-foreground";
3250
+ var ITEM_ACTIVE_CLASSES = "bg-sidebar-accent text-sidebar-foreground font-medium shadow-[inset_0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent";
3067
3251
  var ITEM_DISABLED_CLASSES = "opacity-50 pointer-events-none";
3068
3252
  var ITEM_COLLAPSED_CLASSES = "justify-center px-0 size-8 mx-auto";
3069
3253
  var ICON_CLASSES = "size-4 shrink-0";
@@ -3096,19 +3280,19 @@ function ItemContent({
3096
3280
  const Icon = item.icon;
3097
3281
  if (collapsed) {
3098
3282
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
3099
- Icon ? /* @__PURE__ */ jsx(Icon, { className: ICON_CLASSES }) : null,
3283
+ Icon ? /* @__PURE__ */ jsx(Icon, { className: cn(ICON_CLASSES, item.isActive && "text-sidebar-primary") }) : null,
3100
3284
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: item.label })
3101
3285
  ] });
3102
3286
  }
3103
3287
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
3104
- Icon ? /* @__PURE__ */ jsx(Icon, { className: ICON_CLASSES }) : null,
3288
+ Icon ? /* @__PURE__ */ jsx(Icon, { className: cn(ICON_CLASSES, item.isActive && "text-sidebar-primary") }) : null,
3105
3289
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: item.label }),
3106
3290
  item.badge ? /* @__PURE__ */ jsx(Badge, { variant: item.badge.tone, size: "sm", children: item.badge.label }) : null,
3107
3291
  showChevron ? /* @__PURE__ */ jsx(
3108
3292
  ChevronRight,
3109
3293
  {
3110
3294
  className: cn(
3111
- "size-3.5 shrink-0 text-muted-foreground transition-transform",
3295
+ "size-3.5 shrink-0 text-sidebar-foreground/50 transition-transform duration-micro ease-brand",
3112
3296
  chevronOpen && "rotate-90"
3113
3297
  ),
3114
3298
  "aria-hidden": "true"
@@ -3192,12 +3376,12 @@ function ParentItem({
3192
3376
  renderLink
3193
3377
  }) {
3194
3378
  const hasActiveChild = item.children?.some((c) => c.isActive === true) ?? false;
3195
- const [uncontrolledOpen, setUncontrolledOpen] = React.useState(
3379
+ const [uncontrolledOpen, setUncontrolledOpen] = React10.useState(
3196
3380
  item.isActive === true || hasActiveChild
3197
3381
  );
3198
3382
  const isControlled = item.expanded !== void 0 && item.onExpandedChange !== void 0;
3199
3383
  const open = isControlled ? item.expanded : uncontrolledOpen;
3200
- const setOpen = React.useCallback(
3384
+ const setOpen = React10.useCallback(
3201
3385
  (next) => {
3202
3386
  if (isControlled) {
3203
3387
  item.onExpandedChange?.(next);
@@ -3256,12 +3440,13 @@ function SidebarNav({
3256
3440
  itemClassName,
3257
3441
  header,
3258
3442
  footer,
3259
- renderLink = defaultRenderLink
3443
+ renderLink = defaultRenderLink,
3444
+ navLabel = "Sidebar"
3260
3445
  }) {
3261
3446
  return /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs(
3262
3447
  "nav",
3263
3448
  {
3264
- "aria-label": "Sidebar",
3449
+ "aria-label": navLabel,
3265
3450
  "data-ui": "nebutra-sidebar-nav",
3266
3451
  className: cn(
3267
3452
  "flex h-full flex-col",
@@ -3318,13 +3503,13 @@ function SidebarNav({
3318
3503
  }
3319
3504
  ) });
3320
3505
  }
3321
- var TerminalContext = React.createContext(null);
3322
- var variantStyles2 = {
3506
+ var TerminalContext = React10.createContext(null);
3507
+ var variantStyles = {
3323
3508
  default: "bg-muted border border-border",
3324
3509
  minimal: "bg-background border border-border",
3325
3510
  glass: "bg-muted backdrop-blur-md border border-border"
3326
3511
  };
3327
- var TerminalRoot = React.forwardRef(
3512
+ var TerminalRoot = React10.forwardRef(
3328
3513
  ({ className, variant = "default", children, ...props }, ref) => {
3329
3514
  return /* @__PURE__ */ jsx(TerminalContext.Provider, { value: { variant }, children: /* @__PURE__ */ jsx(
3330
3515
  "div",
@@ -3332,7 +3517,7 @@ var TerminalRoot = React.forwardRef(
3332
3517
  ref,
3333
3518
  className: cn(
3334
3519
  "rounded-[var(--radius-xl)] overflow-hidden font-mono text-sm",
3335
- variantStyles2[variant],
3520
+ variantStyles[variant],
3336
3521
  className
3337
3522
  ),
3338
3523
  ...props,
@@ -3342,7 +3527,7 @@ var TerminalRoot = React.forwardRef(
3342
3527
  }
3343
3528
  );
3344
3529
  TerminalRoot.displayName = "Terminal";
3345
- var TerminalHeader = React.forwardRef(
3530
+ var TerminalHeader = React10.forwardRef(
3346
3531
  ({ className, title, showControls = true, children, ...props }, ref) => {
3347
3532
  return /* @__PURE__ */ jsxs(
3348
3533
  "div",
@@ -3367,13 +3552,13 @@ var TerminalHeader = React.forwardRef(
3367
3552
  }
3368
3553
  );
3369
3554
  TerminalHeader.displayName = "Terminal.Header";
3370
- var TerminalBody = React.forwardRef(
3555
+ var TerminalBody = React10.forwardRef(
3371
3556
  ({ className, children, ...props }, ref) => {
3372
3557
  return /* @__PURE__ */ jsx("div", { ref, className: cn("p-4 space-y-1", className), ...props, children });
3373
3558
  }
3374
3559
  );
3375
3560
  TerminalBody.displayName = "Terminal.Body";
3376
- var TerminalLine = React.forwardRef(
3561
+ var TerminalLine = React10.forwardRef(
3377
3562
  ({ className, prompt = "$", output = false, highlight = false, children, ...props }, ref) => {
3378
3563
  return /* @__PURE__ */ jsxs(
3379
3564
  "div",
@@ -3386,7 +3571,7 @@ var TerminalLine = React.forwardRef(
3386
3571
  ),
3387
3572
  ...props,
3388
3573
  children: [
3389
- !output && /* @__PURE__ */ jsx("span", { className: "text-emerald-400 shrink-0 select-none", children: prompt }),
3574
+ !output && /* @__PURE__ */ jsx("span", { className: "text-success-strong shrink-0 select-none", children: prompt }),
3390
3575
  /* @__PURE__ */ jsx("span", { className: cn("flex-1", output ? "text-muted-foreground" : "text-muted-foreground"), children })
3391
3576
  ]
3392
3577
  }
@@ -3428,7 +3613,7 @@ function subscribePlatform() {
3428
3613
  return () => void 0;
3429
3614
  }
3430
3615
  function usePlatform() {
3431
- return React.useSyncExternalStore(subscribePlatform, getClientPlatform, () => "apple");
3616
+ return React10.useSyncExternalStore(subscribePlatform, getClientPlatform, () => "apple");
3432
3617
  }
3433
3618
  function normalizeKey(children) {
3434
3619
  if (typeof children !== "string") {
@@ -3502,13 +3687,16 @@ function computeInitials(user) {
3502
3687
  }
3503
3688
  return source.slice(0, 2).toUpperCase();
3504
3689
  }
3505
- function DefaultTrigger({ user }) {
3690
+ function DefaultTrigger({
3691
+ user,
3692
+ triggerLabel = "Open user menu"
3693
+ }) {
3506
3694
  const initials2 = computeInitials(user);
3507
3695
  return /* @__PURE__ */ jsx(
3508
3696
  "button",
3509
3697
  {
3510
3698
  type: "button",
3511
- "aria-label": "Open user menu",
3699
+ "aria-label": triggerLabel,
3512
3700
  className: cn(
3513
3701
  "inline-flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full",
3514
3702
  "outline-none transition-[box-shadow,opacity] hover:opacity-90",
@@ -3517,7 +3705,7 @@ function DefaultTrigger({ user }) {
3517
3705
  ),
3518
3706
  children: /* @__PURE__ */ jsxs(Avatar, { size: "sm", children: [
3519
3707
  user.avatarUrl ? /* @__PURE__ */ jsx(AvatarImage, { src: user.avatarUrl, alt: user.name }) : null,
3520
- /* @__PURE__ */ jsx(AvatarFallback, { size: "sm", className: "bg-primary text-white", children: initials2 })
3708
+ /* @__PURE__ */ jsx(AvatarFallback, { size: "sm", className: "bg-primary text-primary-foreground", children: initials2 })
3521
3709
  ] })
3522
3710
  }
3523
3711
  );
@@ -3538,16 +3726,17 @@ function UserMenu(props) {
3538
3726
  renderTrigger,
3539
3727
  renderLink,
3540
3728
  className,
3541
- align = "end"
3729
+ align = "end",
3730
+ triggerLabel
3542
3731
  } = props;
3543
3732
  const initials2 = computeInitials(user);
3544
3733
  return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
3545
- /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: renderTrigger ? renderTrigger(user) : /* @__PURE__ */ jsx(DefaultTrigger, { user }) }),
3734
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: renderTrigger ? renderTrigger(user) : /* @__PURE__ */ jsx(DefaultTrigger, { user, ...triggerLabel !== void 0 ? { triggerLabel } : {} }) }),
3546
3735
  /* @__PURE__ */ jsxs(DropdownMenuContent, { align, sideOffset: 8, className: cn("w-[280px] p-1", className), children: [
3547
3736
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 p-3", children: [
3548
3737
  /* @__PURE__ */ jsxs(Avatar, { size: "md", children: [
3549
3738
  user.avatarUrl ? /* @__PURE__ */ jsx(AvatarImage, { src: user.avatarUrl, alt: user.name }) : null,
3550
- /* @__PURE__ */ jsx(AvatarFallback, { size: "md", className: "bg-primary text-white", children: initials2 })
3739
+ /* @__PURE__ */ jsx(AvatarFallback, { size: "md", className: "bg-primary text-primary-foreground", children: initials2 })
3551
3740
  ] }),
3552
3741
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
3553
3742
  /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-medium text-foreground", children: user.name }),
@@ -3561,12 +3750,12 @@ function UserMenu(props) {
3561
3750
  ] }) : null,
3562
3751
  groups.map((group, groupIndex) => {
3563
3752
  const isLastGroup = groupIndex === groups.length - 1;
3564
- return /* @__PURE__ */ jsxs(React.Fragment, { children: [
3753
+ return /* @__PURE__ */ jsxs(React10.Fragment, { children: [
3565
3754
  group.label ? /* @__PURE__ */ jsx("div", { className: "px-2 py-1 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: group.label }) : null,
3566
3755
  group.items.map((item) => {
3567
3756
  const itemClassName = cn(
3568
3757
  "flex w-full cursor-pointer items-center",
3569
- item.destructive && "text-destructive focus:bg-destructive focus:text-destructive-foreground data-[highlighted]:bg-destructive data-[highlighted]:text-destructive-foreground"
3758
+ item.destructive && "text-destructive-strong focus:bg-destructive focus:text-destructive-foreground data-[highlighted]:bg-destructive data-[highlighted]:text-destructive-foreground"
3570
3759
  );
3571
3760
  if (item.href && !item.disabled) {
3572
3761
  const linkContent = /* @__PURE__ */ jsx(UserMenuItemContent, { item });
@@ -3638,7 +3827,7 @@ function WorkspaceAvatar({ workspace, size = "sm", className }) {
3638
3827
  AvatarFallback,
3639
3828
  {
3640
3829
  size,
3641
- className: "rounded-[var(--radius-md)] bg-primary text-white font-semibold",
3830
+ className: "rounded-[var(--radius-md)] bg-primary text-primary-foreground font-semibold",
3642
3831
  children: initials2
3643
3832
  }
3644
3833
  )
@@ -3650,6 +3839,7 @@ function TriggerButton({
3650
3839
  showRoleBadge,
3651
3840
  disabled,
3652
3841
  className,
3842
+ switchLabel = "Switch workspace",
3653
3843
  ref
3654
3844
  }) {
3655
3845
  const isOwner = activeWorkspace.role === "owner";
@@ -3659,7 +3849,7 @@ function TriggerButton({
3659
3849
  {
3660
3850
  ref,
3661
3851
  type: "button",
3662
- "aria-label": "Switch workspace",
3852
+ "aria-label": switchLabel,
3663
3853
  disabled,
3664
3854
  className: cn(
3665
3855
  "inline-flex items-center gap-1 rounded-[var(--radius-md)] p-1 outline-none transition-colors",
@@ -3680,7 +3870,7 @@ function TriggerButton({
3680
3870
  {
3681
3871
  ref,
3682
3872
  type: "button",
3683
- "aria-label": "Switch workspace",
3873
+ "aria-label": switchLabel,
3684
3874
  disabled,
3685
3875
  className: cn(
3686
3876
  "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",
@@ -3715,8 +3905,8 @@ function WorkspaceItem({ workspace, isActive, onSelect }) {
3715
3905
  "span",
3716
3906
  {
3717
3907
  className: cn(
3718
- "truncate text-sm text-foreground",
3719
- isActive ? "font-semibold" : "font-medium"
3908
+ "truncate font-medium text-sm",
3909
+ isActive ? "text-foreground" : "text-foreground/80"
3720
3910
  ),
3721
3911
  children: workspace.name
3722
3912
  }
@@ -3741,7 +3931,8 @@ function WorkspaceSwitcher({
3741
3931
  headerSlot,
3742
3932
  className,
3743
3933
  showRoleBadge = true,
3744
- disabled = false
3934
+ disabled = false,
3935
+ switchLabel
3745
3936
  }) {
3746
3937
  const activeWorkspace = workspaces.find((ws) => ws.id === activeWorkspaceId) ?? workspaces[0];
3747
3938
  const handleSelect = (id) => {
@@ -3772,7 +3963,8 @@ function WorkspaceSwitcher({
3772
3963
  variant,
3773
3964
  showRoleBadge,
3774
3965
  disabled,
3775
- className
3966
+ className,
3967
+ ...switchLabel !== void 0 ? { switchLabel } : {}
3776
3968
  }
3777
3969
  ) }),
3778
3970
  /* @__PURE__ */ jsxs(