@tangle-network/ui 11.51.16 → 11.51.17

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 (70) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/chat/thinking-indicator.js +9 -15
  3. package/dist/editor/tiptap-editor.js +4 -4
  4. package/dist/files/file-preview.js +1 -1
  5. package/dist/hooks/use-phone.d.ts +4 -0
  6. package/dist/hooks/use-phone.js +14 -0
  7. package/dist/hooks.d.ts +2 -1
  8. package/dist/hooks.js +2 -1
  9. package/dist/index.d.ts +2 -1
  10. package/dist/index.js +2 -1
  11. package/dist/openui/openui-artifact-renderer.js +7 -7
  12. package/dist/presentation.d.ts +1 -1
  13. package/dist/presentation.js +1 -1
  14. package/dist/primitives/artifact-pane.js +1 -1
  15. package/dist/primitives/heading.js +1 -1
  16. package/dist/primitives/progress.js +1 -1
  17. package/dist/primitives/sidebar-drop-zone.js +1 -1
  18. package/dist/primitives/stat-card.js +1 -1
  19. package/dist/primitives/toast.js +1 -1
  20. package/dist/primitives/upload-progress.js +2 -2
  21. package/dist/primitives/wizard.js +2 -2
  22. package/dist/run/expandable-content.js +1 -1
  23. package/dist/run/expanded-tool-detail.js +3 -3
  24. package/dist/run/run-group.js +11 -14
  25. package/dist/run/run-item-primitives.js +1 -1
  26. package/dist/tool-previews/command-preview.js +3 -3
  27. package/dist/tool-previews/diff-preview.js +2 -2
  28. package/dist/tool-previews/question-preview.js +1 -1
  29. package/package.json +1 -1
  30. package/src/chat/thinking-indicator.tsx +2 -4
  31. package/src/editor/document-editor-pane.stories.tsx +1 -1
  32. package/src/editor/tiptap-editor.tsx +4 -4
  33. package/src/files/file-preview.tsx +1 -1
  34. package/src/hooks/index.ts +1 -0
  35. package/src/hooks/use-phone.ts +18 -0
  36. package/src/markdown/markdown.stories.tsx +1 -1
  37. package/src/openui/openui-artifact-renderer.tsx +7 -7
  38. package/src/presentation.ts +1 -1
  39. package/src/primitives/artifact-pane.tsx +1 -1
  40. package/src/primitives/avatar.stories.tsx +3 -3
  41. package/src/primitives/badge.stories.tsx +3 -3
  42. package/src/primitives/card.stories.tsx +1 -1
  43. package/src/primitives/compliance-badge.stories.tsx +3 -3
  44. package/src/primitives/dropdown-menu.stories.tsx +1 -1
  45. package/src/primitives/heading.tsx +1 -1
  46. package/src/primitives/input.stories.tsx +2 -2
  47. package/src/primitives/label.stories.tsx +3 -3
  48. package/src/primitives/progress.stories.tsx +5 -5
  49. package/src/primitives/progress.tsx +1 -1
  50. package/src/primitives/select.stories.tsx +3 -3
  51. package/src/primitives/sidebar-drop-zone.stories.tsx +1 -1
  52. package/src/primitives/sidebar-drop-zone.tsx +1 -1
  53. package/src/primitives/skeleton.stories.tsx +4 -4
  54. package/src/primitives/stat-card.stories.tsx +22 -33
  55. package/src/primitives/stat-card.tsx +1 -1
  56. package/src/primitives/switch.stories.tsx +2 -2
  57. package/src/primitives/tabs.stories.tsx +3 -3
  58. package/src/primitives/toast.tsx +1 -1
  59. package/src/primitives/upload-progress.tsx +2 -2
  60. package/src/primitives/wizard.tsx +1 -1
  61. package/src/run/expandable-content.tsx +1 -1
  62. package/src/run/expanded-tool-detail.tsx +3 -3
  63. package/src/run/inline-thinking-item.stories.tsx +3 -3
  64. package/src/run/inline-tool-item.stories.tsx +3 -3
  65. package/src/run/run-group.tsx +9 -9
  66. package/src/run/run-item-primitives.tsx +1 -1
  67. package/src/styles/presentation.css +1 -1
  68. package/src/tool-previews/command-preview.tsx +3 -3
  69. package/src/tool-previews/diff-preview.tsx +2 -2
  70. package/src/tool-previews/question-preview.tsx +1 -1
@@ -299,19 +299,19 @@ function ConnectionIndicator({
299
299
  }) {
300
300
  const config = {
301
301
  disconnected: {
302
- color: "bg-red-500",
302
+ color: "bg-[var(--surface-danger-text)]",
303
303
  label: "Disconnected",
304
304
  },
305
305
  connecting: {
306
- color: "bg-yellow-500 animate-pulse",
306
+ color: "bg-[var(--surface-warning-text)] animate-pulse motion-reduce:animate-none",
307
307
  label: "Connecting...",
308
308
  },
309
309
  connected: {
310
- color: "bg-blue-500",
310
+ color: "bg-[var(--surface-info-text)]",
311
311
  label: "Connected",
312
312
  },
313
313
  synced: {
314
- color: "bg-green-500",
314
+ color: "bg-[var(--surface-success-text)]",
315
315
  label: "Synced",
316
316
  },
317
317
  }[state];
@@ -379,7 +379,7 @@ export function FilePreview({
379
379
  <div className="flex items-center gap-2 px-3 py-2 border-b border-border shrink-0">
380
380
  <div className="min-w-0 flex-1">
381
381
  <div className="truncate text-sm font-medium text-foreground">{filename}</div>
382
- <div className="mt-0.5 text-[11px] uppercase tracking-[0.12em] text-muted-foreground">
382
+ <div className="mt-0.5 text-xs text-muted-foreground">
383
383
  {previewLabel}
384
384
  </div>
385
385
  </div>
@@ -11,3 +11,4 @@ export * from "./use-sse-stream";
11
11
 
12
12
  export { useEventStream, type EventStreamHandlers, type EventStreamSource, type EventStreamOpener } from "./use-event-stream";
13
13
  export { useFollowTail } from "./use-follow-tail";
14
+ export { usePhone, PHONE_MEDIA } from "./use-phone";
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { useSyncExternalStore } from "react";
3
+
4
+ /** Below the tablet breakpoint a workspace shows one region at a time and an agent opens as a full-screen sheet. */
5
+ export const PHONE_MEDIA = "(max-width: 767px)";
6
+
7
+ /** Whether the page is phone-width. The server renders the desktop shape; the client corrects it on hydration. */
8
+ export function usePhone(media: string = PHONE_MEDIA): boolean {
9
+ return useSyncExternalStore(
10
+ (notify) => {
11
+ const query = window.matchMedia(media);
12
+ query.addEventListener("change", notify);
13
+ return () => query.removeEventListener("change", notify);
14
+ },
15
+ () => window.matchMedia(media).matches,
16
+ () => false,
17
+ );
18
+ }
@@ -30,7 +30,7 @@ Source: \`github.com/tangle-network/gtm-agent\` Live at: [gtm.tangle.tools](http
30
30
 
31
31
  ## What It Is
32
32
 
33
- GTM Agent is an AI-powered go-to-market workspace where founders get a sandboxed environment with an AI co-founder.
33
+ GTM Agent is a go-to-market workspace where founders get a sandboxed environment and an agent that works alongside them.
34
34
 
35
35
  ## Architecture
36
36
 
@@ -232,7 +232,7 @@ function renderNode(
232
232
  return (
233
233
  <div className="space-y-1">
234
234
  {node.kicker && (
235
- <div className="text-[10px] font-semibold uppercase tracking-[0.16em] text-muted-foreground">
235
+ <div className="text-xs font-medium text-muted-foreground">
236
236
  {node.kicker}
237
237
  </div>
238
238
  )}
@@ -275,7 +275,7 @@ function renderNode(
275
275
  return (
276
276
  <Card variant="glass" className="border-border shadow-[var(--shadow-card)]">
277
277
  <CardContent className="space-y-2 p-4">
278
- <div className="text-xs uppercase tracking-[0.12em] text-muted-foreground">
278
+ <div className="text-xs text-muted-foreground">
279
279
  {node.label}
280
280
  </div>
281
281
  <div className="text-2xl font-semibold tracking-tight text-foreground">
@@ -310,7 +310,7 @@ function renderNode(
310
310
  key={item.id ?? `${item.label}-${index}`}
311
311
  className="rounded-[var(--radius-lg)] border border-border bg-card px-4 py-3"
312
312
  >
313
- <dt className="text-[11px] uppercase tracking-[0.12em] text-muted-foreground">
313
+ <dt className="text-xs text-muted-foreground">
314
314
  {item.label}
315
315
  </dt>
316
316
  <dd
@@ -330,7 +330,7 @@ function renderNode(
330
330
  return (
331
331
  <div className="space-y-2">
332
332
  {node.title && (
333
- <div className="text-xs uppercase tracking-[0.12em] text-muted-foreground">
333
+ <div className="text-xs text-muted-foreground">
334
334
  {node.title}
335
335
  </div>
336
336
  )}
@@ -365,7 +365,7 @@ function renderNode(
365
365
  <TableHead
366
366
  key={column.key}
367
367
  className={cn(
368
- "h-10 text-[11px] uppercase tracking-[0.1em] text-muted-foreground",
368
+ "h-10 text-xs text-muted-foreground",
369
369
  column.align === "right" && "text-right",
370
370
  )}
371
371
  >
@@ -408,7 +408,7 @@ function renderNode(
408
408
  <div className="flex items-center gap-3">
409
409
  <div className="h-px flex-1 bg-border" />
410
410
  {node.label && (
411
- <span className="text-[10px] uppercase tracking-[0.14em] text-muted-foreground">
411
+ <span className="text-xs text-muted-foreground">
412
412
  {node.label}
413
413
  </span>
414
414
  )}
@@ -460,7 +460,7 @@ function renderNode(
460
460
  <div className="flex items-start justify-between gap-3">
461
461
  <div className="min-w-0 flex-1 space-y-1">
462
462
  {node.eyebrow && (
463
- <div className="text-[10px] font-semibold uppercase tracking-[0.16em] text-muted-foreground">
463
+ <div className="text-xs font-medium text-muted-foreground">
464
464
  {node.eyebrow}
465
465
  </div>
466
466
  )}
@@ -264,7 +264,7 @@ export const cardPresentation = {
264
264
  variants: {
265
265
  default: "bg-card border-border shadow-[var(--edge-highlight),var(--shadow-card)]",
266
266
  elevated: "bg-muted/50 border-border shadow-[var(--shadow-card)]",
267
- glass: "bg-card/80 backdrop-blur-xl border-border shadow-[var(--shadow-card)]",
267
+ glass: "bg-card border-border shadow-[var(--shadow-card)]",
268
268
  sandbox: "bg-muted/50 border-primary/20 shadow-[var(--shadow-accent)]",
269
269
  },
270
270
  } as const;
@@ -69,7 +69,7 @@ export function ArtifactPane({
69
69
  {!hideTitleBlock && (
70
70
  <>
71
71
  {eyebrow && (
72
- <div className="mb-1 inline-flex max-w-full items-center px-1 py-0.5 text-[10px] font-bold uppercase tracking-wider text-muted-foreground">
72
+ <div className="mb-1 inline-flex max-w-full items-center px-1 py-0.5 text-xs font-medium text-muted-foreground">
73
73
  {eyebrow}
74
74
  </div>
75
75
  )}
@@ -48,7 +48,7 @@ export const Overview: Story = {
48
48
  name: 'Overview',
49
49
  render: () => (
50
50
  <div className="flex flex-col gap-6 p-6">
51
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Sizes</div>
51
+ <div className="text-muted-foreground text-xs font-mono">Sizes</div>
52
52
  <div className="flex items-center gap-4">
53
53
  <Avatar className="h-6 w-6">
54
54
  <AvatarFallback className="text-xs">XS</AvatarFallback>
@@ -66,7 +66,7 @@ export const Overview: Story = {
66
66
  <AvatarFallback className="text-xl">XL</AvatarFallback>
67
67
  </Avatar>
68
68
  </div>
69
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mt-2">Team</div>
69
+ <div className="text-muted-foreground text-xs font-mono mt-2">Team</div>
70
70
  <div className="flex items-center gap-3">
71
71
  {[
72
72
  { initials: 'AK', label: 'Alex Kim' },
@@ -82,7 +82,7 @@ export const Overview: Story = {
82
82
  </div>
83
83
  ))}
84
84
  </div>
85
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mt-2">Stacked</div>
85
+ <div className="text-muted-foreground text-xs font-mono mt-2">Stacked</div>
86
86
  <div className="flex -space-x-2">
87
87
  {['AK', 'JD', 'MR', 'SP', '+4'].map((label) => (
88
88
  <Avatar key={label} className="border-2 border-background">
@@ -29,10 +29,10 @@ export const Cold: Story = { args: { variant: 'cold', dot: true, children: 'Cold
29
29
  export const Deleted: Story = { args: { variant: 'deleted', dot: true, children: 'Deleted' } }
30
30
 
31
31
  export const AllVariants: Story = {
32
- name: 'All Variants',
32
+ name: 'All variants',
33
33
  render: () => (
34
34
  <div className="flex flex-col gap-4 p-6">
35
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Semantic</div>
35
+ <div className="text-muted-foreground text-xs font-mono">Semantic</div>
36
36
  <div className="flex flex-wrap gap-2">
37
37
  <Badge variant="default">Default</Badge>
38
38
  <Badge variant="secondary">Secondary</Badge>
@@ -43,7 +43,7 @@ export const AllVariants: Story = {
43
43
  <Badge variant="error">Error</Badge>
44
44
  <Badge variant="info">Info</Badge>
45
45
  </div>
46
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mt-2">Operational Status</div>
46
+ <div className="text-muted-foreground text-xs font-mono mt-2">Operational status</div>
47
47
  <div className="flex flex-wrap gap-2">
48
48
  <Badge variant="running" dot>Running</Badge>
49
49
  <Badge variant="creating" dot>Creating</Badge>
@@ -15,7 +15,7 @@ const SampleCard = ({ variant, hover }: { variant?: 'default' | 'glass' | 'sandb
15
15
  <Card variant={variant} hover={hover} className="w-72">
16
16
  <CardHeader>
17
17
  <div className="flex items-center justify-between">
18
- <CardTitle>Agent Session</CardTitle>
18
+ <CardTitle>Agent session</CardTitle>
19
19
  <Badge variant="running" dot>Running</Badge>
20
20
  </div>
21
21
  <CardDescription>GPT-4o · Tangle Cloud</CardDescription>
@@ -52,21 +52,21 @@ export const AllStates: Story = {
52
52
  name: 'All States',
53
53
  render: () => (
54
54
  <div className="flex flex-col gap-4 p-6">
55
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">HIPAA</div>
55
+ <div className="text-muted-foreground text-xs font-mono">HIPAA</div>
56
56
  <div className="flex flex-wrap items-center gap-2">
57
57
  <ComplianceBadge status="ready" />
58
58
  <ComplianceBadge status="compliant" />
59
59
  <ComplianceBadge status="ready" size="md" />
60
60
  <ComplianceBadge status="compliant" size="md" />
61
61
  </div>
62
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mt-2">SOC 2</div>
62
+ <div className="text-muted-foreground text-xs font-mono mt-2">SOC 2</div>
63
63
  <div className="flex flex-wrap items-center gap-2">
64
64
  <ComplianceBadge product="soc2" status="ready" />
65
65
  <ComplianceBadge product="soc2" status="compliant" />
66
66
  <ComplianceBadge product="soc2" status="ready" size="md" />
67
67
  <ComplianceBadge product="soc2" status="compliant" size="md" />
68
68
  </div>
69
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mt-2">Linked</div>
69
+ <div className="text-muted-foreground text-xs font-mono mt-2">Linked</div>
70
70
  <div className="flex flex-wrap items-center gap-2">
71
71
  <ComplianceBadge status="ready" href="/trust" />
72
72
  <ComplianceBadge product="soc2" status="compliant" href="/trust" />
@@ -90,7 +90,7 @@ export const RegionSelector: Story = {
90
90
  </button>
91
91
  </DropdownMenuTrigger>
92
92
  <DropdownMenuContent className="w-52">
93
- <DropdownMenuLabel className="text-xs text-muted-foreground font-normal tracking-widest uppercase">
93
+ <DropdownMenuLabel className="text-xs text-muted-foreground font-normal">
94
94
  Regions
95
95
  </DropdownMenuLabel>
96
96
  <DropdownMenuSeparator />
@@ -22,7 +22,7 @@ const VARIANT_CLASS: Record<HeadingVariant, string> = {
22
22
  subsection:
23
23
  "font-semibold text-foreground text-[length:var(--font-size-base,1rem)] leading-[1.4]",
24
24
  eyebrow:
25
- "font-semibold uppercase text-muted-foreground text-[length:var(--font-size-xs,0.75rem)] leading-none tracking-[var(--tracking-wide,0.08em)]",
25
+ "font-medium text-muted-foreground text-[length:var(--font-size-xs,0.75rem)] leading-4",
26
26
  };
27
27
 
28
28
  const DEFAULT_TAG: Record<HeadingVariant, React.ElementType> = {
@@ -90,7 +90,7 @@ export const Overview: Story = {
90
90
  name: 'Overview',
91
91
  render: () => (
92
92
  <div className="flex flex-col gap-6 p-6 w-96">
93
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Input variants</div>
93
+ <div className="text-muted-foreground text-xs font-mono">Input variants</div>
94
94
  <Input label="Sandbox name" placeholder="my-sandbox-01" />
95
95
  <Input
96
96
  variant="sandbox"
@@ -104,7 +104,7 @@ export const Overview: Story = {
104
104
  error="Must be a number between 1 and 32."
105
105
  />
106
106
  <Input label="Region" defaultValue="us-east-1" disabled />
107
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mt-2">Textarea</div>
107
+ <div className="text-muted-foreground text-xs font-mono mt-2">Textarea</div>
108
108
  <Textarea
109
109
  label="Environment variables"
110
110
  placeholder="NODE_ENV=production&#10;PORT=3000"
@@ -49,10 +49,10 @@ export const Overview: Story = {
49
49
  name: 'Overview',
50
50
  render: () => (
51
51
  <div className="flex flex-col gap-6 p-6 w-80">
52
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Standalone</div>
52
+ <div className="text-muted-foreground text-xs font-mono">Standalone</div>
53
53
  <Label>Standalone label</Label>
54
54
 
55
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Paired with input</div>
55
+ <div className="text-muted-foreground text-xs font-mono">Paired with input</div>
56
56
  <div className="flex flex-col gap-1.5">
57
57
  <Label htmlFor="overview-name">Sandbox name</Label>
58
58
  <Input id="overview-name" placeholder="my-sandbox-01" />
@@ -62,7 +62,7 @@ export const Overview: Story = {
62
62
  <Input id="overview-image" placeholder="ubuntu:22.04" />
63
63
  </div>
64
64
 
65
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Paired with switch</div>
65
+ <div className="text-muted-foreground text-xs font-mono">Paired with switch</div>
66
66
  <div className="flex flex-col gap-3">
67
67
  <div className="flex items-center gap-2">
68
68
  <Switch id="overview-sleep" defaultChecked />
@@ -60,27 +60,27 @@ export const Overview: Story = {
60
60
  name: 'Overview',
61
61
  render: () => (
62
62
  <div className="flex flex-col gap-8 p-6 w-96">
63
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Default variant</div>
63
+ <div className="text-muted-foreground text-xs font-mono">Default variant</div>
64
64
  <div className="flex flex-col gap-4">
65
65
  {[0, 25, 50, 75, 100].map((v) => (
66
66
  <div key={v} className="flex items-center gap-3">
67
67
  <span className="text-muted-foreground text-xs w-8 text-right">{v}%</span>
68
- <Progress value={v} className="flex-1" />
68
+ <div className="flex-1"><Progress value={v} /></div>
69
69
  </div>
70
70
  ))}
71
71
  </div>
72
72
 
73
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Sandbox variant</div>
73
+ <div className="text-muted-foreground text-xs font-mono">Sandbox variant</div>
74
74
  <div className="flex flex-col gap-4">
75
75
  {[0, 25, 50, 75, 100].map((v) => (
76
76
  <div key={v} className="flex items-center gap-3">
77
77
  <span className="text-muted-foreground text-xs w-8 text-right">{v}%</span>
78
- <Progress value={v} variant="sandbox" className="flex-1" />
78
+ <div className="flex-1"><Progress value={v} variant="sandbox" /></div>
79
79
  </div>
80
80
  ))}
81
81
  </div>
82
82
 
83
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Sandbox task list</div>
83
+ <div className="text-muted-foreground text-xs font-mono">Sandbox task list</div>
84
84
  <div className="rounded-xl border border-border bg-card p-4 flex flex-col gap-4">
85
85
  {[
86
86
  { label: 'Pulling image', value: 100 },
@@ -42,7 +42,7 @@ const Progress = React.forwardRef<
42
42
  >
43
43
  <ProgressPrimitive.Indicator
44
44
  className={cn(
45
- "h-full w-full flex-1 transition-all duration-300 ease-out",
45
+ "h-full w-full flex-1 transition-transform duration-300 ease-out",
46
46
  tone ? TONE_FILL[tone] : indicatorVariants[variant],
47
47
  )}
48
48
  style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
@@ -117,7 +117,7 @@ export const Overview: Story = {
117
117
  name: 'Overview',
118
118
  render: () => (
119
119
  <div className="flex flex-col gap-6 p-6 w-72">
120
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Region</div>
120
+ <div className="text-muted-foreground text-xs font-mono">Region</div>
121
121
  <Select defaultValue="us-east-1">
122
122
  <SelectTrigger>
123
123
  <SelectValue />
@@ -130,7 +130,7 @@ export const Overview: Story = {
130
130
  </SelectContent>
131
131
  </Select>
132
132
 
133
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Runtime</div>
133
+ <div className="text-muted-foreground text-xs font-mono">Runtime</div>
134
134
  <Select>
135
135
  <SelectTrigger>
136
136
  <SelectValue placeholder="Select runtime..." />
@@ -150,7 +150,7 @@ export const Overview: Story = {
150
150
  </SelectContent>
151
151
  </Select>
152
152
 
153
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Disabled</div>
153
+ <div className="text-muted-foreground text-xs font-mono">Disabled</div>
154
154
  <Select disabled>
155
155
  <SelectTrigger>
156
156
  <SelectValue placeholder="Locked to current plan" />
@@ -12,7 +12,7 @@ const meta: Meta<typeof SidebarDropZone> = {
12
12
  decorators: [
13
13
  (Story) => (
14
14
  <div className="w-64 p-4 rounded-xl border border-border bg-background space-y-3">
15
- <div className="text-xs text-muted-foreground font-mono uppercase tracking-widest">Workspace Files</div>
15
+ <div className="text-xs text-muted-foreground font-mono">Workspace files</div>
16
16
  <div className="space-y-1 text-sm text-foreground">
17
17
  <div className="px-2 py-1 rounded hover:bg-accent">index.ts</div>
18
18
  <div className="px-2 py-1 rounded hover:bg-accent">utils.ts</div>
@@ -108,7 +108,7 @@ export function SidebarDropZone({
108
108
  onDragOver={handleDragOver}
109
109
  onDrop={handleDrop}
110
110
  className={cn(
111
- "rounded-lg border-2 border-dashed transition-all duration-150",
111
+ "rounded-lg border-2 border-dashed transition-colors duration-150",
112
112
  isVisible ? "p-4" : "p-0 border-transparent",
113
113
  dragOver
114
114
  ? "border-[var(--brand-cool,hsl(var(--ring)))] bg-[var(--accent-surface-soft)]"
@@ -42,7 +42,7 @@ export const Overview: Story = {
42
42
  name: 'Overview',
43
43
  render: () => (
44
44
  <div className="flex flex-col gap-8 p-6 w-[560px]">
45
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Inline elements</div>
45
+ <div className="text-muted-foreground text-xs font-mono">Inline elements</div>
46
46
  <div className="flex flex-col gap-2">
47
47
  <Skeleton className="h-5 w-3/4" />
48
48
  <Skeleton className="h-4 w-full" />
@@ -50,7 +50,7 @@ export const Overview: Story = {
50
50
  <Skeleton className="h-4 w-2/3" />
51
51
  </div>
52
52
 
53
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Team list</div>
53
+ <div className="text-muted-foreground text-xs font-mono">Team list</div>
54
54
  <div className="flex flex-col gap-3">
55
55
  {[1, 2, 3].map((i) => (
56
56
  <div key={i} className="flex items-center gap-3">
@@ -64,13 +64,13 @@ export const Overview: Story = {
64
64
  ))}
65
65
  </div>
66
66
 
67
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Cards</div>
67
+ <div className="text-muted-foreground text-xs font-mono">Cards</div>
68
68
  <div className="flex gap-4">
69
69
  <SkeletonCard className="flex-1" />
70
70
  <SkeletonCard className="flex-1" />
71
71
  </div>
72
72
 
73
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">Table</div>
73
+ <div className="text-muted-foreground text-xs font-mono">Table</div>
74
74
  <div className="rounded-xl border border-border bg-card p-4">
75
75
  <SkeletonTable rows={3} />
76
76
  </div>
@@ -1,5 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react'
2
- import { Activity, Cpu, DollarSign, HardDrive, Terminal, Users, Zap } from 'lucide-react'
2
+ import { Terminal } from 'lucide-react'
3
3
  import { StatCard } from './stat-card'
4
4
 
5
5
  const meta: Meta<typeof StatCard> = {
@@ -13,7 +13,7 @@ type Story = StoryObj<typeof StatCard>
13
13
 
14
14
  export const Default: Story = {
15
15
  args: {
16
- title: 'Active Sessions',
16
+ title: 'Active sessions',
17
17
  value: 24,
18
18
  subtitle: 'across 3 regions',
19
19
  icon: <Terminal className="h-5 w-5" />,
@@ -21,10 +21,10 @@ export const Default: Story = {
21
21
  }
22
22
 
23
23
  export const SandboxVariant: Story = {
24
- name: 'Sandbox Variant',
24
+ name: 'Sandbox variant',
25
25
  args: {
26
26
  variant: 'sandbox',
27
- title: 'Active Sessions',
27
+ title: 'Active sessions',
28
28
  value: 24,
29
29
  subtitle: 'across 3 regions',
30
30
  icon: <Terminal className="h-5 w-5" />,
@@ -33,103 +33,92 @@ export const SandboxVariant: Story = {
33
33
  }
34
34
 
35
35
  export const CpuUsage: Story = {
36
- name: 'CPU Usage',
36
+ name: 'CPU usage',
37
37
  args: {
38
- title: 'Avg CPU Usage',
38
+ title: 'Avg CPU usage',
39
39
  value: '68%',
40
40
  subtitle: 'p95: 94%',
41
- icon: <Cpu className="h-5 w-5" />,
42
41
  trend: { value: -4, label: 'vs yesterday' },
43
42
  },
44
43
  }
45
44
 
46
45
  export const MemoryUsage: Story = {
47
- name: 'Memory Usage',
46
+ name: 'Memory usage',
48
47
  args: {
49
- title: 'Memory Allocated',
48
+ title: 'Memory allocated',
50
49
  value: '12.4 GB',
51
50
  subtitle: 'of 32 GB pool',
52
- icon: <HardDrive className="h-5 w-5" />,
53
51
  trend: { value: 8, label: 'vs last hour' },
54
52
  },
55
53
  }
56
54
 
57
55
  export const MonthlyCost: Story = {
58
- name: 'Monthly Cost',
56
+ name: 'Monthly cost',
59
57
  args: {
60
- title: 'Estimated Cost',
58
+ title: 'Estimated cost',
61
59
  value: '$142.80',
62
60
  subtitle: 'current billing cycle',
63
- icon: <DollarSign className="h-5 w-5" />,
64
61
  trend: { value: 0, label: 'vs last month' },
65
62
  },
66
63
  }
67
64
 
68
65
  export const TrendPositive: Story = {
69
- name: 'Trend — Positive',
66
+ name: 'Trend up',
70
67
  args: {
71
- title: 'Sessions Today',
68
+ title: 'Sessions today',
72
69
  value: 1284,
73
- icon: <Activity className="h-5 w-5" />,
74
70
  trend: { value: 23, label: 'vs yesterday' },
75
71
  },
76
72
  }
77
73
 
78
74
  export const TrendNegative: Story = {
79
- name: 'Trend — Negative',
75
+ name: 'Trend down',
80
76
  args: {
81
- title: 'Error Rate',
77
+ title: 'Error rate',
82
78
  value: '1.2%',
83
- icon: <Zap className="h-5 w-5" />,
84
79
  trend: { value: -18, label: 'vs last week' },
85
80
  },
86
81
  }
87
82
 
88
83
  export const InfraGrid: Story = {
89
- name: 'Infrastructure Grid',
84
+ name: 'Infrastructure grid',
90
85
  render: () => (
91
86
  <div className="grid grid-cols-2 gap-4 w-[640px]">
92
87
  <StatCard
93
- title="Active Sessions"
88
+ title="Active sessions"
94
89
  value={24}
95
90
  subtitle="across 3 regions"
96
- icon={<Terminal className="h-5 w-5" />}
97
91
  trend={{ value: 12, label: 'vs last hour' }}
98
92
  />
99
93
  <StatCard
100
- title="CPU Usage"
94
+ title="CPU usage"
101
95
  value="68%"
102
96
  subtitle="p95: 94%"
103
- icon={<Cpu className="h-5 w-5" />}
104
97
  trend={{ value: -4, label: 'vs yesterday' }}
105
98
  />
106
99
  <StatCard
107
- title="Memory Allocated"
100
+ title="Memory allocated"
108
101
  value="12.4 GB"
109
102
  subtitle="of 32 GB pool"
110
- icon={<HardDrive className="h-5 w-5" />}
111
103
  trend={{ value: 8, label: 'vs last hour' }}
112
104
  />
113
105
  <StatCard
114
106
  variant="sandbox"
115
- title="Estimated Cost"
107
+ title="Estimated cost"
116
108
  value="$142.80"
117
109
  subtitle="current billing cycle"
118
- icon={<DollarSign className="h-5 w-5" />}
119
110
  trend={{ value: 3, label: 'vs last month' }}
120
111
  />
121
112
  <StatCard
122
- title="Unique Users"
113
+ title="Unique users"
123
114
  value={312}
124
115
  subtitle="last 30 days"
125
- icon={<Users className="h-5 w-5" />}
126
- trend={{ value: 19, label: 'MoM' }}
116
+ trend={{ value: 19, label: 'vs last month' }}
127
117
  />
128
118
  <StatCard
129
- title="Avg Startup Time"
119
+ title="Avg startup time"
130
120
  value="840ms"
131
121
  subtitle="p99: 1.4s"
132
- icon={<Zap className="h-5 w-5" />}
133
122
  trend={{ value: -11, label: 'vs last week' }}
134
123
  />
135
124
  </div>
@@ -57,7 +57,7 @@ const StatCard = React.forwardRef<HTMLDivElement, StatCardProps>(
57
57
  <div className="flex items-start justify-between">
58
58
  <div className="space-y-1">
59
59
  <p className="text-muted-foreground text-sm">{title}</p>
60
- <p className="font-bold text-3xl tracking-tight">{value}</p>
60
+ <p className="font-medium text-3xl tabular-nums tracking-tight">{value}</p>
61
61
  {/* A token, never `opacity-70` over the muted tone: a translucent
62
62
  foreground renders as the token COMPOSITED over whatever plane sits
63
63
  behind it, so the same class lands a different colour — and a
@@ -41,7 +41,7 @@ export const Overview: Story = {
41
41
  name: 'Overview',
42
42
  render: () => (
43
43
  <div className="flex flex-col gap-6 p-6 w-80">
44
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest">States</div>
44
+ <div className="text-muted-foreground text-xs font-mono">States</div>
45
45
  <div className="flex flex-col gap-4">
46
46
  <div className="flex items-center justify-between">
47
47
  <span className="text-sm text-muted-foreground">Off</span>
@@ -61,7 +61,7 @@ export const Overview: Story = {
61
61
  </div>
62
62
  </div>
63
63
 
64
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mt-2">Settings panel</div>
64
+ <div className="text-muted-foreground text-xs font-mono mt-2">Settings panel</div>
65
65
  <div className="rounded-xl border border-border bg-card p-4 flex flex-col gap-4">
66
66
  {[
67
67
  { id: 'auto-sleep', label: 'Auto-sleep after idle', checked: true },
@@ -104,7 +104,7 @@ export const Overview: Story = {
104
104
  render: () => (
105
105
  <div className="flex flex-col gap-10 p-6 w-[480px]">
106
106
  <div>
107
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mb-4">Default (segmented)</div>
107
+ <div className="text-muted-foreground text-xs font-mono mb-4">Default (segmented)</div>
108
108
  <Tabs defaultValue="overview">
109
109
  <TabsList>
110
110
  <TabsTrigger value="overview">Overview</TabsTrigger>
@@ -137,7 +137,7 @@ export const Overview: Story = {
137
137
  </div>
138
138
 
139
139
  <div>
140
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mb-4">Pills</div>
140
+ <div className="text-muted-foreground text-xs font-mono mb-4">Pills</div>
141
141
  <Tabs defaultValue="all">
142
142
  <TabsList variant="pills">
143
143
  <TabsTrigger value="all" variant="pills">All</TabsTrigger>
@@ -157,7 +157,7 @@ export const Overview: Story = {
157
157
  </div>
158
158
 
159
159
  <div>
160
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mb-4">Underline</div>
160
+ <div className="text-muted-foreground text-xs font-mono mb-4">Underline</div>
161
161
  <Tabs defaultValue="settings">
162
162
  <TabsList variant="underline">
163
163
  <TabsTrigger value="settings" variant="underline">Settings</TabsTrigger>