@toolr/ui-design 0.1.5 → 0.1.7

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 (82) hide show
  1. package/agent-rules.json +91 -0
  2. package/ai-manifest.json +190 -0
  3. package/components/content/info-panel-primitives.tsx +14 -14
  4. package/components/hooks/use-click-outside.ts +10 -3
  5. package/components/hooks/use-modal-behavior.ts +24 -0
  6. package/components/hooks/use-navigation-history.ts +7 -2
  7. package/components/hooks/use-resizable-sidebar.ts +38 -0
  8. package/components/lib/ai-tools.tsx +1 -1
  9. package/components/lib/form-colors.ts +40 -0
  10. package/components/sections/ai-tools-paths/tools-paths-panel.tsx +7 -7
  11. package/components/sections/captured-issues/captured-issues-panel.tsx +13 -13
  12. package/components/sections/captured-issues/use-captured-issues.ts +9 -3
  13. package/components/sections/golden-snapshots/file-diff-viewer.tsx +13 -13
  14. package/components/sections/golden-snapshots/golden-sync-panel.tsx +5 -5
  15. package/components/sections/golden-snapshots/snapshot-manager.tsx +11 -11
  16. package/components/sections/golden-snapshots/status-overview.tsx +20 -20
  17. package/components/sections/golden-snapshots/version-manager.tsx +8 -8
  18. package/components/sections/prompt-editor/file-type-tabbed-prompt-editor.tsx +8 -44
  19. package/components/sections/prompt-editor/index.ts +0 -7
  20. package/components/sections/prompt-editor/simulator-prompt-editor.tsx +9 -45
  21. package/components/sections/prompt-editor/tabbed-prompt-editor.tsx +11 -43
  22. package/components/sections/report-bug/report-bug-form.tsx +14 -14
  23. package/components/sections/report-bug/screenshot-uploader.tsx +6 -6
  24. package/components/sections/snapshot-browser/snapshot-browser-panel.tsx +3 -3
  25. package/components/sections/snapshot-browser/snapshot-tree.tsx +8 -8
  26. package/components/sections/snippets-editor/snippets-editor.tsx +74 -48
  27. package/components/settings/SettingsHeader.tsx +1 -2
  28. package/components/settings/SettingsTreeNav.tsx +31 -16
  29. package/components/ui/action-dialog.tsx +12 -56
  30. package/components/ui/badge.tsx +8 -24
  31. package/components/ui/bottom-panel-header.tsx +4 -4
  32. package/components/ui/breadcrumb.tsx +8 -68
  33. package/components/ui/checkbox.tsx +2 -16
  34. package/components/ui/collapsible-section.tsx +4 -42
  35. package/components/ui/confirm-badge.tsx +3 -20
  36. package/components/ui/cookie-consent.tsx +21 -5
  37. package/components/ui/debounce-border-overlay.tsx +31 -0
  38. package/components/ui/detail-section.tsx +5 -22
  39. package/components/ui/editor-placeholder-card.tsx +17 -16
  40. package/components/ui/editor-toolbar.tsx +12 -0
  41. package/components/ui/execution-details-panel.tsx +8 -13
  42. package/components/ui/extension-list-card.tsx +3 -3
  43. package/components/ui/file-structure-section.tsx +20 -35
  44. package/components/ui/file-tree.tsx +4 -14
  45. package/components/ui/files-panel.tsx +28 -18
  46. package/components/ui/filter-dropdown.tsx +5 -5
  47. package/components/ui/form-actions.tsx +7 -6
  48. package/components/ui/frontmatter-form-header.tsx +4 -4
  49. package/components/ui/icon-button.tsx +3 -2
  50. package/components/ui/input.tsx +15 -31
  51. package/components/ui/label.tsx +7 -21
  52. package/components/ui/layout-tab-bar.tsx +4 -4
  53. package/components/ui/modal.tsx +5 -17
  54. package/components/ui/nav-card.tsx +5 -20
  55. package/components/ui/navigation-bar.tsx +13 -74
  56. package/components/ui/number-input.tsx +4 -4
  57. package/components/ui/registry-browser.tsx +10 -24
  58. package/components/ui/registry-card.tsx +16 -20
  59. package/components/ui/registry-detail.tsx +6 -6
  60. package/components/ui/resizable-textarea.tsx +13 -35
  61. package/components/ui/segmented-toggle.tsx +6 -5
  62. package/components/ui/select.tsx +7 -16
  63. package/components/ui/selection-grid.tsx +6 -54
  64. package/components/ui/setting-row.tsx +2 -4
  65. package/components/ui/settings-card.tsx +3 -3
  66. package/components/ui/settings-info-box.tsx +6 -23
  67. package/components/ui/settings-section-title.tsx +1 -1
  68. package/components/ui/snapshot-card.tsx +7 -7
  69. package/components/ui/snippets-panel.tsx +10 -10
  70. package/components/ui/sort-dropdown.tsx +2 -2
  71. package/components/ui/status-card.tsx +6 -17
  72. package/components/ui/tab-bar.tsx +5 -31
  73. package/components/ui/toggle.tsx +3 -19
  74. package/components/ui/tooltip.tsx +9 -21
  75. package/dist/content.js +14 -14
  76. package/dist/index.d.ts +71 -141
  77. package/dist/index.js +1634 -2450
  78. package/dist/tokens/primitives.css +9 -2
  79. package/index.ts +8 -7
  80. package/package.json +13 -3
  81. package/tokens/primitives.css +9 -2
  82. package/components/sections/prompt-editor/use-prompt-editor.ts +0 -131
@@ -66,7 +66,7 @@ export function ToolsPathsPanel({
66
66
  <div className={cn('w-full', className)}>
67
67
  {/* Header */}
68
68
  <div className="flex items-center justify-between mb-4">
69
- <p className="text-xs text-neutral-500 leading-relaxed max-w-xl">
69
+ <p className="text-sm text-neutral-500 leading-relaxed max-w-xl">
70
70
  Configure CLI paths for AI coding assistants. Specify executable locations
71
71
  to enable integration with your development workflow.
72
72
  </p>
@@ -127,12 +127,12 @@ export function ToolsPathsPanel({
127
127
  </div>
128
128
  <div className="flex items-center gap-3">
129
129
  {tool.detected ? (
130
- <span className="flex items-center gap-1 text-xs text-green-400">
130
+ <span className="flex items-center gap-1 text-sm text-green-400">
131
131
  <Check className="w-3.5 h-3.5" />
132
132
  Installed
133
133
  </span>
134
134
  ) : (
135
- <span className="flex items-center gap-1 text-xs text-neutral-500">
135
+ <span className="flex items-center gap-1 text-sm text-neutral-500">
136
136
  <X className="w-3.5 h-3.5" />
137
137
  Not Found
138
138
  </span>
@@ -183,15 +183,15 @@ export function ToolsPathsPanel({
183
183
 
184
184
  {/* Helper text */}
185
185
  {isEnabled && !displayPath?.includes('/') && !tool.detected && (
186
- <p className="text-xs text-red-400 pl-5">
186
+ <p className="text-sm text-red-400 pl-5">
187
187
  Path required when enabled. Enter full path to binary.
188
188
  </p>
189
189
  )}
190
190
  {tool.detected && !tool.binaryPath && (
191
- <p className="text-xs text-neutral-500 pl-5">Using auto-detected path</p>
191
+ <p className="text-sm text-neutral-500 pl-5">Using auto-detected path</p>
192
192
  )}
193
193
  {!isEnabled && !displayPath?.includes('/') && !tool.detected && (
194
- <p className="text-xs text-neutral-500 pl-5">
194
+ <p className="text-sm text-neutral-500 pl-5">
195
195
  Tool disabled. Enter path to enable.
196
196
  </p>
197
197
  )}
@@ -199,7 +199,7 @@ export function ToolsPathsPanel({
199
199
 
200
200
  {/* Disabled warning */}
201
201
  {tool.detected && !isEnabled && (
202
- <p className="text-xs text-yellow-500">
202
+ <p className="text-sm text-yellow-500">
203
203
  Tool disabled — enable to use in your workflow
204
204
  </p>
205
205
  )}
@@ -23,7 +23,7 @@
23
23
  * - Dark theme with Catppuccin-like colors matching configr
24
24
  */
25
25
 
26
- import { AlertTriangle, Check, X, Send, ChevronDown, Shield, Loader2 } from 'lucide-react'
26
+ import { AlertTriangle, Check, X, Send, ChevronDown, Loader2 } from 'lucide-react'
27
27
  import { cn } from '../../lib/cn.ts'
28
28
  import { Input } from '../../ui/input.tsx'
29
29
  import { ResizableTextarea } from '../../ui/resizable-textarea.tsx'
@@ -75,7 +75,7 @@ export function CapturedIssuesPanel({
75
75
  <div className="flex items-center justify-between">
76
76
  <div className="flex items-center gap-2">
77
77
  <AlertTriangle className="w-4 h-4 text-red-400" />
78
- <span className="text-sm text-neutral-300">
78
+ <span className="text-md text-neutral-300">
79
79
  {errorCount > 0 && (
80
80
  <span className="text-red-400">
81
81
  {errorCount} error{errorCount !== 1 ? 's' : ''}
@@ -93,10 +93,10 @@ export function CapturedIssuesPanel({
93
93
 
94
94
  {/* Error List */}
95
95
  <div className="space-y-2">
96
- <p className="text-sm text-neutral-400">Captured Errors</p>
96
+ <p className="text-md text-neutral-400">Captured Errors</p>
97
97
  <div className="max-h-48 overflow-y-auto bg-neutral-950 border border-neutral-700 rounded-lg p-3 space-y-1">
98
98
  {errors.map((error) => (
99
- <div key={error.fingerprint} className="text-xs font-mono break-words">
99
+ <div key={error.fingerprint} className="text-sm font-mono break-words">
100
100
  <span className={cn('mr-2 shrink-0', error.level === 'warning' ? 'text-yellow-400' : 'text-red-400')}>
101
101
  {error.count > 1 ? `\u00d7${error.count}` : '\u2022'}
102
102
  </span>
@@ -108,7 +108,7 @@ export function CapturedIssuesPanel({
108
108
 
109
109
  {/* Optional Details */}
110
110
  <div className="space-y-3">
111
- <p className="text-sm text-neutral-400">Add context (optional)</p>
111
+ <p className="text-md text-neutral-400">Add context (optional)</p>
112
112
  <Input
113
113
  value={title}
114
114
  onChange={setTitle}
@@ -119,7 +119,7 @@ export function CapturedIssuesPanel({
119
119
  onChange={(e) => setDescription(e.target.value)}
120
120
  placeholder="What were you doing when this happened?"
121
121
  rows={3}
122
- className="w-full px-3 py-1.5 bg-neutral-750 border border-neutral-600 rounded-lg text-neutral-300 placeholder-neutral-500 focus:outline-none focus:border-blue-500 transition-colors resize-none text-sm"
122
+ className="w-full px-3 py-1.5 bg-neutral-800 border border-neutral-600 rounded-lg text-neutral-300 placeholder-neutral-500 focus:outline-none focus:border-blue-500 transition-colors resize-none text-md"
123
123
  />
124
124
  <Input
125
125
  type="text"
@@ -163,8 +163,8 @@ export function CapturedIssuesPanel({
163
163
  <Check className="w-5 h-5 text-green-400" />
164
164
  </div>
165
165
  <div>
166
- <h3 className="text-sm text-neutral-300 font-medium">No Issues Captured</h3>
167
- <p className="text-sm text-neutral-500">Everything is running smoothly.</p>
166
+ <h3 className="text-md text-neutral-300 font-medium">No Issues Captured</h3>
167
+ <p className="text-md text-neutral-500">Everything is running smoothly.</p>
168
168
  </div>
169
169
  </div>
170
170
  </div>
@@ -174,11 +174,11 @@ export function CapturedIssuesPanel({
174
174
  {submittedErrors.length > 0 && (
175
175
  <div className="bg-neutral-900 border border-neutral-700 rounded-lg overflow-hidden">
176
176
  <details className="group">
177
- <summary className="flex items-center justify-between p-4 cursor-pointer hover:bg-neutral-850 transition-colors">
177
+ <summary className="flex items-center justify-between p-4 cursor-pointer hover:bg-neutral-800 transition-colors">
178
178
  <div className="flex items-center gap-2">
179
179
  <Check className="w-4 h-4 text-green-400" />
180
- <span className="text-sm text-neutral-300">Previously Reported</span>
181
- <span className="text-xs text-neutral-500">({submittedErrors.length})</span>
180
+ <span className="text-md text-neutral-300">Previously Reported</span>
181
+ <span className="text-sm text-neutral-500">({submittedErrors.length})</span>
182
182
  </div>
183
183
  <ChevronDown className="w-4 h-4 text-neutral-500 transition-transform group-open:rotate-180" />
184
184
  </summary>
@@ -191,12 +191,12 @@ export function CapturedIssuesPanel({
191
191
  <Check className="w-4 h-4 text-green-400 mt-0.5 shrink-0" />
192
192
  <div className="flex-1 min-w-0">
193
193
  <p
194
- className="text-sm text-neutral-300 font-mono truncate"
194
+ className="text-md text-neutral-300 font-mono truncate"
195
195
  title={error.message}
196
196
  >
197
197
  {error.message}
198
198
  </p>
199
- <div className="flex items-center gap-3 mt-1 text-xs text-neutral-500">
199
+ <div className="flex items-center gap-3 mt-1 text-sm text-neutral-500">
200
200
  {error.count > 0 && (
201
201
  <span className="text-yellow-400/80">+{error.count} since</span>
202
202
  )}
@@ -14,7 +14,7 @@
14
14
  * - Previously reported errors are loaded once on mount
15
15
  */
16
16
 
17
- import { useState, useCallback, useEffect } from 'react'
17
+ import { useState, useCallback, useEffect, useMemo } from 'react'
18
18
  import type { CapturedError, CapturedIssuesApi, SubmittedError } from './types.ts'
19
19
 
20
20
  export interface UseCapturedIssuesOptions {
@@ -50,8 +50,14 @@ export function useCapturedIssues(options: UseCapturedIssuesOptions): UseCapture
50
50
  const [submitError, setSubmitError] = useState<string | null>(null)
51
51
  const [submittedErrors, setSubmittedErrors] = useState<SubmittedError[]>([])
52
52
 
53
- const errorCount = errors.filter((e) => e.level === 'error').length
54
- const warnCount = errors.filter((e) => e.level === 'warning').length
53
+ const { errorCount, warnCount } = useMemo(() => {
54
+ let err = 0, warn = 0
55
+ for (const e of errors) {
56
+ if (e.level === 'error') err++
57
+ else if (e.level === 'warning') warn++
58
+ }
59
+ return { errorCount: err, warnCount: warn }
60
+ }, [errors])
55
61
 
56
62
  useEffect(() => {
57
63
  api.getSubmittedErrors().then(setSubmittedErrors).catch(() => {})
@@ -86,14 +86,14 @@ function DiffFileItem({ file, isSelected, onSelect, onReset, resettingFile, anyR
86
86
  >
87
87
  <button
88
88
  onClick={() => onSelect(file)}
89
- className={`flex-1 flex items-center gap-2 px-3 py-1 text-xs ${
89
+ className={`flex-1 flex items-center gap-2 px-3 py-1 text-sm ${
90
90
  isSelected ? 'text-neutral-300' : 'text-neutral-400'
91
91
  }`}
92
92
  >
93
93
  {icon}
94
94
  <span className="truncate">{filename}</span>
95
95
  {statusLabel && (
96
- <span className={`text-xss font-medium ml-auto flex-shrink-0 ${statusColor}`}>
96
+ <span className={`text-xs font-medium ml-auto flex-shrink-0 ${statusColor}`}>
97
97
  {statusLabel}
98
98
  </span>
99
99
  )}
@@ -165,13 +165,13 @@ function DiffFileTreePanel({ sync, componentLabels, renderFileIcon }: DiffFileTr
165
165
 
166
166
  // Root-level nodes get colored styling, nested folders get muted styling
167
167
  const headerClasses = isRoot
168
- ? `${color.text} ${color.hoverBg} border-l-2 ${color.border} ${color.bg} px-3 py-2 text-sm font-medium`
168
+ ? `${color.text} ${color.hoverBg} border-l-2 ${color.border} ${color.bg} px-3 py-2 text-md font-medium`
169
169
  : 'text-neutral-500 hover:bg-neutral-850 px-3 py-1.5'
170
170
 
171
171
  const chevronSize = isRoot ? 'w-4 h-4' : 'w-3 h-3'
172
172
 
173
173
  const countElement = isRoot ? (
174
- <span className={`ml-auto px-1.5 py-0.5 rounded-full text-xss font-medium ${color.pillBg} ${color.text}`}>
174
+ <span className={`ml-auto px-1.5 py-0.5 rounded-full text-xs font-medium ${color.pillBg} ${color.text}`}>
175
175
  {fileCount}
176
176
  </span>
177
177
  ) : (
@@ -222,7 +222,7 @@ function DiffFileTreePanel({ sync, componentLabels, renderFileIcon }: DiffFileTr
222
222
  <div className="w-72 flex-shrink-0 bg-neutral-900 rounded-lg border border-neutral-700 overflow-hidden flex flex-col">
223
223
  {/* Summary Header */}
224
224
  <div className="p-3 border-b border-neutral-700 flex-shrink-0">
225
- <div className="flex gap-3 text-xs">
225
+ <div className="flex gap-3 text-sm">
226
226
  <span className="text-green-400">+{diff!.summary.added}</span>
227
227
  <span className="text-red-400">-{diff!.summary.removed}</span>
228
228
  <span className="text-yellow-400">~{diff!.summary.modified}</span>
@@ -237,7 +237,7 @@ function DiffFileTreePanel({ sync, componentLabels, renderFileIcon }: DiffFileTr
237
237
  <button
238
238
  key={filter}
239
239
  onClick={() => setDiffFilter(filter)}
240
- className={`px-2 py-1 rounded text-xs transition-colors cursor-pointer ${
240
+ className={`px-2 py-1 rounded text-sm transition-colors cursor-pointer ${
241
241
  diffFilter === filter
242
242
  ? 'bg-neutral-700 text-neutral-300'
243
243
  : 'text-neutral-500 hover:text-neutral-400'
@@ -295,7 +295,7 @@ function DiffEditorPanel({ sync, componentLabels, monacoTheme }: DiffEditorPanel
295
295
  if (!selectedDiffFile) {
296
296
  return (
297
297
  <div className="flex-1 min-w-0 bg-neutral-900 rounded-lg border border-neutral-700 overflow-hidden flex flex-col">
298
- <div className="flex items-center justify-center h-full text-sm text-neutral-500">
298
+ <div className="flex items-center justify-center h-full text-md text-neutral-500">
299
299
  Select a file from the tree to view differences
300
300
  </div>
301
301
  </div>
@@ -310,16 +310,16 @@ function DiffEditorPanel({ sync, componentLabels, monacoTheme }: DiffEditorPanel
310
310
  <div className="flex items-center justify-between px-4 py-2 border-b border-neutral-700 flex-shrink-0">
311
311
  <div className="flex items-center gap-2">
312
312
  <FileCode className="w-4 h-4 flex-shrink-0 text-blue-400/50" />
313
- <span className="text-sm text-neutral-300 font-medium">
313
+ <span className="text-md text-neutral-300 font-medium">
314
314
  {selectedDiffFile.component}/{selectedDiffFile.path}
315
315
  </span>
316
316
  {devtools && hasUnsavedChanges && (
317
- <span className="px-2 py-0.5 bg-amber-500/20 text-amber-400 text-xs rounded">
317
+ <span className="px-2 py-0.5 bg-amber-500/20 text-amber-400 text-sm rounded">
318
318
  Modified
319
319
  </span>
320
320
  )}
321
321
  </div>
322
- <span className="text-xs text-neutral-500">{compLabel}</span>
322
+ <span className="text-sm text-neutral-500">{compLabel}</span>
323
323
  </div>
324
324
 
325
325
  {/* Diff Editor */}
@@ -355,7 +355,7 @@ function DiffEditorPanel({ sync, componentLabels, monacoTheme }: DiffEditorPanel
355
355
  }}
356
356
  />
357
357
  ) : (
358
- <div className="flex items-center justify-center h-full text-sm text-neutral-500">
358
+ <div className="flex items-center justify-center h-full text-md text-neutral-500">
359
359
  Loading file content...
360
360
  </div>
361
361
  )}
@@ -404,14 +404,14 @@ export function FileDiffViewer({ sync, componentLabels, monacoTheme, renderFileI
404
404
  </div>
405
405
 
406
406
  {diffLoading ? (
407
- <div className="text-sm text-neutral-500 text-center py-8">Loading diff...</div>
407
+ <div className="text-md text-neutral-500 text-center py-8">Loading diff...</div>
408
408
  ) : diff ? (
409
409
  <div className="flex gap-4 flex-1 min-h-[400px]">
410
410
  <DiffFileTreePanel sync={sync} componentLabels={componentLabels} renderFileIcon={renderFileIcon} />
411
411
  <DiffEditorPanel sync={sync} componentLabels={componentLabels} monacoTheme={monacoTheme} />
412
412
  </div>
413
413
  ) : (
414
- <div className="text-sm text-neutral-500 text-center py-8">
414
+ <div className="text-md text-neutral-500 text-center py-8">
415
415
  No diff data available. Click refresh to load.
416
416
  </div>
417
417
  )}
@@ -118,7 +118,7 @@ export function GoldenSyncPanel({
118
118
  <h3 className="text-base font-semibold text-neutral-300">
119
119
  {TAB_DESCRIPTIONS[activeTab].title}
120
120
  </h3>
121
- <p className="text-sm text-neutral-400">
121
+ <p className="text-md text-neutral-400">
122
122
  {TAB_DESCRIPTIONS[activeTab].description}
123
123
  </p>
124
124
  </div>
@@ -138,7 +138,7 @@ export function GoldenSyncPanel({
138
138
  <button
139
139
  key={tab.id}
140
140
  onClick={() => handleTabChange(tab.id)}
141
- className={`h-[41px] flex items-center gap-2 px-4 text-sm border-b-2 transition-colors cursor-pointer ${
141
+ className={`h-[41px] flex items-center gap-2 px-4 text-md border-b-2 transition-colors cursor-pointer ${
142
142
  activeTab === tab.id
143
143
  ? `${tab.color} border-current bg-neutral-800/50`
144
144
  : 'border-transparent text-neutral-500 hover:text-neutral-300 hover:bg-neutral-800/30'
@@ -155,7 +155,7 @@ export function GoldenSyncPanel({
155
155
  <div className="bg-red-500/10 border border-red-500/30 rounded-lg p-4 mt-4">
156
156
  <div className="flex items-center gap-3">
157
157
  <AlertCircle className="w-5 h-5 text-red-400 flex-shrink-0" />
158
- <p className="text-red-400 text-sm">{error}</p>
158
+ <p className="text-red-400 text-md">{error}</p>
159
159
  </div>
160
160
  </div>
161
161
  )}
@@ -165,7 +165,7 @@ export function GoldenSyncPanel({
165
165
  <div className="bg-green-500/10 border border-green-500/30 rounded-lg p-4 mt-4">
166
166
  <div className="flex items-center gap-3">
167
167
  <Check className="w-5 h-5 text-green-400 flex-shrink-0" />
168
- <p className="text-green-400 text-sm">{lastAction}</p>
168
+ <p className="text-green-400 text-md">{lastAction}</p>
169
169
  </div>
170
170
  </div>
171
171
  )}
@@ -174,7 +174,7 @@ export function GoldenSyncPanel({
174
174
  {/* Content */}
175
175
  <div className={activeTab === 'diff' ? 'flex-1 min-h-0 mt-4' : 'space-y-6 mt-4'}>
176
176
  {loading && activeTab === 'status' ? (
177
- <div className="text-sm text-neutral-500 text-center py-8">Loading...</div>
177
+ <div className="text-md text-neutral-500 text-center py-8">Loading...</div>
178
178
  ) : activeTab === 'status' ? (
179
179
  <StatusOverview
180
180
  status={status}
@@ -45,7 +45,7 @@ export function SnapshotManager({ sync }: SnapshotManagerProps) {
45
45
  }
46
46
 
47
47
  if (manifestLoading && !manifest) {
48
- return <div className="text-sm text-neutral-500 text-center py-8">Loading snapshots...</div>
48
+ return <div className="text-md text-neutral-500 text-center py-8">Loading snapshots...</div>
49
49
  }
50
50
 
51
51
  return (
@@ -54,9 +54,9 @@ export function SnapshotManager({ sync }: SnapshotManagerProps) {
54
54
  <div className="bg-neutral-900 rounded-lg p-4 border border-neutral-700">
55
55
  <div className="flex items-center gap-3 mb-3">
56
56
  <Plus className="w-5 h-5 text-green-400" />
57
- <h4 className="text-sm text-neutral-300 font-medium">Create Snapshot</h4>
57
+ <h4 className="text-md text-neutral-300 font-medium">Create Snapshot</h4>
58
58
  </div>
59
- <p className="text-xs text-neutral-600 mb-3">
59
+ <p className="text-sm text-neutral-600 mb-3">
60
60
  Archives the current live state. If components differ from golden, their patch version is auto-bumped.
61
61
  </p>
62
62
  <div className="flex gap-2">
@@ -85,8 +85,8 @@ export function SnapshotManager({ sync }: SnapshotManagerProps) {
85
85
  <div className="flex items-center justify-between px-4 py-3 border-b border-neutral-700">
86
86
  <div className="flex items-center gap-2">
87
87
  <Archive className="w-4 h-4 text-neutral-500" />
88
- <h4 className="text-sm text-neutral-300 font-medium">Snapshots</h4>
89
- <span className="text-xs text-neutral-500">({manifest?.snapshots.length ?? 0})</span>
88
+ <h4 className="text-md text-neutral-300 font-medium">Snapshots</h4>
89
+ <span className="text-sm text-neutral-500">({manifest?.snapshots.length ?? 0})</span>
90
90
  </div>
91
91
  <IconButton
92
92
  icon={manifestLoading ? <Loader2 className="animate-spin" /> : <RotateCcw />}
@@ -99,7 +99,7 @@ export function SnapshotManager({ sync }: SnapshotManagerProps) {
99
99
  </div>
100
100
 
101
101
  {!manifest || manifest.snapshots.length === 0 ? (
102
- <div className="text-sm text-neutral-500 text-center py-8">No snapshots yet</div>
102
+ <div className="text-md text-neutral-500 text-center py-8">No snapshots yet</div>
103
103
  ) : (
104
104
  <div className="divide-y divide-neutral-700">
105
105
  {[...manifest.snapshots].reverse().map((snap) => (
@@ -112,9 +112,9 @@ export function SnapshotManager({ sync }: SnapshotManagerProps) {
112
112
  {/* Version + info */}
113
113
  <div className="flex-1 min-w-0">
114
114
  <div className="flex items-center gap-2">
115
- <span className="text-sm font-mono text-neutral-300">v{snap.version}</span>
115
+ <span className="text-md font-mono text-neutral-300">v{snap.version}</span>
116
116
  {snap.version === manifest.activeVersion && (
117
- <span className="px-1.5 py-0.5 bg-green-500/20 text-green-400 text-xss rounded font-medium">
117
+ <span className="px-1.5 py-0.5 bg-green-500/20 text-green-400 text-xs rounded font-medium">
118
118
  active
119
119
  </span>
120
120
  )}
@@ -122,13 +122,13 @@ export function SnapshotManager({ sync }: SnapshotManagerProps) {
122
122
  <Pin className="w-3 h-3 text-amber-400" />
123
123
  )}
124
124
  {snap.metaVersion && (
125
- <span className="text-xs text-neutral-600 font-mono">{snap.metaVersion}</span>
125
+ <span className="text-sm text-neutral-600 font-mono">{snap.metaVersion}</span>
126
126
  )}
127
127
  </div>
128
128
  <div className="flex items-center gap-2 mt-0.5">
129
- <span className="text-xs text-neutral-600">{formatDate(snap.createdAt)}</span>
129
+ <span className="text-sm text-neutral-600">{formatDate(snap.createdAt)}</span>
130
130
  {snap.description && (
131
- <span className="text-xs text-neutral-500 truncate">{snap.description}</span>
131
+ <span className="text-sm text-neutral-500 truncate">{snap.description}</span>
132
132
  )}
133
133
  </div>
134
134
  </div>
@@ -26,7 +26,7 @@ function getComponentVersion(meta: GoldenMeta | undefined, component: string): s
26
26
  function renderVersionBadge(meta: GoldenMeta | undefined, color: string) {
27
27
  if (!meta) return null
28
28
  return (
29
- <span className={`px-2 py-0.5 ${color} text-xs rounded font-mono`}>
29
+ <span className={`px-2 py-0.5 ${color} text-sm rounded font-mono`}>
30
30
  {meta.version}
31
31
  </span>
32
32
  )
@@ -35,7 +35,7 @@ function renderVersionBadge(meta: GoldenMeta | undefined, color: string) {
35
35
  function VersionStatus({ exists, version, mismatch, defaultColor = 'text-green-400/70' }: { exists: boolean; version?: string; mismatch: boolean; defaultColor?: string }) {
36
36
  if (!exists) return <span className="text-red-400">Missing</span>
37
37
  if (!version) return <span className="text-green-400">Found</span>
38
- return <span className={`text-xs font-mono ${mismatch ? 'text-yellow-400' : defaultColor}`}>v{version}</span>
38
+ return <span className={`text-sm font-mono ${mismatch ? 'text-yellow-400' : defaultColor}`}>v{version}</span>
39
39
  }
40
40
 
41
41
  function SyncStatusBanner({ goldenMeta, liveMeta, components }: { goldenMeta: GoldenMeta; liveMeta: GoldenMeta; components: string[] }) {
@@ -48,12 +48,12 @@ function SyncStatusBanner({ goldenMeta, liveMeta, components }: { goldenMeta: Go
48
48
  return mismatches === 0 ? (
49
49
  <div className="flex items-center gap-2 px-3 py-2 rounded-lg bg-green-500/5 border border-green-500/20">
50
50
  <Check className="w-4 h-4 text-green-400" />
51
- <span className="text-sm text-green-400">Golden and Live versions are in sync</span>
51
+ <span className="text-md text-green-400">Golden and Live versions are in sync</span>
52
52
  </div>
53
53
  ) : (
54
54
  <div className="flex items-center gap-2 px-3 py-2 rounded-lg bg-yellow-500/5 border border-yellow-500/20">
55
55
  <AlertTriangle className="w-4 h-4 text-yellow-400" />
56
- <span className="text-sm text-yellow-400">Version mismatch — {mismatches} component{mismatches > 1 ? 's' : ''} differ</span>
56
+ <span className="text-md text-yellow-400">Version mismatch — {mismatches} component{mismatches > 1 ? 's' : ''} differ</span>
57
57
  </div>
58
58
  )
59
59
  }
@@ -84,10 +84,10 @@ export function StatusOverview({
84
84
  <div className="bg-neutral-900 rounded-lg p-4 border border-amber-500/30">
85
85
  <div className="flex items-center gap-3 mb-3">
86
86
  <Archive className="w-5 h-5 text-amber-400" />
87
- <h3 className="text-sm text-neutral-300 font-medium">Bundled Seed (App Distribution)</h3>
87
+ <h3 className="text-md text-neutral-300 font-medium">Bundled Seed (App Distribution)</h3>
88
88
  {status?.seed.meta && renderVersionBadge(status.seed.meta, 'bg-amber-500/20 text-amber-400')}
89
89
  </div>
90
- <div className="grid grid-cols-2 gap-4 text-sm">
90
+ <div className="grid grid-cols-2 gap-4 text-md">
91
91
  <div>
92
92
  <p className="text-neutral-500">Status</p>
93
93
  <p className={status?.seed.exists ? 'text-green-400' : 'text-red-400'}>
@@ -104,7 +104,7 @@ export function StatusOverview({
104
104
  </div>
105
105
  </div>
106
106
  {!devtools && (
107
- <p className="text-xs text-neutral-600 mt-3">
107
+ <p className="text-sm text-neutral-600 mt-3">
108
108
  A compressed archive shipped with every release containing default configuration and templates. On first launch, the seed is extracted to initialize your local files.
109
109
  </p>
110
110
  )}
@@ -121,10 +121,10 @@ export function StatusOverview({
121
121
  <div className="bg-neutral-900 rounded-lg p-4 border border-blue-500/30">
122
122
  <div className="flex items-center gap-2 mb-3">
123
123
  <div className="w-3 h-3 rounded-full bg-blue-400" />
124
- <h4 className="text-sm text-neutral-300 font-medium">Golden (Reference)</h4>
124
+ <h4 className="text-md text-neutral-300 font-medium">Golden (Reference)</h4>
125
125
  {renderVersionBadge(status?.goldenMeta, 'bg-blue-500/20 text-blue-400')}
126
126
  </div>
127
- <div className="space-y-2 text-sm">
127
+ <div className="space-y-2 text-md">
128
128
  {components.map((comp) => {
129
129
  const version = getComponentVersion(status?.goldenMeta, comp)
130
130
  const dirKey = `${comp}Golden`
@@ -143,7 +143,7 @@ export function StatusOverview({
143
143
  })}
144
144
  </div>
145
145
  {!devtools && (
146
- <p className="text-xs text-neutral-600 mt-3">
146
+ <p className="text-sm text-neutral-600 mt-3">
147
147
  Reference copy extracted from the bundled seed. Always overwritten during app updates to match the latest release. Do not edit directly.
148
148
  </p>
149
149
  )}
@@ -153,7 +153,7 @@ export function StatusOverview({
153
153
  <div className="bg-neutral-900 rounded-lg p-4 border border-green-500/30">
154
154
  <div className="flex items-center gap-2 mb-3">
155
155
  <div className="w-3 h-3 rounded-full bg-green-400" />
156
- <h4 className="text-sm text-neutral-300 font-medium">Live (Working Copy)</h4>
156
+ <h4 className="text-md text-neutral-300 font-medium">Live (Working Copy)</h4>
157
157
  {renderVersionBadge(status?.liveMeta, 'bg-green-500/20 text-green-400')}
158
158
  <div className="ml-auto relative" ref={resetMenuRef}>
159
159
  <IconButton
@@ -168,7 +168,7 @@ export function StatusOverview({
168
168
  <div ref={resetMenuDropdownRef} className="absolute right-0 top-full mt-1 w-56 bg-neutral-850 border border-neutral-700 rounded-lg shadow-xl z-50 py-1 overflow-hidden">
169
169
  <button
170
170
  onClick={() => { onResetAll(); setShowResetMenu(false) }}
171
- className="w-full text-left px-3 py-2 text-sm text-neutral-300 hover:bg-neutral-700 transition-colors"
171
+ className="w-full text-left px-3 py-2 text-md text-neutral-300 hover:bg-neutral-700 transition-colors"
172
172
  >
173
173
  Reset All to Golden
174
174
  </button>
@@ -177,7 +177,7 @@ export function StatusOverview({
177
177
  <button
178
178
  key={comp}
179
179
  onClick={() => { onResetComponent(comp); setShowResetMenu(false) }}
180
- className="w-full text-left px-3 py-2 text-sm text-neutral-400 hover:bg-neutral-700 transition-colors"
180
+ className="w-full text-left px-3 py-2 text-md text-neutral-400 hover:bg-neutral-700 transition-colors"
181
181
  >
182
182
  Reset {getLabel(comp)}
183
183
  </button>
@@ -186,7 +186,7 @@ export function StatusOverview({
186
186
  )}
187
187
  </div>
188
188
  </div>
189
- <div className="space-y-2 text-sm">
189
+ <div className="space-y-2 text-md">
190
190
  {components.map((comp) => {
191
191
  const liveV = getComponentVersion(status?.liveMeta, comp)
192
192
  const goldenV = getComponentVersion(status?.goldenMeta, comp)
@@ -212,7 +212,7 @@ export function StatusOverview({
212
212
  })}
213
213
  </div>
214
214
  {!devtools && (
215
- <p className="text-xs text-neutral-600 mt-3">
215
+ <p className="text-sm text-neutral-600 mt-3">
216
216
  Your active working copy — what the app uses at runtime. Customizations are made here and preserved across app updates.
217
217
  </p>
218
218
  )}
@@ -222,10 +222,10 @@ export function StatusOverview({
222
222
  {/* Update Flow — settings only */}
223
223
  {!devtools && (
224
224
  <div className="bg-neutral-900/50 border border-neutral-700 rounded-lg p-4">
225
- <p className="text-xs font-medium text-neutral-400 mb-4">
225
+ <p className="text-sm font-medium text-neutral-400 mb-4">
226
226
  How updates work <span className="font-normal text-neutral-600">— checked per component ({components.map(getLabel).join(', ')})</span>
227
227
  </p>
228
- <div className="grid grid-cols-[auto_auto_auto_auto_auto_auto_auto] items-center gap-x-2 text-xs">
228
+ <div className="grid grid-cols-[auto_auto_auto_auto_auto_auto_auto] items-center gap-x-2 text-sm">
229
229
  {/* Row 1: top branch outcome */}
230
230
  <span /><span /><span /><span /><span />
231
231
  <span className="text-neutral-600 text-base justify-self-center self-end mb-[-4px]">↗</span>
@@ -279,7 +279,7 @@ export function StatusOverview({
279
279
  <span className="text-neutral-600 mt-0.5">has changes</span>
280
280
  </div>
281
281
  </div>
282
- <p className="text-xs text-neutral-600 mt-3">
282
+ <p className="text-sm text-neutral-600 mt-3">
283
283
  When a component has no local changes, it is automatically updated to match the new golden version. Components with customizations are left untouched to preserve your edits — use the File Diff tab to review differences and selectively apply changes. You can reset any component to its golden version at any time using the reset buttons above.
284
284
  </p>
285
285
  </div>
@@ -290,9 +290,9 @@ export function StatusOverview({
290
290
  <div className="bg-neutral-900 rounded-lg p-4 border border-neutral-700">
291
291
  <div className="flex items-center gap-2 mb-3">
292
292
  <Archive className="w-4 h-4 text-neutral-500" />
293
- <h4 className="text-sm text-neutral-300 font-medium">Local Snapshots</h4>
293
+ <h4 className="text-md text-neutral-300 font-medium">Local Snapshots</h4>
294
294
  </div>
295
- <div className="flex gap-6 text-sm">
295
+ <div className="flex gap-6 text-md">
296
296
  <div>
297
297
  <span className="text-neutral-500">Count: </span>
298
298
  <span className="text-neutral-300">{manifest.snapshots.length}</span>
@@ -56,14 +56,14 @@ export function VersionManager({ sync, components, componentLabels }: VersionMan
56
56
  <div className="bg-neutral-900 rounded-lg p-4 border border-teal-500/30">
57
57
  <div className="flex items-center gap-3 mb-3">
58
58
  <Tag className="w-5 h-5 text-teal-400" />
59
- <h4 className="text-sm text-neutral-300 font-medium">Golden Version</h4>
59
+ <h4 className="text-md text-neutral-300 font-medium">Golden Version</h4>
60
60
  {status?.goldenMeta && (
61
- <span className="px-2 py-0.5 bg-teal-500/20 text-teal-400 text-xs rounded font-mono">
61
+ <span className="px-2 py-0.5 bg-teal-500/20 text-teal-400 text-sm rounded font-mono">
62
62
  {status.goldenMeta.version}
63
63
  </span>
64
64
  )}
65
65
  </div>
66
- <p className="text-xs text-neutral-600 mb-3">
66
+ <p className="text-sm text-neutral-600 mb-3">
67
67
  Bump the overall golden version number. This updates the top-level version in meta.json.
68
68
  </p>
69
69
  <div className="flex gap-2">
@@ -100,8 +100,8 @@ export function VersionManager({ sync, components, componentLabels }: VersionMan
100
100
  {/* Component Versions */}
101
101
  <div className="bg-neutral-900 rounded-lg border border-neutral-700 overflow-hidden">
102
102
  <div className="px-4 py-3 border-b border-neutral-700">
103
- <h4 className="text-sm text-neutral-300 font-medium">Component Versions</h4>
104
- <p className="text-xs text-neutral-600 mt-1">
103
+ <h4 className="text-md text-neutral-300 font-medium">Component Versions</h4>
104
+ <p className="text-sm text-neutral-600 mt-1">
105
105
  Update individual component versions. Click a component to edit.
106
106
  </p>
107
107
  </div>
@@ -117,12 +117,12 @@ export function VersionManager({ sync, components, componentLabels }: VersionMan
117
117
  <div key={comp} className="px-4 py-3">
118
118
  <div className="flex items-center justify-between">
119
119
  <div className="flex items-center gap-2">
120
- <span className="text-sm text-neutral-300">{getLabel(comp)}</span>
120
+ <span className="text-md text-neutral-300">{getLabel(comp)}</span>
121
121
  {currentVersion && (
122
- <span className="text-xs font-mono text-neutral-500">v{currentVersion}</span>
122
+ <span className="text-sm font-mono text-neutral-500">v{currentVersion}</span>
123
123
  )}
124
124
  {mismatch && (
125
- <span className="text-xss text-yellow-400">
125
+ <span className="text-xs text-yellow-400">
126
126
  (live: v{liveVersion})
127
127
  </span>
128
128
  )}