@tangle-network/ui 11.51.15 → 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 (78) hide show
  1. package/CHANGELOG.md +12 -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 +3 -2
  9. package/dist/index.d.ts +4 -2
  10. package/dist/index.js +5 -3
  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.d.ts +3 -0
  26. package/dist/run/run-item-primitives.js +12 -0
  27. package/dist/run/run-row-shell.d.ts +9 -0
  28. package/dist/run/run-row-shell.js +14 -1
  29. package/dist/run.d.ts +3 -2
  30. package/dist/run.js +3 -2
  31. package/dist/tool-previews/command-preview.js +3 -3
  32. package/dist/tool-previews/diff-preview.js +2 -2
  33. package/dist/tool-previews/question-preview.js +1 -1
  34. package/package.json +1 -1
  35. package/src/chat/thinking-indicator.tsx +2 -4
  36. package/src/editor/document-editor-pane.stories.tsx +1 -1
  37. package/src/editor/tiptap-editor.tsx +4 -4
  38. package/src/files/file-preview.tsx +1 -1
  39. package/src/hooks/index.ts +1 -0
  40. package/src/hooks/use-phone.ts +18 -0
  41. package/src/markdown/markdown.stories.tsx +1 -1
  42. package/src/openui/openui-artifact-renderer.tsx +7 -7
  43. package/src/presentation.ts +1 -1
  44. package/src/primitives/artifact-pane.tsx +1 -1
  45. package/src/primitives/avatar.stories.tsx +3 -3
  46. package/src/primitives/badge.stories.tsx +3 -3
  47. package/src/primitives/card.stories.tsx +1 -1
  48. package/src/primitives/compliance-badge.stories.tsx +3 -3
  49. package/src/primitives/dropdown-menu.stories.tsx +1 -1
  50. package/src/primitives/heading.tsx +1 -1
  51. package/src/primitives/input.stories.tsx +2 -2
  52. package/src/primitives/label.stories.tsx +3 -3
  53. package/src/primitives/progress.stories.tsx +5 -5
  54. package/src/primitives/progress.tsx +1 -1
  55. package/src/primitives/select.stories.tsx +3 -3
  56. package/src/primitives/sidebar-drop-zone.stories.tsx +1 -1
  57. package/src/primitives/sidebar-drop-zone.tsx +1 -1
  58. package/src/primitives/skeleton.stories.tsx +4 -4
  59. package/src/primitives/stat-card.stories.tsx +22 -33
  60. package/src/primitives/stat-card.tsx +1 -1
  61. package/src/primitives/status-pill.test.tsx +0 -52
  62. package/src/primitives/switch.stories.tsx +2 -2
  63. package/src/primitives/tabs.stories.tsx +3 -3
  64. package/src/primitives/toast.tsx +1 -1
  65. package/src/primitives/upload-progress.tsx +2 -2
  66. package/src/primitives/wizard.tsx +1 -1
  67. package/src/run/expandable-content.tsx +1 -1
  68. package/src/run/expanded-tool-detail.tsx +3 -3
  69. package/src/run/index.ts +2 -0
  70. package/src/run/inline-thinking-item.stories.tsx +3 -3
  71. package/src/run/inline-tool-item.stories.tsx +3 -3
  72. package/src/run/run-group.tsx +9 -9
  73. package/src/run/run-item-primitives.tsx +12 -0
  74. package/src/run/run-row-shell.tsx +16 -0
  75. package/src/styles/presentation.css +1 -1
  76. package/src/tool-previews/command-preview.tsx +3 -3
  77. package/src/tool-previews/diff-preview.tsx +2 -2
  78. package/src/tool-previews/question-preview.tsx +1 -1
package/dist/run.d.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  import { ToolCallStatus, ToolCallType } from "./run/tool-call-step.js";
2
2
  import { FeedSegment, ToolCallData, ToolCallFeed, ToolCallFeedProps, parseToolEvent } from "./run/tool-call-feed.js";
3
3
  import { RunGroup, RunGroupProps } from "./run/run-group.js";
4
- import { RunRowShell, RunRowShellProps, RunRowStatus } from "./run/run-row-shell.js";
4
+ import { RunRowShell, RunRowShellProps, RunRowStatus, RunRowStatusDot } from "./run/run-row-shell.js";
5
5
  import { InlineToolItem, InlineToolItemProps } from "./run/inline-tool-item.js";
6
6
  import { InlineThinkingItem, InlineThinkingItemProps } from "./run/inline-thinking-item.js";
7
7
  import { ExpandedToolDetail, ExpandedToolDetailProps } from "./run/expanded-tool-detail.js";
8
+ import { LiveDuration } from "./run/run-item-primitives.js";
8
9
  import { TaskList, TaskListItem, TaskListProps, TaskStatus, showsTaskPriority, taskProgress, taskStatus } from "./run/task-list.js";
9
10
  import { ApprovalCard, ApprovalCardProps, ApprovalDiffFile, ApprovalDiffSummary, ApprovalPlanStep } from "./run/approval-card.js";
10
11
  import { RunPhase, RunPhaseList } from "./run/run-phase-list.js";
11
12
  import { RunStatus, RunStatusIcon, RunStatusIconProps, StatusMeta, isOpen, runStatus, statusMeta } from "./run/status-meta.js";
12
- export { ApprovalCard, type ApprovalCardProps, type ApprovalDiffFile, ApprovalDiffSummary, type ApprovalPlanStep, ExpandedToolDetail, type ExpandedToolDetailProps, type FeedSegment, InlineThinkingItem, type InlineThinkingItemProps, InlineToolItem, type InlineToolItemProps, RunGroup, type RunGroupProps, type RunPhase, RunPhaseList, RunRowShell, type RunRowShellProps, type RunRowStatus, type RunStatus, RunStatusIcon, type RunStatusIconProps, type StatusMeta, TaskList, type TaskListItem, type TaskListProps, type TaskStatus, type ToolCallData, ToolCallFeed, type ToolCallFeedProps, type ToolCallStatus, type ToolCallType, isOpen, parseToolEvent, runStatus, showsTaskPriority, statusMeta, taskProgress, taskStatus };
13
+ export { ApprovalCard, type ApprovalCardProps, type ApprovalDiffFile, ApprovalDiffSummary, type ApprovalPlanStep, ExpandedToolDetail, type ExpandedToolDetailProps, type FeedSegment, InlineThinkingItem, type InlineThinkingItemProps, InlineToolItem, type InlineToolItemProps, LiveDuration, RunGroup, type RunGroupProps, type RunPhase, RunPhaseList, RunRowShell, type RunRowShellProps, type RunRowStatus, RunRowStatusDot, type RunStatus, RunStatusIcon, type RunStatusIconProps, type StatusMeta, TaskList, type TaskListItem, type TaskListProps, type TaskStatus, type ToolCallData, ToolCallFeed, type ToolCallFeedProps, type ToolCallStatus, type ToolCallType, isOpen, parseToolEvent, runStatus, showsTaskPriority, statusMeta, taskProgress, taskStatus };
package/dist/run.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import { RunStatusIcon, isOpen, runStatus, statusMeta } from "./run/status-meta.js";
2
2
  import { ExpandedToolDetail } from "./run/expanded-tool-detail.js";
3
- import { RunRowShell } from "./run/run-row-shell.js";
3
+ import { RunRowShell, RunRowStatusDot } from "./run/run-row-shell.js";
4
4
  import { InlineToolItem } from "./run/inline-tool-item.js";
5
5
  import { InlineThinkingItem } from "./run/inline-thinking-item.js";
6
6
  import { RunGroup } from "./run/run-group.js";
7
+ import { LiveDuration } from "./run/run-item-primitives.js";
7
8
  import { ToolCallFeed, parseToolEvent } from "./run/tool-call-feed.js";
8
9
  import { TaskList, showsTaskPriority, taskProgress, taskStatus } from "./run/task-list.js";
9
10
  import { ApprovalCard, ApprovalDiffSummary } from "./run/approval-card.js";
10
11
  import { RunPhaseList } from "./run/run-phase-list.js";
11
- export { ApprovalCard, ApprovalDiffSummary, ExpandedToolDetail, InlineThinkingItem, InlineToolItem, RunGroup, RunPhaseList, RunRowShell, RunStatusIcon, TaskList, ToolCallFeed, isOpen, parseToolEvent, runStatus, showsTaskPriority, statusMeta, taskProgress, taskStatus };
12
+ export { ApprovalCard, ApprovalDiffSummary, ExpandedToolDetail, InlineThinkingItem, InlineToolItem, LiveDuration, RunGroup, RunPhaseList, RunRowShell, RunRowStatusDot, RunStatusIcon, TaskList, ToolCallFeed, isOpen, parseToolEvent, runStatus, showsTaskPriority, statusMeta, taskProgress, taskStatus };
@@ -107,7 +107,7 @@ function parseStructured(text) {
107
107
  * prints below. A clean run stays quiet green. */
108
108
  function ExitBadge({ output, status }) {
109
109
  if (status === "running" || status === "pending") return /* @__PURE__ */ jsxs("span", {
110
- className: "inline-flex shrink-0 items-center gap-1 text-[11px] text-muted-foreground",
110
+ className: "inline-flex shrink-0 items-center gap-1 text-xs text-muted-foreground",
111
111
  children: [/* @__PURE__ */ jsx(Loader2, {
112
112
  className: "h-3 w-3 animate-spin",
113
113
  "aria-hidden": "true"
@@ -134,7 +134,7 @@ function ExitBadge({ output, status }) {
134
134
  }
135
135
  if (label === null) return null;
136
136
  return /* @__PURE__ */ jsx("span", {
137
- className: cn("inline-flex shrink-0 items-center rounded-full border px-1.5 py-px font-sans text-[11px] font-medium tabular-nums", tone === "danger" && "border-transparent bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]", tone === "success" && "border-transparent bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]", tone === "warning" && "border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]"),
137
+ className: cn("inline-flex shrink-0 items-center rounded-full border px-1.5 py-px font-sans text-xs font-medium tabular-nums", tone === "danger" && "border-transparent bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]", tone === "success" && "border-transparent bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]", tone === "warning" && "border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]"),
138
138
  children: label
139
139
  });
140
140
  }
@@ -177,7 +177,7 @@ function OutputRegion({ label, text, className }) {
177
177
  }), clipped && !full ? /* @__PURE__ */ jsxs("button", {
178
178
  type: "button",
179
179
  onClick: () => setFull(true),
180
- className: cn("w-full border-t border-white/10 px-3 py-1.5 text-left font-sans text-[11px] font-medium text-muted-foreground transition-colors hover:text-foreground", focusRing),
180
+ className: cn("w-full border-t border-white/10 px-3 py-1.5 text-left font-sans text-xs font-medium text-muted-foreground transition-colors hover:text-foreground", focusRing),
181
181
  children: [
182
182
  "Show all ",
183
183
  label,
@@ -49,7 +49,7 @@ const DiffPreview = memo(({ part }) => {
49
49
  !payload.diff && payload.before ? /* @__PURE__ */ jsxs("div", {
50
50
  className: "space-y-2",
51
51
  children: [/* @__PURE__ */ jsx("div", {
52
- className: "text-xs font-semibold uppercase tracking-[0.08em] text-muted-foreground",
52
+ className: "text-xs font-medium text-muted-foreground",
53
53
  children: "Before"
54
54
  }), /* @__PURE__ */ jsx(CodeBlock, {
55
55
  code: payload.before,
@@ -60,7 +60,7 @@ const DiffPreview = memo(({ part }) => {
60
60
  !payload.diff && payload.after ? /* @__PURE__ */ jsxs("div", {
61
61
  className: "space-y-2",
62
62
  children: [/* @__PURE__ */ jsx("div", {
63
- className: "text-xs font-semibold uppercase tracking-[0.08em] text-muted-foreground",
63
+ className: "text-xs font-medium text-muted-foreground",
64
64
  children: "After"
65
65
  }), /* @__PURE__ */ jsx(CodeBlock, {
66
66
  code: payload.after,
@@ -42,7 +42,7 @@ const QuestionPreview = memo(({ part }) => {
42
42
  className: "rounded-[var(--radius-md)] border border-border bg-muted px-3 py-3",
43
43
  children: [
44
44
  /* @__PURE__ */ jsxs("div", {
45
- className: "text-xs font-semibold uppercase tracking-[0.08em] text-muted-foreground",
45
+ className: "text-xs font-medium text-muted-foreground",
46
46
  children: ["Question ", index + 1]
47
47
  }),
48
48
  /* @__PURE__ */ jsx("div", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/ui",
3
- "version": "11.51.15",
3
+ "version": "11.51.17",
4
4
  "description": "Generic React UI components for Tangle products — primitives, chat, run, files, editor, markdown.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -19,10 +19,8 @@ export function ThinkingIndicator({ className }: ThinkingIndicatorProps) {
19
19
  aria-label="Agent is thinking"
20
20
  className={cn("flex items-center gap-2 px-3 py-1.5", className)}
21
21
  >
22
- <div className="flex gap-[3px]">
23
- <span className="h-[var(--indicator-dot-size)] w-[var(--indicator-dot-size)] animate-bounce rounded-full bg-[var(--brand-glow)]" style={{ animationDelay: "0ms" }} />
24
- <span className="h-[var(--indicator-dot-size)] w-[var(--indicator-dot-size)] animate-bounce rounded-full bg-[var(--brand-glow)]" style={{ animationDelay: "150ms" }} />
25
- <span className="h-[var(--indicator-dot-size)] w-[var(--indicator-dot-size)] animate-bounce rounded-full bg-[var(--brand-glow)]" style={{ animationDelay: "300ms" }} />
22
+ <div className="flex gap-1">
23
+ {[0, 200, 400].map((delay) => <span key={delay} className="h-[var(--indicator-dot-size)] w-[var(--indicator-dot-size)] animate-[tangle-breathe_var(--motion-ambient)_infinite] rounded-full bg-[var(--brand-glow)] motion-reduce:animate-none" style={{ animationDelay: `${delay}ms` }} />)}
26
24
  </div>
27
25
  {elapsed > 3 && (
28
26
  <span className="text-[length:var(--font-size-xs)] tabular-nums text-muted-foreground">
@@ -9,7 +9,7 @@ Source: \`github.com/tangle-network/gtm-agent\`
9
9
 
10
10
  ## What It Is
11
11
 
12
- GTM Agent is an AI-powered go-to-market workspace where founders get a sandboxed environment.
12
+ GTM Agent is a go-to-market workspace where founders get a sandboxed environment.
13
13
 
14
14
  ## Architecture
15
15
 
@@ -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>