@tangle-network/sandbox-ui 0.8.4 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -133,16 +133,15 @@ There is a built-in Tangle default theme, but consumers can restyle the library
133
133
 
134
134
  `WorkspaceLayout` and `SandboxWorkbench` support:
135
135
 
136
- - `theme="operator"`
137
- - `theme="builder"`
138
- - `theme="consumer"`
136
+ - `theme="vault"` — light theme with solid surfaces
137
+ - No theme prop — default dark theme
139
138
 
140
139
  They also support `density="comfortable"` and `density="compact"`.
141
140
 
142
141
  ```tsx
143
142
  <SandboxWorkbench
144
143
  layout={{
145
- theme: "consumer",
144
+ theme: "vault",
146
145
  density: "comfortable",
147
146
  }}
148
147
  session={{ ... }}
@@ -152,7 +151,7 @@ They also support `density="comfortable"` and `density="compact"`.
152
151
  If you are not using `SandboxWorkbench`, you can set the same attributes yourself:
153
152
 
154
153
  ```tsx
155
- <div data-sandbox-ui data-sandbox-theme="consumer" data-density="compact">
154
+ <div data-sandbox-ui data-sandbox-theme="vault" data-density="compact">
156
155
  <YourSandboxApp />
157
156
  </div>
158
157
  ```
@@ -257,7 +256,7 @@ Retheming is absolutely supported, but the documentation was thinner than it sho
257
256
  - [Tailwind CSS](https://tailwindcss.com/) v4
258
257
  - [Lucide](https://lucide.dev/) icons
259
258
  - [CVA](https://cva.style/) for variant management
260
- - Shared semantic tokens for `operator`, `builder`, and `consumer` sandbox themes
259
+ - Shared semantic tokens for default dark and `vault` light sandbox themes
261
260
  - ESM-only, tree-shakeable, fully typed
262
261
 
263
262
  ## License
package/dist/auth.js CHANGED
@@ -3,9 +3,9 @@ import {
3
3
  GitHubLoginButton,
4
4
  LoginLayout,
5
5
  UserMenu
6
- } from "./chunk-VOUV7GGB.js";
6
+ } from "./chunk-DI3NZ5ZX.js";
7
7
  import "./chunk-34A66VBG.js";
8
- import "./chunk-2QZ6G7NM.js";
8
+ import "./chunk-MKTSMWVD.js";
9
9
  import "./chunk-RQHJBTEU.js";
10
10
  export {
11
11
  AuthHeader,
package/dist/chat.js CHANGED
@@ -8,17 +8,17 @@ import {
8
8
  MessageList,
9
9
  ThinkingIndicator,
10
10
  UserMessage
11
- } from "./chunk-BUOQTBTO.js";
11
+ } from "./chunk-JLKYXLFN.js";
12
12
  import "./chunk-54SQQMMM.js";
13
13
  import "./chunk-EXSOPXIY.js";
14
14
  import "./chunk-HRMUF35V.js";
15
15
  import "./chunk-MT5FJ3ZT.js";
16
16
  import "./chunk-BX6AQMUS.js";
17
- import "./chunk-WXK43R62.js";
17
+ import "./chunk-PLTZB5BC.js";
18
18
  import "./chunk-34I7UFSX.js";
19
19
  import "./chunk-T7HMZEVO.js";
20
20
  import "./chunk-ZMNSRDMH.js";
21
- import "./chunk-2QZ6G7NM.js";
21
+ import "./chunk-MKTSMWVD.js";
22
22
  import "./chunk-RQHJBTEU.js";
23
23
  export {
24
24
  AgentTimeline,
@@ -20,7 +20,7 @@ import {
20
20
  } from "./chunk-ZMNSRDMH.js";
21
21
  import {
22
22
  Button
23
- } from "./chunk-2QZ6G7NM.js";
23
+ } from "./chunk-MKTSMWVD.js";
24
24
  import {
25
25
  cn
26
26
  } from "./chunk-RQHJBTEU.js";
@@ -157,7 +157,7 @@ function Sidebar({ children, className, style }) {
157
157
  {
158
158
  "data-sidebar": "true",
159
159
  className: cn(
160
- "fixed inset-y-0 left-0 z-40 flex bg-card/80 backdrop-blur-3xl border-r border-border transition-[transform,width] duration-200 ease-in-out shadow-sm",
160
+ "fixed inset-y-0 left-0 z-40 flex bg-card border-r border-border transition-[transform,width] duration-200 ease-in-out",
161
161
  hidden && "-translate-x-full",
162
162
  className
163
163
  ),
@@ -193,7 +193,7 @@ function RailButton({ icon: Icon2, label, isActive, badge, onClick, className })
193
193
  "hover:bg-[var(--accent-surface-soft)] hover:text-[var(--accent-text)]",
194
194
  "active:scale-95",
195
195
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
196
- isActive && "bg-[var(--accent-surface-strong)] text-[var(--accent-text)] shadow-[0_0_12px_-2px_rgba(130,99,255,0.3)]",
196
+ isActive && "bg-[var(--accent-surface-strong)] text-[var(--accent-text)]",
197
197
  !isActive && "text-muted-foreground",
198
198
  className
199
199
  ),
@@ -224,7 +224,7 @@ function SidebarPanel({ children, className }) {
224
224
  "div",
225
225
  {
226
226
  className: cn(
227
- "transition-[opacity] duration-150 h-full overflow-hidden border-l border-border bg-card/50 backdrop-blur-xl",
227
+ "transition-[opacity] duration-150 h-full overflow-hidden border-l border-border bg-card",
228
228
  panelOpen ? "w-[260px] opacity-100" : "w-0 opacity-0 pointer-events-none",
229
229
  className
230
230
  ),
@@ -319,7 +319,7 @@ function ProfileAvatar({
319
319
  import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
320
320
  function ClusterStatusBar({ items, latency, className }) {
321
321
  if (!items?.length) return null;
322
- return /* @__PURE__ */ jsx3("div", { className: cn("fixed bottom-6 left-1/2 -translate-x-1/2 z-40 w-max max-w-[90vw] animate-in slide-in-from-bottom flex justify-center", className), children: /* @__PURE__ */ jsxs2("div", { className: "glass-panel-heavy overflow-hidden rounded-full px-6 py-3 flex flex-wrap sm:flex-nowrap items-center justify-between gap-8 border-primary/20 shadow-sm backdrop-blur-2xl", children: [
322
+ return /* @__PURE__ */ jsx3("div", { className: cn("fixed bottom-6 left-1/2 -translate-x-1/2 z-40 w-max max-w-[90vw] animate-in slide-in-from-bottom flex justify-center", className), children: /* @__PURE__ */ jsxs2("div", { className: "overflow-hidden rounded-full border border-border bg-card px-6 py-3 flex flex-wrap sm:flex-nowrap items-center justify-between gap-8 shadow-sm", children: [
323
323
  /* @__PURE__ */ jsx3("div", { className: "flex items-center gap-6", children: items.map((item, i) => /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
324
324
  /* @__PURE__ */ jsx3("span", { className: "text-[var(--md3-primary)] [&_svg]:h-[18px] [&_svg]:w-[18px]", children: item.icon }),
325
325
  /* @__PURE__ */ jsxs2("div", { className: "flex flex-col", children: [
@@ -516,6 +516,10 @@ function XIcon({ className }) {
516
516
  /* @__PURE__ */ jsx7("path", { d: "m6 6 12 12" })
517
517
  ] });
518
518
  }
519
+ function formatNotifDate(raw) {
520
+ const d = new Date(raw);
521
+ return Number.isNaN(d.getTime()) ? raw : d.toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" });
522
+ }
519
523
  function DefaultLink2({
520
524
  href,
521
525
  to,
@@ -546,10 +550,30 @@ function DashboardLayoutInner({
546
550
  LinkComponent = DefaultLink2,
547
551
  footer,
548
552
  railFooter,
549
- profileMenuItems
553
+ profileMenuItems,
554
+ notifications: notifData
550
555
  }) {
551
556
  const Link = LinkComponent;
552
557
  const [mobileMenuOpen, setMobileMenuOpen] = React3.useState(false);
558
+ const [notificationsOpen, setNotificationsOpen] = React3.useState(false);
559
+ const notifRef = React3.useRef(null);
560
+ React3.useEffect(() => {
561
+ if (!notificationsOpen) return;
562
+ const handler = (e) => {
563
+ if (notifRef.current && !notifRef.current.contains(e.target)) {
564
+ setNotificationsOpen(false);
565
+ }
566
+ };
567
+ const keyHandler = (e) => {
568
+ if (e.key === "Escape") setNotificationsOpen(false);
569
+ };
570
+ document.addEventListener("mousedown", handler);
571
+ document.addEventListener("keydown", keyHandler);
572
+ return () => {
573
+ document.removeEventListener("mousedown", handler);
574
+ document.removeEventListener("keydown", keyHandler);
575
+ };
576
+ }, [notificationsOpen]);
553
577
  const { contentMargin, hidden, mode, hasPanels, panelOpen } = useSidebar();
554
578
  const modeSet = React3.useMemo(() => new Set(modeItems), [modeItems]);
555
579
  const sidebarUser = user ? { email: user.email, name: user.name, tier: user.tier, avatarUrl: user.avatarUrl } : void 0;
@@ -608,7 +632,7 @@ function DashboardLayoutInner({
608
632
  /* @__PURE__ */ jsxs6(
609
633
  "nav",
610
634
  {
611
- className: "fixed top-0 z-50 bg-card/80 backdrop-blur-3xl border-b border-border flex justify-between items-center px-8 h-14 font-sans text-[13px] tracking-tight transition-[left,width] duration-200 ease-in-out shadow-sm",
635
+ className: "fixed top-0 z-50 bg-card border-b border-border flex justify-between items-center px-8 h-14 font-sans text-[13px] tracking-tight transition-[left,width] duration-200 ease-in-out",
612
636
  style: {
613
637
  left: hidden ? 0 : contentMargin,
614
638
  width: hidden ? "100%" : `calc(100% - ${contentMargin}px)`
@@ -633,14 +657,68 @@ function DashboardLayoutInner({
633
657
  {
634
658
  type: "button",
635
659
  onClick: onNewSandbox,
636
- className: "hidden md:flex items-center gap-2 bg-[var(--accent-surface-soft)] border border-border text-[var(--accent-text)] px-4 py-2 rounded-lg font-bold hover:bg-[var(--accent-surface-strong)] transition-all active:scale-95 text-xs",
660
+ className: "hidden md:flex items-center gap-2 bg-[var(--btn-primary-bg)] border border-[var(--border-accent)] text-[var(--btn-primary-text)] px-4 py-2 rounded-lg font-bold hover:bg-[var(--btn-primary-hover)] transition-all active:scale-95 text-xs",
637
661
  children: [
638
662
  /* @__PURE__ */ jsx7(Plus, { className: "h-3.5 w-3.5" }),
639
663
  "New Sandbox"
640
664
  ]
641
665
  }
642
666
  ),
643
- /* @__PURE__ */ jsx7("button", { type: "button", className: "text-muted-foreground hover:text-foreground transition-colors p-2 rounded-lg hover:bg-muted/50", children: /* @__PURE__ */ jsx7(Bell, { className: "h-4 w-4" }) })
667
+ /* @__PURE__ */ jsxs6("div", { className: "relative", ref: notifRef, children: [
668
+ /* @__PURE__ */ jsxs6(
669
+ "button",
670
+ {
671
+ type: "button",
672
+ className: "relative text-muted-foreground hover:text-foreground transition-colors p-2 rounded-lg hover:bg-muted/50",
673
+ onClick: () => setNotificationsOpen(!notificationsOpen),
674
+ "aria-label": "Notifications",
675
+ "aria-expanded": notificationsOpen,
676
+ children: [
677
+ /* @__PURE__ */ jsx7(Bell, { className: "h-4 w-4" }),
678
+ (notifData?.unreadCount ?? 0) > 0 && /* @__PURE__ */ jsx7("span", { className: "absolute top-1 right-1 h-2 w-2 rounded-full bg-destructive" })
679
+ ]
680
+ }
681
+ ),
682
+ notificationsOpen && /* @__PURE__ */ jsxs6("div", { className: "absolute right-0 top-full mt-2 w-80 rounded-lg border border-border bg-card shadow-lg z-50", children: [
683
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between border-b border-border px-4 py-3", children: [
684
+ /* @__PURE__ */ jsx7("p", { className: "font-bold text-foreground text-sm", children: "Notifications" }),
685
+ (notifData?.unreadCount ?? 0) > 0 && notifData?.onMarkAllRead && /* @__PURE__ */ jsx7(
686
+ "button",
687
+ {
688
+ type: "button",
689
+ onClick: () => {
690
+ notifData.onMarkAllRead?.();
691
+ },
692
+ className: "text-primary text-xs font-medium hover:underline",
693
+ children: "Mark all read"
694
+ }
695
+ )
696
+ ] }),
697
+ !notifData?.items || notifData.items.length === 0 ? /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center justify-center px-4 py-8 text-center", children: [
698
+ /* @__PURE__ */ jsx7(Bell, { className: "h-8 w-8 text-muted-foreground/40 mb-2" }),
699
+ /* @__PURE__ */ jsx7("p", { className: "text-muted-foreground text-sm", children: "No notifications yet" }),
700
+ /* @__PURE__ */ jsx7("p", { className: "text-muted-foreground/60 text-xs mt-1", children: "We'll notify you about important updates" })
701
+ ] }) : /* @__PURE__ */ jsx7("div", { className: "max-h-80 overflow-y-auto", children: notifData.items.map((n) => /* @__PURE__ */ jsxs6(
702
+ "button",
703
+ {
704
+ type: "button",
705
+ className: cn(
706
+ "w-full text-left px-4 py-3 border-b border-border last:border-0 transition-colors",
707
+ n.read ? "cursor-default" : "bg-primary/5 hover:bg-muted/50"
708
+ ),
709
+ onClick: () => {
710
+ if (!n.read) notifData.onMarkRead?.(n.id);
711
+ },
712
+ children: [
713
+ /* @__PURE__ */ jsx7("p", { className: cn("text-sm", !n.read ? "font-semibold text-foreground" : "text-muted-foreground"), children: n.title }),
714
+ /* @__PURE__ */ jsx7("p", { className: "text-xs text-muted-foreground mt-0.5 line-clamp-2", children: n.message }),
715
+ /* @__PURE__ */ jsx7("p", { className: "text-[10px] text-muted-foreground/50 mt-1", children: formatNotifDate(n.createdAt) })
716
+ ]
717
+ },
718
+ n.id
719
+ )) })
720
+ ] })
721
+ ] })
644
722
  ] }),
645
723
  /* @__PURE__ */ jsx7(
646
724
  "button",
@@ -669,8 +747,8 @@ function DashboardLayoutInner({
669
747
  }
670
748
  ),
671
749
  /* @__PURE__ */ jsx7(Sidebar, { className: cn("hidden lg:flex", sidebarClassName), children: sidebarContent }),
672
- /* @__PURE__ */ jsx7(SidebarContent, { className: cn("pt-16 px-6 pb-8 hidden lg:block", contentClassName), children }),
673
- /* @__PURE__ */ jsx7("main", { className: cn("pt-16 px-6 pb-8 min-h-screen lg:hidden", contentClassName), children }),
750
+ /* @__PURE__ */ jsx7(SidebarContent, { className: cn("pt-16 px-8 pb-8 hidden lg:block bg-background", contentClassName), children }),
751
+ /* @__PURE__ */ jsx7("main", { className: cn("pt-16 px-6 pb-8 min-h-screen lg:hidden bg-background", contentClassName), children }),
674
752
  footer
675
753
  ] });
676
754
  }
@@ -740,33 +818,33 @@ function SandboxCard({
740
818
  const isTransitioning = sandbox.status === "provisioning" || sandbox.status === "creating";
741
819
  const isStopped = !isRunning && !isTransitioning;
742
820
  return /* @__PURE__ */ jsxs8("div", { className: cn(
743
- "group relative glass-panel flex flex-col justify-between overflow-hidden rounded-3xl p-6 transition-all duration-500 hover:-translate-y-1 hover:shadow-2xl hover:shadow-[var(--md3-primary)]/10",
744
- isRunning ? "border-[var(--md3-primary)]/30 glow-primary" : "border-border",
821
+ "group relative flex flex-col justify-between overflow-hidden rounded-lg border bg-card p-5 transition-colors",
822
+ isRunning ? "border-[var(--status-running)]/30" : "border-border",
823
+ "hover:border-foreground/15",
745
824
  className
746
825
  ), children: [
747
- isRunning && /* @__PURE__ */ jsx9("div", { className: "absolute -top-20 -right-20 h-40 w-40 rounded-full bg-[var(--md3-primary)]/20 blur-[60px] pointer-events-none" }),
748
- /* @__PURE__ */ jsxs8("div", { className: "relative z-10 flex items-start justify-between", children: [
826
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-start justify-between", children: [
749
827
  /* @__PURE__ */ jsxs8("div", { children: [
750
- /* @__PURE__ */ jsxs8("h3", { className: "flex items-center gap-2 font-headline text-xl font-bold tracking-tight text-foreground", children: [
828
+ /* @__PURE__ */ jsxs8("h3", { className: "flex items-center gap-2 text-sm font-bold text-foreground", children: [
751
829
  sandbox.name,
752
- isRunning && /* @__PURE__ */ jsxs8("span", { className: "relative flex h-2.5 w-2.5", children: [
753
- /* @__PURE__ */ jsx9("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-75" }),
754
- /* @__PURE__ */ jsx9("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-green-500" })
830
+ isRunning && /* @__PURE__ */ jsxs8("span", { className: "relative flex h-2 w-2", children: [
831
+ /* @__PURE__ */ jsx9("span", { className: "absolute inline-flex h-full w-full animate-pulse rounded-full bg-[var(--status-running)] opacity-75" }),
832
+ /* @__PURE__ */ jsx9("span", { className: "relative inline-flex h-1.5 w-1.5 rounded-full bg-[var(--status-running)]" })
755
833
  ] })
756
834
  ] }),
757
- /* @__PURE__ */ jsx9("p", { className: "font-mono text-[10px] tracking-wider text-[var(--md3-on-surface-variant)] mt-1 uppercase font-bold", children: sandbox.nodeId || "Unknown Node" })
835
+ /* @__PURE__ */ jsx9("p", { className: "mt-0.5 font-mono text-[10px] tracking-wider text-muted-foreground uppercase", children: sandbox.nodeId || "Unknown Node" })
758
836
  ] }),
759
- /* @__PURE__ */ jsx9("div", { className: "flex items-center gap-1 z-50", children: /* @__PURE__ */ jsxs8(DropdownMenu, { children: [
837
+ /* @__PURE__ */ jsxs8(DropdownMenu, { children: [
760
838
  /* @__PURE__ */ jsx9(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx9(
761
839
  "button",
762
840
  {
763
841
  type: "button",
764
- className: "rounded-full flex items-center justify-center p-2 text-[var(--md3-on-surface-variant)] transition-colors hover:bg-muted hover:text-foreground shrink-0 outline-none",
842
+ className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground outline-none",
765
843
  "aria-label": "Sandbox options",
766
- children: /* @__PURE__ */ jsx9(MoreVertical, { className: "h-5 w-5" })
844
+ children: /* @__PURE__ */ jsx9(MoreVertical, { className: "h-4 w-4" })
767
845
  }
768
846
  ) }),
769
- /* @__PURE__ */ jsxs8(DropdownMenuContent, { align: "end", className: "glass-panel-heavy border-[var(--md3-outline-variant)] min-w-[180px]", children: [
847
+ /* @__PURE__ */ jsxs8(DropdownMenuContent, { align: "end", className: "min-w-[180px]", children: [
770
848
  isRunning && /* @__PURE__ */ jsxs8(Fragment5, { children: [
771
849
  onStop && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onStop(sandbox.id), children: [
772
850
  /* @__PURE__ */ jsx9(PowerOff, { className: "mr-2 h-4 w-4" }),
@@ -776,7 +854,7 @@ function SandboxCard({
776
854
  /* @__PURE__ */ jsx9(Clock, { className: "mr-2 h-4 w-4" }),
777
855
  " Keep Alive"
778
856
  ] }),
779
- /* @__PURE__ */ jsx9(DropdownMenuSeparator, { className: "bg-[var(--md3-outline-variant)]" }),
857
+ (onStop || onKeepAlive) && /* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
780
858
  onUsage && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onUsage(sandbox.id), children: [
781
859
  /* @__PURE__ */ jsx9(BarChart2, { className: "mr-2 h-4 w-4" }),
782
860
  " View Usage"
@@ -785,12 +863,14 @@ function SandboxCard({
785
863
  /* @__PURE__ */ jsx9(Activity, { className: "mr-2 h-4 w-4" }),
786
864
  " Health Check"
787
865
  ] }),
788
- /* @__PURE__ */ jsx9(DropdownMenuSeparator, { className: "bg-[var(--md3-outline-variant)]" }),
789
- onFork && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onFork(sandbox.id), children: [
790
- /* @__PURE__ */ jsx9(Copy, { className: "mr-2 h-4 w-4" }),
791
- " Fork Sandbox"
792
- ] }),
793
- /* @__PURE__ */ jsx9(DropdownMenuSeparator, { className: "bg-[var(--md3-outline-variant)]" })
866
+ (onUsage || onHealth) && /* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
867
+ onFork && /* @__PURE__ */ jsxs8(Fragment5, { children: [
868
+ /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onFork(sandbox.id), children: [
869
+ /* @__PURE__ */ jsx9(Copy, { className: "mr-2 h-4 w-4" }),
870
+ " Fork Sandbox"
871
+ ] }),
872
+ /* @__PURE__ */ jsx9(DropdownMenuSeparator, {})
873
+ ] })
794
874
  ] }),
795
875
  isStopped && /* @__PURE__ */ jsxs8(Fragment5, { children: [
796
876
  onResume && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onResume(sandbox.id), children: [
@@ -801,46 +881,46 @@ function SandboxCard({
801
881
  /* @__PURE__ */ jsx9(Copy, { className: "mr-2 h-4 w-4" }),
802
882
  " Fork Sandbox"
803
883
  ] }),
804
- /* @__PURE__ */ jsx9(DropdownMenuSeparator, { className: "bg-[var(--md3-outline-variant)]" })
884
+ (onResume || onFork) && /* @__PURE__ */ jsx9(DropdownMenuSeparator, {})
805
885
  ] }),
806
- onDelete && /* @__PURE__ */ jsxs8(DropdownMenuItem, { className: "text-red-400 focus:bg-red-500/10 focus:text-red-300", onClick: () => onDelete(sandbox.id), children: [
886
+ onDelete && /* @__PURE__ */ jsxs8(DropdownMenuItem, { className: "text-destructive focus:bg-destructive/10 focus:text-destructive", onClick: () => onDelete(sandbox.id), children: [
807
887
  /* @__PURE__ */ jsx9(Trash2, { className: "mr-2 h-4 w-4" }),
808
888
  " Delete Sandbox"
809
889
  ] })
810
890
  ] })
811
- ] }) })
891
+ ] })
812
892
  ] }),
813
- /* @__PURE__ */ jsxs8("div", { className: "relative z-10 my-8", children: [
814
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 bg-muted/50 border border-border rounded-2xl p-4", children: [
815
- /* @__PURE__ */ jsx9("div", { className: cn("flex h-12 w-12 items-center justify-center rounded-xl", isRunning ? "bg-[var(--md3-primary)]/20" : "bg-white/5"), children: sandbox.imageIcon ? sandbox.imageIcon : sandbox.image?.includes("node") ? /* @__PURE__ */ jsx9(Code2, { className: cn("h-6 w-6", isRunning ? "text-[var(--md3-primary)]" : "text-[var(--md3-on-surface-variant)]") }) : /* @__PURE__ */ jsx9(Terminal, { className: cn("h-6 w-6", isRunning ? "text-[var(--md3-primary)]" : "text-[var(--md3-on-surface-variant)]") }) }),
893
+ /* @__PURE__ */ jsxs8("div", { className: "my-4", children: [
894
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 rounded-md border border-border bg-muted/30 p-3", children: [
895
+ /* @__PURE__ */ jsx9("div", { className: cn("flex h-10 w-10 items-center justify-center rounded-md", isRunning ? "bg-[var(--surface-success-bg)]" : "bg-muted"), children: sandbox.imageIcon ? sandbox.imageIcon : sandbox.image?.includes("node") ? /* @__PURE__ */ jsx9(Code2, { className: cn("h-5 w-5", isRunning ? "text-[var(--surface-success-text)]" : "text-muted-foreground") }) : /* @__PURE__ */ jsx9(Terminal, { className: cn("h-5 w-5", isRunning ? "text-[var(--surface-success-text)]" : "text-muted-foreground") }) }),
816
896
  /* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
817
- /* @__PURE__ */ jsx9("span", { className: "text-[10px] text-[var(--md3-on-surface-variant)] uppercase tracking-widest font-bold", children: "Environment" }),
818
- /* @__PURE__ */ jsx9("span", { className: "text-sm font-medium text-foreground font-mono mt-0.5", children: sandbox.image || "Universal" })
897
+ /* @__PURE__ */ jsx9("span", { className: "text-[10px] text-muted-foreground uppercase tracking-widest font-bold", children: "Environment" }),
898
+ /* @__PURE__ */ jsx9("span", { className: "text-xs font-medium text-foreground font-mono mt-0.5", children: sandbox.image || "Universal" })
819
899
  ] })
820
900
  ] }),
821
- isTransitioning && /* @__PURE__ */ jsxs8("div", { className: "mt-4 animate-in", children: [
822
- /* @__PURE__ */ jsxs8("div", { className: "flex justify-between text-xs text-[var(--md3-primary)] font-medium mb-1", children: [
901
+ isTransitioning && /* @__PURE__ */ jsxs8("div", { className: "mt-3", children: [
902
+ /* @__PURE__ */ jsxs8("div", { className: "flex justify-between text-xs text-muted-foreground font-medium mb-1", children: [
823
903
  /* @__PURE__ */ jsx9("span", { children: sandbox.provisioningMessage || "Starting..." }),
824
904
  /* @__PURE__ */ jsxs8("span", { children: [
825
905
  sandbox.provisioningPercent || 0,
826
906
  "%"
827
907
  ] })
828
908
  ] }),
829
- /* @__PURE__ */ jsx9("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-white/10", children: /* @__PURE__ */ jsx9(
909
+ /* @__PURE__ */ jsx9("div", { className: "h-1 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx9(
830
910
  "div",
831
911
  {
832
- className: "h-full bg-gradient-to-r from-[var(--md3-primary)] to-[#ada3ff] transition-all duration-500 rounded-full",
912
+ className: "h-full bg-primary transition-all duration-500 rounded-full",
833
913
  style: { width: `${sandbox.provisioningPercent || 5}%` }
834
914
  }
835
915
  ) })
836
916
  ] })
837
917
  ] }),
838
- /* @__PURE__ */ jsx9("div", { className: "relative z-10 flex items-center gap-3 border-t border-[var(--md3-outline-variant)] pt-4", children: isRunning ? /* @__PURE__ */ jsxs8(
918
+ /* @__PURE__ */ jsx9("div", { className: "border-t border-border pt-3", children: isRunning ? /* @__PURE__ */ jsxs8(
839
919
  "button",
840
920
  {
841
921
  type: "button",
842
922
  onClick: () => onOpenIDE?.(sandbox.id),
843
- className: "flex w-full items-center justify-center gap-2 rounded-xl bg-[var(--md3-primary)]/20 px-4 py-2.5 font-bold text-sm text-[var(--md3-primary)] shadow-[0_0_15px_rgba(173,163,255,0.1)] transition-all hover:bg-[var(--md3-primary)] hover:text-primary-foreground hover:shadow-[var(--shadow-glow)] active:scale-95 border border-[var(--md3-primary)]/30",
923
+ className: "flex w-full items-center justify-center gap-2 rounded-md bg-[var(--btn-primary-bg)] px-4 py-2 text-sm font-semibold text-[var(--btn-primary-text)] transition-colors hover:bg-[var(--btn-primary-hover)] active:scale-[0.97]",
844
924
  children: [
845
925
  /* @__PURE__ */ jsx9(Network, { className: "h-4 w-4" }),
846
926
  "Connect Session"
@@ -853,8 +933,8 @@ function SandboxCard({
853
933
  onClick: () => onWake?.(sandbox.id),
854
934
  disabled: isTransitioning,
855
935
  className: cn(
856
- "flex flex-1 items-center justify-center gap-2 rounded-xl px-4 py-2.5 font-bold text-sm transition-all border",
857
- isTransitioning ? "bg-muted/30 text-[var(--md3-on-surface-variant)] cursor-not-allowed border-border" : "bg-[var(--md3-primary)]/10 text-[var(--md3-primary)] hover:bg-[var(--md3-primary)] hover:text-foreground shadow-[0_0_15px_rgba(173,163,255,0.1)] hover:shadow-[0_0_20px_rgba(173,163,255,0.4)] active:scale-95 border-[var(--md3-primary)]/30"
936
+ "flex w-full items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-semibold transition-colors border",
937
+ isTransitioning ? "bg-muted text-muted-foreground cursor-not-allowed border-border" : "bg-card text-foreground hover:bg-muted border-border active:scale-[0.97]"
858
938
  ),
859
939
  children: [
860
940
  /* @__PURE__ */ jsx9(Play, { className: "h-4 w-4" }),
@@ -871,14 +951,13 @@ function NewSandboxCard({ onClick, className }) {
871
951
  type: "button",
872
952
  onClick,
873
953
  className: cn(
874
- "relative border-2 border-dashed border-border rounded-xl p-5 flex flex-col items-center justify-center text-center group cursor-pointer hover:border-[var(--border-accent)] hover:bg-[var(--accent-surface-soft)] transition-all duration-300 w-full min-h-[160px]",
954
+ "border-2 border-dashed border-border rounded-lg p-5 flex flex-col items-center justify-center text-center cursor-pointer hover:border-foreground/20 hover:bg-muted/30 transition-colors w-full min-h-[160px]",
875
955
  className
876
956
  ),
877
957
  children: [
878
- /* @__PURE__ */ jsx9("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_center,rgba(155,140,255,0.1)_0,transparent_100%)] opacity-0 transition-opacity duration-300 group-hover:opacity-100" }),
879
- /* @__PURE__ */ jsx9("div", { className: "flex h-16 w-16 items-center justify-center rounded-3xl bg-[var(--md3-primary)]/20 text-[var(--md3-primary)] shadow-[0_0_20px_rgba(155,140,255,0.2)] transition-transform duration-300 group-hover:scale-110 group-hover:shadow-[0_0_30px_rgba(155,140,255,0.4)]", children: /* @__PURE__ */ jsx9(Plus2, { className: "h-8 w-8" }) }),
880
- /* @__PURE__ */ jsx9("span", { className: "mt-6 font-headline text-xl font-bold text-foreground tracking-tight", children: "New Sandbox" }),
881
- /* @__PURE__ */ jsx9("span", { className: "mt-2 text-sm text-[var(--md3-primary)] font-medium", children: "Deploy a new isolated environment" })
958
+ /* @__PURE__ */ jsx9("div", { className: "flex h-12 w-12 items-center justify-center rounded-lg bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx9(Plus2, { className: "h-6 w-6" }) }),
959
+ /* @__PURE__ */ jsx9("span", { className: "mt-4 text-sm font-semibold text-foreground", children: "New Sandbox" }),
960
+ /* @__PURE__ */ jsx9("span", { className: "mt-1 text-xs text-muted-foreground", children: "Deploy a new isolated environment" })
882
961
  ]
883
962
  }
884
963
  );
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-34A66VBG.js";
12
12
  import {
13
13
  Button
14
- } from "./chunk-2QZ6G7NM.js";
14
+ } from "./chunk-MKTSMWVD.js";
15
15
  import {
16
16
  cn
17
17
  } from "./chunk-RQHJBTEU.js";
@@ -174,28 +174,14 @@ function LoginLayout({
174
174
  children,
175
175
  className
176
176
  }) {
177
- return /* @__PURE__ */ jsxs2("div", { className: cn("relative flex min-h-screen items-center justify-center bg-[var(--md3-background)] overflow-hidden antialiased font-sans flex-col", className), children: [
178
- /* @__PURE__ */ jsxs2("div", { className: "pointer-events-none absolute inset-0 z-0 overflow-hidden", children: [
179
- /* @__PURE__ */ jsx2("div", { className: "absolute top-1/4 -right-1/4 h-[800px] w-[800px] rounded-full bg-[var(--md3-primary)] opacity-10 blur-[150px] mix-blend-screen" }),
180
- /* @__PURE__ */ jsx2("div", { className: "absolute -bottom-1/4 -left-1/4 h-[800px] w-[800px] rounded-full bg-[var(--md3-primary-dim)] opacity-20 blur-[150px] mix-blend-screen" }),
181
- /* @__PURE__ */ jsx2("div", { className: "absolute left-1/2 top-1/2 h-[600px] w-[600px] -translate-x-1/2 -translate-y-1/2 rounded-full bg-[radial-gradient(circle_at_center,rgba(255,255,255,0.03)_0%,transparent_100%)] blur-[50px]" }),
182
- /* @__PURE__ */ jsx2("div", { className: "absolute inset-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTIwIDB2MjBIMFYweiIgZmlsbD0ibm9uZSIvPPHBhdGggZD0iTTE5LjUgMEwxOS41IDIwTTIwIC41TDAgLjVIMjAiIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiYSgyNTUsIDI1NSLCAyNTUsIDAuMDMpIiBzdHJva2Utd2lkdGg9IjEiLz48L3N2Zz4=')] opacity-30", style: { maskImage: "radial-gradient(circle at center, black, transparent)", WebkitMaskImage: "radial-gradient(circle at center, black 40%, transparent 100%)" } })
177
+ return /* @__PURE__ */ jsx2("div", { className: cn("relative flex min-h-screen items-center justify-center bg-background overflow-hidden antialiased font-sans flex-col", className), children: /* @__PURE__ */ jsxs2("div", { className: "z-10 w-full max-w-md px-6 animate-in flex flex-col items-center", children: [
178
+ /* @__PURE__ */ jsxs2("div", { className: "mb-10 text-center flex flex-col items-center", children: [
179
+ /* @__PURE__ */ jsx2("div", { className: "inline-flex h-14 w-14 mb-4 items-center justify-center rounded-lg bg-muted border border-border", children: brandIcon || /* @__PURE__ */ jsx2(Terminal, { className: "h-7 w-7 text-foreground" }) }),
180
+ /* @__PURE__ */ jsx2("h1", { className: "text-2xl font-bold tracking-tight text-foreground font-display", children: title }),
181
+ /* @__PURE__ */ jsx2("p", { className: "mt-2 text-sm text-muted-foreground", children: subtitle })
183
182
  ] }),
184
- /* @__PURE__ */ jsxs2("div", { className: "z-10 w-full max-w-md px-6 animate-in flex flex-col items-center", children: [
185
- /* @__PURE__ */ jsxs2("div", { className: "mb-10 text-center flex flex-col items-center", children: [
186
- /* @__PURE__ */ jsxs2("div", { className: "inline-flex h-16 w-16 mb-4 items-center justify-center rounded-2xl glass-panel shadow-[0_0_30px_rgba(173,163,255,0.15)] glow-primary relative", children: [
187
- /* @__PURE__ */ jsx2("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_center,rgba(255,255,255,0.1)_0,transparent_100%)] pointer-events-none rounded-2xl" }),
188
- brandIcon || /* @__PURE__ */ jsx2(Terminal, { className: "h-8 w-8 text-[var(--md3-primary)]" })
189
- ] }),
190
- /* @__PURE__ */ jsx2("h1", { className: "text-3xl font-bold tracking-tight text-foreground", children: title }),
191
- /* @__PURE__ */ jsx2("p", { className: "mt-2 text-[var(--md3-on-surface-variant)]", children: subtitle })
192
- ] }),
193
- /* @__PURE__ */ jsxs2("div", { className: "w-full glass-panel-heavy p-8 border border-border shadow-sm relative overflow-hidden backdrop-blur-3xl rounded-[32px]", children: [
194
- /* @__PURE__ */ jsx2("div", { className: "absolute inset-x-0 top-0 h-[1px] bg-gradient-to-r from-transparent via-[var(--md3-primary)] to-transparent opacity-50" }),
195
- children
196
- ] })
197
- ] })
198
- ] });
183
+ /* @__PURE__ */ jsx2("div", { className: "w-full bg-card p-8 border border-border rounded-lg", children })
184
+ ] }) });
199
185
  }
200
186
 
201
187
  export {
@@ -16,7 +16,7 @@ import {
16
16
  } from "./chunk-BX6AQMUS.js";
17
17
  import {
18
18
  OpenUIArtifactRenderer
19
- } from "./chunk-WXK43R62.js";
19
+ } from "./chunk-PLTZB5BC.js";
20
20
  import {
21
21
  Markdown
22
22
  } from "./chunk-T7HMZEVO.js";
@@ -12,13 +12,13 @@ var buttonVariants = cva(
12
12
  {
13
13
  variants: {
14
14
  variant: {
15
- default: "bg-primary/20 border border-primary/30 text-primary hover:text-primary-foreground shadow-[var(--shadow-accent)] hover:bg-primary hover:shadow-[var(--shadow-glow)] active:scale-[0.97] duration-[var(--transition-fast)]",
16
- destructive: "bg-destructive/10 border border-destructive/30 text-destructive hover:text-destructive-foreground hover:bg-destructive/80 active:scale-[0.97] duration-[var(--transition-fast)]",
17
- outline: "border border-border bg-card/50 backdrop-blur-xl hover:bg-muted hover:border-primary/20 active:scale-[0.97] duration-[var(--transition-fast)] text-foreground shadow-sm",
18
- secondary: "bg-muted/50 border border-border text-foreground backdrop-blur-xl hover:bg-muted active:scale-[0.97] duration-[var(--transition-fast)] shadow-sm",
15
+ default: "bg-primary text-primary-foreground hover:bg-primary/90 active:scale-[0.97] duration-[var(--transition-fast)]",
16
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 active:scale-[0.97] duration-[var(--transition-fast)]",
17
+ outline: "border border-border bg-card hover:bg-muted active:scale-[0.97] duration-[var(--transition-fast)] text-foreground",
18
+ secondary: "bg-muted border border-border text-foreground hover:bg-muted/80 active:scale-[0.97] duration-[var(--transition-fast)]",
19
19
  ghost: "hover:bg-muted hover:text-foreground duration-[var(--transition-fast)] text-muted-foreground border border-transparent",
20
20
  link: "text-primary underline-offset-4 hover:underline",
21
- sandbox: "bg-[image:var(--accent-gradient-strong)] text-white shadow-[var(--shadow-accent)] backdrop-blur-2xl border border-[var(--border-accent)] hover:brightness-110 active:scale-[0.97] duration-[var(--transition-fast)]"
21
+ sandbox: "bg-[var(--btn-primary-bg)] text-[var(--btn-primary-text)] border border-[var(--border-accent)] hover:bg-[var(--btn-primary-hover)] active:scale-[0.97] duration-[var(--transition-fast)]"
22
22
  },
23
23
  size: {
24
24
  default: "h-[var(--control-height)] px-4 py-2",
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-ZMNSRDMH.js";
12
12
  import {
13
13
  Button
14
- } from "./chunk-2QZ6G7NM.js";
14
+ } from "./chunk-MKTSMWVD.js";
15
15
  import {
16
16
  cn
17
17
  } from "./chunk-RQHJBTEU.js";
@@ -20,7 +20,7 @@ import {
20
20
  } from "./chunk-ZMNSRDMH.js";
21
21
  import {
22
22
  Button
23
- } from "./chunk-2QZ6G7NM.js";
23
+ } from "./chunk-MKTSMWVD.js";
24
24
  import {
25
25
  cn
26
26
  } from "./chunk-RQHJBTEU.js";
@@ -10,10 +10,10 @@ import {
10
10
  } from "./chunk-MA7YKRUP.js";
11
11
  import {
12
12
  ChatContainer
13
- } from "./chunk-BUOQTBTO.js";
13
+ } from "./chunk-JLKYXLFN.js";
14
14
  import {
15
15
  OpenUIArtifactRenderer
16
- } from "./chunk-WXK43R62.js";
16
+ } from "./chunk-PLTZB5BC.js";
17
17
  import {
18
18
  FileArtifactPane,
19
19
  FileTree,
@@ -16,7 +16,7 @@ var DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PUR
16
16
  {
17
17
  ref,
18
18
  className: cn(
19
- "fixed inset-0 z-50 bg-black/80 backdrop-blur-sm",
19
+ "fixed inset-0 z-50 bg-black/40",
20
20
  "data-[state=closed]:animate-out data-[state=open]:animate-in",
21
21
  "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
22
22
  className
@@ -38,7 +38,7 @@ var DialogContent = React.forwardRef(({ className, children, variant = "default"
38
38
  ref,
39
39
  className: cn(
40
40
  "fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%]",
41
- "gap-4 rounded-2xl border bg-card/95 backdrop-blur-xl p-6 shadow-2xl duration-200",
41
+ "gap-4 rounded-lg border bg-card p-6 shadow-lg duration-200",
42
42
  "data-[state=closed]:animate-out data-[state=open]:animate-in",
43
43
  "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
44
44
  "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
@@ -44,6 +44,20 @@ function TemplateCard({ template, onUseTemplate, className }) {
44
44
  );
45
45
  }
46
46
 
47
+ // src/dashboard/info-panel.tsx
48
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
49
+ function InfoPanel({ label, title, description, className }) {
50
+ return /* @__PURE__ */ jsxs2("div", { className: cn("rounded-lg bg-[var(--brand-strong)] p-5 text-[var(--brand-strong-text)] relative overflow-hidden", className), children: [
51
+ /* @__PURE__ */ jsxs2("div", { className: "relative z-10", children: [
52
+ /* @__PURE__ */ jsx2("p", { className: "text-[10px] font-bold uppercase tracking-widest text-[var(--brand-strong-text-dim)]", children: label }),
53
+ /* @__PURE__ */ jsx2("h3", { className: "mt-1 text-lg font-bold", children: title }),
54
+ /* @__PURE__ */ jsx2("p", { className: "mt-1 text-sm text-[var(--brand-strong-text-muted)]", children: description })
55
+ ] }),
56
+ /* @__PURE__ */ jsx2("div", { className: "absolute right-0 top-0 h-full w-1/3 bg-white/5 -skew-x-12 translate-x-12 pointer-events-none" })
57
+ ] });
58
+ }
59
+
47
60
  export {
48
- TemplateCard
61
+ TemplateCard,
62
+ InfoPanel
49
63
  };