@brijbyte/agentic-ui 0.0.1 → 0.0.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.
Files changed (173) hide show
  1. package/README.md +183 -111
  2. package/dist/accordion/accordion.css +6 -10
  3. package/dist/accordion/accordion.d.ts +1 -1
  4. package/dist/accordion/accordion.js +1 -1
  5. package/dist/accordion/accordion.module.js.map +1 -1
  6. package/dist/accordion/parts.d.ts +1 -1
  7. package/dist/accordion/parts.js +2 -2
  8. package/dist/alert-dialog/alert-dialog.css +84 -0
  9. package/dist/alert-dialog/alert-dialog.d.ts +44 -0
  10. package/dist/alert-dialog/alert-dialog.d.ts.map +1 -0
  11. package/dist/alert-dialog/alert-dialog.js +46 -0
  12. package/dist/alert-dialog/alert-dialog.js.map +1 -0
  13. package/dist/alert-dialog/alert-dialog.module.css.d.ts +2 -0
  14. package/dist/alert-dialog/alert-dialog.module.js +14 -0
  15. package/dist/alert-dialog/alert-dialog.module.js.map +1 -0
  16. package/dist/alert-dialog/index.d.ts +3 -0
  17. package/dist/alert-dialog/index.js +4 -0
  18. package/dist/alert-dialog/parts.d.ts +28 -0
  19. package/dist/alert-dialog/parts.d.ts.map +1 -0
  20. package/dist/alert-dialog/parts.js +62 -0
  21. package/dist/alert-dialog/parts.js.map +1 -0
  22. package/dist/badge/badge.css +3 -7
  23. package/dist/badge/badge.d.ts +1 -1
  24. package/dist/badge/badge.module.js.map +1 -1
  25. package/dist/button/button.css +36 -22
  26. package/dist/button/button.d.ts +7 -7
  27. package/dist/button/button.js +1 -1
  28. package/dist/button/button.js.map +1 -1
  29. package/dist/button/button.module.js.map +1 -1
  30. package/dist/card/card.css +5 -9
  31. package/dist/card/card.d.ts +1 -1
  32. package/dist/card/card.module.js.map +1 -1
  33. package/dist/checkbox/checkbox.css +3 -7
  34. package/dist/checkbox/checkbox.d.ts +1 -1
  35. package/dist/checkbox/checkbox.js +1 -1
  36. package/dist/checkbox/checkbox.module.js.map +1 -1
  37. package/dist/checkbox/parts.js +1 -1
  38. package/dist/collapsible/collapsible.css +7 -11
  39. package/dist/collapsible/collapsible.d.ts +1 -1
  40. package/dist/collapsible/collapsible.module.js.map +1 -1
  41. package/dist/collapsible/parts.js +1 -1
  42. package/dist/context-menu/context-menu.css +151 -0
  43. package/dist/context-menu/context-menu.d.ts +36 -0
  44. package/dist/context-menu/context-menu.d.ts.map +1 -0
  45. package/dist/context-menu/context-menu.js +54 -0
  46. package/dist/context-menu/context-menu.js.map +1 -0
  47. package/dist/context-menu/context-menu.module.css.d.ts +2 -0
  48. package/dist/context-menu/context-menu.module.js +18 -0
  49. package/dist/context-menu/context-menu.module.js.map +1 -0
  50. package/dist/context-menu/index.d.ts +3 -0
  51. package/dist/context-menu/index.js +4 -0
  52. package/dist/context-menu/parts.d.ts +38 -0
  53. package/dist/context-menu/parts.d.ts.map +1 -0
  54. package/dist/context-menu/parts.js +91 -0
  55. package/dist/context-menu/parts.js.map +1 -0
  56. package/dist/dialog/dialog.css +27 -22
  57. package/dist/dialog/dialog.d.ts +9 -1
  58. package/dist/dialog/dialog.d.ts.map +1 -1
  59. package/dist/dialog/dialog.js +7 -4
  60. package/dist/dialog/dialog.js.map +1 -1
  61. package/dist/dialog/dialog.module.js +2 -0
  62. package/dist/dialog/dialog.module.js.map +1 -1
  63. package/dist/dialog/parts.js +1 -1
  64. package/dist/drawer/drawer.css +9 -13
  65. package/dist/drawer/drawer.d.ts +1 -1
  66. package/dist/drawer/drawer.module.js.map +1 -1
  67. package/dist/drawer/parts.d.ts +1 -1
  68. package/dist/drawer/parts.js +1 -1
  69. package/dist/index.css +1603 -1299
  70. package/dist/index.d.ts +30 -24
  71. package/dist/index.js +41 -32
  72. package/dist/input/input.css +5 -9
  73. package/dist/input/input.js +1 -1
  74. package/dist/input/input.module.js.map +1 -1
  75. package/dist/layer-order.css +22 -0
  76. package/dist/menu/menu.css +13 -17
  77. package/dist/menu/menu.d.ts +1 -1
  78. package/dist/menu/menu.module.js.map +1 -1
  79. package/dist/menu/menuitemshortcut.js +1 -1
  80. package/dist/menu/parts.js +1 -1
  81. package/dist/number-field/number-field.css +12 -16
  82. package/dist/number-field/number-field.d.ts +1 -1
  83. package/dist/number-field/number-field.js +1 -1
  84. package/dist/number-field/number-field.module.js.map +1 -1
  85. package/dist/number-field/parts.js +1 -1
  86. package/dist/progress/parts.js +1 -1
  87. package/dist/progress/progress.css +1 -5
  88. package/dist/progress/progress.module.js.map +1 -1
  89. package/dist/reset.css +6 -6
  90. package/dist/select/parts.js +1 -1
  91. package/dist/select/select.css +14 -16
  92. package/dist/select/select.d.ts +5 -2
  93. package/dist/select/select.d.ts.map +1 -1
  94. package/dist/select/select.js +11 -2
  95. package/dist/select/select.js.map +1 -1
  96. package/dist/select/select.module.js.map +1 -1
  97. package/dist/separator/separator.css +1 -5
  98. package/dist/separator/separator.js +1 -1
  99. package/dist/separator/separator.module.js.map +1 -1
  100. package/dist/slider/index.d.ts +3 -0
  101. package/dist/slider/index.js +4 -0
  102. package/dist/slider/parts.d.ts +38 -0
  103. package/dist/slider/parts.d.ts.map +1 -0
  104. package/dist/slider/parts.js +69 -0
  105. package/dist/slider/parts.js.map +1 -0
  106. package/dist/slider/slider.css +97 -0
  107. package/dist/slider/slider.d.ts +38 -0
  108. package/dist/slider/slider.d.ts.map +1 -0
  109. package/dist/slider/slider.js +41 -0
  110. package/dist/slider/slider.js.map +1 -0
  111. package/dist/slider/slider.module.css.d.ts +2 -0
  112. package/dist/slider/slider.module.js +15 -0
  113. package/dist/slider/slider.module.js.map +1 -0
  114. package/dist/styles/reset.css +6 -6
  115. package/dist/styles/tokens.css +91 -76
  116. package/dist/switch/parts.js +1 -1
  117. package/dist/switch/switch.css +2 -6
  118. package/dist/switch/switch.d.ts +1 -1
  119. package/dist/switch/switch.js +1 -1
  120. package/dist/switch/switch.module.js.map +1 -1
  121. package/dist/tabs/parts.js +1 -1
  122. package/dist/tabs/tabs.css +5 -9
  123. package/dist/tabs/tabs.d.ts +1 -1
  124. package/dist/tabs/tabs.module.js.map +1 -1
  125. package/dist/tailwind-theme.css +23 -23
  126. package/dist/toast/parts.js +1 -1
  127. package/dist/toast/toast.css +11 -15
  128. package/dist/toast/toast.d.ts +1 -1
  129. package/dist/toast/toast.module.js.map +1 -1
  130. package/dist/tokens.css +98 -82
  131. package/dist/tooltip/parts.js +1 -1
  132. package/dist/tooltip/tooltip.css +7 -11
  133. package/dist/tooltip/tooltip.d.ts +1 -1
  134. package/dist/tooltip/tooltip.module.js.map +1 -1
  135. package/package.json +18 -1
  136. package/src/accordion/accordion.module.css +6 -20
  137. package/src/alert-dialog/alert-dialog.module.css +91 -0
  138. package/src/alert-dialog/alert-dialog.tsx +69 -0
  139. package/src/alert-dialog/index.ts +7 -0
  140. package/src/alert-dialog/parts.tsx +73 -0
  141. package/src/badge/badge.module.css +3 -13
  142. package/src/button/button.module.css +44 -64
  143. package/src/button/button.tsx +7 -7
  144. package/src/card/card.module.css +5 -16
  145. package/src/checkbox/checkbox.module.css +3 -14
  146. package/src/collapsible/collapsible.module.css +7 -20
  147. package/src/context-menu/context-menu.module.css +168 -0
  148. package/src/context-menu/context-menu.tsx +75 -0
  149. package/src/context-menu/index.ts +21 -0
  150. package/src/context-menu/parts.tsx +99 -0
  151. package/src/dialog/dialog.module.css +26 -33
  152. package/src/dialog/dialog.tsx +14 -1
  153. package/src/drawer/drawer.module.css +9 -58
  154. package/src/index.ts +21 -185
  155. package/src/input/input.module.css +5 -21
  156. package/src/menu/menu.module.css +13 -43
  157. package/src/number-field/number-field.module.css +12 -28
  158. package/src/progress/progress.module.css +1 -10
  159. package/src/select/select.module.css +14 -35
  160. package/src/select/select.tsx +14 -5
  161. package/src/separator/separator.module.css +1 -5
  162. package/src/slider/index.ts +14 -0
  163. package/src/slider/parts.tsx +90 -0
  164. package/src/slider/slider.module.css +110 -0
  165. package/src/slider/slider.tsx +68 -0
  166. package/src/styles/layer-order.css +22 -0
  167. package/src/styles/reset.css +6 -6
  168. package/src/styles/tailwind-theme.css +23 -23
  169. package/src/styles/tokens.css +98 -82
  170. package/src/switch/switch.module.css +2 -12
  171. package/src/tabs/tabs.module.css +5 -18
  172. package/src/toast/toast.module.css +11 -51
  173. package/src/tooltip/tooltip.module.css +7 -18
@@ -0,0 +1,91 @@
1
+ @layer components {
2
+ .backdrop {
3
+ position: fixed;
4
+ inset: 0;
5
+ min-height: 100dvh;
6
+ background-color: rgba(0, 0, 0, 0.48);
7
+ z-index: var(--z-overlay);
8
+ transition: opacity var(--duration-slow) var(--easing-standard);
9
+
10
+ @supports (-webkit-touch-callout: none) {
11
+ position: absolute;
12
+ }
13
+ }
14
+
15
+ .backdrop[data-starting-style],
16
+ .backdrop[data-ending-style] {
17
+ opacity: 0;
18
+ }
19
+
20
+ .popup {
21
+ position: fixed;
22
+ top: 50%;
23
+ left: 50%;
24
+ transform: translate(-50%, -50%);
25
+ z-index: var(--z-modal);
26
+ background-color: var(--color-elevated);
27
+ border: var(--border-width-base) solid var(--color-line);
28
+ border-radius: var(--radius-2xl);
29
+ box-shadow: var(--shadow-xl);
30
+ padding: var(--space-5) var(--space-6);
31
+ width: min(380px, calc(100vw - var(--space-8)));
32
+ outline: none;
33
+ overflow: hidden;
34
+ display: flex;
35
+ flex-direction: column;
36
+ gap: var(--space-3);
37
+ transition:
38
+ opacity 200ms var(--easing-ease-out),
39
+ transform 200ms var(--easing-spring);
40
+ }
41
+
42
+ .popup[data-starting-style] {
43
+ opacity: 0;
44
+ transform: translate(-50%, -48%) scale(0.96);
45
+ }
46
+
47
+ .popup[data-ending-style] {
48
+ opacity: 0;
49
+ transform: translate(-50%, -50%) scale(0.98);
50
+ transition:
51
+ opacity 150ms var(--easing-ease-in),
52
+ transform 150ms var(--easing-ease-in);
53
+ }
54
+
55
+ /* ─── Header ──────────────────────────────────────────────────── */
56
+
57
+ .header {
58
+ display: flex;
59
+ flex-direction: column;
60
+ gap: var(--space-1-5);
61
+ }
62
+
63
+ .icon {
64
+ margin-bottom: var(--space-1);
65
+ }
66
+
67
+ .title {
68
+ font-family: var(--font-sans);
69
+ font-size: var(--font-size-lg);
70
+ font-weight: var(--font-weight-bold);
71
+ color: var(--color-primary);
72
+ line-height: var(--line-height-tight);
73
+ }
74
+
75
+ .description {
76
+ font-family: var(--font-sans);
77
+ font-size: var(--font-size-md);
78
+ color: var(--color-secondary);
79
+ line-height: var(--line-height-relaxed);
80
+ }
81
+
82
+ /* ─── Actions ─────────────────────────────────────────────────── */
83
+
84
+ .actions {
85
+ display: flex;
86
+ align-items: center;
87
+ justify-content: flex-end;
88
+ gap: var(--space-2);
89
+ padding-top: var(--space-1);
90
+ }
91
+ }
@@ -0,0 +1,69 @@
1
+ import type { ReactNode, ReactElement } from "react";
2
+ import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog";
3
+ import { Button } from "../button/button";
4
+ import styles from "./alert-dialog.module.css";
5
+
6
+ export interface AlertAction {
7
+ label: ReactNode;
8
+ /** Called when the action button is clicked. The dialog closes automatically. */
9
+ onAction?: () => void;
10
+ /** Renders as a filled accent button — use for the primary confirm action. */
11
+ primary?: boolean;
12
+ /** Renders as a soft destructive button. Sits on the left when combined with other actions. */
13
+ destructive?: boolean;
14
+ }
15
+
16
+ export interface AlertDialogProps {
17
+ open?: boolean;
18
+ defaultOpen?: boolean;
19
+ onOpenChange?: (open: boolean, eventDetails: unknown) => void;
20
+ trigger?: ReactElement;
21
+ /** Optional icon shown above the title. */
22
+ icon?: ReactNode;
23
+ title: ReactNode;
24
+ description?: ReactNode;
25
+ /**
26
+ * Action buttons rendered right-aligned.
27
+ * Use `primary: true` for the confirm action (solid), leave unset for cancel (outline).
28
+ * Use `destructive: true` to apply destructive tone to the confirm action.
29
+ */
30
+ actions: AlertAction[];
31
+ className?: string;
32
+ }
33
+
34
+ export function AlertDialog({ trigger, icon, title, description, actions, className, onOpenChange, ...props }: AlertDialogProps) {
35
+ return (
36
+ <BaseAlertDialog.Root onOpenChange={onOpenChange as never} {...props}>
37
+ {trigger && <BaseAlertDialog.Trigger render={trigger} />}
38
+ <BaseAlertDialog.Portal>
39
+ <BaseAlertDialog.Backdrop className={styles.backdrop} />
40
+ <BaseAlertDialog.Popup className={`${styles.popup} ${className ?? ""}`}>
41
+ <div className={styles.header}>
42
+ {icon && <div className={styles.icon}>{icon}</div>}
43
+ <BaseAlertDialog.Title className={styles.title}>{title}</BaseAlertDialog.Title>
44
+ {description && <BaseAlertDialog.Description className={styles.description}>{description}</BaseAlertDialog.Description>}
45
+ </div>
46
+ <div className={styles.actions}>
47
+ {actions.map((action, i) => (
48
+ <BaseAlertDialog.Close
49
+ key={i}
50
+ render={
51
+ <Button
52
+ variant={action.primary ? "solid" : "outline"}
53
+ tone={action.destructive ? "destructive" : "primary"}
54
+ size="sm"
55
+ onClick={action.onAction}
56
+ />
57
+ }
58
+ >
59
+ {action.label}
60
+ </BaseAlertDialog.Close>
61
+ ))}
62
+ </div>
63
+ </BaseAlertDialog.Popup>
64
+ </BaseAlertDialog.Portal>
65
+ </BaseAlertDialog.Root>
66
+ );
67
+ }
68
+
69
+ export { styles as AlertDialogStyles };
@@ -0,0 +1,7 @@
1
+ export { AlertDialog } from "./alert-dialog";
2
+ export type { AlertDialogProps, AlertAction } from "./alert-dialog";
3
+
4
+ export { AlertDialogBackdrop, AlertDialogPopup, AlertDialogTitle, AlertDialogDescription } from "./parts";
5
+ export type { AlertDialogBackdropProps, AlertDialogPopupProps, AlertDialogTitleProps, AlertDialogDescriptionProps } from "./parts";
6
+
7
+ export { AlertDialogStyles } from "./alert-dialog";
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Styled primitives for AlertDialog.
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * import { AlertDialog as BaseAlertDialog } from '@base-ui/react/alert-dialog';
7
+ * import { Button } from '@brijbyte/agentic-ui/button';
8
+ * import { AlertDialogBackdrop, AlertDialogPopup, AlertDialogTitle, AlertDialogDescription } from '@brijbyte/agentic-ui/alert-dialog';
9
+ *
10
+ * <BaseAlertDialog.Root>
11
+ * <BaseAlertDialog.Trigger render={<button>Open</button>} />
12
+ * <BaseAlertDialog.Portal>
13
+ * <AlertDialogBackdrop />
14
+ * <AlertDialogPopup>
15
+ * <AlertDialogTitle>Delete account?</AlertDialogTitle>
16
+ * <AlertDialogDescription>This cannot be undone.</AlertDialogDescription>
17
+ * <div>
18
+ * <BaseAlertDialog.Close render={<Button variant="soft" tone="destructive" size="sm" />}>Delete</BaseAlertDialog.Close>
19
+ * <BaseAlertDialog.Close render={<Button variant="outline" size="sm" />}>Cancel</BaseAlertDialog.Close>
20
+ * </div>
21
+ * </AlertDialogPopup>
22
+ * </BaseAlertDialog.Portal>
23
+ * </BaseAlertDialog.Root>
24
+ * ```
25
+ */
26
+ import { forwardRef } from "react";
27
+ import type { ComponentRef, ComponentPropsWithoutRef } from "react";
28
+ import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog";
29
+ import styles from "./alert-dialog.module.css";
30
+
31
+ type BaseBackdropProps = ComponentPropsWithoutRef<typeof BaseAlertDialog.Backdrop>;
32
+ type BasePopupProps = ComponentPropsWithoutRef<typeof BaseAlertDialog.Popup>;
33
+ type BaseTitleProps = ComponentPropsWithoutRef<typeof BaseAlertDialog.Title>;
34
+ type BaseDescriptionProps = ComponentPropsWithoutRef<typeof BaseAlertDialog.Description>;
35
+
36
+ export interface AlertDialogBackdropProps extends Omit<BaseBackdropProps, "className"> {
37
+ className?: string;
38
+ }
39
+ export interface AlertDialogPopupProps extends Omit<BasePopupProps, "className"> {
40
+ className?: string;
41
+ }
42
+ export interface AlertDialogTitleProps extends Omit<BaseTitleProps, "className"> {
43
+ className?: string;
44
+ }
45
+ export interface AlertDialogDescriptionProps extends Omit<BaseDescriptionProps, "className"> {
46
+ className?: string;
47
+ }
48
+
49
+ export const AlertDialogBackdrop = forwardRef<ComponentRef<typeof BaseAlertDialog.Backdrop>, AlertDialogBackdropProps>(
50
+ function AlertDialogBackdrop({ className, ...props }, ref) {
51
+ return <BaseAlertDialog.Backdrop ref={ref} className={`${styles.backdrop} ${className ?? ""}`} {...props} />;
52
+ },
53
+ );
54
+
55
+ export const AlertDialogPopup = forwardRef<ComponentRef<typeof BaseAlertDialog.Popup>, AlertDialogPopupProps>(function AlertDialogPopup(
56
+ { className, ...props },
57
+ ref,
58
+ ) {
59
+ return <BaseAlertDialog.Popup ref={ref} className={`${styles.popup} ${className ?? ""}`} {...props} />;
60
+ });
61
+
62
+ export const AlertDialogTitle = forwardRef<ComponentRef<typeof BaseAlertDialog.Title>, AlertDialogTitleProps>(function AlertDialogTitle(
63
+ { className, ...props },
64
+ ref,
65
+ ) {
66
+ return <BaseAlertDialog.Title ref={ref} className={`${styles.title} ${className ?? ""}`} {...props} />;
67
+ });
68
+
69
+ export const AlertDialogDescription = forwardRef<ComponentRef<typeof BaseAlertDialog.Description>, AlertDialogDescriptionProps>(
70
+ function AlertDialogDescription({ className, ...props }, ref) {
71
+ return <BaseAlertDialog.Description ref={ref} className={`${styles.description} ${className ?? ""}`} {...props} />;
72
+ },
73
+ );
@@ -1,5 +1,3 @@
1
- @layer theme, base, components, utilities;
2
-
3
1
  @layer components {
4
2
  .root {
5
3
  display: inline-flex;
@@ -15,50 +13,42 @@
15
13
  padding: 2px var(--space-1-5);
16
14
  white-space: nowrap;
17
15
  }
18
-
19
16
  /* Variants */
20
17
  .variant-default {
21
18
  background-color: var(--color-surface-3);
22
- border-color: var(--color-border-base);
23
- color: var(--color-text-secondary);
19
+ border-color: var(--color-line);
20
+ color: var(--color-secondary);
24
21
  }
25
-
26
22
  .variant-solid {
27
23
  background-color: var(--color-accent);
28
24
  border-color: var(--color-accent);
29
- color: var(--color-text-on-accent);
25
+ color: var(--color-on-accent);
30
26
  }
31
-
32
27
  .variant-soft {
33
28
  background-color: var(--color-accent-tint);
34
29
  border-color: var(--color-accent-tint-hover);
35
30
  color: var(--color-accent);
36
31
  }
37
-
38
32
  .variant-success {
39
33
  background-color: var(--color-success-bg);
40
34
  border-color: var(--color-success-border);
41
35
  color: var(--color-success-text);
42
36
  }
43
-
44
37
  .variant-warning {
45
38
  background-color: var(--color-warning-bg);
46
39
  border-color: var(--color-warning-border);
47
40
  color: var(--color-warning-text);
48
41
  }
49
-
50
42
  .variant-error {
51
43
  background-color: var(--color-error-bg);
52
44
  border-color: var(--color-error-border);
53
45
  color: var(--color-error-text);
54
46
  }
55
-
56
47
  .variant-info {
57
48
  background-color: var(--color-info-bg);
58
49
  border-color: var(--color-info-border);
59
50
  color: var(--color-info-text);
60
51
  }
61
-
62
52
  /* Dot indicator */
63
53
  .dot {
64
54
  width: 5px;
@@ -25,49 +25,40 @@
25
25
  outline: none;
26
26
  position: relative;
27
27
  }
28
-
29
28
  .root:active:not([data-disabled]) {
30
29
  transform: scale(0.97);
31
30
  }
32
-
33
31
  .root:focus-visible {
34
32
  box-shadow: var(--shadow-focus);
35
33
  }
36
-
37
34
  .root[data-disabled] {
38
35
  cursor: not-allowed;
39
36
  opacity: 0.44;
40
37
  pointer-events: none;
41
38
  }
42
-
43
39
  /* ─── Sizes ──────────────────────────────────────────────────────── */
44
-
45
40
  .size-xs {
46
41
  height: 22px;
47
42
  padding-inline: var(--space-2);
48
43
  font-size: var(--font-size-xs);
49
44
  border-radius: var(--radius-sm);
50
45
  }
51
-
52
46
  .size-sm {
53
47
  height: 26px;
54
48
  padding-inline: var(--space-2-5);
55
49
  font-size: var(--font-size-sm);
56
50
  }
57
-
58
51
  .size-md {
59
52
  height: 30px;
60
53
  padding-inline: var(--space-3);
61
54
  font-size: var(--font-size-md);
62
55
  }
63
-
64
56
  .size-lg {
65
57
  height: 36px;
66
58
  padding-inline: var(--space-4);
67
59
  font-size: var(--font-size-lg);
68
60
  border-radius: var(--radius-lg);
69
61
  }
70
-
71
62
  /* Icon-only */
72
63
  .icon-only.size-xs {
73
64
  width: 22px;
@@ -85,149 +76,142 @@
85
76
  width: 36px;
86
77
  padding-inline: 0;
87
78
  }
88
-
89
79
  /* ─── Tones — set scoped color tokens ────────────────────────────── */
90
80
  /*
91
- * Each tone exposes four custom properties consumed by the variants below:
92
- * --btn-color solid bg / soft text / outline+ghost hover text
93
- * --btn-color-hover solid bg hover
94
- * --btn-color-pressed solid bg pressed
81
+ * Each tone exposes scoped custom properties consumed by the variants below:
82
+ * --btn-color solid bg color
83
+ * --btn-color-hover solid bg on hover
84
+ * --btn-color-pressed solid bg on press
85
+ * --btn-text-color text color for soft / outline / ghost variants
86
+ * (may differ from --btn-color for contrast on tinted surfaces)
95
87
  * --btn-tint soft bg
96
- * --btn-tint-hover soft bg hover
88
+ * --btn-tint-hover soft bg on hover
97
89
  * --btn-on-color text on solid bg
98
90
  */
99
-
100
91
  .tone-primary {
101
- --btn-color: var(--color-accent);
92
+ --btn-color: var(--color-accent-solid);
102
93
  --btn-color-hover: var(--color-accent-hover);
103
94
  --btn-color-pressed: var(--color-accent-pressed);
95
+ --btn-text-color: var(--color-accent-text);
104
96
  --btn-tint: var(--color-accent-tint);
105
97
  --btn-tint-hover: var(--color-accent-tint-hover);
106
- --btn-on-color: var(--color-text-on-accent);
98
+ --btn-on-color: var(--color-on-accent);
107
99
  }
108
-
109
100
  .tone-secondary {
110
- --btn-color: var(--color-text-secondary);
111
- --btn-color-hover: var(--color-text-primary);
112
- --btn-color-pressed: var(--color-text-primary);
113
- --btn-tint: var(--color-surface-hover);
114
- --btn-tint-hover: var(--color-surface-active);
115
- --btn-on-color: var(--color-bg-base);
116
- }
117
-
101
+ --btn-color: var(--color-secondary);
102
+ --btn-color-hover: var(--color-primary);
103
+ --btn-color-pressed: var(--color-primary);
104
+ --btn-text-color: var(--color-secondary);
105
+ --btn-tint: var(--color-hover);
106
+ --btn-tint-hover: var(--color-active);
107
+ --btn-on-color: var(--color-canvas);
108
+ }
118
109
  .tone-destructive {
119
110
  --btn-color: var(--color-error-solid);
120
111
  --btn-color-hover: var(--color-error-solid);
121
112
  --btn-color-pressed: var(--color-error-solid);
113
+ --btn-text-color: var(--color-error-text);
122
114
  --btn-tint: var(--color-error-bg);
123
115
  --btn-tint-hover: var(--color-error-bg);
124
- --btn-on-color: #ffffff;
116
+ --btn-on-color: var(--color-error-on-solid);
125
117
  }
126
-
127
118
  .tone-success {
128
119
  --btn-color: var(--color-success-solid);
129
120
  --btn-color-hover: var(--color-success-solid);
130
121
  --btn-color-pressed: var(--color-success-solid);
122
+ --btn-text-color: var(--color-success-text);
131
123
  --btn-tint: var(--color-success-bg);
132
124
  --btn-tint-hover: var(--color-success-bg);
133
- --btn-on-color: #ffffff;
125
+ --btn-on-color: var(--color-success-on-solid);
134
126
  }
135
-
136
127
  .tone-warning {
137
128
  --btn-color: var(--color-warning-solid);
138
129
  --btn-color-hover: var(--color-warning-solid);
139
130
  --btn-color-pressed: var(--color-warning-solid);
131
+ --btn-text-color: var(--color-warning-text);
140
132
  --btn-tint: var(--color-warning-bg);
141
133
  --btn-tint-hover: var(--color-warning-bg);
142
- --btn-on-color: #ffffff;
134
+ --btn-on-color: var(--color-warning-on-solid);
143
135
  }
144
-
145
136
  /* ─── Variants — consume tone tokens ────────────────────────────── */
146
-
147
137
  .variant-solid {
148
138
  background-color: var(--btn-color);
149
139
  border-color: var(--btn-color);
150
140
  color: var(--btn-on-color);
151
141
  }
152
-
153
142
  .variant-solid:hover:not([data-disabled]) {
154
143
  background-color: var(--btn-color-hover);
155
144
  border-color: var(--btn-color-hover);
156
145
  filter: brightness(0.92);
157
146
  }
158
-
159
147
  .variant-solid:active:not([data-disabled]),
160
148
  .variant-solid[data-pressed]:not([data-disabled]) {
161
149
  background-color: var(--btn-color-pressed);
162
150
  border-color: var(--btn-color-pressed);
163
151
  filter: brightness(0.84);
164
152
  }
165
-
166
153
  /* primary solid gets its own hover tokens instead of filter */
167
154
  .variant-solid.tone-primary:hover:not([data-disabled]) {
168
155
  background-color: var(--btn-color-hover);
169
156
  border-color: var(--btn-color-hover);
170
157
  filter: none;
171
158
  }
172
-
173
159
  .variant-solid.tone-primary:active:not([data-disabled]),
174
160
  .variant-solid.tone-primary[data-pressed]:not([data-disabled]) {
175
161
  background-color: var(--btn-color-pressed);
176
162
  border-color: var(--btn-color-pressed);
177
163
  filter: none;
178
164
  }
179
-
180
165
  .variant-soft {
181
166
  background-color: var(--btn-tint);
182
167
  border-color: transparent;
183
- color: var(--btn-color);
168
+ color: var(--btn-text-color);
184
169
  }
185
-
186
170
  .variant-soft:hover:not([data-disabled]) {
187
171
  background-color: var(--btn-tint-hover);
188
172
  }
189
-
190
173
  .variant-soft:active:not([data-disabled]),
191
174
  .variant-soft[data-pressed]:not([data-disabled]) {
192
175
  background-color: var(--btn-tint-hover);
193
176
  filter: brightness(0.95);
194
177
  }
195
-
196
178
  .variant-outline {
197
179
  background-color: transparent;
198
- border-color: var(--color-border-strong);
199
- color: var(--color-text-primary);
180
+ border-color: var(--color-line-strong);
181
+ color: var(--color-primary);
182
+ }
183
+ /* Non-secondary tones show their tone color at rest */
184
+ .variant-outline:not(.tone-secondary) {
185
+ border-color: var(--btn-text-color);
186
+ color: var(--btn-text-color);
200
187
  }
201
-
202
188
  .variant-outline:hover:not([data-disabled]) {
203
- background-color: var(--color-surface-hover);
204
- border-color: var(--btn-color);
205
- color: var(--btn-color);
189
+ background-color: var(--color-hover);
190
+ border-color: var(--btn-text-color);
191
+ color: var(--btn-text-color);
206
192
  }
207
-
208
193
  .variant-outline:active:not([data-disabled]),
209
194
  .variant-outline[data-pressed]:not([data-disabled]) {
210
- background-color: var(--color-surface-active);
195
+ background-color: var(--color-active);
211
196
  }
212
-
213
197
  .variant-ghost {
214
198
  background-color: transparent;
215
199
  border-color: transparent;
216
- color: var(--color-text-secondary);
200
+ color: var(--color-secondary);
201
+ }
202
+ /* Non-secondary tones show their tone color at rest */
203
+ .variant-ghost:not(.tone-secondary) {
204
+ color: var(--btn-text-color);
217
205
  }
218
-
219
206
  .variant-ghost:hover:not([data-disabled]) {
220
- background-color: var(--color-surface-hover);
221
- color: var(--btn-color);
207
+ background-color: var(--color-hover);
208
+ color: var(--btn-text-color);
222
209
  }
223
-
224
210
  .variant-ghost:active:not([data-disabled]),
225
211
  .variant-ghost[data-pressed]:not([data-disabled]) {
226
- background-color: var(--color-surface-active);
212
+ background-color: var(--color-active);
227
213
  }
228
-
229
214
  /* ─── Loader ─────────────────────────────────────────────────────── */
230
-
231
215
  /* Always in the DOM, always position:absolute so it never affects layout */
232
216
  .loader {
233
217
  position: absolute;
@@ -238,21 +222,17 @@
238
222
  opacity: 0;
239
223
  pointer-events: none;
240
224
  }
241
-
242
225
  .loader-visible {
243
226
  opacity: 1;
244
227
  }
245
-
246
228
  .content-loading {
247
229
  visibility: hidden;
248
230
  }
249
-
250
231
  @keyframes spin {
251
232
  to {
252
233
  transform: rotate(360deg);
253
234
  }
254
235
  }
255
-
256
236
  .spinner {
257
237
  width: 12px;
258
238
  height: 12px;
@@ -10,18 +10,18 @@ export type ButtonSize = "xs" | "sm" | "md" | "lg";
10
10
  export interface ButtonProps extends ComponentPropsWithoutRef<"button"> {
11
11
  variant?: ButtonVariant;
12
12
  /** Semantic color. Defaults to "primary". */
13
- tone?: ButtonTone;
14
- size?: ButtonSize;
15
- loading?: boolean;
13
+ tone?: ButtonTone | undefined;
14
+ size?: ButtonSize | undefined;
15
+ loading?: boolean | undefined;
16
16
  /**
17
17
  * Text shown in place of children while loading.
18
18
  * When provided the button width adapts to this text (variable width).
19
19
  * When omitted, children stay rendered invisibly — width stays stable.
20
20
  */
21
- loadingText?: string;
22
- iconOnly?: boolean;
23
- render?: ReactElement;
24
- nativeButton?: boolean;
21
+ loadingText?: string | undefined;
22
+ iconOnly?: boolean | undefined;
23
+ render?: ReactElement | undefined;
24
+ nativeButton?: boolean | undefined;
25
25
  }
26
26
 
27
27
  export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
@@ -1,17 +1,13 @@
1
- @layer theme, base, components, utilities;
2
-
3
1
  @layer components {
4
2
  .root {
5
3
  background-color: var(--color-surface-1);
6
- border: var(--border-width-base) solid var(--color-border-base);
4
+ border: var(--border-width-base) solid var(--color-line);
7
5
  border-radius: var(--radius-xl);
8
6
  overflow: hidden;
9
7
  }
10
-
11
8
  .root-elevated {
12
9
  box-shadow: var(--shadow-sm);
13
10
  }
14
-
15
11
  .root-interactive {
16
12
  cursor: pointer;
17
13
  transition:
@@ -19,47 +15,40 @@
19
15
  box-shadow var(--duration-fast) var(--easing-standard),
20
16
  transform var(--duration-fast) var(--easing-standard);
21
17
  }
22
-
23
18
  .root-interactive:hover {
24
19
  border-color: var(--color-accent);
25
20
  box-shadow: var(--shadow-md);
26
21
  }
27
-
28
22
  .root-interactive:active {
29
23
  transform: scale(0.995);
30
24
  }
31
-
32
25
  .header {
33
26
  padding: var(--space-4) var(--space-5);
34
- border-bottom: var(--border-width-base) solid var(--color-border-subtle);
27
+ border-bottom: var(--border-width-base) solid var(--color-line-subtle);
35
28
  display: flex;
36
29
  flex-direction: column;
37
30
  gap: var(--space-0-5);
38
31
  }
39
-
40
32
  .title {
41
33
  font-family: var(--font-mono);
42
34
  font-size: var(--font-size-md);
43
35
  font-weight: var(--font-weight-semibold);
44
- color: var(--color-text-primary);
36
+ color: var(--color-primary);
45
37
  line-height: var(--line-height-tight);
46
38
  letter-spacing: var(--letter-spacing-tight);
47
39
  }
48
-
49
40
  .description {
50
41
  font-family: var(--font-mono);
51
42
  font-size: var(--font-size-sm);
52
- color: var(--color-text-secondary);
43
+ color: var(--color-secondary);
53
44
  line-height: var(--line-height-normal);
54
45
  }
55
-
56
46
  .body {
57
47
  padding: var(--space-4) var(--space-5);
58
48
  }
59
-
60
49
  .footer {
61
50
  padding: var(--space-3) var(--space-5);
62
- border-top: var(--border-width-base) solid var(--color-border-subtle);
51
+ border-top: var(--border-width-base) solid var(--color-line-subtle);
63
52
  display: flex;
64
53
  align-items: center;
65
54
  gap: var(--space-2);