sonance-brand-mcp 1.3.110 → 1.3.112

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 (84) hide show
  1. package/dist/assets/api/sonance-ai-edit/route.ts +30 -7
  2. package/dist/assets/api/sonance-save-image/route.ts +625 -0
  3. package/dist/assets/api/sonance-vision-apply/image-styling-detection.ts +1360 -0
  4. package/dist/assets/api/sonance-vision-apply/route.ts +1020 -64
  5. package/dist/assets/api/sonance-vision-apply/styling-detection.ts +730 -0
  6. package/dist/assets/api/sonance-vision-apply/theme-discovery.ts +1 -1
  7. package/dist/assets/api/sonance-vision-edit/route.ts +33 -8
  8. package/dist/assets/brand-system.ts +13 -12
  9. package/dist/assets/components/accordion.tsx +15 -7
  10. package/dist/assets/components/alert-dialog.tsx +35 -10
  11. package/dist/assets/components/alert.tsx +11 -10
  12. package/dist/assets/components/avatar.tsx +4 -4
  13. package/dist/assets/components/badge.tsx +16 -12
  14. package/dist/assets/components/button.stories.tsx +3 -3
  15. package/dist/assets/components/button.tsx +50 -31
  16. package/dist/assets/components/calendar.tsx +12 -8
  17. package/dist/assets/components/card.tsx +35 -29
  18. package/dist/assets/components/checkbox.tsx +9 -8
  19. package/dist/assets/components/code.tsx +19 -11
  20. package/dist/assets/components/command.tsx +32 -13
  21. package/dist/assets/components/context-menu.tsx +37 -16
  22. package/dist/assets/components/dialog.tsx +8 -5
  23. package/dist/assets/components/divider.tsx +15 -5
  24. package/dist/assets/components/drawer.tsx +4 -3
  25. package/dist/assets/components/dropdown-menu.tsx +15 -13
  26. package/dist/assets/components/hover-card.tsx +4 -1
  27. package/dist/assets/components/image.tsx +1 -1
  28. package/dist/assets/components/input.tsx +29 -14
  29. package/dist/assets/components/kbd.stories.tsx +3 -3
  30. package/dist/assets/components/kbd.tsx +29 -13
  31. package/dist/assets/components/listbox.tsx +8 -8
  32. package/dist/assets/components/menubar.tsx +50 -23
  33. package/dist/assets/components/navbar.stories.tsx +140 -13
  34. package/dist/assets/components/navbar.tsx +22 -5
  35. package/dist/assets/components/navigation-menu.tsx +28 -6
  36. package/dist/assets/components/pagination.tsx +10 -10
  37. package/dist/assets/components/popover.tsx +10 -8
  38. package/dist/assets/components/progress.tsx +6 -4
  39. package/dist/assets/components/radio-group.tsx +5 -5
  40. package/dist/assets/components/select.tsx +49 -29
  41. package/dist/assets/components/separator.tsx +3 -3
  42. package/dist/assets/components/sheet.tsx +4 -4
  43. package/dist/assets/components/sidebar.tsx +10 -10
  44. package/dist/assets/components/skeleton.tsx +13 -5
  45. package/dist/assets/components/slider.tsx +12 -10
  46. package/dist/assets/components/switch.tsx +4 -4
  47. package/dist/assets/components/table.tsx +5 -5
  48. package/dist/assets/components/tabs.tsx +8 -8
  49. package/dist/assets/components/textarea.tsx +11 -9
  50. package/dist/assets/components/toast.tsx +7 -7
  51. package/dist/assets/components/toggle.tsx +27 -7
  52. package/dist/assets/components/tooltip.tsx +10 -8
  53. package/dist/assets/components/user.tsx +8 -6
  54. package/dist/assets/dev-tools/SonanceDevTools.tsx +851 -708
  55. package/dist/assets/dev-tools/components/ApplyFirstPreview.tsx +10 -10
  56. package/dist/assets/dev-tools/components/ChatHistory.tsx +145 -0
  57. package/dist/assets/dev-tools/components/ChatInterface.tsx +444 -295
  58. package/dist/assets/dev-tools/components/ChatTabBar.tsx +82 -0
  59. package/dist/assets/dev-tools/components/DiffPreview.tsx +1 -1
  60. package/dist/assets/dev-tools/components/InlineDiffPreview.tsx +528 -0
  61. package/dist/assets/dev-tools/components/InspectorOverlay.tsx +21 -18
  62. package/dist/assets/dev-tools/components/PropertiesPanel.tsx +1345 -0
  63. package/dist/assets/dev-tools/components/ScreenshotAnnotator.tsx +1 -1
  64. package/dist/assets/dev-tools/components/SectionHighlight.tsx +1 -1
  65. package/dist/assets/dev-tools/components/VisionDiffPreview.tsx +7 -7
  66. package/dist/assets/dev-tools/components/VisionModeBorder.tsx +12 -63
  67. package/dist/assets/dev-tools/constants.ts +38 -6
  68. package/dist/assets/dev-tools/hooks/index.ts +69 -0
  69. package/dist/assets/dev-tools/hooks/useComponentDetection.ts +132 -0
  70. package/dist/assets/dev-tools/hooks/useComputedStyles.ts +471 -0
  71. package/dist/assets/dev-tools/hooks/useContentHash.ts +212 -0
  72. package/dist/assets/dev-tools/hooks/useElementScanner.ts +398 -0
  73. package/dist/assets/dev-tools/hooks/useImageDetection.ts +162 -0
  74. package/dist/assets/dev-tools/hooks/useTextDetection.ts +217 -0
  75. package/dist/assets/dev-tools/index.ts +3 -0
  76. package/dist/assets/dev-tools/panels/AnalysisPanel.tsx +32 -32
  77. package/dist/assets/dev-tools/panels/ComponentsPanel.tsx +384 -131
  78. package/dist/assets/dev-tools/panels/TextPanel.tsx +10 -10
  79. package/dist/assets/dev-tools/types.ts +93 -2
  80. package/dist/assets/globals.css +225 -9
  81. package/dist/assets/styles/brand-overrides.css +3 -2
  82. package/dist/assets/utils.ts +2 -1
  83. package/dist/index.js +22 -3
  84. package/package.json +2 -1
@@ -13,14 +13,30 @@ interface NavbarProps extends React.HTMLAttributes<HTMLElement> {
13
13
  export const Navbar = forwardRef<HTMLElement, NavbarProps>(
14
14
  ({ className, variant = "default", sticky = false, bordered = true, children, ...props }, ref) => {
15
15
  const variantClasses = {
16
- default: "bg-background",
16
+ default: "bg-white/70 dark:bg-white/[0.03] backdrop-blur-lg",
17
17
  dark: "bg-sonance-charcoal text-sonance-white",
18
18
  transparent: "bg-transparent",
19
- blur: "bg-backdrop backdrop-blur-md",
19
+ blur: "bg-white/60 dark:bg-black/40 backdrop-blur-xl",
20
+ };
21
+
22
+ const borderClasses = {
23
+ default: "border-b border-black/8 dark:border-white/8",
24
+ dark: "border-b border-white/10",
25
+ transparent: "",
26
+ blur: "border-b border-black/8 dark:border-white/8",
20
27
  };
21
28
 
22
29
  return (
23
- <nav data-sonance-name="navbar"
30
+ <nav
31
+ ref={ref}
32
+ data-sonance-name="navbar"
33
+ className={cn(
34
+ "w-full px-4 md:px-6 py-3",
35
+ variantClasses[variant],
36
+ bordered && borderClasses[variant],
37
+ sticky && "sticky top-0 z-50",
38
+ className
39
+ )}
24
40
  {...props}
25
41
  >
26
42
  {children}
@@ -133,7 +149,8 @@ export function NavbarMobileMenu({ isOpen, children, className }: NavbarMobileMe
133
149
  <div
134
150
  className={cn(
135
151
  "md:hidden absolute left-0 right-0 top-full",
136
- "bg-background border-b border-border shadow-lg",
152
+ "bg-white/90 dark:bg-black/80 backdrop-blur-xl",
153
+ "border-b border-black/10 dark:border-white/10 shadow-xl",
137
154
  "animate-in slide-in-from-top-2 duration-200",
138
155
  className
139
156
  )}
@@ -198,7 +215,7 @@ export function ResponsiveNavbar({
198
215
  {item.label}
199
216
  </a>
200
217
  ))}
201
- {actions && <div className="pt-4 border-t border-border">{actions}</div>}
218
+ {actions && <div className="pt-4 border-t border-black/8 dark:border-white/8">{actions}</div>}
202
219
  </NavbarMobileMenu>
203
220
  </Navbar>
204
221
  );
@@ -12,6 +12,7 @@ const NavigationMenu = React.forwardRef<
12
12
  >(({ className, children, ...props }, ref) => (
13
13
  <NavigationMenuPrimitive.Root
14
14
  ref={ref}
15
+ data-sonance-name="navigation-menu"
15
16
  className={cn(
16
17
  "relative z-10 flex max-w-max flex-1 items-center justify-center",
17
18
  className
@@ -42,7 +43,16 @@ NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
42
43
  const NavigationMenuItem = NavigationMenuPrimitive.Item;
43
44
 
44
45
  const navigationMenuTriggerStyle = cva(
45
- "group inline-flex h-10 w-max items-center justify-center rounded-sm bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-secondary-hover hover:text-foreground focus:bg-secondary-hover focus:text-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-secondary-hover/50 data-[state=open]:bg-secondary-hover/50"
46
+ cn(
47
+ "group inline-flex h-10 w-max items-center justify-center rounded-xl px-4 py-2 text-sm font-medium",
48
+ "transition-all duration-150",
49
+ "bg-transparent backdrop-blur-sm",
50
+ "hover:bg-white/60 dark:hover:bg-white/10 hover:text-foreground",
51
+ "focus:bg-white/60 dark:focus:bg-white/10 focus:text-foreground focus:outline-none",
52
+ "disabled:pointer-events-none disabled:opacity-50",
53
+ "data-[active]:bg-white/50 dark:data-[active]:bg-white/8",
54
+ "data-[state=open]:bg-white/60 dark:data-[state=open]:bg-white/10"
55
+ )
46
56
  );
47
57
 
48
58
  const NavigationMenuTrigger = React.forwardRef<
@@ -70,7 +80,12 @@ const NavigationMenuContent = React.forwardRef<
70
80
  <NavigationMenuPrimitive.Content
71
81
  ref={ref}
72
82
  className={cn(
73
- "left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto",
83
+ "left-0 top-0 w-full",
84
+ "data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out",
85
+ "data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out",
86
+ "data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52",
87
+ "data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52",
88
+ "md:absolute md:w-auto",
74
89
  className
75
90
  )}
76
91
  {...props}
@@ -84,10 +99,18 @@ const NavigationMenuViewport = React.forwardRef<
84
99
  React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
85
100
  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
86
101
  >(({ className, ...props }, ref) => (
87
- <div data-sonance-name="navigation-menu" className={cn("absolute left-0 top-full flex justify-center")}>
102
+ <div
103
+ data-sonance-name="navigation-menu"
104
+ className={cn("absolute left-0 top-full flex justify-center")}
105
+ >
88
106
  <NavigationMenuPrimitive.Viewport
89
107
  className={cn(
90
- "origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-sm border border-border bg-card text-foreground shadow-lg",
108
+ "origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden",
109
+ "rounded-xl backdrop-blur-xl",
110
+ "bg-white/90 dark:bg-black/80",
111
+ "border border-black/10 dark:border-white/10",
112
+ "shadow-[0_8px_32px_rgba(0,0,0,0.12)] dark:shadow-[0_8px_32px_rgba(0,0,0,0.4)]",
113
+ "text-foreground",
91
114
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
92
115
  "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90",
93
116
  "md:w-[var(--radix-navigation-menu-viewport-width)]",
@@ -115,7 +138,7 @@ const NavigationMenuIndicator = React.forwardRef<
115
138
  )}
116
139
  {...props}
117
140
  >
118
- <div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
141
+ <div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-white/80 dark:bg-white/10 shadow-md" />
119
142
  </NavigationMenuPrimitive.Indicator>
120
143
  ));
121
144
  NavigationMenuIndicator.displayName =
@@ -132,4 +155,3 @@ export {
132
155
  NavigationMenuIndicator,
133
156
  NavigationMenuViewport,
134
157
  };
135
-
@@ -8,14 +8,14 @@ import { cn } from "@/lib/utils";
8
8
  export type PaginationButtonState = "default" | "hover" | "focus" | "active" | "disabled";
9
9
 
10
10
  const paginationButtonVariants = cva(
11
- "flex items-center justify-center font-medium border transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-primary/20 focus:ring-offset-2",
11
+ "flex items-center justify-center font-medium border transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-[color:var(--sonance-blue)]/30 focus:ring-offset-2 backdrop-blur-sm",
12
12
  {
13
13
  variants: {
14
14
  size: {
15
- xs: "h-6 min-w-6 px-1.5 text-[10px] rounded-md",
16
- sm: "h-7 min-w-7 px-2 text-xs rounded-lg",
17
- md: "h-8 min-w-8 px-2.5 text-sm rounded-lg",
18
- lg: "h-9 min-w-9 px-3 text-sm rounded-xl",
15
+ xs: "h-6 min-w-6 px-1.5 text-[10px] rounded-lg",
16
+ sm: "h-7 min-w-7 px-2 text-xs rounded-xl",
17
+ md: "h-8 min-w-8 px-2.5 text-sm rounded-xl",
18
+ lg: "h-9 min-w-9 px-3 text-sm rounded-2xl",
19
19
  },
20
20
  },
21
21
  defaultVariants: {
@@ -29,9 +29,9 @@ const getButtonStateStyles = (state?: PaginationButtonState) => {
29
29
  if (!state || state === "default") return "";
30
30
 
31
31
  const stateMap: Record<string, string> = {
32
- hover: "bg-secondary-hover",
33
- focus: "ring-2 ring-primary/20 ring-offset-2",
34
- active: "bg-primary text-primary-foreground border-primary",
32
+ hover: "bg-white/50 dark:bg-white/10",
33
+ focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2",
34
+ active: "bg-[color:var(--sonance-blue)] text-white border-[color:var(--sonance-blue)]",
35
35
  disabled: "opacity-50 cursor-not-allowed",
36
36
  };
37
37
 
@@ -194,10 +194,10 @@ const PaginationButton = forwardRef<HTMLButtonElement, PaginationButtonProps>(
194
194
  className={cn(
195
195
  paginationButtonVariants({ size }),
196
196
  isActive
197
- ? "bg-primary text-primary-foreground border-primary"
197
+ ? "bg-[color:var(--sonance-blue)] text-white border-[color:var(--sonance-blue)]"
198
198
  : isDisabled
199
199
  ? "bg-transparent text-foreground-subtle border-transparent cursor-not-allowed"
200
- : "bg-transparent text-foreground border-border hover:bg-secondary-hover",
200
+ : "bg-white/60 dark:bg-white/5 text-foreground border-black/8 dark:border-white/8 hover:bg-white/70 dark:hover:bg-white/10 hover:border-black/12 dark:hover:border-white/12",
201
201
  getButtonStateStyles(state),
202
202
  className
203
203
  )} data-sonance-name="pagination"
@@ -16,18 +16,20 @@ const popoverVariants = cva(
16
16
  {
17
17
  variants: {
18
18
  size: {
19
- compact: "rounded-lg",
20
- default: "rounded-xl",
21
- spacious: "rounded-2xl",
19
+ compact: "rounded-xl",
20
+ default: "rounded-2xl",
21
+ spacious: "rounded-3xl",
22
22
  },
23
23
  popoverVariant: {
24
- default: "bg-card border-border",
25
- glass: "bg-card/95 border-border/50 backdrop-blur-xl",
24
+ // Glass morphism - default style
25
+ default: "bg-white/90 dark:bg-black/70 border-black/10 dark:border-white/10 backdrop-blur-xl shadow-[0_8px_32px_rgba(0,0,0,0.12)] dark:shadow-[0_8px_32px_rgba(0,0,0,0.4)]",
26
+ // Non-glass solid variant
27
+ solid: "bg-card border-border backdrop-blur-none",
26
28
  },
27
29
  },
28
30
  defaultVariants: {
29
31
  size: "default",
30
- popoverVariant: "glass",
32
+ popoverVariant: "default",
31
33
  },
32
34
  }
33
35
  );
@@ -58,7 +60,7 @@ export function Popover({
58
60
  triggerOn = "click",
59
61
  className,
60
62
  size = "default",
61
- popoverVariant = "glass",
63
+ popoverVariant = "default",
62
64
  }: PopoverProps) {
63
65
  const [isOpen, setIsOpen] = useState(false);
64
66
  const [portalPosition, setPortalPosition] = useState<PortalPosition>({ top: 0, left: 0 });
@@ -178,7 +180,7 @@ export function Popover({
178
180
  };
179
181
 
180
182
  return (
181
- <PopoverContext.Provider value={{ size }}>
183
+ <PopoverContext.Provider value={{ size: size ?? "default" }}>
182
184
  <div data-sonance-name="popover"
183
185
  ref={containerRef}
184
186
  className="relative inline-block"
@@ -42,12 +42,14 @@ export const Progress = forwardRef<HTMLDivElement, ProgressProps>(
42
42
  aria-valuemax={max}
43
43
  aria-valuenow={value}
44
44
  className={cn(
45
- "w-full overflow-hidden rounded-full bg-background-secondary",
45
+ "w-full overflow-hidden rounded-full",
46
+ "bg-white/60 dark:bg-white/[0.05] backdrop-blur-sm",
47
+ "border border-black/5 dark:border-white/5",
46
48
  heightClasses[size]
47
49
  )}
48
50
  >
49
51
  <div
50
- className="h-full bg-primary transition-all duration-300 ease-out"
52
+ className="h-full bg-[color:var(--sonance-blue)] transition-all duration-300 ease-out"
51
53
  style={{ width: `${percentage}%` }}
52
54
  />
53
55
  </div>
@@ -99,7 +101,7 @@ export function CircularProgress({
99
101
  fill="none"
100
102
  stroke="currentColor"
101
103
  strokeWidth={strokeWidth}
102
- className="text-background-secondary"
104
+ className="text-black/10 dark:text-white/10"
103
105
  />
104
106
  {/* Progress circle */}
105
107
  <circle
@@ -112,7 +114,7 @@ export function CircularProgress({
112
114
  strokeLinecap="round"
113
115
  strokeDasharray={circumference}
114
116
  strokeDashoffset={strokeDashoffset}
115
- className="text-primary transition-all duration-300 ease-out"
117
+ className="text-[color:var(--sonance-blue)] transition-all duration-300 ease-out"
116
118
  />
117
119
  </svg>
118
120
  {showValue && (
@@ -7,7 +7,7 @@ import { cn } from "@/lib/utils";
7
7
  export type RadioGroupItemState = "default" | "hover" | "focus" | "checked" | "disabled";
8
8
 
9
9
  const radioItemVariants = cva(
10
- "peer shrink-0 appearance-none rounded-full border border-border bg-input transition-all duration-150 hover:border-border-hover checked:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 focus:ring-offset-2 focus:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",
10
+ "peer shrink-0 appearance-none rounded-full border transition-all duration-150 focus:outline-none focus:ring-2 focus:ring-[color:var(--sonance-blue)]/30 focus:ring-offset-2 focus:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 backdrop-blur-sm bg-white/60 dark:bg-white/5 border-black/8 dark:border-white/8 hover:border-black/15 dark:hover:border-white/15 checked:border-[color:var(--sonance-blue)]",
11
11
  {
12
12
  variants: {
13
13
  size: {
@@ -35,9 +35,9 @@ const getStateStyles = (state?: RadioGroupItemState) => {
35
35
  if (!state || state === "default") return "";
36
36
 
37
37
  const stateMap: Record<string, string> = {
38
- hover: "border-border-hover",
39
- focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
40
- checked: "border-primary",
38
+ hover: "border-black/15 dark:border-white/15",
39
+ focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
40
+ checked: "border-[color:var(--sonance-blue)]",
41
41
  disabled: "opacity-50 cursor-not-allowed",
42
42
  };
43
43
 
@@ -142,7 +142,7 @@ export const RadioGroupItem = forwardRef<HTMLInputElement, RadioGroupItemProps>(
142
142
  />
143
143
  <div data-sonance-name="radio-group"
144
144
  className={cn(
145
- "pointer-events-none absolute rounded-full bg-primary",
145
+ "pointer-events-none absolute rounded-full bg-[color:var(--sonance-blue)]",
146
146
  "scale-0 transition-all duration-150",
147
147
  radioIndicatorSizes[size],
148
148
  isChecked && "scale-100"
@@ -8,18 +8,22 @@ import { cn } from "@/lib/utils";
8
8
  export type SelectState = "default" | "hover" | "focus" | "open" | "error" | "disabled";
9
9
 
10
10
  const selectTriggerVariants = cva(
11
- "flex w-full items-center justify-between border border-input-border bg-input text-left text-foreground transition-all duration-200 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50",
11
+ "flex w-full items-center justify-between text-left text-foreground transition-all duration-200 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 backdrop-blur-sm",
12
12
  {
13
13
  variants: {
14
14
  size: {
15
- xs: "h-7 px-2.5 text-xs rounded-md",
16
- sm: "h-8 px-3 text-sm rounded-lg",
17
- md: "h-9 px-3.5 text-sm rounded-lg",
18
- lg: "h-10 px-4 text-sm rounded-xl",
15
+ xs: "h-7 px-3 text-xs rounded-lg",
16
+ sm: "h-8 px-3.5 text-sm rounded-xl",
17
+ md: "h-9 px-4 text-sm rounded-xl",
18
+ lg: "h-10 px-4 text-sm rounded-2xl",
19
19
  },
20
20
  selectVariant: {
21
- default: "hover:border-border-hover focus:border-input-focus focus:ring-2 focus:ring-primary/10",
22
- glass: "bg-input/80 backdrop-blur-sm hover:border-border-hover focus:border-input-focus focus:ring-2 focus:ring-primary/20",
21
+ // Glass morphism - default style
22
+ default:
23
+ "bg-white/60 dark:bg-white/[0.03] border border-black/8 dark:border-white/8 hover:border-black/12 dark:hover:border-white/12 focus:border-[color:var(--sonance-blue)] focus:shadow-[0_0_20px_var(--glow-primary)] focus:ring-0",
24
+ // Non-glass solid variant for fallback
25
+ solid:
26
+ "bg-input border border-input-border hover:border-border-hover focus:border-input-focus focus:ring-2 focus:ring-primary/10 backdrop-blur-none",
23
27
  },
24
28
  },
25
29
  defaultVariants: {
@@ -30,14 +34,26 @@ const selectTriggerVariants = cva(
30
34
  );
31
35
 
32
36
  // State styles for Storybook/Figma visualization
33
- const getStateStyles = (state?: SelectState) => {
37
+ const getStateStyles = (state?: SelectState, selectVariant?: string | null) => {
34
38
  if (!state || state === "default") return "";
35
39
 
40
+ if (selectVariant === "solid") {
41
+ const stateMap: Record<string, string> = {
42
+ hover: "border-border-hover",
43
+ focus: "border-input-focus ring-2 ring-primary/10",
44
+ open: "border-input-focus ring-2 ring-primary/10",
45
+ error: "border-error ring-2 ring-error/10",
46
+ disabled: "opacity-50 cursor-not-allowed",
47
+ };
48
+ return stateMap[state] || "";
49
+ }
50
+
51
+ // Glass variant states
36
52
  const stateMap: Record<string, string> = {
37
- hover: "border-border-hover",
38
- focus: "border-input-focus ring-2 ring-primary/10",
39
- open: "border-input-focus ring-2 ring-primary/10",
40
- error: "border-error ring-2 ring-error/10",
53
+ hover: "border-black/12 dark:border-white/12",
54
+ focus: "border-[color:var(--sonance-blue)] shadow-[0_0_20px_var(--glow-primary)]",
55
+ open: "border-[color:var(--sonance-blue)] shadow-[0_0_20px_var(--glow-primary)]",
56
+ error: "border-error shadow-[0_0_15px_rgba(198,40,40,0.2)]",
41
57
  disabled: "opacity-50 cursor-not-allowed",
42
58
  };
43
59
 
@@ -139,9 +155,9 @@ export function Select({
139
155
  style={style}
140
156
  className={cn(
141
157
  selectTriggerVariants({ size, selectVariant }),
142
- hasError && "border-error ring-2 ring-error/10",
143
- (isOpen || isOpenState) && "border-input-focus ring-2 ring-primary/10",
144
- getStateStyles(state)
158
+ hasError && (selectVariant === "solid" ? "border-error ring-2 ring-error/10" : "border-error shadow-[0_0_15px_rgba(198,40,40,0.2)]"),
159
+ (isOpen || isOpenState) && (selectVariant === "solid" ? "border-input-focus ring-2 ring-primary/10" : "border-[color:var(--sonance-blue)] shadow-[0_0_20px_var(--glow-primary)]"),
160
+ getStateStyles(state, selectVariant)
145
161
  )}
146
162
  >
147
163
  <span id="span-selectedoptionlabel-" className={cn(!selectedOption && "text-input-placeholder")}>
@@ -158,8 +174,11 @@ export function Select({
158
174
  {isOpen && (
159
175
  <div
160
176
  className={cn(
161
- "absolute z-50 mt-1.5 w-full rounded-xl border border-border bg-card/95 backdrop-blur-md shadow-xl",
162
- "max-h-60 overflow-auto p-1",
177
+ "absolute z-50 mt-2 w-full rounded-2xl backdrop-blur-xl",
178
+ "bg-white/90 dark:bg-black/80",
179
+ "border border-black/10 dark:border-white/10",
180
+ "shadow-[0_8px_32px_rgba(0,0,0,0.12)] dark:shadow-[0_8px_32px_rgba(0,0,0,0.4)]",
181
+ "max-h-60 overflow-auto p-1.5",
163
182
  "animate-in fade-in-0 zoom-in-95 duration-150"
164
183
  )}
165
184
  >
@@ -170,11 +189,11 @@ export function Select({
170
189
  onClick={() => !option.disabled && handleSelect(option.value)}
171
190
  disabled={option.disabled}
172
191
  className={cn(
173
- "flex w-full items-center justify-between px-3 py-2 text-left text-sm rounded-lg",
174
- "transition-colors duration-150",
192
+ "flex w-full items-center justify-between px-3 py-2 text-left text-sm rounded-xl",
193
+ "transition-all duration-150",
175
194
  option.value === value
176
- ? "bg-primary text-primary-foreground"
177
- : "text-foreground hover:bg-secondary-hover",
195
+ ? "bg-[color:var(--sonance-blue)] text-white"
196
+ : "text-foreground hover:bg-white/50 dark:hover:bg-white/10",
178
197
  option.disabled && "cursor-not-allowed opacity-50"
179
198
  )}
180
199
  >
@@ -223,10 +242,10 @@ export const NativeSelect = forwardRef<HTMLSelectElement, NativeSelectProps>(
223
242
  const hasError = error || state === "error";
224
243
 
225
244
  const sizeClasses = {
226
- xs: "h-7 px-2.5 pr-8 text-xs rounded-md",
227
- sm: "h-8 px-3 pr-9 text-sm rounded-lg",
228
- md: "h-9 px-3.5 pr-9 text-sm rounded-lg",
229
- lg: "h-10 px-4 pr-10 text-sm rounded-xl",
245
+ xs: "h-7 px-3 pr-8 text-xs rounded-lg",
246
+ sm: "h-8 px-3.5 pr-9 text-sm rounded-xl",
247
+ md: "h-9 px-4 pr-9 text-sm rounded-xl",
248
+ lg: "h-10 px-4 pr-10 text-sm rounded-2xl",
230
249
  };
231
250
 
232
251
  return (
@@ -241,13 +260,14 @@ export const NativeSelect = forwardRef<HTMLSelectElement, NativeSelectProps>(
241
260
  ref={ref}
242
261
  disabled={isDisabled}
243
262
  className={cn(
244
- "w-full appearance-none border border-input-border bg-input",
263
+ "w-full appearance-none backdrop-blur-sm",
264
+ "bg-white/60 dark:bg-white/[0.03] border border-black/8 dark:border-white/8",
245
265
  sizeClasses[size],
246
266
  "text-foreground transition-all duration-200",
247
- "hover:border-border-hover",
248
- "focus:border-input-focus focus:outline-none focus:ring-2 focus:ring-primary/10",
267
+ "hover:border-black/12 dark:hover:border-white/12",
268
+ "focus:border-[color:var(--sonance-blue)] focus:outline-none focus:shadow-[0_0_20px_var(--glow-primary)]",
249
269
  "disabled:cursor-not-allowed disabled:opacity-50",
250
- hasError && "border-error ring-2 ring-error/10",
270
+ hasError && "border-error shadow-[0_0_15px_rgba(198,40,40,0.2)]",
251
271
  getNativeSelectStateStyles(state),
252
272
  className
253
273
  )} data-sonance-name="select"
@@ -13,12 +13,13 @@ const Separator = React.forwardRef<
13
13
  { className, orientation = "horizontal", decorative = true, ...props },
14
14
  ref
15
15
  ) => (
16
- <SeparatorPrimitive.Root data-sonance-name="separator"
16
+ <SeparatorPrimitive.Root
17
+ data-sonance-name="separator"
17
18
  ref={ref}
18
19
  decorative={decorative}
19
20
  orientation={orientation}
20
21
  className={cn(
21
- "shrink-0 bg-border",
22
+ "shrink-0 bg-black/8 dark:bg-white/8",
22
23
  orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
23
24
  className
24
25
  )}
@@ -29,4 +30,3 @@ const Separator = React.forwardRef<
29
30
  Separator.displayName = SeparatorPrimitive.Root.displayName
30
31
 
31
32
  export { Separator }
32
-
@@ -21,7 +21,7 @@ const SheetOverlay = React.forwardRef<
21
21
  >(({ className, ...props }, ref) => (
22
22
  <SheetPrimitive.Overlay
23
23
  className={cn(
24
- "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
24
+ "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
25
25
  className
26
26
  )}
27
27
  {...props}
@@ -31,7 +31,7 @@ const SheetOverlay = React.forwardRef<
31
31
  SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
32
32
 
33
33
  const sheetVariants = cva(
34
- "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
34
+ "fixed z-50 gap-4 bg-white/90 dark:bg-black/80 backdrop-blur-xl p-6 shadow-xl transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500 border-black/10 dark:border-white/10",
35
35
  {
36
36
  variants: {
37
37
  side: {
@@ -65,7 +65,7 @@ const SheetContent = React.forwardRef<
65
65
  {...props}
66
66
  >
67
67
  {children}
68
- <SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
68
+ <SheetPrimitive.Close className="absolute right-4 top-4 rounded-xl p-1.5 opacity-70 transition-all hover:opacity-100 hover:bg-white/50 dark:hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-[color:var(--sonance-blue)]/30 disabled:pointer-events-none">
69
69
  <X className="h-4 w-4" />
70
70
  <span id="sheet-content-span-close" className="sr-only">Close</span>
71
71
  </SheetPrimitive.Close>
@@ -116,7 +116,7 @@ const SheetDescription = React.forwardRef<
116
116
  >(({ className, ...props }, ref) => (
117
117
  <SheetPrimitive.Description
118
118
  ref={ref}
119
- className={cn("text-sm text-muted-foreground", className)}
119
+ className={cn("text-sm text-foreground-muted", className)}
120
120
  {...props}
121
121
  />
122
122
  ))
@@ -240,7 +240,7 @@ const Sidebar = React.forwardRef<
240
240
  >
241
241
  <div
242
242
  data-sidebar="sidebar"
243
- className="flex h-full w-full flex-col bg-sidebar-background group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow"
243
+ className="flex h-full w-full flex-col bg-sidebar-background group-data-[variant=floating]:rounded-2xl group-data-[variant=floating]:border group-data-[variant=floating]:border-black/8 dark:group-data-[variant=floating]:border-white/8 group-data-[variant=floating]:shadow-xl group-data-[variant=floating]:backdrop-blur-lg"
244
244
  >
245
245
  {children}
246
246
  </div>
@@ -433,7 +433,7 @@ const SidebarGroupLabel = React.forwardRef<
433
433
  ref={ref}
434
434
  data-sidebar="group-label"
435
435
  className={cn(
436
- "duration-200 flex h-8 shrink-0 items-center rounded-sm px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
436
+ "duration-200 flex h-8 shrink-0 items-center rounded-xl px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 focus-visible:ring-[color:var(--sonance-blue)]/30 [&>svg]:size-4 [&>svg]:shrink-0",
437
437
  "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
438
438
  className
439
439
  )}
@@ -454,7 +454,7 @@ const SidebarGroupAction = React.forwardRef<
454
454
  ref={ref}
455
455
  data-sidebar="group-action"
456
456
  className={cn(
457
- "absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-sm p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
457
+ "absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-lg p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-all hover:bg-white/50 dark:hover:bg-white/10 hover:text-sidebar-accent-foreground focus-visible:ring-2 focus-visible:ring-[color:var(--sonance-blue)]/30 [&>svg]:size-4 [&>svg]:shrink-0",
458
458
  // Increases the hit area of the button on mobile.
459
459
  "after:absolute after:-inset-2 after:md:hidden",
460
460
  "group-data-[collapsible=icon]:hidden",
@@ -506,13 +506,13 @@ const SidebarMenuItem = React.forwardRef<
506
506
  SidebarMenuItem.displayName = "SidebarMenuItem"
507
507
 
508
508
  const sidebarMenuButtonVariants = cva(
509
- "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-sm p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
509
+ "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-xl p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding,background-color] hover:bg-white/50 dark:hover:bg-white/10 hover:text-sidebar-accent-foreground focus-visible:ring-2 focus-visible:ring-[color:var(--sonance-blue)]/30 active:bg-white/60 dark:active:bg-white/15 active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-white/50 dark:data-[active=true]:bg-white/10 data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-white/50 dark:data-[state=open]:hover:bg-white/10 data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
510
510
  {
511
511
  variants: {
512
512
  variant: {
513
- default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
513
+ default: "hover:bg-white/50 dark:hover:bg-white/10 hover:text-sidebar-accent-foreground",
514
514
  outline:
515
- "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-border))]",
515
+ "bg-white/60 dark:bg-white/5 border border-black/8 dark:border-white/8 hover:bg-white/70 dark:hover:bg-white/10 hover:text-sidebar-accent-foreground",
516
516
  },
517
517
  size: {
518
518
  default: "h-8 text-sm",
@@ -600,7 +600,7 @@ const SidebarMenuAction = React.forwardRef<
600
600
  ref={ref}
601
601
  data-sidebar="menu-action"
602
602
  className={cn(
603
- "absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-sm p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0",
603
+ "absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-lg p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-all hover:bg-white/50 dark:hover:bg-white/10 hover:text-sidebar-accent-foreground focus-visible:ring-2 focus-visible:ring-[color:var(--sonance-blue)]/30 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0",
604
604
  // Increases the hit area of the button on mobile.
605
605
  "after:absolute after:-inset-2 after:md:hidden",
606
606
  "peer-data-[size=sm]/menu-button:top-1",
@@ -684,7 +684,7 @@ const SidebarMenuSub = React.forwardRef<
684
684
  ref={ref}
685
685
  data-sidebar="menu-sub"
686
686
  className={cn(
687
- "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5",
687
+ "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-black/8 dark:border-white/8 px-2.5 py-0.5",
688
688
  "group-data-[collapsible=icon]:hidden",
689
689
  className
690
690
  )} data-sonance-name="sidebar"
@@ -716,8 +716,8 @@ const SidebarMenuSubButton = React.forwardRef<
716
716
  data-size={size}
717
717
  data-active={isActive}
718
718
  className={cn(
719
- "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-sm px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
720
- "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
719
+ "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-xl px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-white/50 dark:hover:bg-white/10 hover:text-sidebar-accent-foreground focus-visible:ring-2 focus-visible:ring-[color:var(--sonance-blue)]/30 active:bg-white/60 dark:active:bg-white/15 active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
720
+ "data-[active=true]:bg-white/50 dark:data-[active=true]:bg-white/10 data-[active=true]:text-sidebar-accent-foreground",
721
721
  size === "sm" && "text-xs",
722
722
  size === "md" && "text-sm",
723
723
  "group-data-[collapsible=icon]:hidden",
@@ -15,16 +15,18 @@ export function Skeleton({
15
15
  ...props
16
16
  }: SkeletonProps) {
17
17
  const variantClasses = {
18
- text: "rounded",
18
+ text: "rounded-lg",
19
19
  circular: "rounded-full",
20
- rectangular: "rounded-sm",
20
+ rectangular: "rounded-xl",
21
21
  };
22
22
 
23
23
  return (
24
24
  <div
25
25
  data-sonance-name="skeleton"
26
26
  className={cn(
27
- "animate-pulse bg-background-secondary",
27
+ "animate-pulse",
28
+ "bg-white/50 dark:bg-white/[0.03]",
29
+ "backdrop-blur-sm",
28
30
  variantClasses[variant],
29
31
  className
30
32
  )}
@@ -74,7 +76,13 @@ export function SkeletonAvatar({
74
76
 
75
77
  export function SkeletonCard({ className }: { className?: string }) {
76
78
  return (
77
- <div className={cn("border border-border p-4 space-y-4", className)}>
79
+ <div
80
+ className={cn(
81
+ "border border-black/8 dark:border-white/8 rounded-2xl p-4 space-y-4",
82
+ "bg-white/30 dark:bg-white/[0.02] backdrop-blur-sm",
83
+ className
84
+ )}
85
+ >
78
86
  <Skeleton className="h-40 w-full" />
79
87
  <div className="space-y-2">
80
88
  <Skeleton className="h-4 w-3/4" />
@@ -96,7 +104,7 @@ export function SkeletonTable({
96
104
  return (
97
105
  <div className={cn("w-full space-y-2", className)}>
98
106
  {/* Header */}
99
- <div className="flex gap-4 border-b border-border pb-2">
107
+ <div className="flex gap-4 border-b border-black/8 dark:border-white/8 pb-2">
100
108
  {Array.from({ length: columns }).map((_, i) => (
101
109
  <Skeleton key={i} className="h-4 flex-1" />
102
110
  ))}