@actuate-media/cms-admin 0.56.0 → 0.56.2

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 (216) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/__tests__/components/posts-badges.test.js +3 -3
  3. package/dist/__tests__/components/posts-badges.test.js.map +1 -1
  4. package/dist/actuate-admin.css +1 -1
  5. package/dist/components/AICoauthorBubbleMenu.js +2 -2
  6. package/dist/components/AICoauthorBubbleMenu.js.map +1 -1
  7. package/dist/components/Breadcrumbs.js +2 -2
  8. package/dist/components/Breadcrumbs.js.map +1 -1
  9. package/dist/components/CoauthorResultPopover.d.ts.map +1 -1
  10. package/dist/components/CoauthorResultPopover.js +1 -1
  11. package/dist/components/CoauthorResultPopover.js.map +1 -1
  12. package/dist/components/CommandPalette.d.ts.map +1 -1
  13. package/dist/components/CommandPalette.js +11 -11
  14. package/dist/components/CommandPalette.js.map +1 -1
  15. package/dist/components/CommentSidePanel.js +11 -11
  16. package/dist/components/CommentSidePanel.js.map +1 -1
  17. package/dist/components/ContentOverviewChart.js +2 -2
  18. package/dist/components/ContentOverviewChart.js.map +1 -1
  19. package/dist/components/FocalPointPicker.js +1 -1
  20. package/dist/components/FocalPointPicker.js.map +1 -1
  21. package/dist/components/LivePreview.d.ts.map +1 -1
  22. package/dist/components/LivePreview.js +5 -5
  23. package/dist/components/LivePreview.js.map +1 -1
  24. package/dist/components/LogoPlaceholder.js +1 -1
  25. package/dist/components/LogoPlaceholder.js.map +1 -1
  26. package/dist/components/MentionableTextarea.js +3 -3
  27. package/dist/components/MentionableTextarea.js.map +1 -1
  28. package/dist/components/NotificationBell.js +1 -1
  29. package/dist/components/NotificationBell.js.map +1 -1
  30. package/dist/components/OfflineStatus.js +8 -8
  31. package/dist/components/OfflineStatus.js.map +1 -1
  32. package/dist/components/PresenceChips.d.ts.map +1 -1
  33. package/dist/components/PresenceChips.js +10 -6
  34. package/dist/components/PresenceChips.js.map +1 -1
  35. package/dist/components/SEOConfigPanel.d.ts.map +1 -1
  36. package/dist/components/SEOConfigPanel.js +10 -10
  37. package/dist/components/SEOConfigPanel.js.map +1 -1
  38. package/dist/components/SEOPanel.js +12 -12
  39. package/dist/components/SEOPanel.js.map +1 -1
  40. package/dist/components/SEOPerformance.d.ts.map +1 -1
  41. package/dist/components/SEOPerformance.js +3 -3
  42. package/dist/components/SEOPerformance.js.map +1 -1
  43. package/dist/components/TipTapEditor.js +6 -6
  44. package/dist/components/TipTapEditor.js.map +1 -1
  45. package/dist/components/pages/tag-badges.js +6 -6
  46. package/dist/components/pages/tag-badges.js.map +1 -1
  47. package/dist/components/posts/badges.d.ts +0 -4
  48. package/dist/components/posts/badges.d.ts.map +1 -1
  49. package/dist/components/posts/badges.js +28 -42
  50. package/dist/components/posts/badges.js.map +1 -1
  51. package/dist/components/ui/Badge.js +5 -5
  52. package/dist/components/ui/Badge.js.map +1 -1
  53. package/dist/components/ui/Toast.d.ts.map +1 -1
  54. package/dist/components/ui/Toast.js +4 -4
  55. package/dist/components/ui/Toast.js.map +1 -1
  56. package/dist/fields/ComponentBlockField.js +2 -2
  57. package/dist/fields/ComponentBlockField.js.map +1 -1
  58. package/dist/fields/FieldRenderer.js +1 -1
  59. package/dist/fields/FieldRenderer.js.map +1 -1
  60. package/dist/fields/PropInput.js +1 -1
  61. package/dist/fields/PropInput.js.map +1 -1
  62. package/dist/fields/RelationshipField.js +5 -5
  63. package/dist/fields/RelationshipField.js.map +1 -1
  64. package/dist/fields/ToggleField.js +1 -1
  65. package/dist/fields/ToggleField.js.map +1 -1
  66. package/dist/views/Dashboard.js +5 -5
  67. package/dist/views/Dashboard.js.map +1 -1
  68. package/dist/views/DocumentEdit.d.ts.map +1 -1
  69. package/dist/views/DocumentEdit.js +5 -5
  70. package/dist/views/DocumentEdit.js.map +1 -1
  71. package/dist/views/ForgotPassword.d.ts.map +1 -1
  72. package/dist/views/ForgotPassword.js +3 -2
  73. package/dist/views/ForgotPassword.js.map +1 -1
  74. package/dist/views/FormEditor.d.ts.map +1 -1
  75. package/dist/views/FormEditor.js +5 -5
  76. package/dist/views/FormEditor.js.map +1 -1
  77. package/dist/views/Login.d.ts.map +1 -1
  78. package/dist/views/Login.js +17 -17
  79. package/dist/views/Login.js.map +1 -1
  80. package/dist/views/PageEditor.d.ts.map +1 -1
  81. package/dist/views/PageEditor.js +2 -2
  82. package/dist/views/PageEditor.js.map +1 -1
  83. package/dist/views/Pages/PagesListView.js +6 -6
  84. package/dist/views/Pages/PagesListView.js.map +1 -1
  85. package/dist/views/Pages.d.ts.map +1 -1
  86. package/dist/views/Pages.js +16 -19
  87. package/dist/views/Pages.js.map +1 -1
  88. package/dist/views/ResetPassword.d.ts.map +1 -1
  89. package/dist/views/ResetPassword.js +3 -2
  90. package/dist/views/ResetPassword.js.map +1 -1
  91. package/dist/views/Settings.js +2 -2
  92. package/dist/views/Settings.js.map +1 -1
  93. package/dist/views/SetupWizard.d.ts.map +1 -1
  94. package/dist/views/SetupWizard.js +6 -5
  95. package/dist/views/SetupWizard.js.map +1 -1
  96. package/dist/views/page-builder/DesignScore.js +12 -12
  97. package/dist/views/page-builder/DesignScore.js.map +1 -1
  98. package/dist/views/page-builder/SEOPanel.js +9 -9
  99. package/dist/views/page-builder/SEOPanel.js.map +1 -1
  100. package/dist/views/page-editor/EditorCanvas.js +1 -1
  101. package/dist/views/page-editor/EditorCanvas.js.map +1 -1
  102. package/dist/views/page-editor/EditorTopBar.js +2 -2
  103. package/dist/views/page-editor/EditorTopBar.js.map +1 -1
  104. package/dist/views/page-editor/PagePreview.js +1 -1
  105. package/dist/views/page-editor/PagePreview.js.map +1 -1
  106. package/dist/views/page-editor/SectionInspector.js +1 -1
  107. package/dist/views/page-editor/SectionInspector.js.map +1 -1
  108. package/dist/views/page-editor/SitePreviewFrame.js +1 -1
  109. package/dist/views/page-editor/SitePreviewFrame.js.map +1 -1
  110. package/dist/views/page-editor/sections/ArticleBodySection.js +1 -1
  111. package/dist/views/page-editor/sections/ArticleBodySection.js.map +1 -1
  112. package/dist/views/page-editor/sections/AuthorBioSection.js +2 -2
  113. package/dist/views/page-editor/sections/AuthorBioSection.js.map +1 -1
  114. package/dist/views/page-editor/sections/ByTheNumbersSection.js +1 -1
  115. package/dist/views/page-editor/sections/ByTheNumbersSection.js.map +1 -1
  116. package/dist/views/page-editor/sections/CtaBannerSection.js +1 -1
  117. package/dist/views/page-editor/sections/CtaBannerSection.js.map +1 -1
  118. package/dist/views/page-editor/sections/EmbedSection.d.ts.map +1 -1
  119. package/dist/views/page-editor/sections/EmbedSection.js +1 -1
  120. package/dist/views/page-editor/sections/EmbedSection.js.map +1 -1
  121. package/dist/views/page-editor/sections/FeatureHighlightSection.d.ts.map +1 -1
  122. package/dist/views/page-editor/sections/FeatureHighlightSection.js +2 -2
  123. package/dist/views/page-editor/sections/FeatureHighlightSection.js.map +1 -1
  124. package/dist/views/page-editor/sections/GallerySection.d.ts.map +1 -1
  125. package/dist/views/page-editor/sections/GallerySection.js +1 -1
  126. package/dist/views/page-editor/sections/GallerySection.js.map +1 -1
  127. package/dist/views/page-editor/sections/HeroBannerSection.js +1 -1
  128. package/dist/views/page-editor/sections/HeroBannerSection.js.map +1 -1
  129. package/dist/views/page-editor/sections/MissionSection.d.ts.map +1 -1
  130. package/dist/views/page-editor/sections/MissionSection.js +1 -1
  131. package/dist/views/page-editor/sections/MissionSection.js.map +1 -1
  132. package/dist/views/page-editor/sections/PullQuoteSection.js +1 -1
  133. package/dist/views/page-editor/sections/PullQuoteSection.js.map +1 -1
  134. package/dist/views/page-editor/sections/RelatedPostsSection.js +1 -1
  135. package/dist/views/page-editor/sections/RelatedPostsSection.js.map +1 -1
  136. package/dist/views/page-editor/sections/SectionRenderer.js +1 -1
  137. package/dist/views/page-editor/sections/SectionRenderer.js.map +1 -1
  138. package/dist/views/page-editor/sections/parts.js +6 -6
  139. package/dist/views/page-editor/sections/parts.js.map +1 -1
  140. package/dist/views/post-editor/PostEditorCanvas.js +2 -2
  141. package/dist/views/post-editor/PostEditorCanvas.js.map +1 -1
  142. package/dist/views/post-editor/PostHeader.js +2 -2
  143. package/dist/views/post-editor/PostHeader.js.map +1 -1
  144. package/dist/views/post-editor/PostHeaderPanel.js +1 -1
  145. package/dist/views/post-editor/PostHeaderPanel.js.map +1 -1
  146. package/dist/views/post-editor/PostPreview.js +1 -1
  147. package/dist/views/post-editor/PostPreview.js.map +1 -1
  148. package/dist/views/profile/AccountSecurity.js +1 -1
  149. package/dist/views/profile/AccountSecurity.js.map +1 -1
  150. package/dist/views/settings/components.js +1 -1
  151. package/dist/views/settings/components.js.map +1 -1
  152. package/package.json +2 -2
  153. package/src/__tests__/components/posts-badges.test.tsx +3 -3
  154. package/src/components/AICoauthorBubbleMenu.tsx +4 -4
  155. package/src/components/Breadcrumbs.tsx +5 -5
  156. package/src/components/CoauthorResultPopover.tsx +26 -23
  157. package/src/components/CommandPalette.tsx +41 -39
  158. package/src/components/CommentSidePanel.tsx +20 -20
  159. package/src/components/ContentOverviewChart.tsx +4 -4
  160. package/src/components/FocalPointPicker.tsx +2 -2
  161. package/src/components/LivePreview.tsx +20 -17
  162. package/src/components/LogoPlaceholder.tsx +1 -1
  163. package/src/components/MentionableTextarea.tsx +5 -5
  164. package/src/components/NotificationBell.tsx +10 -10
  165. package/src/components/OfflineStatus.tsx +8 -8
  166. package/src/components/PresenceChips.tsx +12 -8
  167. package/src/components/SEOConfigPanel.tsx +40 -38
  168. package/src/components/SEOPanel.tsx +15 -15
  169. package/src/components/SEOPerformance.tsx +25 -23
  170. package/src/components/TipTapEditor.tsx +7 -7
  171. package/src/components/pages/tag-badges.tsx +6 -6
  172. package/src/components/posts/badges.tsx +28 -46
  173. package/src/components/ui/Badge.tsx +5 -5
  174. package/src/components/ui/Toast.tsx +4 -5
  175. package/src/fields/ComponentBlockField.tsx +2 -2
  176. package/src/fields/FieldRenderer.tsx +1 -1
  177. package/src/fields/PropInput.tsx +1 -1
  178. package/src/fields/RelationshipField.tsx +5 -5
  179. package/src/fields/ToggleField.tsx +1 -1
  180. package/src/views/Dashboard.tsx +5 -5
  181. package/src/views/DocumentEdit.tsx +13 -11
  182. package/src/views/ForgotPassword.tsx +21 -18
  183. package/src/views/FormEditor.tsx +74 -69
  184. package/src/views/Login.tsx +45 -39
  185. package/src/views/PageEditor.tsx +26 -22
  186. package/src/views/Pages/PagesListView.tsx +6 -6
  187. package/src/views/Pages.tsx +64 -65
  188. package/src/views/ResetPassword.tsx +32 -29
  189. package/src/views/Settings.tsx +2 -2
  190. package/src/views/SetupWizard.tsx +42 -33
  191. package/src/views/page-builder/DesignScore.tsx +12 -12
  192. package/src/views/page-builder/SEOPanel.tsx +12 -12
  193. package/src/views/page-editor/EditorCanvas.tsx +1 -1
  194. package/src/views/page-editor/EditorTopBar.tsx +2 -2
  195. package/src/views/page-editor/PagePreview.tsx +1 -1
  196. package/src/views/page-editor/SectionInspector.tsx +1 -1
  197. package/src/views/page-editor/SitePreviewFrame.tsx +1 -1
  198. package/src/views/page-editor/sections/ArticleBodySection.tsx +5 -5
  199. package/src/views/page-editor/sections/AuthorBioSection.tsx +6 -6
  200. package/src/views/page-editor/sections/ByTheNumbersSection.tsx +5 -5
  201. package/src/views/page-editor/sections/CtaBannerSection.tsx +1 -1
  202. package/src/views/page-editor/sections/EmbedSection.tsx +6 -4
  203. package/src/views/page-editor/sections/FeatureHighlightSection.tsx +7 -5
  204. package/src/views/page-editor/sections/GallerySection.tsx +6 -4
  205. package/src/views/page-editor/sections/HeroBannerSection.tsx +2 -2
  206. package/src/views/page-editor/sections/MissionSection.tsx +4 -2
  207. package/src/views/page-editor/sections/PullQuoteSection.tsx +4 -4
  208. package/src/views/page-editor/sections/RelatedPostsSection.tsx +5 -5
  209. package/src/views/page-editor/sections/SectionRenderer.tsx +2 -2
  210. package/src/views/page-editor/sections/parts.tsx +6 -6
  211. package/src/views/post-editor/PostEditorCanvas.tsx +4 -4
  212. package/src/views/post-editor/PostHeader.tsx +5 -5
  213. package/src/views/post-editor/PostHeaderPanel.tsx +1 -1
  214. package/src/views/post-editor/PostPreview.tsx +1 -1
  215. package/src/views/profile/AccountSecurity.tsx +1 -1
  216. package/src/views/settings/components.tsx +1 -1
@@ -23,8 +23,8 @@ interface SEOSummary {
23
23
  }
24
24
 
25
25
  function ScoreBadge({ score }: { score: number }) {
26
- const color = score >= 80 ? 'text-green-600' : score >= 60 ? 'text-amber-500' : 'text-red-500'
27
- const bg = score >= 80 ? 'bg-green-50' : score >= 60 ? 'bg-amber-50' : 'bg-red-50'
26
+ const color = score >= 80 ? 'text-success' : score >= 60 ? 'text-warning' : 'text-destructive'
27
+ const bg = score >= 80 ? 'bg-success/10' : score >= 60 ? 'bg-warning/10' : 'bg-destructive/10'
28
28
  return (
29
29
  <span
30
30
  className={`inline-flex h-9 w-9 items-center justify-center rounded-full text-sm font-medium ${color} ${bg}`}
@@ -53,38 +53,40 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
53
53
  const visible = topContent.slice(page * perPage, (page + 1) * perPage)
54
54
 
55
55
  return (
56
- <div className="rounded-lg border border-gray-200 bg-white">
57
- <div className="flex items-center justify-between border-b border-gray-200 p-4">
56
+ <div className="border-border bg-card rounded-lg border">
57
+ <div className="border-border flex items-center justify-between border-b p-4">
58
58
  <div className="flex items-center gap-2">
59
- <Search className="h-4 w-4 text-gray-500" />
60
- <h2 className="text-sm font-medium text-gray-900">SEO Performance</h2>
59
+ <Search className="text-muted-foreground h-4 w-4" />
60
+ <h2 className="text-foreground text-sm font-medium">SEO Performance</h2>
61
61
  </div>
62
62
  {totalIssues > 0 && (
63
- <span className="text-xs text-gray-500">
63
+ <span className="text-muted-foreground text-xs">
64
64
  {totalIssues} issue{totalIssues !== 1 ? 's' : ''} found
65
65
  </span>
66
66
  )}
67
67
  </div>
68
68
 
69
- <div className="grid grid-cols-1 divide-y divide-gray-200 lg:grid-cols-12 lg:divide-x lg:divide-y-0">
69
+ <div className="divide-border grid grid-cols-1 divide-y lg:grid-cols-12 lg:divide-x lg:divide-y-0">
70
70
  <div className="p-4 lg:col-span-7">
71
- <h3 className="mb-3 text-sm font-medium text-gray-700">Top Performing Content</h3>
71
+ <h3 className="text-foreground mb-3 text-sm font-medium">Top Performing Content</h3>
72
72
  <div className="space-y-2">
73
73
  {visible.map((item) => (
74
74
  <div key={item.id} className="flex items-center justify-between py-2">
75
75
  <div className="mr-3 min-w-0 flex-1">
76
- <p className="truncate text-sm font-medium text-gray-900">{item.title}</p>
77
- <p className="text-xs text-gray-500 capitalize">{item.collection}</p>
76
+ <p className="text-foreground truncate text-sm font-medium">{item.title}</p>
77
+ <p className="text-muted-foreground text-xs capitalize">{item.collection}</p>
78
78
  </div>
79
79
  <ScoreBadge score={item.score} />
80
80
  </div>
81
81
  ))}
82
82
  {visible.length === 0 && (
83
- <p className="py-4 text-center text-sm text-gray-400">No published content yet</p>
83
+ <p className="text-muted-foreground py-4 text-center text-sm">
84
+ No published content yet
85
+ </p>
84
86
  )}
85
87
  </div>
86
88
  {topContent.length > perPage && (
87
- <div className="mt-3 flex items-center justify-between border-t border-gray-100 pt-3 text-xs text-gray-500">
89
+ <div className="text-muted-foreground mt-3 flex items-center justify-between border-t border-gray-100 pt-3 text-xs">
88
90
  <span>
89
91
  Showing {page * perPage + 1}-{Math.min((page + 1) * perPage, topContent.length)} of{' '}
90
92
  {topContent.length}
@@ -93,7 +95,7 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
93
95
  <button
94
96
  onClick={() => setPage(Math.max(0, page - 1))}
95
97
  disabled={page === 0}
96
- className="rounded p-1 hover:bg-gray-100 disabled:opacity-30"
98
+ className="hover:bg-accent rounded p-1 disabled:opacity-30"
97
99
  >
98
100
  <ChevronLeft className="h-3.5 w-3.5" />
99
101
  </button>
@@ -103,7 +105,7 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
103
105
  <button
104
106
  onClick={() => setPage(Math.min(totalPages - 1, page + 1))}
105
107
  disabled={page >= totalPages - 1}
106
- className="rounded p-1 hover:bg-gray-100 disabled:opacity-30"
108
+ className="hover:bg-accent rounded p-1 disabled:opacity-30"
107
109
  >
108
110
  <ChevronRight className="h-3.5 w-3.5" />
109
111
  </button>
@@ -113,38 +115,38 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
113
115
  </div>
114
116
 
115
117
  <div className="p-4 lg:col-span-5">
116
- <h3 className="mb-3 text-sm font-medium text-gray-700">SEO Issues</h3>
118
+ <h3 className="text-foreground mb-3 text-sm font-medium">SEO Issues</h3>
117
119
  <div className="space-y-3">
118
120
  <div className="flex items-center justify-between">
119
121
  <div className="flex items-center gap-2">
120
122
  <FileWarning className="h-4 w-4 text-red-400" />
121
- <span className="text-sm text-gray-700">Missing meta descriptions</span>
123
+ <span className="text-foreground text-sm">Missing meta descriptions</span>
122
124
  </div>
123
- <span className="text-sm font-medium text-gray-900">
125
+ <span className="text-foreground text-sm font-medium">
124
126
  {issues.missingMetaDescriptions}
125
127
  </span>
126
128
  </div>
127
129
  <div className="flex items-center justify-between">
128
130
  <div className="flex items-center gap-2">
129
131
  <LinkIcon className="h-4 w-4 text-red-400" />
130
- <span className="text-sm text-gray-700">Broken internal links</span>
132
+ <span className="text-foreground text-sm">Broken internal links</span>
131
133
  </div>
132
- <span className="text-sm font-medium text-gray-900">
134
+ <span className="text-foreground text-sm font-medium">
133
135
  {issues.brokenInternalLinks}
134
136
  </span>
135
137
  </div>
136
138
  <div className="flex items-center justify-between">
137
139
  <div className="flex items-center gap-2">
138
140
  <ImageOff className="h-4 w-4 text-red-400" />
139
- <span className="text-sm text-gray-700">Missing alt text</span>
141
+ <span className="text-foreground text-sm">Missing alt text</span>
140
142
  </div>
141
- <span className="text-sm font-medium text-gray-900">{issues.missingAltText}</span>
143
+ <span className="text-foreground text-sm font-medium">{issues.missingAltText}</span>
142
144
  </div>
143
145
  </div>
144
146
  {totalIssues > 0 && (
145
147
  <button
146
148
  onClick={() => onNavigate?.('/seo')}
147
- className="mt-4 text-sm font-medium text-blue-600 hover:text-blue-700"
149
+ className="text-primary hover:text-primary/80 mt-4 text-sm font-medium"
148
150
  >
149
151
  View All Issues
150
152
  </button>
@@ -233,8 +233,8 @@ function ToolbarButton({
233
233
  title={title}
234
234
  className={`rounded p-1.5 transition-colors ${
235
235
  isActive
236
- ? 'bg-blue-100 text-blue-700'
237
- : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900'
236
+ ? 'bg-info/10 text-info'
237
+ : 'text-muted-foreground hover:bg-accent hover:text-foreground'
238
238
  } ${disabled ? 'cursor-not-allowed opacity-40' : ''}`}
239
239
  >
240
240
  {children}
@@ -243,7 +243,7 @@ function ToolbarButton({
243
243
  }
244
244
 
245
245
  function Divider() {
246
- return <div className="mx-1 h-6 w-px bg-gray-200" />
246
+ return <div className="bg-muted mx-1 h-6 w-px" />
247
247
  }
248
248
 
249
249
  function Toolbar({ editor, onOpenMediaPicker }: { editor: Editor; onOpenMediaPicker: () => void }) {
@@ -265,7 +265,7 @@ function Toolbar({ editor, onOpenMediaPicker }: { editor: Editor; onOpenMediaPic
265
265
  const isInTable = editor.isActive('table')
266
266
 
267
267
  return (
268
- <div className="sticky top-0 z-10 flex flex-wrap items-center gap-0.5 border-b border-gray-200 bg-gray-50 p-2">
268
+ <div className="border-border bg-muted sticky top-0 z-10 flex flex-wrap items-center gap-0.5 border-b p-2">
269
269
  {/* Group 1: Text formatting */}
270
270
  <ToolbarButton
271
271
  onClick={() => editor.chain().focus().toggleBold().run()}
@@ -544,7 +544,7 @@ export function TipTapEditor({
544
544
  UnderlineExt,
545
545
  Link.configure({
546
546
  openOnClick: false,
547
- HTMLAttributes: { class: 'text-blue-600 underline' },
547
+ HTMLAttributes: { class: 'text-primary underline' },
548
548
  }),
549
549
  Image.configure({
550
550
  inline: true,
@@ -656,10 +656,10 @@ export function TipTapEditor({
656
656
 
657
657
  const editorPane = (
658
658
  <div
659
- className={`flex-1 overflow-hidden rounded-lg border border-gray-200 bg-white ${className ?? ''}`}
659
+ className={`border-border bg-card flex-1 overflow-hidden rounded-lg border ${className ?? ''}`}
660
660
  >
661
661
  {collaboration && awareness && (
662
- <div className="flex items-center justify-between gap-2 border-b border-gray-100 bg-white px-2 py-1.5">
662
+ <div className="bg-card flex items-center justify-between gap-2 border-b border-gray-100 px-2 py-1.5">
663
663
  <PresenceChips awareness={awareness} status={collabStatus} />
664
664
  <OfflineStatus connection={collabStatus} offline={offlineStatus} />
665
665
  </div>
@@ -14,12 +14,12 @@ import { paletteFor } from '../posts/badges.js'
14
14
  */
15
15
 
16
16
  const DOT_COLOR: Record<string, string> = {
17
- purple: 'bg-violet-500',
18
- green: 'bg-emerald-500',
19
- orange: 'bg-amber-500',
20
- red: 'bg-red-500',
21
- blue: 'bg-blue-500',
22
- pink: 'bg-pink-500',
17
+ purple: 'bg-brand',
18
+ green: 'bg-success',
19
+ orange: 'bg-warning',
20
+ red: 'bg-destructive',
21
+ blue: 'bg-info',
22
+ pink: 'bg-chart-4',
23
23
  gray: 'bg-muted-foreground',
24
24
  }
25
25
 
@@ -5,53 +5,45 @@ import type { PostStatus } from '../../lib/posts-service.js'
5
5
 
6
6
  /**
7
7
  * Shared status / type / SEO indicators for the Posts admin area.
8
- *
9
- * Colors are restricted to the theme tokens already used elsewhere in
10
- * the admin (`success`, `warning`, `destructive`, `primary`, `muted`)
11
- * plus a small named-color palette (`purple`, `green`, `orange`, ...)
12
- * that maps to fixed Tailwind utilities. This keeps the badges working
13
- * in both light and dark mode and avoids leaking `bg-[#...]` arbitrary
14
- * values into components.
8
+ * Colors use semantic theme tokens only.
15
9
  */
16
10
 
17
- // ─── Named color palette ─────────────────────────────────────────────
18
-
19
11
  const PALETTE: Record<string, { bg: string; text: string; ring: string; border: string }> = {
20
12
  purple: {
21
- bg: 'bg-violet-50 dark:bg-violet-950/40',
22
- text: 'text-violet-700 dark:text-violet-300',
23
- ring: 'ring-violet-200 dark:ring-violet-900',
24
- border: 'border-violet-500',
13
+ bg: 'bg-brand/10',
14
+ text: 'text-brand',
15
+ ring: 'ring-brand/20',
16
+ border: 'border-brand',
25
17
  },
26
18
  green: {
27
- bg: 'bg-emerald-50 dark:bg-emerald-950/40',
28
- text: 'text-emerald-700 dark:text-emerald-300',
29
- ring: 'ring-emerald-200 dark:ring-emerald-900',
30
- border: 'border-emerald-500',
19
+ bg: 'bg-success/10',
20
+ text: 'text-success',
21
+ ring: 'ring-success/20',
22
+ border: 'border-success',
31
23
  },
32
24
  orange: {
33
- bg: 'bg-amber-50 dark:bg-amber-950/40',
34
- text: 'text-amber-700 dark:text-amber-300',
35
- ring: 'ring-amber-200 dark:ring-amber-900',
36
- border: 'border-amber-500',
25
+ bg: 'bg-warning/10',
26
+ text: 'text-warning',
27
+ ring: 'ring-warning/20',
28
+ border: 'border-warning',
37
29
  },
38
30
  red: {
39
- bg: 'bg-red-50 dark:bg-red-950/40',
40
- text: 'text-red-700 dark:text-red-300',
41
- ring: 'ring-red-200 dark:ring-red-900',
42
- border: 'border-red-500',
31
+ bg: 'bg-destructive/10',
32
+ text: 'text-destructive',
33
+ ring: 'ring-destructive/20',
34
+ border: 'border-destructive',
43
35
  },
44
36
  blue: {
45
- bg: 'bg-blue-50 dark:bg-blue-950/40',
46
- text: 'text-blue-700 dark:text-blue-300',
47
- ring: 'ring-blue-200 dark:ring-blue-900',
48
- border: 'border-blue-500',
37
+ bg: 'bg-info/10',
38
+ text: 'text-info',
39
+ ring: 'ring-info/20',
40
+ border: 'border-info',
49
41
  },
50
42
  pink: {
51
- bg: 'bg-pink-50 dark:bg-pink-950/40',
52
- text: 'text-pink-700 dark:text-pink-300',
53
- ring: 'ring-pink-200 dark:ring-pink-900',
54
- border: 'border-pink-500',
43
+ bg: 'bg-chart-4/15',
44
+ text: 'text-chart-4',
45
+ ring: 'ring-chart-4/20',
46
+ border: 'border-chart-4',
55
47
  },
56
48
  gray: {
57
49
  bg: 'bg-muted',
@@ -66,8 +58,6 @@ export function paletteFor(color: string | null | undefined) {
66
58
  return PALETTE[color] ?? PALETTE.gray!
67
59
  }
68
60
 
69
- // ─── PostStatusBadge ─────────────────────────────────────────────────
70
-
71
61
  const STATUS_LABEL: Record<PostStatus, string> = {
72
62
  PUBLISHED: 'Published',
73
63
  DRAFT: 'Draft',
@@ -104,8 +94,6 @@ export function PostStatusBadge({ status }: { status: PostStatus }) {
104
94
  )
105
95
  }
106
96
 
107
- // ─── PostTypeBadge ───────────────────────────────────────────────────
108
-
109
97
  export function PostTypeBadge({
110
98
  label,
111
99
  color,
@@ -127,12 +115,6 @@ export function PostTypeBadge({
127
115
  return <span className={className}>{label}</span>
128
116
  }
129
117
 
130
- // ─── SeoScoreIndicator ───────────────────────────────────────────────
131
-
132
- /**
133
- * Returns the palette key for an SEO score so callers can match the
134
- * colored dot. 80+ green, 60–79 orange, 1–59 red, missing = gray.
135
- */
136
118
  export function seoScorePalette(score: number | null): string {
137
119
  if (score === null || Number.isNaN(score)) return 'gray'
138
120
  if (score >= 80) return 'green'
@@ -158,10 +140,10 @@ export function SeoScoreIndicator({ score }: { score: number | null }) {
158
140
  aria-hidden
159
141
  className={`h-2 w-2 rounded-full ${
160
142
  colorKey === 'green'
161
- ? 'bg-emerald-500'
143
+ ? 'bg-success'
162
144
  : colorKey === 'orange'
163
- ? 'bg-amber-500'
164
- : 'bg-red-500'
145
+ ? 'bg-warning'
146
+ : 'bg-destructive'
165
147
  }`}
166
148
  />
167
149
  <span className="tabular-nums">{score}</span>
@@ -4,11 +4,11 @@ import { cv, type VariantProps } from '../../lib/cv.js'
4
4
  const badge = cv('inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium', {
5
5
  variants: {
6
6
  tone: {
7
- neutral: 'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300',
8
- success: 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400',
9
- warning: 'bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400',
10
- danger: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',
11
- info: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
7
+ neutral: 'bg-muted text-muted-foreground',
8
+ success: 'bg-success/10 text-success',
9
+ warning: 'bg-warning/10 text-warning',
10
+ danger: 'bg-destructive/10 text-destructive',
11
+ info: 'bg-info/10 text-info',
12
12
  primary: 'bg-[var(--primary)]/15 text-[var(--primary)] dark:bg-[var(--primary)]/25',
13
13
  },
14
14
  size: {
@@ -11,11 +11,10 @@ interface Toast {
11
11
  }
12
12
 
13
13
  const typeClasses: Record<ToastType, string> = {
14
- success:
15
- 'border-emerald-500 bg-emerald-50 text-emerald-900 dark:bg-emerald-900/20 dark:text-emerald-300',
16
- error: 'border-red-500 bg-red-50 text-red-900 dark:bg-red-900/20 dark:text-red-300',
17
- warning: 'border-amber-500 bg-amber-50 text-amber-900 dark:bg-amber-900/20 dark:text-amber-300',
18
- info: 'border-blue-500 bg-blue-50 text-blue-900 dark:bg-blue-900/20 dark:text-blue-300',
14
+ success: 'border-success bg-success/10 text-success',
15
+ error: 'border-destructive bg-destructive/10 text-destructive',
16
+ warning: 'border-warning bg-warning/10 text-warning',
17
+ info: 'border-info bg-info/10 text-info',
19
18
  }
20
19
 
21
20
  export function useToast() {
@@ -117,7 +117,7 @@ export function ComponentBlockField({
117
117
 
118
118
  if (!currentSpec) {
119
119
  return (
120
- <div className="rounded-md border border-[var(--destructive)] bg-red-50 p-3 text-sm text-[var(--destructive)]">
120
+ <div className="bg-destructive/10 rounded-md border border-[var(--destructive)] p-3 text-sm text-[var(--destructive)]">
121
121
  Component block has no components to choose from.
122
122
  </div>
123
123
  )
@@ -147,7 +147,7 @@ export function ComponentBlockField({
147
147
  ) : null}
148
148
 
149
149
  {errorMessage ? (
150
- <div className="rounded-md border border-[var(--destructive)] bg-red-50 px-3 py-2 text-xs text-[var(--destructive)]">
150
+ <div className="bg-destructive/10 rounded-md border border-[var(--destructive)] px-3 py-2 text-xs text-[var(--destructive)]">
151
151
  {errorMessage}
152
152
  </div>
153
153
  ) : null}
@@ -62,7 +62,7 @@ export function FieldRenderer({ field, value, onChange }: FieldRendererProps) {
62
62
 
63
63
  if (!Component) {
64
64
  return (
65
- <div className="rounded-md border border-[var(--destructive)] bg-red-50 p-3 text-sm text-[var(--destructive)]">
65
+ <div className="bg-destructive/10 rounded-md border border-[var(--destructive)] p-3 text-sm text-[var(--destructive)]">
66
66
  Unknown field type: <code>{field.type}</code>
67
67
  </div>
68
68
  )
@@ -259,7 +259,7 @@ function BooleanInput({
259
259
  }`}
260
260
  >
261
261
  <span
262
- className={`pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow-sm ring-0 transition-transform ${
262
+ className={`bg-card pointer-events-none inline-block h-5 w-5 rounded-full shadow-sm ring-0 transition-transform ${
263
263
  boolVal ? 'translate-x-5' : 'translate-x-0'
264
264
  }`}
265
265
  />
@@ -26,10 +26,10 @@ interface RelatedDoc {
26
26
  }
27
27
 
28
28
  const STATUS_STYLES: Record<string, string> = {
29
- PUBLISHED: 'bg-green-100 text-green-800',
30
- DRAFT: 'bg-yellow-100 text-yellow-800',
31
- ARCHIVED: 'bg-gray-100 text-gray-600',
32
- SCHEDULED: 'bg-blue-100 text-blue-800',
29
+ PUBLISHED: 'bg-success/10 text-success',
30
+ DRAFT: 'bg-warning/10 text-warning',
31
+ ARCHIVED: 'bg-muted text-muted-foreground',
32
+ SCHEDULED: 'bg-info/10 text-info',
33
33
  }
34
34
 
35
35
  function relativeTime(dateStr: string | undefined): string {
@@ -150,7 +150,7 @@ export function RelationshipField({
150
150
  function renderOption(opt: RelatedDoc, isSelected: boolean) {
151
151
  const status = opt.status ?? (opt.data as any)?.status
152
152
  const collection = opt.collection ?? relationTo
153
- const statusClass = STATUS_STYLES[status] ?? 'bg-gray-100 text-gray-600'
153
+ const statusClass = STATUS_STYLES[status] ?? 'bg-muted text-muted-foreground'
154
154
 
155
155
  return (
156
156
  <button
@@ -24,7 +24,7 @@ export function ToggleField({ label, value = false, onChange, helpText }: Toggle
24
24
  }`}
25
25
  >
26
26
  <span
27
- className={`pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow-sm ring-0 transition-transform ${
27
+ className={`bg-card pointer-events-none inline-block h-5 w-5 rounded-full shadow-sm ring-0 transition-transform ${
28
28
  value ? 'translate-x-5' : 'translate-x-0'
29
29
  }`}
30
30
  />
@@ -795,7 +795,7 @@ export function Dashboard({ config, session, onNavigate }: DashboardProps) {
795
795
  : contentHealth.tone === 'warn'
796
796
  ? 'text-warning'
797
797
  : contentHealth.tone === 'err'
798
- ? 'text-red-600 dark:text-red-400'
798
+ ? 'text-destructive dark:text-red-400'
799
799
  : 'text-muted-foreground'
800
800
  }`}
801
801
  >
@@ -810,7 +810,7 @@ export function Dashboard({ config, session, onNavigate }: DashboardProps) {
810
810
  : contentHealth.tone === 'warn'
811
811
  ? 'bg-warning'
812
812
  : contentHealth.tone === 'err'
813
- ? 'bg-red-500'
813
+ ? 'bg-destructive'
814
814
  : 'bg-muted-foreground/40'
815
815
  }`}
816
816
  style={{ width: `${Math.max(0, Math.min(100, contentHealth.score))}%` }}
@@ -833,7 +833,7 @@ export function Dashboard({ config, session, onNavigate }: DashboardProps) {
833
833
  <span
834
834
  className={`h-1.5 w-1.5 shrink-0 rounded-full ${
835
835
  iss.tone === 'err'
836
- ? 'bg-red-500'
836
+ ? 'bg-destructive'
837
837
  : iss.tone === 'warn'
838
838
  ? 'bg-warning'
839
839
  : 'bg-muted-foreground'
@@ -846,7 +846,7 @@ export function Dashboard({ config, session, onNavigate }: DashboardProps) {
846
846
  <span
847
847
  className={`shrink-0 text-sm font-medium ${
848
848
  iss.tone === 'err'
849
- ? 'text-red-600 dark:text-red-400'
849
+ ? 'text-destructive dark:text-red-400'
850
850
  : iss.tone === 'warn'
851
851
  ? 'text-warning'
852
852
  : 'text-muted-foreground'
@@ -1040,7 +1040,7 @@ function DeliveryTile({
1040
1040
  : tone === 'warn'
1041
1041
  ? 'text-warning'
1042
1042
  : tone === 'err'
1043
- ? 'text-red-600 dark:text-red-400'
1043
+ ? 'text-destructive dark:text-red-400'
1044
1044
  : 'text-muted-foreground'
1045
1045
  return (
1046
1046
  <div className="px-4 py-3.5">
@@ -292,15 +292,15 @@ export function DocumentEdit({
292
292
 
293
293
  const statusColor =
294
294
  docStatus === 'PUBLISHED'
295
- ? 'bg-green-100 text-green-800'
295
+ ? 'bg-success/10 text-success'
296
296
  : docStatus === 'SCHEDULED'
297
- ? 'bg-blue-100 text-blue-800'
298
- : 'bg-yellow-100 text-yellow-800'
297
+ ? 'bg-info/10 text-info'
298
+ : 'bg-warning/10 text-warning'
299
299
 
300
300
  if (loading) {
301
301
  return (
302
302
  <div className="flex min-h-[300px] items-center justify-center">
303
- <Loader2 className="h-8 w-8 animate-spin text-gray-400" />
303
+ <Loader2 className="text-muted-foreground h-8 w-8 animate-spin" />
304
304
  </div>
305
305
  )
306
306
  }
@@ -316,7 +316,7 @@ export function DocumentEdit({
316
316
  {docStatus}
317
317
  </span>
318
318
  {documentId && <PresenceIndicator documentId={documentId} />}
319
- {isDirty && <span className="text-xs font-medium text-amber-600">Unsaved changes</span>}
319
+ {isDirty && <span className="text-warning text-xs font-medium">Unsaved changes</span>}
320
320
  </div>
321
321
  <div className="flex items-center gap-2">
322
322
  <button
@@ -362,13 +362,15 @@ export function DocumentEdit({
362
362
  <div className="space-y-6">
363
363
  {fields.length === 0 ? (
364
364
  <div className="flex flex-col items-center justify-center rounded-lg border border-[var(--border)] py-16 text-center">
365
- <div className="mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-gray-100">
366
- <AlertTriangle className="h-6 w-6 text-gray-400" />
365
+ <div className="bg-muted mb-4 flex h-12 w-12 items-center justify-center rounded-full">
366
+ <AlertTriangle className="text-muted-foreground h-6 w-6" />
367
367
  </div>
368
- <h3 className="mb-1 text-sm font-medium text-gray-900">
368
+ <h3 className="text-foreground mb-1 text-sm font-medium">
369
369
  Collection schema not found
370
370
  </h3>
371
- <p className="text-sm text-gray-500">No fields are defined for this collection.</p>
371
+ <p className="text-muted-foreground text-sm">
372
+ No fields are defined for this collection.
373
+ </p>
372
374
  </div>
373
375
  ) : (
374
376
  <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
@@ -410,14 +412,14 @@ export function DocumentEdit({
410
412
  {!isNew && (
411
413
  <button
412
414
  onClick={() => setShowSchedule(true)}
413
- className="inline-flex w-full items-center justify-center gap-1.5 rounded-md border border-[var(--border)] bg-white px-3 py-1.5 text-sm font-medium text-gray-700 hover:bg-gray-50"
415
+ className="border-border bg-card text-foreground hover:bg-accent inline-flex w-full items-center justify-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium"
414
416
  >
415
417
  <Calendar className="h-4 w-4" />
416
418
  {scheduledAt || scheduledUnpublishAt ? 'Reschedule' : 'Schedule'}
417
419
  </button>
418
420
  )}
419
421
  {!isNew && (scheduledAt || scheduledUnpublishAt) && (
420
- <div className="space-y-1 rounded-md border border-blue-100 bg-blue-50 px-3 py-2 text-xs text-blue-900">
422
+ <div className="border-info/30 bg-info/10 text-foreground space-y-1 rounded-md border px-3 py-2 text-xs">
421
423
  {scheduledAt && (
422
424
  <div className="flex items-center gap-1.5">
423
425
  <Calendar className="h-3.5 w-3.5" />