@actuate-media/cms-admin 0.54.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 (229) hide show
  1. package/CHANGELOG.md +30 -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/__tests__/lib/page-editor-service.test.js +1 -0
  5. package/dist/__tests__/lib/page-editor-service.test.js.map +1 -1
  6. package/dist/actuate-admin.css +1 -1
  7. package/dist/components/AICoauthorBubbleMenu.js +2 -2
  8. package/dist/components/AICoauthorBubbleMenu.js.map +1 -1
  9. package/dist/components/Breadcrumbs.js +2 -2
  10. package/dist/components/Breadcrumbs.js.map +1 -1
  11. package/dist/components/CoauthorResultPopover.d.ts.map +1 -1
  12. package/dist/components/CoauthorResultPopover.js +1 -1
  13. package/dist/components/CoauthorResultPopover.js.map +1 -1
  14. package/dist/components/CommandPalette.d.ts.map +1 -1
  15. package/dist/components/CommandPalette.js +11 -11
  16. package/dist/components/CommandPalette.js.map +1 -1
  17. package/dist/components/CommentSidePanel.js +11 -11
  18. package/dist/components/CommentSidePanel.js.map +1 -1
  19. package/dist/components/ContentOverviewChart.js +2 -2
  20. package/dist/components/ContentOverviewChart.js.map +1 -1
  21. package/dist/components/FocalPointPicker.js +1 -1
  22. package/dist/components/FocalPointPicker.js.map +1 -1
  23. package/dist/components/LivePreview.d.ts.map +1 -1
  24. package/dist/components/LivePreview.js +5 -5
  25. package/dist/components/LivePreview.js.map +1 -1
  26. package/dist/components/LogoPlaceholder.js +1 -1
  27. package/dist/components/LogoPlaceholder.js.map +1 -1
  28. package/dist/components/MentionableTextarea.js +3 -3
  29. package/dist/components/MentionableTextarea.js.map +1 -1
  30. package/dist/components/NotificationBell.js +1 -1
  31. package/dist/components/NotificationBell.js.map +1 -1
  32. package/dist/components/OfflineStatus.js +8 -8
  33. package/dist/components/OfflineStatus.js.map +1 -1
  34. package/dist/components/PresenceChips.d.ts.map +1 -1
  35. package/dist/components/PresenceChips.js +10 -6
  36. package/dist/components/PresenceChips.js.map +1 -1
  37. package/dist/components/SEOConfigPanel.d.ts.map +1 -1
  38. package/dist/components/SEOConfigPanel.js +10 -10
  39. package/dist/components/SEOConfigPanel.js.map +1 -1
  40. package/dist/components/SEOPanel.js +12 -12
  41. package/dist/components/SEOPanel.js.map +1 -1
  42. package/dist/components/SEOPerformance.d.ts.map +1 -1
  43. package/dist/components/SEOPerformance.js +3 -3
  44. package/dist/components/SEOPerformance.js.map +1 -1
  45. package/dist/components/TipTapEditor.js +6 -6
  46. package/dist/components/TipTapEditor.js.map +1 -1
  47. package/dist/components/pages/tag-badges.js +6 -6
  48. package/dist/components/pages/tag-badges.js.map +1 -1
  49. package/dist/components/posts/badges.d.ts +0 -4
  50. package/dist/components/posts/badges.d.ts.map +1 -1
  51. package/dist/components/posts/badges.js +28 -42
  52. package/dist/components/posts/badges.js.map +1 -1
  53. package/dist/components/ui/Badge.js +5 -5
  54. package/dist/components/ui/Badge.js.map +1 -1
  55. package/dist/components/ui/Toast.d.ts.map +1 -1
  56. package/dist/components/ui/Toast.js +4 -4
  57. package/dist/components/ui/Toast.js.map +1 -1
  58. package/dist/fields/ComponentBlockField.js +2 -2
  59. package/dist/fields/ComponentBlockField.js.map +1 -1
  60. package/dist/fields/FieldRenderer.js +1 -1
  61. package/dist/fields/FieldRenderer.js.map +1 -1
  62. package/dist/fields/PropInput.js +1 -1
  63. package/dist/fields/PropInput.js.map +1 -1
  64. package/dist/fields/RelationshipField.js +5 -5
  65. package/dist/fields/RelationshipField.js.map +1 -1
  66. package/dist/fields/ToggleField.js +1 -1
  67. package/dist/fields/ToggleField.js.map +1 -1
  68. package/dist/lib/seo-service.d.ts +0 -2
  69. package/dist/lib/seo-service.d.ts.map +1 -1
  70. package/dist/lib/seo-service.js.map +1 -1
  71. package/dist/views/Dashboard.js +5 -5
  72. package/dist/views/Dashboard.js.map +1 -1
  73. package/dist/views/DocumentEdit.d.ts.map +1 -1
  74. package/dist/views/DocumentEdit.js +5 -5
  75. package/dist/views/DocumentEdit.js.map +1 -1
  76. package/dist/views/ForgotPassword.d.ts.map +1 -1
  77. package/dist/views/ForgotPassword.js +3 -2
  78. package/dist/views/ForgotPassword.js.map +1 -1
  79. package/dist/views/FormEditor.d.ts.map +1 -1
  80. package/dist/views/FormEditor.js +5 -5
  81. package/dist/views/FormEditor.js.map +1 -1
  82. package/dist/views/Login.d.ts.map +1 -1
  83. package/dist/views/Login.js +17 -17
  84. package/dist/views/Login.js.map +1 -1
  85. package/dist/views/PageEditor.d.ts.map +1 -1
  86. package/dist/views/PageEditor.js +2 -2
  87. package/dist/views/PageEditor.js.map +1 -1
  88. package/dist/views/Pages/PagesListView.js +6 -6
  89. package/dist/views/Pages/PagesListView.js.map +1 -1
  90. package/dist/views/Pages.d.ts.map +1 -1
  91. package/dist/views/Pages.js +16 -19
  92. package/dist/views/Pages.js.map +1 -1
  93. package/dist/views/ResetPassword.d.ts.map +1 -1
  94. package/dist/views/ResetPassword.js +3 -2
  95. package/dist/views/ResetPassword.js.map +1 -1
  96. package/dist/views/Settings.js +2 -2
  97. package/dist/views/Settings.js.map +1 -1
  98. package/dist/views/SetupWizard.d.ts.map +1 -1
  99. package/dist/views/SetupWizard.js +6 -5
  100. package/dist/views/SetupWizard.js.map +1 -1
  101. package/dist/views/page-builder/DesignScore.js +12 -12
  102. package/dist/views/page-builder/DesignScore.js.map +1 -1
  103. package/dist/views/page-builder/SEOPanel.js +9 -9
  104. package/dist/views/page-builder/SEOPanel.js.map +1 -1
  105. package/dist/views/page-editor/EditorCanvas.js +1 -1
  106. package/dist/views/page-editor/EditorCanvas.js.map +1 -1
  107. package/dist/views/page-editor/EditorTopBar.js +2 -2
  108. package/dist/views/page-editor/EditorTopBar.js.map +1 -1
  109. package/dist/views/page-editor/PagePreview.js +1 -1
  110. package/dist/views/page-editor/PagePreview.js.map +1 -1
  111. package/dist/views/page-editor/SectionInspector.js +1 -1
  112. package/dist/views/page-editor/SectionInspector.js.map +1 -1
  113. package/dist/views/page-editor/SitePreviewFrame.js +1 -1
  114. package/dist/views/page-editor/SitePreviewFrame.js.map +1 -1
  115. package/dist/views/page-editor/sections/ArticleBodySection.js +1 -1
  116. package/dist/views/page-editor/sections/ArticleBodySection.js.map +1 -1
  117. package/dist/views/page-editor/sections/AuthorBioSection.js +2 -2
  118. package/dist/views/page-editor/sections/AuthorBioSection.js.map +1 -1
  119. package/dist/views/page-editor/sections/ByTheNumbersSection.js +1 -1
  120. package/dist/views/page-editor/sections/ByTheNumbersSection.js.map +1 -1
  121. package/dist/views/page-editor/sections/CtaBannerSection.js +1 -1
  122. package/dist/views/page-editor/sections/CtaBannerSection.js.map +1 -1
  123. package/dist/views/page-editor/sections/EmbedSection.d.ts +10 -0
  124. package/dist/views/page-editor/sections/EmbedSection.d.ts.map +1 -0
  125. package/dist/views/page-editor/sections/EmbedSection.js +24 -0
  126. package/dist/views/page-editor/sections/EmbedSection.js.map +1 -0
  127. package/dist/views/page-editor/sections/FeatureHighlightSection.d.ts.map +1 -1
  128. package/dist/views/page-editor/sections/FeatureHighlightSection.js +2 -2
  129. package/dist/views/page-editor/sections/FeatureHighlightSection.js.map +1 -1
  130. package/dist/views/page-editor/sections/GallerySection.d.ts.map +1 -1
  131. package/dist/views/page-editor/sections/GallerySection.js +1 -1
  132. package/dist/views/page-editor/sections/GallerySection.js.map +1 -1
  133. package/dist/views/page-editor/sections/HeroBannerSection.js +1 -1
  134. package/dist/views/page-editor/sections/HeroBannerSection.js.map +1 -1
  135. package/dist/views/page-editor/sections/MissionSection.d.ts.map +1 -1
  136. package/dist/views/page-editor/sections/MissionSection.js +1 -1
  137. package/dist/views/page-editor/sections/MissionSection.js.map +1 -1
  138. package/dist/views/page-editor/sections/PullQuoteSection.js +1 -1
  139. package/dist/views/page-editor/sections/PullQuoteSection.js.map +1 -1
  140. package/dist/views/page-editor/sections/RelatedPostsSection.js +1 -1
  141. package/dist/views/page-editor/sections/RelatedPostsSection.js.map +1 -1
  142. package/dist/views/page-editor/sections/SectionRenderer.d.ts.map +1 -1
  143. package/dist/views/page-editor/sections/SectionRenderer.js +5 -1
  144. package/dist/views/page-editor/sections/SectionRenderer.js.map +1 -1
  145. package/dist/views/page-editor/sections/parts.js +6 -6
  146. package/dist/views/page-editor/sections/parts.js.map +1 -1
  147. package/dist/views/post-editor/PostEditorCanvas.js +2 -2
  148. package/dist/views/post-editor/PostEditorCanvas.js.map +1 -1
  149. package/dist/views/post-editor/PostHeader.js +2 -2
  150. package/dist/views/post-editor/PostHeader.js.map +1 -1
  151. package/dist/views/post-editor/PostHeaderPanel.js +1 -1
  152. package/dist/views/post-editor/PostHeaderPanel.js.map +1 -1
  153. package/dist/views/post-editor/PostPreview.js +1 -1
  154. package/dist/views/post-editor/PostPreview.js.map +1 -1
  155. package/dist/views/profile/AccountSecurity.js +1 -1
  156. package/dist/views/profile/AccountSecurity.js.map +1 -1
  157. package/dist/views/seo/TechnicalTab.d.ts.map +1 -1
  158. package/dist/views/seo/TechnicalTab.js +0 -10
  159. package/dist/views/seo/TechnicalTab.js.map +1 -1
  160. package/dist/views/settings/components.js +1 -1
  161. package/dist/views/settings/components.js.map +1 -1
  162. package/package.json +2 -2
  163. package/src/__tests__/components/posts-badges.test.tsx +3 -3
  164. package/src/__tests__/lib/page-editor-service.test.ts +1 -0
  165. package/src/components/AICoauthorBubbleMenu.tsx +4 -4
  166. package/src/components/Breadcrumbs.tsx +5 -5
  167. package/src/components/CoauthorResultPopover.tsx +26 -23
  168. package/src/components/CommandPalette.tsx +41 -39
  169. package/src/components/CommentSidePanel.tsx +20 -20
  170. package/src/components/ContentOverviewChart.tsx +4 -4
  171. package/src/components/FocalPointPicker.tsx +2 -2
  172. package/src/components/LivePreview.tsx +20 -17
  173. package/src/components/LogoPlaceholder.tsx +1 -1
  174. package/src/components/MentionableTextarea.tsx +5 -5
  175. package/src/components/NotificationBell.tsx +10 -10
  176. package/src/components/OfflineStatus.tsx +8 -8
  177. package/src/components/PresenceChips.tsx +12 -8
  178. package/src/components/SEOConfigPanel.tsx +40 -38
  179. package/src/components/SEOPanel.tsx +15 -15
  180. package/src/components/SEOPerformance.tsx +25 -23
  181. package/src/components/TipTapEditor.tsx +7 -7
  182. package/src/components/pages/tag-badges.tsx +6 -6
  183. package/src/components/posts/badges.tsx +28 -46
  184. package/src/components/ui/Badge.tsx +5 -5
  185. package/src/components/ui/Toast.tsx +4 -5
  186. package/src/fields/ComponentBlockField.tsx +2 -2
  187. package/src/fields/FieldRenderer.tsx +1 -1
  188. package/src/fields/PropInput.tsx +1 -1
  189. package/src/fields/RelationshipField.tsx +5 -5
  190. package/src/fields/ToggleField.tsx +1 -1
  191. package/src/lib/seo-service.ts +0 -2
  192. package/src/views/Dashboard.tsx +5 -5
  193. package/src/views/DocumentEdit.tsx +13 -11
  194. package/src/views/ForgotPassword.tsx +21 -18
  195. package/src/views/FormEditor.tsx +74 -69
  196. package/src/views/Login.tsx +45 -39
  197. package/src/views/PageEditor.tsx +26 -22
  198. package/src/views/Pages/PagesListView.tsx +6 -6
  199. package/src/views/Pages.tsx +64 -65
  200. package/src/views/ResetPassword.tsx +32 -29
  201. package/src/views/Settings.tsx +2 -2
  202. package/src/views/SetupWizard.tsx +42 -33
  203. package/src/views/page-builder/DesignScore.tsx +12 -12
  204. package/src/views/page-builder/SEOPanel.tsx +12 -12
  205. package/src/views/page-editor/EditorCanvas.tsx +1 -1
  206. package/src/views/page-editor/EditorTopBar.tsx +2 -2
  207. package/src/views/page-editor/PagePreview.tsx +1 -1
  208. package/src/views/page-editor/SectionInspector.tsx +1 -1
  209. package/src/views/page-editor/SitePreviewFrame.tsx +1 -1
  210. package/src/views/page-editor/sections/ArticleBodySection.tsx +5 -5
  211. package/src/views/page-editor/sections/AuthorBioSection.tsx +6 -6
  212. package/src/views/page-editor/sections/ByTheNumbersSection.tsx +5 -5
  213. package/src/views/page-editor/sections/CtaBannerSection.tsx +1 -1
  214. package/src/views/page-editor/sections/EmbedSection.tsx +43 -0
  215. package/src/views/page-editor/sections/FeatureHighlightSection.tsx +7 -5
  216. package/src/views/page-editor/sections/GallerySection.tsx +6 -4
  217. package/src/views/page-editor/sections/HeroBannerSection.tsx +2 -2
  218. package/src/views/page-editor/sections/MissionSection.tsx +4 -2
  219. package/src/views/page-editor/sections/PullQuoteSection.tsx +4 -4
  220. package/src/views/page-editor/sections/RelatedPostsSection.tsx +5 -5
  221. package/src/views/page-editor/sections/SectionRenderer.tsx +6 -2
  222. package/src/views/page-editor/sections/parts.tsx +6 -6
  223. package/src/views/post-editor/PostEditorCanvas.tsx +4 -4
  224. package/src/views/post-editor/PostHeader.tsx +5 -5
  225. package/src/views/post-editor/PostHeaderPanel.tsx +1 -1
  226. package/src/views/post-editor/PostPreview.tsx +1 -1
  227. package/src/views/profile/AccountSecurity.tsx +1 -1
  228. package/src/views/seo/TechnicalTab.tsx +0 -10
  229. package/src/views/settings/components.tsx +1 -1
@@ -21,11 +21,14 @@ function passwordStrength(pw: string): { score: number; label: string; color: st
21
21
  if (/\d/.test(pw)) score++
22
22
  if (/[^a-zA-Z0-9]/.test(pw)) score++
23
23
 
24
- if (score <= 2) return { score, label: 'Weak', color: 'bg-red-500' }
25
- if (score <= 4) return { score, label: 'Fair', color: 'bg-yellow-500' }
26
- return { score, label: 'Strong', color: 'bg-green-500' }
24
+ if (score <= 2) return { score, label: 'Weak', color: 'bg-destructive' }
25
+ if (score <= 4) return { score, label: 'Fair', color: 'bg-warning' }
26
+ return { score, label: 'Strong', color: 'bg-success' }
27
27
  }
28
28
 
29
+ const fieldClass =
30
+ 'w-full rounded-lg border border-border bg-input-background px-3 py-2.5 text-sm text-foreground focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:outline-none'
31
+
29
32
  export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizardProps) {
30
33
  const [name, setName] = useState('')
31
34
  const [email, setEmail] = useState('')
@@ -69,18 +72,18 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
69
72
 
70
73
  if (done) {
71
74
  return (
72
- <div className="flex min-h-screen items-center justify-center bg-gray-50 px-4">
75
+ <div className="bg-muted flex min-h-screen items-center justify-center px-4">
73
76
  <div className="w-full max-w-md text-center">
74
- <div className="mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full bg-green-100">
75
- <CheckCircle2 className="h-8 w-8 text-green-600" />
77
+ <div className="bg-success/10 mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full">
78
+ <CheckCircle2 className="text-success h-8 w-8" />
76
79
  </div>
77
- <h1 className="mb-2 text-2xl font-medium text-gray-900">Setup Complete</h1>
78
- <p className="mb-6 text-gray-600">
80
+ <h1 className="text-foreground mb-2 text-2xl font-medium">Setup Complete</h1>
81
+ <p className="text-muted-foreground mb-6">
79
82
  Your admin account has been created. You can now sign in to manage your content.
80
83
  </p>
81
84
  <button
82
85
  onClick={() => window.location.reload()}
83
- className="w-full rounded-lg bg-blue-600 px-6 py-3 font-medium text-white transition-colors hover:bg-blue-700"
86
+ className="bg-primary text-primary-foreground hover:bg-primary/90 w-full rounded-lg px-6 py-3 font-medium transition-colors"
84
87
  >
85
88
  Go to Login
86
89
  </button>
@@ -90,29 +93,32 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
90
93
  }
91
94
 
92
95
  return (
93
- <div className="flex min-h-screen items-center justify-center bg-gray-50 px-4">
96
+ <div className="bg-muted flex min-h-screen items-center justify-center px-4">
94
97
  <div className="w-full max-w-md">
95
98
  <div className="mb-8 text-center">
96
- <div className="mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-xl bg-blue-600">
97
- <Shield className="h-7 w-7 text-white" />
99
+ <div className="bg-primary mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-xl">
100
+ <Shield className="text-primary-foreground h-7 w-7" />
98
101
  </div>
99
- <h1 className="text-2xl font-medium text-gray-900">Welcome to {siteName}</h1>
100
- <p className="mt-2 text-gray-600">Create your admin account to get started</p>
102
+ <h1 className="text-foreground text-2xl font-medium">Welcome to {siteName}</h1>
103
+ <p className="text-muted-foreground mt-2">Create your admin account to get started</p>
101
104
  </div>
102
105
 
103
106
  <form
104
107
  onSubmit={handleSubmit}
105
- className="space-y-5 rounded-xl border border-gray-200 bg-white p-6 shadow-sm"
108
+ className="border-border bg-card space-y-5 rounded-xl border p-6 shadow-sm"
106
109
  >
107
110
  {error && (
108
- <div className="flex items-start gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
109
- <AlertTriangle className="mt-0.5 h-5 w-5 shrink-0 text-red-600" />
110
- <p className="text-sm text-red-800">{error}</p>
111
+ <div className="border-destructive/30 bg-destructive/10 flex items-start gap-3 rounded-lg border p-3">
112
+ <AlertTriangle className="text-destructive mt-0.5 h-5 w-5 shrink-0" />
113
+ <p className="text-destructive text-sm">{error}</p>
111
114
  </div>
112
115
  )}
113
116
 
114
117
  <div>
115
- <label htmlFor="setup-name" className="mb-1.5 block text-sm font-medium text-gray-700">
118
+ <label
119
+ htmlFor="setup-name"
120
+ className="text-foreground mb-1.5 block text-sm font-medium"
121
+ >
116
122
  Full Name
117
123
  </label>
118
124
  <input
@@ -121,7 +127,7 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
121
127
  value={name}
122
128
  onChange={(e) => setName(e.target.value)}
123
129
  placeholder="Jane Smith"
124
- className="w-full rounded-lg border border-gray-300 px-3 py-2.5 text-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none"
130
+ className={fieldClass}
125
131
  required
126
132
  autoFocus
127
133
  autoComplete="name"
@@ -129,7 +135,10 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
129
135
  </div>
130
136
 
131
137
  <div>
132
- <label htmlFor="setup-email" className="mb-1.5 block text-sm font-medium text-gray-700">
138
+ <label
139
+ htmlFor="setup-email"
140
+ className="text-foreground mb-1.5 block text-sm font-medium"
141
+ >
133
142
  Email Address
134
143
  </label>
135
144
  <input
@@ -138,7 +147,7 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
138
147
  value={email}
139
148
  onChange={(e) => setEmail(e.target.value)}
140
149
  placeholder="admin@example.com"
141
- className="w-full rounded-lg border border-gray-300 px-3 py-2.5 text-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none"
150
+ className={fieldClass}
142
151
  required
143
152
  autoComplete="email"
144
153
  />
@@ -147,7 +156,7 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
147
156
  <div>
148
157
  <label
149
158
  htmlFor="setup-password"
150
- className="mb-1.5 block text-sm font-medium text-gray-700"
159
+ className="text-foreground mb-1.5 block text-sm font-medium"
151
160
  >
152
161
  Password
153
162
  </label>
@@ -158,7 +167,7 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
158
167
  value={password}
159
168
  onChange={(e) => setPassword(e.target.value)}
160
169
  placeholder="Minimum 12 characters"
161
- className="w-full rounded-lg border border-gray-300 px-3 py-2.5 pr-10 text-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none"
170
+ className={`${fieldClass} pr-10`}
162
171
  required
163
172
  minLength={12}
164
173
  autoComplete="new-password"
@@ -166,7 +175,7 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
166
175
  <button
167
176
  type="button"
168
177
  onClick={() => setShowPassword(!showPassword)}
169
- className="absolute top-1/2 right-3 -translate-y-1/2 text-gray-400 hover:text-gray-600"
178
+ className="text-muted-foreground hover:text-foreground absolute top-1/2 right-3 -translate-y-1/2"
170
179
  tabIndex={-1}
171
180
  >
172
181
  {showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
@@ -175,13 +184,13 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
175
184
  {password && (
176
185
  <div className="mt-2">
177
186
  <div className="flex items-center gap-2">
178
- <div className="h-1.5 flex-1 overflow-hidden rounded-full bg-gray-200">
187
+ <div className="bg-muted h-1.5 flex-1 overflow-hidden rounded-full">
179
188
  <div
180
189
  className={`h-full rounded-full transition-all ${strength.color}`}
181
190
  style={{ width: `${(strength.score / 6) * 100}%` }}
182
191
  />
183
192
  </div>
184
- <span className="text-xs text-gray-600">{strength.label}</span>
193
+ <span className="text-muted-foreground text-xs">{strength.label}</span>
185
194
  </div>
186
195
  </div>
187
196
  )}
@@ -190,7 +199,7 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
190
199
  <div>
191
200
  <label
192
201
  htmlFor="setup-confirm"
193
- className="mb-1.5 block text-sm font-medium text-gray-700"
202
+ className="text-foreground mb-1.5 block text-sm font-medium"
194
203
  >
195
204
  Confirm Password
196
205
  </label>
@@ -200,26 +209,26 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
200
209
  value={confirmPassword}
201
210
  onChange={(e) => setConfirmPassword(e.target.value)}
202
211
  placeholder="Re-enter your password"
203
- className={`w-full rounded-lg border px-3 py-2.5 text-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none ${
204
- confirmPassword && !passwordsMatch ? 'border-red-300' : 'border-gray-300'
212
+ className={`${fieldClass} ${
213
+ confirmPassword && !passwordsMatch ? 'border-destructive' : ''
205
214
  }`}
206
215
  required
207
216
  autoComplete="new-password"
208
217
  />
209
218
  {confirmPassword && !passwordsMatch && (
210
- <p className="mt-1 text-xs text-red-600">Passwords do not match</p>
219
+ <p className="text-destructive mt-1 text-xs">Passwords do not match</p>
211
220
  )}
212
221
  </div>
213
222
 
214
223
  <button
215
224
  type="submit"
216
225
  disabled={!canSubmit}
217
- className="w-full rounded-lg bg-blue-600 py-2.5 font-medium text-white transition-colors hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-50"
226
+ className="bg-primary text-primary-foreground hover:bg-primary/90 w-full rounded-lg py-2.5 font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50"
218
227
  >
219
228
  {submitting ? 'Creating Account...' : 'Create Admin Account'}
220
229
  </button>
221
230
 
222
- <p className="text-center text-xs text-gray-500">
231
+ <p className="text-muted-foreground text-center text-xs">
223
232
  This form is only available during initial setup. Once an admin account exists, it will
224
233
  be replaced by the login screen.
225
234
  </p>
@@ -25,16 +25,16 @@ export interface DesignScorePanelProps {
25
25
 
26
26
  function getScoreColor(score: number, max: number): string {
27
27
  const ratio = max > 0 ? score / max : 0
28
- if (ratio >= 0.8) return 'text-green-500'
29
- if (ratio >= 0.5) return 'text-amber-500'
30
- return 'text-red-500'
28
+ if (ratio >= 0.8) return 'text-success'
29
+ if (ratio >= 0.5) return 'text-warning'
30
+ return 'text-destructive'
31
31
  }
32
32
 
33
33
  function getBarColor(score: number, max: number): string {
34
34
  const ratio = max > 0 ? score / max : 0
35
- if (ratio >= 0.8) return 'bg-green-500'
36
- if (ratio >= 0.5) return 'bg-amber-500'
37
- return 'bg-red-500'
35
+ if (ratio >= 0.8) return 'bg-success'
36
+ if (ratio >= 0.5) return 'bg-warning'
37
+ return 'bg-destructive'
38
38
  }
39
39
 
40
40
  function getScoreLabel(score: number): string {
@@ -53,19 +53,19 @@ function getRingStrokeColor(score: number): string {
53
53
  function StatusIcon({ status }: { status: BuilderDesignCheck['status'] }) {
54
54
  switch (status) {
55
55
  case 'good':
56
- return <CheckCircle2 size={14} className="shrink-0 text-green-500" />
56
+ return <CheckCircle2 size={14} className="text-success shrink-0" />
57
57
  case 'warning':
58
- return <AlertCircle size={14} className="shrink-0 text-amber-500" />
58
+ return <AlertCircle size={14} className="text-warning shrink-0" />
59
59
  case 'error':
60
- return <XCircle size={14} className="shrink-0 text-red-500" />
60
+ return <XCircle size={14} className="text-destructive shrink-0" />
61
61
  }
62
62
  }
63
63
 
64
64
  function SeverityBadge({ severity }: { severity: DesignSuggestion['severity'] }) {
65
65
  const classes: Record<DesignSuggestion['severity'], string> = {
66
- important: 'bg-red-100 text-red-700',
67
- suggestion: 'bg-amber-100 text-amber-700',
68
- info: 'bg-blue-100 text-blue-700',
66
+ important: 'bg-destructive/10 text-destructive',
67
+ suggestion: 'bg-warning/10 text-warning',
68
+ info: 'bg-info/10 text-info',
69
69
  }
70
70
 
71
71
  return (
@@ -33,9 +33,9 @@ export interface BuilderSEOPanelProps {
33
33
  }
34
34
 
35
35
  function getScoreColor(score: number): string {
36
- if (score >= 70) return 'text-green-500'
37
- if (score >= 40) return 'text-amber-500'
38
- return 'text-red-500'
36
+ if (score >= 70) return 'text-success'
37
+ if (score >= 40) return 'text-warning'
38
+ return 'text-destructive'
39
39
  }
40
40
 
41
41
  function getRingStrokeColor(score: number): string {
@@ -54,11 +54,11 @@ function getScoreLabel(score: number): string {
54
54
  function StatusIcon({ status }: { status: BuilderSEOCheck['status'] }) {
55
55
  switch (status) {
56
56
  case 'good':
57
- return <CheckCircle2 size={14} className="shrink-0 text-green-500" />
57
+ return <CheckCircle2 size={14} className="text-success shrink-0" />
58
58
  case 'warning':
59
- return <AlertCircle size={14} className="shrink-0 text-amber-500" />
59
+ return <AlertCircle size={14} className="text-warning shrink-0" />
60
60
  case 'error':
61
- return <XCircle size={14} className="shrink-0 text-red-500" />
61
+ return <XCircle size={14} className="text-destructive shrink-0" />
62
62
  }
63
63
  }
64
64
 
@@ -109,15 +109,15 @@ function ScoreSummary({ checks }: { checks: BuilderSEOCheck[] }) {
109
109
  return (
110
110
  <div className="flex flex-col gap-1">
111
111
  <div className="flex items-center gap-1.5">
112
- <CheckCircle2 size={12} className="text-green-500" />
112
+ <CheckCircle2 size={12} className="text-success" />
113
113
  <span className="text-muted-foreground text-xs">{passed} passed</span>
114
114
  </div>
115
115
  <div className="flex items-center gap-1.5">
116
- <AlertCircle size={12} className="text-amber-500" />
116
+ <AlertCircle size={12} className="text-warning" />
117
117
  <span className="text-muted-foreground text-xs">{warnings} warnings</span>
118
118
  </div>
119
119
  <div className="flex items-center gap-1.5">
120
- <XCircle size={12} className="text-red-500" />
120
+ <XCircle size={12} className="text-destructive" />
121
121
  <span className="text-muted-foreground text-xs">{errors} issues</span>
122
122
  </div>
123
123
  </div>
@@ -265,7 +265,7 @@ function BasicSEOFields({
265
265
  <div className="flex items-center justify-between">
266
266
  <label className="text-foreground text-xs font-medium">Meta Title</label>
267
267
  <span
268
- className={`text-xs ${metaTitleLength > 60 ? 'text-red-500' : metaTitleLength > 0 ? 'text-muted-foreground' : 'text-muted-foreground'}`}
268
+ className={`text-xs ${metaTitleLength > 60 ? 'text-destructive' : metaTitleLength > 0 ? 'text-muted-foreground' : 'text-muted-foreground'}`}
269
269
  >
270
270
  {metaTitleLength}/60
271
271
  </span>
@@ -283,7 +283,7 @@ function BasicSEOFields({
283
283
  <div className="flex items-center justify-between">
284
284
  <label className="text-foreground text-xs font-medium">Meta Description</label>
285
285
  <span
286
- className={`text-xs ${metaDescLength > 160 ? 'text-red-500' : metaDescLength > 0 ? 'text-muted-foreground' : 'text-muted-foreground'}`}
286
+ className={`text-xs ${metaDescLength > 160 ? 'text-destructive' : metaDescLength > 0 ? 'text-muted-foreground' : 'text-muted-foreground'}`}
287
287
  >
288
288
  {metaDescLength}/160
289
289
  </span>
@@ -321,7 +321,7 @@ function SearchPreview({ pageSettings }: { pageSettings: PageSettings }) {
321
321
  <p className="text-muted-foreground mb-2 text-xs">Google Search Preview</p>
322
322
  <div className="flex flex-col gap-1">
323
323
  <p className="text-primary truncate text-sm">{title}</p>
324
- <p className="truncate text-xs text-green-600">example.com/{slug}</p>
324
+ <p className="text-success truncate text-xs">example.com/{slug}</p>
325
325
  <p className="text-muted-foreground line-clamp-2 text-xs">{description}</p>
326
326
  </div>
327
327
  </div>
@@ -85,7 +85,7 @@ export function EditorCanvas({
85
85
  >
86
86
  <div
87
87
  ref={surfaceRef}
88
- className="border-border origin-top overflow-hidden rounded-xl border bg-white shadow-sm"
88
+ className="border-border bg-card origin-top overflow-hidden rounded-xl border shadow-sm"
89
89
  style={{
90
90
  width: vp.width,
91
91
  transform: `scale(${scale})`,
@@ -72,9 +72,9 @@ const VIEWPORT_ICONS: Record<string, LucideIcon> = {
72
72
  }
73
73
 
74
74
  const STATUS_TEXT: Record<PageStatus, { label: string; className: string }> = {
75
- DRAFT: { label: 'Draft', className: 'text-amber-600 dark:text-amber-400' },
75
+ DRAFT: { label: 'Draft', className: 'text-warning dark:text-amber-400' },
76
76
  PUBLISHED: { label: 'Published', className: 'text-emerald-600 dark:text-emerald-400' },
77
- SCHEDULED: { label: 'Scheduled', className: 'text-amber-600 dark:text-amber-400' },
77
+ SCHEDULED: { label: 'Scheduled', className: 'text-warning dark:text-amber-400' },
78
78
  ARCHIVED: { label: 'Archived', className: 'text-muted-foreground' },
79
79
  }
80
80
 
@@ -91,7 +91,7 @@ export function PagePreview({ documentId, onNavigate }: PagePreviewProps) {
91
91
 
92
92
  {/* The canvas is intentionally white regardless of the admin theme:
93
93
  it emulates the public page surface, not admin chrome. */}
94
- <div className="flex-1 overflow-auto bg-white">
94
+ <div className="bg-card flex-1 overflow-auto">
95
95
  {visible.length === 0 ? (
96
96
  <div className="text-muted-foreground flex h-full items-center justify-center text-sm">
97
97
  This page has no visible sections yet.
@@ -513,7 +513,7 @@ function BooleanField({
513
513
  }`}
514
514
  >
515
515
  <span
516
- className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
516
+ className={`bg-card inline-block h-4 w-4 transform rounded-full transition-transform ${
517
517
  value ? 'translate-x-4' : 'translate-x-0.5'
518
518
  }`}
519
519
  />
@@ -70,7 +70,7 @@ export function SitePreviewFrame({
70
70
  src={src}
71
71
  title={title}
72
72
  onLoad={() => setLoaded(true)}
73
- className="border-border rounded-xl border bg-white shadow-sm"
73
+ className="border-border bg-card rounded-xl border shadow-sm"
74
74
  style={{
75
75
  width: vp.width,
76
76
  height: frameHeight / scale,
@@ -27,22 +27,22 @@ export function ArticleBodySection({
27
27
  return (
28
28
  <div className={`mx-auto px-6 ${wide ? 'max-w-4xl' : 'max-w-2xl'}`}>
29
29
  {showToc && (
30
- <div className="mb-8 rounded-lg border border-zinc-200 bg-zinc-50 p-4">
31
- <p className="text-xs font-semibold tracking-wider text-zinc-500 uppercase">
30
+ <div className="border-border bg-muted mb-8 rounded-lg border p-4">
31
+ <p className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">
32
32
  On this page
33
33
  </p>
34
- <p className="mt-1 text-sm text-zinc-400">
34
+ <p className="text-muted-foreground mt-1 text-sm">
35
35
  A table of contents will be generated from the body headings.
36
36
  </p>
37
37
  </div>
38
38
  )}
39
39
  {html.trim() ? (
40
40
  <div
41
- className="prose prose-zinc max-w-none text-base leading-relaxed text-zinc-700"
41
+ className="prose prose-zinc text-foreground max-w-none text-base leading-relaxed"
42
42
  dangerouslySetInnerHTML={{ __html: html }}
43
43
  />
44
44
  ) : (
45
- <p className="text-base leading-relaxed text-zinc-400 italic">
45
+ <p className="text-muted-foreground text-base leading-relaxed italic">
46
46
  {source === 'field'
47
47
  ? "This will show the post's Body content."
48
48
  : 'Add body copy in the inspector.'}
@@ -27,7 +27,7 @@ export function AuthorBioSection({
27
27
 
28
28
  return (
29
29
  <div className="mx-auto max-w-3xl px-6">
30
- <div className="flex items-start gap-4 rounded-xl border border-zinc-200 bg-zinc-50 p-5">
30
+ <div className="border-border bg-muted flex items-start gap-4 rounded-xl border p-5">
31
31
  {showAvatar &&
32
32
  (avatarUrl ? (
33
33
  <img
@@ -36,20 +36,20 @@ export function AuthorBioSection({
36
36
  className="h-14 w-14 shrink-0 rounded-full object-cover"
37
37
  />
38
38
  ) : (
39
- <span className="flex h-14 w-14 shrink-0 items-center justify-center rounded-full bg-violet-100 text-sm font-medium text-violet-700">
39
+ <span className="bg-brand/10 text-brand flex h-14 w-14 shrink-0 items-center justify-center rounded-full text-sm font-medium">
40
40
  {initials || '?'}
41
41
  </span>
42
42
  ))}
43
43
  <div className="min-w-0">
44
44
  {heading && (
45
- <p className="text-xs font-semibold tracking-wider text-zinc-500 uppercase">
45
+ <p className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">
46
46
  {heading}
47
47
  </p>
48
48
  )}
49
- <p className="mt-0.5 text-base font-medium text-zinc-900">{name}</p>
50
- <p className="mt-1 text-sm leading-relaxed text-zinc-600">{bio}</p>
49
+ <p className="text-foreground mt-0.5 text-base font-medium">{name}</p>
50
+ <p className="text-muted-foreground mt-1 text-sm leading-relaxed">{bio}</p>
51
51
  {showSocial && (
52
- <div className="mt-2 flex gap-3 text-sm text-violet-600">
52
+ <div className="text-brand mt-2 flex gap-3 text-sm">
53
53
  <span>Twitter</span>
54
54
  <span>LinkedIn</span>
55
55
  </div>
@@ -16,21 +16,21 @@ export function ByTheNumbersSection({ section }: { section: PageSection }) {
16
16
  return (
17
17
  <div className="mx-auto max-w-5xl px-6 text-center">
18
18
  {heading && (
19
- <h2 className="text-2xl font-semibold tracking-tight text-zinc-900 sm:text-3xl">
19
+ <h2 className="text-foreground text-2xl font-semibold tracking-tight sm:text-3xl">
20
20
  {heading}
21
21
  </h2>
22
22
  )}
23
- {body && <p className="mx-auto mt-4 max-w-2xl text-base text-zinc-600">{body}</p>}
23
+ {body && <p className="text-muted-foreground mx-auto mt-4 max-w-2xl text-base">{body}</p>}
24
24
  {stats.length > 0 && (
25
25
  <dl className="mt-10 grid grid-cols-1 gap-8 sm:grid-cols-3">
26
26
  {stats.map((s, i) => (
27
27
  <div key={i}>
28
- <dt className="text-4xl font-semibold tracking-tight text-violet-600">
28
+ <dt className="text-brand text-4xl font-semibold tracking-tight">
29
29
  {String(s.value ?? '')}
30
30
  </dt>
31
- <dd className="mt-2 text-sm font-medium text-zinc-700">{String(s.label ?? '')}</dd>
31
+ <dd className="text-foreground mt-2 text-sm font-medium">{String(s.label ?? '')}</dd>
32
32
  {s.description ? (
33
- <dd className="mt-1 text-xs text-zinc-500">{String(s.description)}</dd>
33
+ <dd className="text-muted-foreground mt-1 text-xs">{String(s.description)}</dd>
34
34
  ) : null}
35
35
  </div>
36
36
  ))}
@@ -12,7 +12,7 @@ export function CtaBannerSection({ section }: { section: PageSection }) {
12
12
  <h2 className="text-2xl font-semibold tracking-tight sm:text-3xl">{heading}</h2>
13
13
  {body && (
14
14
  <p
15
- className={`mx-auto mt-3 max-w-xl text-base ${dark ? 'text-violet-100' : 'text-zinc-600'}`}
15
+ className={`mx-auto mt-3 max-w-xl text-base ${dark ? 'text-brand-foreground/80' : 'text-muted-foreground'}`}
16
16
  >
17
17
  {body}
18
18
  </p>
@@ -0,0 +1,43 @@
1
+ import { PlayCircle } from 'lucide-react'
2
+ import { parseEmbed, EMBED_PROVIDER_LABEL } from '@actuate-media/cms-core/page-sections'
3
+ import type { PageSection } from '../../../lib/page-editor-service.js'
4
+ import { str } from './parts.js'
5
+
6
+ const RATIO_CLASS: Record<string, string> = {
7
+ '16:9': 'aspect-video',
8
+ '4:3': 'aspect-[4/3]',
9
+ '1:1': 'aspect-square',
10
+ '9:16': 'aspect-[9/16]',
11
+ }
12
+
13
+ /**
14
+ * Canvas body for the `embed` (video) section. Mirrors the public renderer's
15
+ * reserved aspect-ratio box, but shows a lightweight provider placeholder
16
+ * instead of loading the live external iframe inside the editor.
17
+ */
18
+ export function EmbedSection({ section }: { section: PageSection }) {
19
+ const c = section.content
20
+ const parsed = parseEmbed(str(c, 'url'))
21
+ const ratioClass = RATIO_CLASS[str(c, 'ratio', '16:9')] ?? RATIO_CLASS['16:9']
22
+ const title = str(c, 'title')
23
+ const caption = str(c, 'caption')
24
+
25
+ return (
26
+ <figure className="mx-auto max-w-3xl px-6">
27
+ <div
28
+ className={`bg-muted text-muted-foreground relative flex w-full flex-col items-center justify-center gap-2 overflow-hidden rounded-xl ${ratioClass}`}
29
+ >
30
+ <PlayCircle className="h-10 w-10" aria-hidden />
31
+ <p className="text-foreground text-sm font-medium">
32
+ {parsed ? `${EMBED_PROVIDER_LABEL[parsed.provider]} video` : 'No valid video URL'}
33
+ </p>
34
+ {title && <p className="text-muted-foreground px-4 text-center text-xs">{title}</p>}
35
+ </div>
36
+ {caption && (
37
+ <figcaption className="text-muted-foreground mt-2 text-center text-sm">
38
+ {caption}
39
+ </figcaption>
40
+ )}
41
+ </figure>
42
+ )
43
+ }
@@ -14,12 +14,14 @@ export function FeatureHighlightSection({ section }: { section: PageSection }) {
14
14
  const text = (
15
15
  <div className="flex-1">
16
16
  {label && (
17
- <span className="mb-3 inline-block rounded bg-violet-600 px-2 py-0.5 text-xs font-medium text-white">
17
+ <span className="bg-brand mb-3 inline-block rounded px-2 py-0.5 text-xs font-medium text-white">
18
18
  {label}
19
19
  </span>
20
20
  )}
21
- <h2 className="text-2xl font-semibold tracking-tight text-zinc-900 sm:text-3xl">{heading}</h2>
22
- {body && <p className="mt-4 text-base leading-relaxed text-zinc-600">{body}</p>}
21
+ <h2 className="text-foreground text-2xl font-semibold tracking-tight sm:text-3xl">
22
+ {heading}
23
+ </h2>
24
+ {body && <p className="text-muted-foreground mt-4 text-base leading-relaxed">{body}</p>}
23
25
  <div className="mt-6">
24
26
  <PreviewButton label={str(c, 'buttonLabel')} href={str(c, 'buttonUrl')} tone="primary" />
25
27
  </div>
@@ -36,8 +38,8 @@ export function FeatureHighlightSection({ section }: { section: PageSection }) {
36
38
  className="aspect-[4/3] w-full rounded-xl object-cover"
37
39
  />
38
40
  ) : (
39
- <div className="flex aspect-[4/3] w-full items-center justify-center rounded-xl bg-violet-50">
40
- <ImageIcon className="h-10 w-10 text-violet-300" aria-hidden />
41
+ <div className="bg-brand/10 flex aspect-[4/3] w-full items-center justify-center rounded-xl">
42
+ <ImageIcon className="text-brand h-10 w-10" aria-hidden />
41
43
  </div>
42
44
  )}
43
45
  </div>
@@ -25,19 +25,21 @@ export function GallerySection({ section }: { section: PageSection }) {
25
25
  return (
26
26
  <div className="mx-auto max-w-5xl px-6">
27
27
  {heading && (
28
- <h2 className="mb-6 text-2xl font-semibold tracking-tight text-zinc-900">{heading}</h2>
28
+ <h2 className="text-foreground mb-6 text-2xl font-semibold tracking-tight">{heading}</h2>
29
29
  )}
30
30
  {withUrl.length > 0 ? (
31
31
  <div className={`grid grid-cols-1 gap-3 ${cols}`}>
32
32
  {withUrl.map((img, i) => (
33
- <figure key={i} className="overflow-hidden rounded-lg border border-zinc-200">
33
+ <figure key={i} className="border-border overflow-hidden rounded-lg border">
34
34
  <img
35
35
  src={img.url}
36
36
  alt={img.alt ?? ''}
37
37
  className="aspect-square w-full object-cover"
38
38
  />
39
39
  {img.caption && (
40
- <figcaption className="px-2 py-1.5 text-xs text-zinc-500">{img.caption}</figcaption>
40
+ <figcaption className="text-muted-foreground px-2 py-1.5 text-xs">
41
+ {img.caption}
42
+ </figcaption>
41
43
  )}
42
44
  </figure>
43
45
  ))}
@@ -45,7 +47,7 @@ export function GallerySection({ section }: { section: PageSection }) {
45
47
  ) : (
46
48
  <div className={`grid grid-cols-1 gap-3 ${cols}`}>
47
49
  {Array.from({ length: columns }, (_, i) => (
48
- <div key={i} className="aspect-square rounded-lg bg-zinc-100" aria-hidden />
50
+ <div key={i} className="bg-muted aspect-square rounded-lg" aria-hidden />
49
51
  ))}
50
52
  </div>
51
53
  )}
@@ -12,7 +12,7 @@ export function HeroBannerSection({ section }: { section: PageSection }) {
12
12
  <div className="mx-auto max-w-3xl px-6 text-center">
13
13
  {eyebrow && (
14
14
  <p
15
- className={`mb-3 text-sm font-medium tracking-wide uppercase ${dark ? 'text-violet-200' : 'text-violet-600'}`}
15
+ className={`mb-3 text-sm font-medium tracking-wide uppercase ${dark ? 'text-brand-foreground/80' : 'text-brand'}`}
16
16
  >
17
17
  {eyebrow}
18
18
  </p>
@@ -22,7 +22,7 @@ export function HeroBannerSection({ section }: { section: PageSection }) {
22
22
  </h1>
23
23
  {body && (
24
24
  <p
25
- className={`mx-auto mt-5 max-w-2xl text-base sm:text-lg ${dark ? 'text-violet-100' : 'text-zinc-600'}`}
25
+ className={`mx-auto mt-5 max-w-2xl text-base sm:text-lg ${dark ? 'text-brand-foreground/80' : 'text-muted-foreground'}`}
26
26
  >
27
27
  {body}
28
28
  </p>
@@ -12,11 +12,13 @@ export function MissionSection({ section }: { section: PageSection }) {
12
12
  return (
13
13
  <div className={`max-w-3xl px-6 ${align}`}>
14
14
  {heading && (
15
- <h2 className="text-2xl font-semibold tracking-tight text-zinc-900 sm:text-3xl">
15
+ <h2 className="text-foreground text-2xl font-semibold tracking-tight sm:text-3xl">
16
16
  {heading}
17
17
  </h2>
18
18
  )}
19
- {body && <p className="mt-4 text-base leading-relaxed text-zinc-600 sm:text-lg">{body}</p>}
19
+ {body && (
20
+ <p className="text-muted-foreground mt-4 text-base leading-relaxed sm:text-lg">{body}</p>
21
+ )}
20
22
  </div>
21
23
  )
22
24
  }