@nebutra/ui 0.2.2 → 0.2.3

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.
@@ -30,7 +30,7 @@ function ArtifactShiftCard({
30
30
  "div",
31
31
  {
32
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",
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-ambient-lg focus-within:-translate-y-1 focus-within:border-foreground/25",
34
34
  className
35
35
  ),
36
36
  "data-taste": "nebutra-shift-card",
@@ -71,7 +71,7 @@ function ArtifactShiftCardPreview({
71
71
  {
72
72
  "aria-label": label,
73
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",
74
+ "relative min-h-[260px] overflow-hidden rounded-[var(--radius-xl)] border border-border/60 bg-background/80 p-3 shadow-ambient-sm 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-ambient-md group-focus-within/card:-translate-y-1 group-focus-within/card:border-foreground/20 sm:p-4",
75
75
  className
76
76
  ),
77
77
  ...props,
@@ -122,7 +122,7 @@ function ArtifactShiftCardFooter({ className, ...props }) {
122
122
  "footer",
123
123
  {
124
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",
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-ambient-sm 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-ambient-md group-focus-within/card:-translate-y-2 group-focus-within/card:border-foreground/20",
126
126
  className
127
127
  ),
128
128
  ...props
@@ -150,7 +150,7 @@ var CardRoot = React.forwardRef(
150
150
  {
151
151
  ref,
152
152
  className: cn(
153
- "rounded-[var(--radius-xl)] transition-[background-color,border-color,box-shadow,color] duration-200",
153
+ "rounded-[var(--radius-xl)] transition-[background-color,border-color,box-shadow,color] duration-micro",
154
154
  variantStyles[variant],
155
155
  paddingMap[padding],
156
156
  className
@@ -377,7 +377,7 @@ function DashboardCommandSurface({
377
377
  /* @__PURE__ */ jsxs("div", { className: "relative z-10 flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between", children: [
378
378
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
379
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)]" }),
380
+ /* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-success shadow-[0_0_0_3px_hsl(var(--success)/0.18)]" }),
381
381
  /* @__PURE__ */ jsx("p", { className: "text-[11px] font-medium uppercase text-muted-foreground", children: status })
382
382
  ] }) : null,
383
383
  /* @__PURE__ */ jsx("h1", { className: "mt-2 text-2xl font-semibold tracking-normal text-card-foreground sm:text-[28px]", children: title }),
@@ -446,7 +446,7 @@ function DashboardMetricTile({
446
446
  {
447
447
  "data-pattern": "nebutra-dashboard-metric",
448
448
  className: cn(
449
- "group h-full rounded-[var(--radius-lg)] border border-border bg-muted/40 p-3 transition-colors duration-150",
449
+ "group h-full rounded-[var(--radius-lg)] border border-border bg-muted/40 p-3 transition-colors duration-micro",
450
450
  "hover:border-muted-foreground/30 hover:bg-muted/65",
451
451
  className
452
452
  ),
@@ -474,7 +474,7 @@ function DashboardMetricTile({
474
474
  );
475
475
  }
476
476
  var badgeVariants = cva(
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",
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 border border-transparent",
478
478
  {
479
479
  variants: {
480
480
  variant: {
@@ -496,15 +496,26 @@ var badgeVariants = cva(
496
496
  purple: "bg-secondary text-secondary-foreground fill-current",
497
497
  "purple-subtle": "bg-secondary/40 text-secondary-foreground fill-current border-transparent",
498
498
  amber: "bg-warning text-warning-foreground fill-current",
499
- "amber-subtle": "bg-warning/15 text-warning fill-current border-transparent",
499
+ "amber-subtle": (
500
+ // --warning is a FILL (2.13:1). As ink on its own tint it measured 1.91:1.
501
+ // --warning-strong is the AA-safe amber foreground: 5.01:1 light / 6.20:1 dark.
502
+ "bg-warning/10 text-[hsl(var(--warning-strong))] fill-current border-transparent"
503
+ ),
500
504
  red: "bg-destructive text-destructive-foreground fill-current",
501
- "red-subtle": "bg-destructive/15 text-destructive fill-current border-transparent",
505
+ "red-subtle": (
506
+ // --destructive is fill-only in dark (2.01:1 as ink on its own tint).
507
+ // --destructive-strong: 4.58:1 light / 4.97:1 dark.
508
+ "bg-destructive/10 text-[hsl(var(--destructive-strong))] fill-current border-transparent"
509
+ ),
502
510
  pink: "bg-accent text-accent-foreground fill-current",
503
511
  "pink-subtle": "bg-accent/40 text-accent-foreground fill-current border-transparent",
504
512
  green: "bg-success text-success-foreground fill-current",
505
- "green-subtle": "bg-success/15 text-success fill-current border-transparent",
513
+ "green-subtle": (
514
+ // --success-strong closes the 4.49:1 light gap: 4.99:1 light / 4.83:1 dark.
515
+ "bg-success/10 text-[hsl(var(--success-strong))] fill-current border-transparent"
516
+ ),
506
517
  teal: "bg-info text-info-foreground fill-current",
507
- "teal-subtle": "bg-info/15 text-info fill-current border-transparent",
518
+ "teal-subtle": "bg-info/10 text-info fill-current border-transparent",
508
519
  inverted: "bg-foreground text-background fill-current",
509
520
  // Special visual treatments (intentional product design, not brand hex)
510
521
  trial: "bg-gradient-to-br from-trial-start to-trial-end text-primary-foreground fill-current",
@@ -854,9 +865,9 @@ var badgeToneToVariant = {
854
865
  };
855
866
  var cardClassName = cn(
856
867
  "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",
868
+ "transition-[border-color,box-shadow,transform] duration-micro motion-reduce:transition-none motion-reduce:transform-none",
858
869
  "hover:border-neutral-7 hover:shadow-sm hover:-translate-y-px motion-reduce:hover:translate-y-0",
859
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
870
+ "focus-visible:outline-none"
860
871
  );
861
872
  function GalleryCardActionsMenu({ actions, title }) {
862
873
  function stop(event) {
@@ -875,7 +886,7 @@ function GalleryCardActionsMenu({ actions, title }) {
875
886
  "inline-flex h-7 w-7 items-center justify-center rounded-[var(--radius-md)]",
876
887
  "text-muted-foreground transition-colors",
877
888
  "hover:bg-accent hover:text-accent-foreground",
878
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1"
889
+ "focus-visible:outline-none"
879
890
  ),
880
891
  children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" })
881
892
  }
@@ -1035,7 +1046,7 @@ function KineticFeatureCard({
1035
1046
  "article",
1036
1047
  {
1037
1048
  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",
1049
+ "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-glass-md 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-glass-lg focus-within:-translate-y-1 focus-within:border-foreground/25 sm:p-7",
1039
1050
  className
1040
1051
  ),
1041
1052
  "data-taste": "nebutra-texture-cutout-card",
@@ -1058,7 +1069,7 @@ function KineticFeatureCard({
1058
1069
  ),
1059
1070
  /* @__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
1071
  /* @__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 }) }),
1072
+ /* @__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-glass-sm transition-transform duration-500 group-hover/kinetic:-translate-y-1", children: renderedIcon }) }),
1062
1073
  /* @__PURE__ */ jsx(
1063
1074
  "h3",
1064
1075
  {
@@ -1085,7 +1096,7 @@ function KineticCodePreview({
1085
1096
  "div",
1086
1097
  {
1087
1098
  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)]",
1099
+ "relative overflow-hidden rounded-[var(--radius-xl)] border border-border/60 bg-muted/30 shadow-ambient-md transition-[transform,border-color,box-shadow] duration-500 group-hover/kinetic:-translate-y-2 group-hover/kinetic:border-foreground/20 group-hover/kinetic:shadow-ambient-lg",
1089
1100
  className
1090
1101
  ),
1091
1102
  ...props,
@@ -1123,7 +1134,7 @@ function KineticConsoleFrame({
1123
1134
  "div",
1124
1135
  {
1125
1136
  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)]",
1137
+ "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-glass-md backdrop-blur-3xl transition-[transform,border-color,box-shadow] duration-500 hover:-translate-y-1 hover:border-foreground/25 hover:shadow-glass-lg",
1127
1138
  className
1128
1139
  ),
1129
1140
  "data-taste": "nebutra-terminal-animation",
@@ -1169,7 +1180,7 @@ function KineticMorphSurface({
1169
1180
  "div",
1170
1181
  {
1171
1182
  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",
1183
+ "group/kinetic relative overflow-hidden rounded-[var(--radius-panel)] border border-border/65 bg-background/80 p-3 shadow-glass-md backdrop-blur-2xl transition-[border-color,box-shadow,background-color] duration-500 hover:border-foreground/20 hover:bg-background/92 hover:shadow-glass-lg sm:p-4 lg:p-5",
1173
1184
  className
1174
1185
  ),
1175
1186
  "data-active-key": activeKey,
@@ -1206,7 +1217,7 @@ function KineticSignalMarquee({
1206
1217
  "div",
1207
1218
  {
1208
1219
  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",
1220
+ "group/kinetic relative mx-auto overflow-hidden rounded-[var(--radius-panel)] border border-border/55 bg-background/72 px-3 py-8 shadow-glass-md backdrop-blur-2xl sm:px-5",
1210
1221
  className
1211
1222
  ),
1212
1223
  "data-taste": "nebutra-provider-grid",
@@ -1256,7 +1267,7 @@ function KineticCommandBox({
1256
1267
  "div",
1257
1268
  {
1258
1269
  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",
1270
+ "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-glass-sm 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-glass-md sm:flex-row sm:items-center",
1260
1271
  className
1261
1272
  ),
1262
1273
  "data-taste": "nebutra-texture-command",
@@ -1279,7 +1290,7 @@ function KineticCommandBox({
1279
1290
  {
1280
1291
  type: "button",
1281
1292
  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",
1293
+ 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-sheen transition-[transform,opacity] hover:-translate-y-px hover:opacity-90 sm:mt-0",
1283
1294
  children: [
1284
1295
  copied ? /* @__PURE__ */ jsx(Check, { className: "size-4" }) : /* @__PURE__ */ jsx(Copy, { className: "size-4" }),
1285
1296
  copied ? copiedLabel : copyLabel
@@ -1295,7 +1306,7 @@ function KineticStepRail({ className, children, ...props }) {
1295
1306
  "div",
1296
1307
  {
1297
1308
  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",
1309
+ "relative overflow-hidden rounded-[var(--radius-panel)] border border-border/65 bg-background/78 p-6 shadow-glass-md backdrop-blur-2xl md:p-10",
1299
1310
  className
1300
1311
  ),
1301
1312
  "data-taste": "nebutra-grid-beam",
@@ -1341,12 +1352,12 @@ function KineticStep({
1341
1352
  "article",
1342
1353
  {
1343
1354
  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)]",
1355
+ "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-ambient-md backdrop-blur-xl transition-[transform,border-color,box-shadow] duration-500 hover:-translate-y-1 hover:border-foreground/25 hover:shadow-ambient-lg",
1345
1356
  className
1346
1357
  ),
1347
1358
  ...props,
1348
1359
  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: [
1360
+ /* @__PURE__ */ jsxs("div", { className: "relative mb-6 grid size-16 place-items-center rounded-[var(--radius-xl)] border border-border/65 bg-background shadow-glass-sm", children: [
1350
1361
  /* @__PURE__ */ jsx(
1351
1362
  "span",
1352
1363
  {
@@ -1408,7 +1419,6 @@ var buttonVariants = cva(
1408
1419
  "rounded-[var(--btn-default-radius,var(--radius-md))]",
1409
1420
  "text-[length:var(--control-font-size-md,0.875rem)] font-[number:var(--font-weight-medium,500)]",
1410
1421
  "transition-colors duration-micro ease-out",
1411
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
1412
1422
  "disabled:pointer-events-none disabled:opacity-50",
1413
1423
  "aria-busy:cursor-wait"
1414
1424
  ].join(" "),
@@ -1435,8 +1445,30 @@ var buttonVariants = cva(
1435
1445
  },
1436
1446
  shape: {
1437
1447
  default: "",
1438
- square: "",
1439
- circle: ""
1448
+ // Radius from --btn-default-radius / --radius-md — brand-switchable.
1449
+ // Do not hardcode rounded-md here; a language must be able to retarget
1450
+ // the corner treatment of every icon trigger at once.
1451
+ square: "rounded-[var(--btn-default-radius,var(--radius-md))]",
1452
+ // Pill radius token, not Tailwind rounded-full — same 9999px default,
1453
+ // but a brand that ships a softer "circle" can override --radius-pill.
1454
+ circle: "rounded-[var(--radius-pill,9999px)]",
1455
+ pill: "rounded-[var(--radius-pill,9999px)]"
1456
+ },
1457
+ // Icon-only box size — orthogonal to `size` (which tunes text-button
1458
+ // height/padding/font together) and to `shape` (which picks the
1459
+ // corner treatment). Only takes effect combined with shape="square"
1460
+ // or shape="circle" (see compoundVariants below); every other
1461
+ // combination ignores it. 28/32/36 cover the icon-trigger sizes that
1462
+ // actually occur in the app — 24/40/48 are already reachable via
1463
+ // shape + size (tiny/default/lg). Heights read --control-height-icon-*
1464
+ // so density-aware Brand Packages can scale them with the ladder.
1465
+ iconSize: {
1466
+ sm: "",
1467
+ // 28px default
1468
+ md: "",
1469
+ // 32px default
1470
+ lg: ""
1471
+ // 36px default
1440
1472
  }
1441
1473
  },
1442
1474
  compoundVariants: [
@@ -1447,22 +1479,56 @@ var buttonVariants = cva(
1447
1479
  {
1448
1480
  shape: "circle",
1449
1481
  size: "tiny",
1450
- className: "w-[var(--control-height-tiny,1.5rem)] px-0 rounded-full"
1482
+ className: "w-[var(--control-height-tiny,1.5rem)] px-0"
1451
1483
  },
1452
1484
  {
1453
1485
  shape: "circle",
1454
1486
  size: "sm",
1455
- className: "w-[var(--control-height-sm,2rem)] px-0 rounded-full"
1487
+ className: "w-[var(--control-height-sm,2rem)] px-0"
1456
1488
  },
1457
1489
  {
1458
1490
  shape: "circle",
1459
1491
  size: "default",
1460
- className: "w-[var(--control-height-md,2.5rem)] px-0 rounded-full"
1492
+ className: "w-[var(--control-height-md,2.5rem)] px-0"
1461
1493
  },
1462
1494
  {
1463
1495
  shape: "circle",
1464
1496
  size: "lg",
1465
- className: "w-[var(--control-height-lg,3rem)] px-0 rounded-full"
1497
+ className: "w-[var(--control-height-lg,3rem)] px-0"
1498
+ },
1499
+ // iconSize wins over the size-driven box above — matched on shape +
1500
+ // iconSize only, so it applies regardless of whatever `size` was
1501
+ // passed (or left at its "default" fallback). Corner treatment stays
1502
+ // on the shape variant (token-backed); only the box is set here.
1503
+ {
1504
+ shape: "square",
1505
+ iconSize: "sm",
1506
+ className: "h-[var(--control-height-icon-sm,1.75rem)] w-[var(--control-height-icon-sm,1.75rem)] px-0"
1507
+ },
1508
+ {
1509
+ shape: "square",
1510
+ iconSize: "md",
1511
+ className: "h-[var(--control-height-icon-md,2rem)] w-[var(--control-height-icon-md,2rem)] px-0"
1512
+ },
1513
+ {
1514
+ shape: "square",
1515
+ iconSize: "lg",
1516
+ className: "h-[var(--control-height-icon-lg,2.25rem)] w-[var(--control-height-icon-lg,2.25rem)] px-0"
1517
+ },
1518
+ {
1519
+ shape: "circle",
1520
+ iconSize: "sm",
1521
+ className: "h-[var(--control-height-icon-sm,1.75rem)] w-[var(--control-height-icon-sm,1.75rem)] px-0"
1522
+ },
1523
+ {
1524
+ shape: "circle",
1525
+ iconSize: "md",
1526
+ className: "h-[var(--control-height-icon-md,2rem)] w-[var(--control-height-icon-md,2rem)] px-0"
1527
+ },
1528
+ {
1529
+ shape: "circle",
1530
+ iconSize: "lg",
1531
+ className: "h-[var(--control-height-icon-lg,2.25rem)] w-[var(--control-height-icon-lg,2.25rem)] px-0"
1466
1532
  }
1467
1533
  ],
1468
1534
  defaultVariants: {
@@ -1484,7 +1550,10 @@ function Spinner({ className }) {
1484
1550
  }
1485
1551
  );
1486
1552
  }
1487
- function getIconSizeClass(size) {
1553
+ function getIconSizeClass(size, iconSize) {
1554
+ if (iconSize === "sm") return "[&>svg]:size-3.5";
1555
+ if (iconSize === "md") return "[&>svg]:size-3.5";
1556
+ if (iconSize === "lg") return "[&>svg]:size-4";
1488
1557
  switch (size) {
1489
1558
  case "tiny":
1490
1559
  return "[&>svg]:size-3";
@@ -1499,7 +1568,10 @@ function getIconSizeClass(size) {
1499
1568
  return "[&>svg]:size-4";
1500
1569
  }
1501
1570
  }
1502
- function getSpinnerSizeClass(size) {
1571
+ function getSpinnerSizeClass(size, iconSize) {
1572
+ if (iconSize === "sm") return "size-3.5";
1573
+ if (iconSize === "md") return "size-3.5";
1574
+ if (iconSize === "lg") return "size-4";
1503
1575
  switch (size) {
1504
1576
  case "tiny":
1505
1577
  return "size-3";
@@ -1524,10 +1596,10 @@ function resolveShadowClass(shadow) {
1524
1596
  const level = shadow === true ? "md" : shadow;
1525
1597
  return SHADOW_CLASSES[level];
1526
1598
  }
1527
- function ButtonContent({ loading, prefix, suffix, size, children }) {
1528
- const iconSizeClass = getIconSizeClass(size);
1599
+ function ButtonContent({ loading, prefix, suffix, size, iconSize, children }) {
1600
+ const iconSizeClass = getIconSizeClass(size, iconSize);
1529
1601
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1530
- loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size) }),
1602
+ loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size, iconSize) }),
1531
1603
  prefix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: prefix }),
1532
1604
  children,
1533
1605
  suffix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: suffix })
@@ -1538,6 +1610,7 @@ var Button = ({
1538
1610
  variant,
1539
1611
  size,
1540
1612
  shape,
1613
+ iconSize,
1541
1614
  asChild = false,
1542
1615
  loading = false,
1543
1616
  disabled,
@@ -1555,11 +1628,21 @@ var Button = ({
1555
1628
  Comp,
1556
1629
  {
1557
1630
  ref,
1558
- className: cn(buttonVariants({ variant, size, shape }), shadowClass, className),
1631
+ className: cn(buttonVariants({ variant, size, shape, iconSize }), shadowClass, className),
1559
1632
  disabled: isDisabled,
1560
1633
  "aria-busy": loading || void 0,
1561
1634
  ...props,
1562
- children: asChild ? children : /* @__PURE__ */ jsx(ButtonContent, { loading, prefix, suffix, size, children })
1635
+ children: asChild ? children : /* @__PURE__ */ jsx(
1636
+ ButtonContent,
1637
+ {
1638
+ loading,
1639
+ prefix,
1640
+ suffix,
1641
+ size,
1642
+ iconSize,
1643
+ children
1644
+ }
1645
+ )
1563
1646
  }
1564
1647
  );
1565
1648
  };
@@ -1626,6 +1709,10 @@ var tabsTokens = {
1626
1709
  };
1627
1710
 
1628
1711
  // src/utils/primitive-props.ts
1712
+ function asPlainStyle(style) {
1713
+ if (style == null || typeof style === "function") return {};
1714
+ return style;
1715
+ }
1629
1716
  function withHtmlProps(Component) {
1630
1717
  return Component;
1631
1718
  }
@@ -1736,7 +1823,7 @@ var tabsListVariants = cva(
1736
1823
  }
1737
1824
  );
1738
1825
  var tabsTriggerVariants = cva(
1739
- "relative inline-flex h-[calc(var(--tabs-height)-var(--tabs-padding)*2)] min-w-[var(--tabs-trigger-min-width)] shrink-0 cursor-pointer items-center justify-center gap-[var(--tabs-trigger-gap)] whitespace-nowrap rounded-[var(--tabs-trigger-radius)] px-[var(--tabs-trigger-padding-x)] font-medium text-[length:var(--tabs-font-size)] outline-none transition-[background-color,border-color,box-shadow,color,opacity] duration-[var(--tabs-duration)] ease-[var(--tabs-easing)] focus-visible:ring-[length:var(--tabs-focus-ring-width)] focus-visible:ring-ring focus-visible:ring-offset-[length:var(--tabs-focus-ring-offset)] focus-visible:ring-offset-background disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 [&_svg]:size-[var(--tabs-icon-size)] [&_svg]:shrink-0",
1826
+ "relative inline-flex h-[calc(var(--tabs-height)-var(--tabs-padding)*2)] min-w-[var(--tabs-trigger-min-width)] shrink-0 cursor-pointer items-center justify-center gap-[var(--tabs-trigger-gap)] whitespace-nowrap rounded-[var(--tabs-trigger-radius)] px-[var(--tabs-trigger-padding-x)] font-medium text-[length:var(--tabs-font-size)] outline-none transition-[background-color,border-color,box-shadow,color,opacity] duration-[var(--tabs-duration)] ease-[var(--tabs-easing)] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 [&_svg]:size-[var(--tabs-icon-size)] [&_svg]:shrink-0",
1740
1827
  {
1741
1828
  variants: {
1742
1829
  variant: {
@@ -1773,7 +1860,7 @@ var tabsIndicatorVariants = cva(
1773
1860
  }
1774
1861
  );
1775
1862
  var tabsContentVariants = cva(
1776
- "mt-[var(--tabs-panel-gap)] text-[length:var(--tabs-font-size)] text-muted-foreground focus-visible:outline-none focus-visible:ring-[length:var(--tabs-focus-ring-width)] focus-visible:ring-ring focus-visible:ring-offset-[length:var(--tabs-focus-ring-offset)] focus-visible:ring-offset-background",
1863
+ "mt-[var(--tabs-panel-gap)] text-[length:var(--tabs-font-size)] text-muted-foreground focus-visible:outline-none",
1777
1864
  {
1778
1865
  variants: {
1779
1866
  variant: {
@@ -1815,7 +1902,7 @@ function getTabsStyle(size, style) {
1815
1902
  "--tabs-badge-font-size": `${tabsTokens.badgeFontSize}px`,
1816
1903
  "--tabs-duration": `${tabsTokens.motion.duration}ms`,
1817
1904
  "--tabs-easing": tabsTokens.motion.easing,
1818
- ...style
1905
+ ...asPlainStyle(style)
1819
1906
  };
1820
1907
  }
1821
1908
  function getFirstEnabledValue(tabs) {
@@ -2046,7 +2133,7 @@ function getTextareaStyle(size, style) {
2046
2133
  "--textarea-focus-ring-width": `${textareaTokens.focusRingWidth}px`,
2047
2134
  borderRadius: "var(--textarea-radius)",
2048
2135
  outline: "none",
2049
- ...style
2136
+ ...asPlainStyle(style)
2050
2137
  };
2051
2138
  }
2052
2139
  function getTextareaFieldStyle() {
@@ -2294,7 +2381,7 @@ function MarkdownEditor({
2294
2381
  value,
2295
2382
  onChange: (e) => onChange(e.target.value),
2296
2383
  placeholder,
2297
- className: "resize-none rounded-none border-0 font-mono text-sm shadow-none focus-visible:ring-0",
2384
+ className: "resize-none rounded-none border-0 font-mono text-sm shadow-none",
2298
2385
  style: { minHeight }
2299
2386
  }
2300
2387
  ) }),
@@ -2397,9 +2484,18 @@ function getAvatarFallbackClass(size) {
2397
2484
  }
2398
2485
  function getAvatarStyle(size, style) {
2399
2486
  if (typeof size !== "number") return style;
2400
- return {
2487
+ const numericVars = {
2401
2488
  "--avatar-size": `${size}px`,
2402
- "--avatar-font-size": `${Math.max(10, Math.round(size * 0.375))}px`,
2489
+ "--avatar-font-size": `${Math.max(10, Math.round(size * 0.375))}px`
2490
+ };
2491
+ if (typeof style === "function") {
2492
+ return (state) => ({
2493
+ ...numericVars,
2494
+ ...style(state)
2495
+ });
2496
+ }
2497
+ return {
2498
+ ...numericVars,
2403
2499
  ...style
2404
2500
  };
2405
2501
  }
@@ -2674,7 +2770,7 @@ function QAPage({
2674
2770
  return bScore - aScore;
2675
2771
  });
2676
2772
  }, [answers]);
2677
- return /* @__PURE__ */ jsxs("div", { className: cn("mx-auto w-full max-w-5xl p-4 md:p-6", className), children: [
2773
+ return /* @__PURE__ */ jsxs("div", { className: cn("mx-auto w-full max-w-[var(--container-content)] p-4 md:p-6", className), children: [
2678
2774
  /* @__PURE__ */ jsxs("header", { className: "mb-6", children: [
2679
2775
  /* @__PURE__ */ jsx("h1", { className: "mb-4 font-bold text-2xl leading-tight text-foreground", children: question.title }),
2680
2776
  /* @__PURE__ */ jsxs("div", { className: "mb-4 flex items-center gap-4 text-muted-foreground text-sm", children: [
@@ -3160,7 +3256,7 @@ function SidebarNav({
3160
3256
  return /* @__PURE__ */ jsxs("section", { className: "group/section", children: [
3161
3257
  section.label && !collapsed ? /* @__PURE__ */ jsxs("div", { className: "mb-1.5 flex items-center justify-between px-2.5", children: [
3162
3258
  /* @__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) => {
3259
+ visibleActions ? /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 opacity-0 transition-opacity duration-micro group-hover/section:opacity-100 focus-within:opacity-100", children: visibleActions.map((action) => {
3164
3260
  const ActionIcon = action.icon;
3165
3261
  const defaultButton = /* @__PURE__ */ jsx(
3166
3262
  "button",
@@ -3169,7 +3265,7 @@ function SidebarNav({
3169
3265
  "aria-label": action.label,
3170
3266
  title: action.label,
3171
3267
  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",
3268
+ 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",
3173
3269
  children: /* @__PURE__ */ jsx(ActionIcon, { className: "size-3" })
3174
3270
  }
3175
3271
  );
@@ -3397,7 +3493,7 @@ function DefaultTrigger({ user }) {
3397
3493
  className: cn(
3398
3494
  "inline-flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full",
3399
3495
  "outline-none transition-[box-shadow,opacity] hover:opacity-90",
3400
- "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
3496
+ "",
3401
3497
  "hover:ring-1 hover:ring-border"
3402
3498
  ),
3403
3499
  children: /* @__PURE__ */ jsxs(Avatar, { size: "sm", children: [
@@ -3492,7 +3588,7 @@ function getInitials(workspace) {
3492
3588
  if (!trimmed) return "??";
3493
3589
  const parts = trimmed.split(/\s+/).filter(Boolean);
3494
3590
  if (parts.length >= 2) {
3495
- return `${parts[0][0] ?? ""}${parts[1][0] ?? ""}`.toUpperCase();
3591
+ return `${parts[0]?.[0] ?? ""}${parts[1]?.[0] ?? ""}`.toUpperCase();
3496
3592
  }
3497
3593
  return trimmed.slice(0, 2).toUpperCase();
3498
3594
  }
@@ -3549,7 +3645,7 @@ function TriggerButton({
3549
3645
  className: cn(
3550
3646
  "inline-flex items-center gap-1 rounded-[var(--radius-md)] p-1 outline-none transition-colors",
3551
3647
  "hover:bg-accent hover:text-accent-foreground",
3552
- "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
3648
+ "",
3553
3649
  "disabled:cursor-not-allowed disabled:opacity-50",
3554
3650
  className
3555
3651
  ),
@@ -3570,7 +3666,7 @@ function TriggerButton({
3570
3666
  className: cn(
3571
3667
  "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
3668
  "hover:bg-accent hover:text-accent-foreground",
3573
- "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
3669
+ "",
3574
3670
  "disabled:cursor-not-allowed disabled:opacity-50",
3575
3671
  className
3576
3672
  ),