@actuate-media/cms-admin 0.9.0 → 0.11.0

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 (294) hide show
  1. package/dist/AdminRoot.d.ts.map +1 -1
  2. package/dist/AdminRoot.js +8 -5
  3. package/dist/AdminRoot.js.map +1 -1
  4. package/dist/__tests__/layout/primitives.test.d.ts +2 -0
  5. package/dist/__tests__/layout/primitives.test.d.ts.map +1 -0
  6. package/dist/__tests__/layout/primitives.test.js +34 -0
  7. package/dist/__tests__/layout/primitives.test.js.map +1 -0
  8. package/dist/__tests__/lib/cv.test.d.ts +2 -0
  9. package/dist/__tests__/lib/cv.test.d.ts.map +1 -0
  10. package/dist/__tests__/lib/cv.test.js +66 -0
  11. package/dist/__tests__/lib/cv.test.js.map +1 -0
  12. package/dist/actuate-admin.css +1 -1
  13. package/dist/assets/actuate-logo.d.ts +36 -0
  14. package/dist/assets/actuate-logo.d.ts.map +1 -0
  15. package/dist/assets/actuate-logo.js +15 -0
  16. package/dist/assets/actuate-logo.js.map +1 -0
  17. package/dist/components/Breadcrumbs.js +2 -2
  18. package/dist/components/CommandPalette.js +10 -10
  19. package/dist/components/ContentOverviewChart.js +3 -3
  20. package/dist/components/ErrorBoundary.js +1 -1
  21. package/dist/components/FocalPointPicker.js +2 -2
  22. package/dist/components/FolderTree.js +20 -20
  23. package/dist/components/LivePreview.js +3 -3
  24. package/dist/components/LocaleSwitcher.js +1 -1
  25. package/dist/components/MediaPickerModal.js +4 -4
  26. package/dist/components/PresenceIndicator.js +1 -1
  27. package/dist/components/SEOConfigPanel.d.ts +2 -0
  28. package/dist/components/SEOConfigPanel.d.ts.map +1 -0
  29. package/dist/components/SEOConfigPanel.js +174 -0
  30. package/dist/components/SEOConfigPanel.js.map +1 -0
  31. package/dist/components/SEOPanel.js +9 -9
  32. package/dist/components/SEOPerformance.js +2 -2
  33. package/dist/components/SchedulePublishDialog.d.ts +18 -0
  34. package/dist/components/SchedulePublishDialog.d.ts.map +1 -0
  35. package/dist/components/SchedulePublishDialog.js +106 -0
  36. package/dist/components/SchedulePublishDialog.js.map +1 -0
  37. package/dist/components/SharePreviewLinkDialog.d.ts +17 -0
  38. package/dist/components/SharePreviewLinkDialog.d.ts.map +1 -0
  39. package/dist/components/SharePreviewLinkDialog.js +83 -0
  40. package/dist/components/SharePreviewLinkDialog.js.map +1 -0
  41. package/dist/components/TipTapEditor.js +5 -5
  42. package/dist/components/VersionHistory.js +2 -2
  43. package/dist/components/ui/Badge.d.ts +33 -3
  44. package/dist/components/ui/Badge.d.ts.map +1 -1
  45. package/dist/components/ui/Badge.js +42 -8
  46. package/dist/components/ui/Badge.js.map +1 -1
  47. package/dist/components/ui/Button.d.ts +19 -8
  48. package/dist/components/ui/Button.d.ts.map +1 -1
  49. package/dist/components/ui/Button.js +35 -14
  50. package/dist/components/ui/Button.js.map +1 -1
  51. package/dist/components/ui/Card.d.ts +26 -0
  52. package/dist/components/ui/Card.d.ts.map +1 -0
  53. package/dist/components/ui/Card.js +45 -0
  54. package/dist/components/ui/Card.js.map +1 -0
  55. package/dist/components/ui/DataTable.js +1 -1
  56. package/dist/components/ui/Input.d.ts +15 -0
  57. package/dist/components/ui/Input.d.ts.map +1 -0
  58. package/dist/components/ui/Input.js +23 -0
  59. package/dist/components/ui/Input.js.map +1 -0
  60. package/dist/components/ui/SearchInput.js +1 -1
  61. package/dist/components/ui/Select.d.ts +16 -0
  62. package/dist/components/ui/Select.d.ts.map +1 -0
  63. package/dist/components/ui/Select.js +25 -0
  64. package/dist/components/ui/Select.js.map +1 -0
  65. package/dist/components/ui/Toast.js +1 -1
  66. package/dist/components/ui/index.d.ts +10 -4
  67. package/dist/components/ui/index.d.ts.map +1 -1
  68. package/dist/components/ui/index.js +5 -2
  69. package/dist/components/ui/index.js.map +1 -1
  70. package/dist/fields/BlockBuilderField.js +3 -3
  71. package/dist/fields/DateField.js +1 -1
  72. package/dist/fields/RelationshipField.js +3 -3
  73. package/dist/fields/TextField.js +1 -1
  74. package/dist/index.d.ts +6 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +5 -0
  77. package/dist/index.js.map +1 -1
  78. package/dist/layout/Header.js +1 -1
  79. package/dist/layout/Layout.d.ts +14 -0
  80. package/dist/layout/Layout.d.ts.map +1 -1
  81. package/dist/layout/Layout.js +17 -11
  82. package/dist/layout/Layout.js.map +1 -1
  83. package/dist/layout/Sidebar.d.ts.map +1 -1
  84. package/dist/layout/Sidebar.js +21 -11
  85. package/dist/layout/Sidebar.js.map +1 -1
  86. package/dist/layout/primitives/AdminShell.d.ts +43 -0
  87. package/dist/layout/primitives/AdminShell.d.ts.map +1 -0
  88. package/dist/layout/primitives/AdminShell.js +51 -0
  89. package/dist/layout/primitives/AdminShell.js.map +1 -0
  90. package/dist/layout/primitives/Box.d.ts +19 -0
  91. package/dist/layout/primitives/Box.d.ts.map +1 -0
  92. package/dist/layout/primitives/Box.js +12 -0
  93. package/dist/layout/primitives/Box.js.map +1 -0
  94. package/dist/layout/primitives/Cluster.d.ts +27 -0
  95. package/dist/layout/primitives/Cluster.d.ts.map +1 -0
  96. package/dist/layout/primitives/Cluster.js +37 -0
  97. package/dist/layout/primitives/Cluster.js.map +1 -0
  98. package/dist/layout/primitives/Grid.d.ts +45 -0
  99. package/dist/layout/primitives/Grid.d.ts.map +1 -0
  100. package/dist/layout/primitives/Grid.js +59 -0
  101. package/dist/layout/primitives/Grid.js.map +1 -0
  102. package/dist/layout/primitives/PageContainer.d.ts +36 -0
  103. package/dist/layout/primitives/PageContainer.d.ts.map +1 -0
  104. package/dist/layout/primitives/PageContainer.js +41 -0
  105. package/dist/layout/primitives/PageContainer.js.map +1 -0
  106. package/dist/layout/primitives/Split.d.ts +34 -0
  107. package/dist/layout/primitives/Split.d.ts.map +1 -0
  108. package/dist/layout/primitives/Split.js +27 -0
  109. package/dist/layout/primitives/Split.js.map +1 -0
  110. package/dist/layout/primitives/Stack.d.ts +23 -0
  111. package/dist/layout/primitives/Stack.d.ts.map +1 -0
  112. package/dist/layout/primitives/Stack.js +34 -0
  113. package/dist/layout/primitives/Stack.js.map +1 -0
  114. package/dist/layout/primitives/index.d.ts +30 -0
  115. package/dist/layout/primitives/index.d.ts.map +1 -0
  116. package/dist/layout/primitives/index.js +22 -0
  117. package/dist/layout/primitives/index.js.map +1 -0
  118. package/dist/layout/primitives/tokens.d.ts +48 -0
  119. package/dist/layout/primitives/tokens.d.ts.map +1 -0
  120. package/dist/layout/primitives/tokens.js +54 -0
  121. package/dist/layout/primitives/tokens.js.map +1 -0
  122. package/dist/lib/cv.d.ts +53 -0
  123. package/dist/lib/cv.d.ts.map +1 -0
  124. package/dist/lib/cv.js +39 -0
  125. package/dist/lib/cv.js.map +1 -0
  126. package/dist/views/ApiKeys.d.ts.map +1 -1
  127. package/dist/views/ApiKeys.js +13 -11
  128. package/dist/views/ApiKeys.js.map +1 -1
  129. package/dist/views/CollectionList.js +8 -8
  130. package/dist/views/Dashboard.d.ts.map +1 -1
  131. package/dist/views/Dashboard.js +333 -78
  132. package/dist/views/Dashboard.js.map +1 -1
  133. package/dist/views/DocumentEdit.d.ts.map +1 -1
  134. package/dist/views/DocumentEdit.js +17 -5
  135. package/dist/views/DocumentEdit.js.map +1 -1
  136. package/dist/views/ForgotPassword.js +2 -2
  137. package/dist/views/FormEditor.js +5 -5
  138. package/dist/views/FormSubmissions.js +6 -6
  139. package/dist/views/Forms.js +2 -2
  140. package/dist/views/Login.d.ts +16 -1
  141. package/dist/views/Login.d.ts.map +1 -1
  142. package/dist/views/Login.js +17 -7
  143. package/dist/views/Login.js.map +1 -1
  144. package/dist/views/MediaBrowser.js +16 -16
  145. package/dist/views/PageEditor.js +2 -2
  146. package/dist/views/Pages.js +10 -10
  147. package/dist/views/PostEditor.js +2 -2
  148. package/dist/views/Posts.js +4 -4
  149. package/dist/views/Redirects.js +4 -4
  150. package/dist/views/ResetPassword.js +2 -2
  151. package/dist/views/SEO.js +6 -6
  152. package/dist/views/ScriptTagEditor.js +4 -4
  153. package/dist/views/ScriptTags.js +2 -2
  154. package/dist/views/Settings.d.ts.map +1 -1
  155. package/dist/views/Settings.js +9 -8
  156. package/dist/views/Settings.js.map +1 -1
  157. package/dist/views/SetupWizard.js +2 -2
  158. package/dist/views/Users.js +4 -4
  159. package/dist/views/page-builder/AIBlockAssist.js +1 -1
  160. package/dist/views/page-builder/AIGenerateDialog.js +10 -10
  161. package/dist/views/page-builder/BlockEditor.js +10 -10
  162. package/dist/views/page-builder/BlockPicker.js +4 -4
  163. package/dist/views/page-builder/BottomBar.js +1 -1
  164. package/dist/views/page-builder/BuilderToolbar.js +2 -2
  165. package/dist/views/page-builder/ContextPanel.js +2 -2
  166. package/dist/views/page-builder/DesignScore.js +9 -9
  167. package/dist/views/page-builder/NodeSettings.js +8 -8
  168. package/dist/views/page-builder/PageBuilder.js +3 -3
  169. package/dist/views/page-builder/PageSettings.js +1 -1
  170. package/dist/views/page-builder/PageTemplates.js +2 -2
  171. package/dist/views/page-builder/SEOPanel.js +13 -13
  172. package/dist/views/page-builder/SavedSections.js +5 -5
  173. package/dist/views/page-builder/TemplatePicker.js +2 -2
  174. package/dist/views/page-builder/block-renderers/CTAPreview.js +5 -5
  175. package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
  176. package/dist/views/page-builder/block-renderers/CodePreview.js +1 -1
  177. package/dist/views/page-builder/block-renderers/FAQPreview.js +3 -3
  178. package/dist/views/page-builder/block-renderers/FallbackPreview.js +1 -1
  179. package/dist/views/page-builder/block-renderers/FormPreview.js +3 -3
  180. package/dist/views/page-builder/block-renderers/GalleryPreview.js +5 -5
  181. package/dist/views/page-builder/block-renderers/HeroPreview.js +3 -3
  182. package/dist/views/page-builder/block-renderers/ImagePreview.js +3 -3
  183. package/dist/views/page-builder/block-renderers/TextPreview.js +3 -3
  184. package/dist/views/page-builder/block-renderers/VideoPreview.js +4 -4
  185. package/dist/views/page-builder/canvas/BlockRenderer.js +1 -1
  186. package/dist/views/page-builder/canvas/BuilderCanvas.js +3 -3
  187. package/dist/views/page-builder/canvas/ColumnRenderer.js +2 -2
  188. package/dist/views/page-builder/canvas/ContainerRenderer.js +2 -2
  189. package/dist/views/page-builder/canvas/RowRenderer.js +2 -2
  190. package/dist/views/page-builder/canvas/SectionRenderer.js +2 -2
  191. package/package.json +6 -2
  192. package/src/AdminRoot.tsx +21 -11
  193. package/src/__tests__/layout/primitives.test.ts +37 -0
  194. package/src/__tests__/lib/cv.test.ts +74 -0
  195. package/src/assets/actuate-logo.tsx +72 -0
  196. package/src/components/Breadcrumbs.tsx +6 -6
  197. package/src/components/CommandPalette.tsx +34 -34
  198. package/src/components/ContentOverviewChart.tsx +3 -3
  199. package/src/components/ErrorBoundary.tsx +3 -3
  200. package/src/components/FocalPointPicker.tsx +4 -4
  201. package/src/components/FolderTree.tsx +38 -38
  202. package/src/components/LivePreview.tsx +16 -16
  203. package/src/components/LocaleSwitcher.tsx +7 -7
  204. package/src/components/MediaPickerModal.tsx +21 -21
  205. package/src/components/PresenceIndicator.tsx +2 -2
  206. package/src/components/SEOConfigPanel.tsx +582 -0
  207. package/src/components/SEOPanel.tsx +46 -46
  208. package/src/components/SEOPerformance.tsx +21 -21
  209. package/src/components/SchedulePublishDialog.tsx +241 -0
  210. package/src/components/SharePreviewLinkDialog.tsx +227 -0
  211. package/src/components/TipTapEditor.tsx +33 -33
  212. package/src/components/VersionHistory.tsx +16 -16
  213. package/src/components/ui/Badge.tsx +66 -14
  214. package/src/components/ui/Button.tsx +70 -33
  215. package/src/components/ui/Card.tsx +101 -0
  216. package/src/components/ui/DataTable.tsx +1 -1
  217. package/src/components/ui/Input.tsx +35 -0
  218. package/src/components/ui/SearchInput.tsx +4 -4
  219. package/src/components/ui/Select.tsx +56 -0
  220. package/src/components/ui/Toast.tsx +1 -1
  221. package/src/components/ui/index.ts +18 -4
  222. package/src/fields/BlockBuilderField.tsx +3 -3
  223. package/src/fields/DateField.tsx +1 -1
  224. package/src/fields/RelationshipField.tsx +10 -10
  225. package/src/fields/TextField.tsx +1 -1
  226. package/src/index.ts +32 -0
  227. package/src/layout/Header.tsx +28 -28
  228. package/src/layout/Layout.tsx +39 -46
  229. package/src/layout/Sidebar.tsx +37 -64
  230. package/src/layout/primitives/AdminShell.tsx +118 -0
  231. package/src/layout/primitives/Box.tsx +30 -0
  232. package/src/layout/primitives/Cluster.tsx +74 -0
  233. package/src/layout/primitives/Grid.tsx +120 -0
  234. package/src/layout/primitives/PageContainer.tsx +96 -0
  235. package/src/layout/primitives/Split.tsx +73 -0
  236. package/src/layout/primitives/Stack.tsx +67 -0
  237. package/src/layout/primitives/index.ts +36 -0
  238. package/src/layout/primitives/tokens.ts +76 -0
  239. package/src/lib/cv.ts +96 -0
  240. package/src/styles/build-input.css +1 -1
  241. package/src/views/ApiKeys.tsx +57 -57
  242. package/src/views/CollectionList.tsx +30 -30
  243. package/src/views/Dashboard.tsx +737 -186
  244. package/src/views/DocumentEdit.tsx +90 -10
  245. package/src/views/ForgotPassword.tsx +18 -18
  246. package/src/views/FormEditor.tsx +75 -75
  247. package/src/views/FormSubmissions.tsx +76 -76
  248. package/src/views/Forms.tsx +27 -27
  249. package/src/views/Login.tsx +65 -25
  250. package/src/views/MediaBrowser.tsx +127 -127
  251. package/src/views/PageEditor.tsx +25 -25
  252. package/src/views/Pages.tsx +59 -59
  253. package/src/views/PostEditor.tsx +37 -37
  254. package/src/views/Posts.tsx +48 -48
  255. package/src/views/Redirects.tsx +21 -21
  256. package/src/views/ResetPassword.tsx +28 -28
  257. package/src/views/SEO.tsx +144 -144
  258. package/src/views/ScriptTagEditor.tsx +24 -24
  259. package/src/views/ScriptTags.tsx +10 -10
  260. package/src/views/Settings.tsx +88 -80
  261. package/src/views/SetupWizard.tsx +28 -28
  262. package/src/views/Users.tsx +20 -20
  263. package/src/views/page-builder/AIBlockAssist.tsx +1 -1
  264. package/src/views/page-builder/AIGenerateDialog.tsx +63 -63
  265. package/src/views/page-builder/BlockEditor.tsx +26 -26
  266. package/src/views/page-builder/BlockPicker.tsx +22 -22
  267. package/src/views/page-builder/BottomBar.tsx +8 -8
  268. package/src/views/page-builder/BuilderToolbar.tsx +17 -17
  269. package/src/views/page-builder/ContextPanel.tsx +3 -3
  270. package/src/views/page-builder/DesignScore.tsx +21 -21
  271. package/src/views/page-builder/NodeSettings.tsx +27 -27
  272. package/src/views/page-builder/PageBuilder.tsx +11 -11
  273. package/src/views/page-builder/PageSettings.tsx +4 -4
  274. package/src/views/page-builder/PageTemplates.tsx +18 -18
  275. package/src/views/page-builder/SEOPanel.tsx +53 -53
  276. package/src/views/page-builder/SavedSections.tsx +37 -37
  277. package/src/views/page-builder/TemplatePicker.tsx +17 -17
  278. package/src/views/page-builder/block-renderers/CTAPreview.tsx +13 -13
  279. package/src/views/page-builder/block-renderers/CardsPreview.tsx +5 -5
  280. package/src/views/page-builder/block-renderers/CodePreview.tsx +6 -6
  281. package/src/views/page-builder/block-renderers/FAQPreview.tsx +13 -13
  282. package/src/views/page-builder/block-renderers/FallbackPreview.tsx +3 -3
  283. package/src/views/page-builder/block-renderers/FormPreview.tsx +20 -20
  284. package/src/views/page-builder/block-renderers/GalleryPreview.tsx +8 -8
  285. package/src/views/page-builder/block-renderers/HeroPreview.tsx +16 -16
  286. package/src/views/page-builder/block-renderers/ImagePreview.tsx +4 -4
  287. package/src/views/page-builder/block-renderers/TextPreview.tsx +14 -14
  288. package/src/views/page-builder/block-renderers/VideoPreview.tsx +12 -12
  289. package/src/views/page-builder/canvas/BlockRenderer.tsx +4 -4
  290. package/src/views/page-builder/canvas/BuilderCanvas.tsx +6 -6
  291. package/src/views/page-builder/canvas/ColumnRenderer.tsx +3 -3
  292. package/src/views/page-builder/canvas/ContainerRenderer.tsx +2 -2
  293. package/src/views/page-builder/canvas/RowRenderer.tsx +2 -2
  294. package/src/views/page-builder/canvas/SectionRenderer.tsx +2 -2
@@ -27,6 +27,7 @@ import { useApiData } from '../lib/useApiData.js'
27
27
  import { cmsApi } from '../lib/api.js'
28
28
  import { useTheme } from '../components/ThemeProvider.js'
29
29
  import { RelationshipField } from '../fields/RelationshipField.js'
30
+ import { SEOConfigPanel } from '../components/SEOConfigPanel.js'
30
31
 
31
32
  export interface SettingsProps {
32
33
  onNavigate?: (path: string) => void
@@ -149,8 +150,8 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
149
150
 
150
151
  if (loading) {
151
152
  return (
152
- <div className="p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64">
153
- <Loader2 className="w-6 h-6 animate-spin text-blue-600" />
153
+ <div className="flex h-64 items-center justify-center p-3 pr-6 sm:p-4 sm:pr-8">
154
+ <Loader2 className="h-6 w-6 animate-spin text-blue-600" />
154
155
  </div>
155
156
  )
156
157
  }
@@ -159,11 +160,11 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
159
160
  <div className="p-3 pr-6 sm:p-4 sm:pr-8">
160
161
  {error && (
161
162
  <div className="mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
162
- <AlertTriangle className="w-5 h-5 text-red-600 shrink-0" />
163
- <span className="text-sm text-red-800 flex-1">{error}</span>
163
+ <AlertTriangle className="h-5 w-5 shrink-0 text-red-600" />
164
+ <span className="flex-1 text-sm text-red-800">{error}</span>
164
165
  <button
165
166
  onClick={refetch}
166
- className="px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors"
167
+ className="rounded-lg border border-red-300 px-3 py-1 text-sm text-red-700 transition-colors hover:bg-red-100"
167
168
  >
168
169
  Retry
169
170
  </button>
@@ -176,7 +177,7 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
176
177
  </div>
177
178
 
178
179
  <Tabs.Root value={activeTab} onValueChange={setActiveTab}>
179
- <Tabs.List className="mb-4 flex gap-1 border-b border-gray-200 overflow-x-auto">
180
+ <Tabs.List className="mb-4 flex gap-1 overflow-x-auto border-b border-gray-200">
180
181
  <Tabs.Trigger value="general" className={tabTriggerClass}>
181
182
  General
182
183
  </Tabs.Trigger>
@@ -186,7 +187,7 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
186
187
  {hasLayoutRegions && (
187
188
  <Tabs.Trigger value="layout" className={tabTriggerClass}>
188
189
  <span className="flex items-center gap-1.5">
189
- <Layers className="w-4 h-4" />
190
+ <Layers className="h-4 w-4" />
190
191
  Layout
191
192
  </span>
192
193
  </Tabs.Trigger>
@@ -194,9 +195,12 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
194
195
  <Tabs.Trigger value="security" className={tabTriggerClass}>
195
196
  Security
196
197
  </Tabs.Trigger>
198
+ <Tabs.Trigger value="seo" className={tabTriggerClass}>
199
+ SEO
200
+ </Tabs.Trigger>
197
201
  <Tabs.Trigger value="ai" className={tabTriggerClass}>
198
202
  <span className="flex items-center gap-1.5">
199
- <Bot className="w-4 h-4" />
203
+ <Bot className="h-4 w-4" />
200
204
  AI
201
205
  </span>
202
206
  </Tabs.Trigger>
@@ -205,7 +209,7 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
205
209
  </Tabs.Trigger>
206
210
  <Tabs.Trigger value="updates" className={tabTriggerClass}>
207
211
  <span className="flex items-center gap-1.5">
208
- <Download className="w-4 h-4" />
212
+ <Download className="h-4 w-4" />
209
213
  Updates
210
214
  </span>
211
215
  </Tabs.Trigger>
@@ -221,7 +225,7 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
221
225
  type="text"
222
226
  value={siteTitle}
223
227
  onChange={(e) => setSiteTitle(e.target.value)}
224
- className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
228
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
225
229
  />
226
230
  </div>
227
231
  <div>
@@ -230,7 +234,7 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
230
234
  type="text"
231
235
  value={tagline}
232
236
  onChange={(e) => setTagline(e.target.value)}
233
- className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
237
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
234
238
  />
235
239
  </div>
236
240
  <div>
@@ -239,7 +243,7 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
239
243
  type="url"
240
244
  value={siteUrl}
241
245
  onChange={(e) => setSiteUrl(e.target.value)}
242
- className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
246
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
243
247
  />
244
248
  </div>
245
249
  </div>
@@ -252,7 +256,7 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
252
256
  <select
253
257
  value={language}
254
258
  onChange={(e) => setLanguage(e.target.value)}
255
- className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
259
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
256
260
  >
257
261
  <option value="en">English</option>
258
262
  <option value="es">Spanish</option>
@@ -265,7 +269,7 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
265
269
  <select
266
270
  value={timezone}
267
271
  onChange={(e) => setTimezone(e.target.value)}
268
- className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
272
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
269
273
  >
270
274
  <option value="UTC">UTC</option>
271
275
  <option value="America/New_York">Eastern Time</option>
@@ -276,9 +280,9 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
276
280
  </div>
277
281
  </div>
278
282
  </div>
279
- <div className="rounded-lg border border-border bg-card p-4">
280
- <h3 className="mb-1 text-sm font-medium text-foreground">SEO & Robots Defaults</h3>
281
- <p className="mb-4 text-xs text-muted-foreground">
283
+ <div className="border-border bg-card rounded-lg border p-4">
284
+ <h3 className="text-foreground mb-1 text-sm font-medium">SEO & Robots Defaults</h3>
285
+ <p className="text-muted-foreground mb-4 text-xs">
282
286
  Set the site-wide default for search engine indexing. Individual pages can inherit or
283
287
  override these rules in their SEO panel.
284
288
  </p>
@@ -359,12 +363,12 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
359
363
  </div>
360
364
  </div>
361
365
  <div className="rounded-lg border border-gray-200 bg-gray-50 p-4">
362
- <h3 className="text-sm font-semibold text-gray-700 mb-2">
366
+ <h3 className="mb-2 text-sm font-semibold text-gray-700">
363
367
  How Layout Inheritance Works
364
368
  </h3>
365
369
  <ul className="space-y-1.5 text-xs text-gray-600">
366
370
  <li className="flex items-start gap-2">
367
- <span className="w-4 h-4 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center text-[10px] font-bold shrink-0 mt-0.5">
371
+ <span className="mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-blue-100 text-[10px] font-bold text-blue-600">
368
372
  1
369
373
  </span>
370
374
  <span>
@@ -373,20 +377,20 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
373
377
  </span>
374
378
  </li>
375
379
  <li className="flex items-start gap-2">
376
- <span className="w-4 h-4 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center text-[10px] font-bold shrink-0 mt-0.5">
380
+ <span className="mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-blue-100 text-[10px] font-bold text-blue-600">
377
381
  2
378
382
  </span>
379
383
  <span>
380
384
  Child pages automatically inherit their parent&apos;s layout. For example,{' '}
381
- <code className="font-mono bg-gray-200 px-1 rounded">
385
+ <code className="rounded bg-gray-200 px-1 font-mono">
382
386
  /hampton-roads/thank-you
383
387
  </code>{' '}
384
388
  inherits from{' '}
385
- <code className="font-mono bg-gray-200 px-1 rounded">/hampton-roads</code>.
389
+ <code className="rounded bg-gray-200 px-1 font-mono">/hampton-roads</code>.
386
390
  </span>
387
391
  </li>
388
392
  <li className="flex items-start gap-2">
389
- <span className="w-4 h-4 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center text-[10px] font-bold shrink-0 mt-0.5">
393
+ <span className="mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-blue-100 text-[10px] font-bold text-blue-600">
390
394
  3
391
395
  </span>
392
396
  <span>
@@ -425,6 +429,10 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
425
429
  </div>
426
430
  </Tabs.Content>
427
431
 
432
+ <Tabs.Content value="seo" className="space-y-4">
433
+ <SEOConfigPanel />
434
+ </Tabs.Content>
435
+
428
436
  <Tabs.Content value="ai" className="space-y-4">
429
437
  <div className="rounded-lg border border-gray-200 bg-white p-4">
430
438
  <h3 className="mb-1 text-sm font-semibold text-gray-900">AI Provider & API Key</h3>
@@ -437,7 +445,7 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
437
445
  <select
438
446
  value={aiProvider}
439
447
  onChange={(e) => setAiProvider(e.target.value)}
440
- className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
448
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
441
449
  >
442
450
  <option value="anthropic">Anthropic (Claude)</option>
443
451
  <option value="openai">OpenAI (GPT)</option>
@@ -467,14 +475,14 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
467
475
  ? 'sk-...'
468
476
  : 'AIza...'
469
477
  }
470
- className="w-full rounded-lg border border-gray-300 px-3 py-2 pr-10 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
478
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 pr-10 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
471
479
  />
472
480
  <button
473
481
  type="button"
474
482
  onClick={() => setShowApiKey(!showApiKey)}
475
- className="absolute right-2 top-1/2 -translate-y-1/2 p-1 text-gray-400 hover:text-gray-600"
483
+ className="absolute top-1/2 right-2 -translate-y-1/2 p-1 text-gray-400 hover:text-gray-600"
476
484
  >
477
- {showApiKey ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
485
+ {showApiKey ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
478
486
  </button>
479
487
  </div>
480
488
  <button
@@ -496,8 +504,8 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
496
504
  </div>
497
505
 
498
506
  <div className="rounded-lg border border-gray-200 bg-white p-4">
499
- <div className="flex items-center gap-2 mb-1">
500
- <Image className="w-4 h-4 text-blue-600" />
507
+ <div className="mb-1 flex items-center gap-2">
508
+ <Image className="h-4 w-4 text-blue-600" />
501
509
  <h3 className="text-sm font-semibold text-gray-900">Media Intelligence</h3>
502
510
  </div>
503
511
  <p className="mb-4 text-xs text-gray-500">AI-powered image and media analysis</p>
@@ -518,8 +526,8 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
518
526
  </div>
519
527
 
520
528
  <div className="rounded-lg border border-gray-200 bg-white p-4">
521
- <div className="flex items-center gap-2 mb-1">
522
- <FileCode2 className="w-4 h-4 text-purple-600" />
529
+ <div className="mb-1 flex items-center gap-2">
530
+ <FileCode2 className="h-4 w-4 text-purple-600" />
523
531
  <h3 className="text-sm font-semibold text-gray-900">Content SEO</h3>
524
532
  </div>
525
533
  <p className="mb-4 text-xs text-gray-500">
@@ -548,8 +556,8 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
548
556
  </div>
549
557
 
550
558
  <div className="rounded-lg border border-gray-200 bg-white p-4">
551
- <div className="flex items-center gap-2 mb-1">
552
- <MessageSquare className="w-4 h-4 text-green-600" />
559
+ <div className="mb-1 flex items-center gap-2">
560
+ <MessageSquare className="h-4 w-4 text-green-600" />
553
561
  <h3 className="text-sm font-semibold text-gray-900">Brand Voice & Writing</h3>
554
562
  </div>
555
563
  <p className="mb-4 text-xs text-gray-500">
@@ -572,8 +580,8 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
572
580
  </div>
573
581
 
574
582
  <div className="rounded-lg border border-gray-200 bg-white p-4">
575
- <div className="flex items-center gap-2 mb-1">
576
- <Sparkles className="w-4 h-4 text-yellow-600" />
583
+ <div className="mb-1 flex items-center gap-2">
584
+ <Sparkles className="h-4 w-4 text-yellow-600" />
577
585
  <h3 className="text-sm font-semibold text-gray-900">Content Quality</h3>
578
586
  </div>
579
587
  <p className="mb-4 text-xs text-gray-500">
@@ -596,11 +604,11 @@ export function Settings({ config, ..._props }: SettingsProps = {}) {
596
604
  </div>
597
605
 
598
606
  <div className="rounded-lg border border-indigo-200 bg-indigo-50 p-4">
599
- <div className="flex items-center gap-2 mb-1">
600
- <BookOpen className="w-4 h-4 text-indigo-600" />
607
+ <div className="mb-1 flex items-center gap-2">
608
+ <BookOpen className="h-4 w-4 text-indigo-600" />
601
609
  <h3 className="text-sm font-semibold text-indigo-900">AI Usage This Month</h3>
602
610
  </div>
603
- <div className="grid grid-cols-3 gap-4 mt-3">
611
+ <div className="mt-3 grid grid-cols-3 gap-4">
604
612
  <div>
605
613
  <div className="text-lg font-semibold text-indigo-900">0</div>
606
614
  <div className="text-xs text-indigo-700">API Calls</div>
@@ -670,7 +678,7 @@ function ThemeSelect() {
670
678
  <select
671
679
  value={theme}
672
680
  onChange={(e) => setTheme(e.target.value as 'light' | 'dark' | 'system')}
673
- className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
681
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
674
682
  >
675
683
  <option value="light">Light</option>
676
684
  <option value="dark">Dark</option>
@@ -693,8 +701,8 @@ function ToggleSetting({
693
701
  return (
694
702
  <div className="flex items-center justify-between gap-4">
695
703
  <div className="flex-1">
696
- <label className="text-sm font-medium text-foreground">{label}</label>
697
- <p className="mt-0.5 text-xs text-muted-foreground">{description}</p>
704
+ <label className="text-foreground text-sm font-medium">{label}</label>
705
+ <p className="text-muted-foreground mt-0.5 text-xs">{description}</p>
698
706
  </div>
699
707
  <button
700
708
  type="button"
@@ -702,7 +710,7 @@ function ToggleSetting({
702
710
  aria-checked={checked}
703
711
  aria-label={label}
704
712
  onClick={() => onChange(!checked)}
705
- className={`relative h-6 w-11 shrink-0 rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-primary ${checked ? 'bg-primary' : 'bg-muted'}`}
713
+ className={`focus:ring-primary relative h-6 w-11 shrink-0 rounded-full transition-colors focus:ring-2 focus:outline-none ${checked ? 'bg-primary' : 'bg-muted'}`}
706
714
  >
707
715
  <span
708
716
  className={`absolute top-0.5 block h-5 w-5 rounded-full bg-white transition-transform ${
@@ -853,7 +861,7 @@ function UpdatesPanel() {
853
861
  disabled={checking}
854
862
  className="flex items-center gap-2 rounded-lg border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 disabled:opacity-50"
855
863
  >
856
- <RefreshCw className={`w-4 h-4 ${checking ? 'animate-spin' : ''}`} />
864
+ <RefreshCw className={`h-4 w-4 ${checking ? 'animate-spin' : ''}`} />
857
865
  {checking ? 'Checking...' : 'Check for Updates'}
858
866
  </button>
859
867
  </div>
@@ -862,11 +870,11 @@ function UpdatesPanel() {
862
870
  {/* Error State */}
863
871
  {checkError && (
864
872
  <div className="flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
865
- <AlertTriangle className="w-5 h-5 text-red-600 shrink-0" />
866
- <span className="text-sm text-red-800 flex-1">{checkError}</span>
873
+ <AlertTriangle className="h-5 w-5 shrink-0 text-red-600" />
874
+ <span className="flex-1 text-sm text-red-800">{checkError}</span>
867
875
  <button
868
876
  onClick={checkForUpdates}
869
- className="px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors"
877
+ className="rounded-lg border border-red-300 px-3 py-1 text-sm text-red-700 transition-colors hover:bg-red-100"
870
878
  >
871
879
  Retry
872
880
  </button>
@@ -876,10 +884,10 @@ function UpdatesPanel() {
876
884
  {/* Up to Date */}
877
885
  {hasChecked && updateInfo && !updateInfo.updateAvailable && !checkError && (
878
886
  <div className="flex items-center gap-3 rounded-lg border border-green-200 bg-green-50 p-4">
879
- <CheckCircle2 className="w-6 h-6 text-green-600 shrink-0" />
887
+ <CheckCircle2 className="h-6 w-6 shrink-0 text-green-600" />
880
888
  <div>
881
889
  <h3 className="text-sm font-semibold text-green-900">You&apos;re up to date!</h3>
882
- <p className="text-sm text-green-700 mt-0.5">
890
+ <p className="mt-0.5 text-sm text-green-700">
883
891
  Actuate CMS <span className="font-mono">{updateInfo.current}</span> is the latest
884
892
  version.
885
893
  </p>
@@ -895,7 +903,7 @@ function UpdatesPanel() {
895
903
  >
896
904
  <div className="flex items-start gap-3">
897
905
  <ArrowUpCircle
898
- className={`w-6 h-6 mt-0.5 shrink-0 ${severityColors[updateInfo.severity ?? 'patch']?.text ?? 'text-blue-700'}`}
906
+ className={`mt-0.5 h-6 w-6 shrink-0 ${severityColors[updateInfo.severity ?? 'patch']?.text ?? 'text-blue-700'}`}
899
907
  />
900
908
  <div className="flex-1">
901
909
  <div className="flex items-center gap-2">
@@ -905,16 +913,16 @@ function UpdatesPanel() {
905
913
  Update Available
906
914
  </h3>
907
915
  <span
908
- className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${severityColors[updateInfo.severity ?? 'patch']?.bg ?? 'bg-blue-50'} ${severityColors[updateInfo.severity ?? 'patch']?.text ?? 'text-blue-700'} border ${severityColors[updateInfo.severity ?? 'patch']?.border ?? 'border-blue-200'}`}
916
+ className={`inline-flex items-center rounded px-2 py-0.5 text-xs font-medium ${severityColors[updateInfo.severity ?? 'patch']?.bg ?? 'bg-blue-50'} ${severityColors[updateInfo.severity ?? 'patch']?.text ?? 'text-blue-700'} border ${severityColors[updateInfo.severity ?? 'patch']?.border ?? 'border-blue-200'}`}
909
917
  >
910
918
  {severityColors[updateInfo.severity ?? 'patch']?.label ?? 'Update'}
911
919
  </span>
912
920
  </div>
913
- <p className="text-sm mt-1" style={{ color: 'inherit' }}>
921
+ <p className="mt-1 text-sm" style={{ color: 'inherit' }}>
914
922
  <span className="font-mono">{updateInfo.current}</span> &rarr;{' '}
915
923
  <span className="font-mono font-semibold">{updateInfo.latest}</span>
916
924
  {updateInfo.releaseDate && (
917
- <span className="text-xs ml-2 opacity-70">
925
+ <span className="ml-2 text-xs opacity-70">
918
926
  Released {updateInfo.releaseDate}
919
927
  </span>
920
928
  )}
@@ -931,12 +939,12 @@ function UpdatesPanel() {
931
939
  >
932
940
  {applying ? (
933
941
  <>
934
- <Loader2 className="w-4 h-4 animate-spin" />
942
+ <Loader2 className="h-4 w-4 animate-spin" />
935
943
  Creating PR...
936
944
  </>
937
945
  ) : (
938
946
  <>
939
- <GitPullRequest className="w-4 h-4" />
947
+ <GitPullRequest className="h-4 w-4" />
940
948
  Create Update PR
941
949
  </>
942
950
  )}
@@ -946,8 +954,8 @@ function UpdatesPanel() {
946
954
 
947
955
  {updateInfo.updateCommand && (
948
956
  <div className="mt-3 rounded border border-gray-200 bg-white p-3">
949
- <p className="text-xs text-gray-500 mb-1">Or update manually:</p>
950
- <code className="block text-xs font-mono text-gray-800 bg-gray-50 rounded px-2 py-1.5 select-all">
957
+ <p className="mb-1 text-xs text-gray-500">Or update manually:</p>
958
+ <code className="block rounded bg-gray-50 px-2 py-1.5 font-mono text-xs text-gray-800 select-all">
951
959
  {updateInfo.updateCommand}
952
960
  </code>
953
961
  </div>
@@ -957,14 +965,14 @@ function UpdatesPanel() {
957
965
  {/* Changelog */}
958
966
  {updateInfo.changelog && updateInfo.changelog.length > 0 && (
959
967
  <div className="rounded-lg border border-gray-200 bg-white p-4">
960
- <h3 className="text-sm font-semibold text-gray-900 mb-3">Changelog</h3>
961
- <div className="space-y-2 max-h-64 overflow-y-auto">
968
+ <h3 className="mb-3 text-sm font-semibold text-gray-900">Changelog</h3>
969
+ <div className="max-h-64 space-y-2 overflow-y-auto">
962
970
  {updateInfo.changelog.map((entry) => (
963
971
  <div key={entry.version} className="flex items-baseline gap-3 text-sm">
964
- <span className="font-mono text-xs text-gray-500 shrink-0 w-14">
972
+ <span className="w-14 shrink-0 font-mono text-xs text-gray-500">
965
973
  {entry.version}
966
974
  </span>
967
- <span className="text-xs text-gray-400 shrink-0 w-20">{entry.date}</span>
975
+ <span className="w-20 shrink-0 text-xs text-gray-400">{entry.date}</span>
968
976
  <span className="text-gray-700">{entry.summary}</span>
969
977
  </div>
970
978
  ))}
@@ -978,13 +986,13 @@ function UpdatesPanel() {
978
986
  {prResult && (
979
987
  <div className="rounded-lg border border-green-200 bg-green-50 p-4">
980
988
  <div className="flex items-start gap-3">
981
- <GitPullRequest className="w-5 h-5 text-green-600 mt-0.5 shrink-0" />
989
+ <GitPullRequest className="mt-0.5 h-5 w-5 shrink-0 text-green-600" />
982
990
  <div>
983
991
  <h3 className="text-sm font-semibold text-green-900">Pull Request Created</h3>
984
- <p className="text-sm text-green-700 mt-1">
992
+ <p className="mt-1 text-sm text-green-700">
985
993
  PR #{prResult.prNumber} has been created on your repository. Review and merge it to
986
994
  apply the update, then run{' '}
987
- <code className="text-xs font-mono bg-green-100 px-1 rounded">
995
+ <code className="rounded bg-green-100 px-1 font-mono text-xs">
988
996
  npx prisma migrate deploy
989
997
  </code>
990
998
  .
@@ -993,9 +1001,9 @@ function UpdatesPanel() {
993
1001
  href={prResult.prUrl}
994
1002
  target="_blank"
995
1003
  rel="noopener noreferrer"
996
- className="inline-flex items-center gap-1.5 mt-2 text-sm font-medium text-green-700 hover:text-green-800"
1004
+ className="mt-2 inline-flex items-center gap-1.5 text-sm font-medium text-green-700 hover:text-green-800"
997
1005
  >
998
- <ExternalLink className="w-4 h-4" />
1006
+ <ExternalLink className="h-4 w-4" />
999
1007
  View Pull Request
1000
1008
  </a>
1001
1009
  </div>
@@ -1005,8 +1013,8 @@ function UpdatesPanel() {
1005
1013
 
1006
1014
  {/* GitHub Configuration */}
1007
1015
  <div className="rounded-lg border border-gray-200 bg-white p-4">
1008
- <h3 className="text-sm font-semibold text-gray-900 mb-1">GitHub Integration</h3>
1009
- <p className="text-xs text-gray-500 mb-4">
1016
+ <h3 className="mb-1 text-sm font-semibold text-gray-900">GitHub Integration</h3>
1017
+ <p className="mb-4 text-xs text-gray-500">
1010
1018
  Connect your repository to enable one-click update PRs. Credentials are encrypted at rest
1011
1019
  (AES-256-GCM).
1012
1020
  </p>
@@ -1019,11 +1027,11 @@ function UpdatesPanel() {
1019
1027
  value={ghRepo}
1020
1028
  onChange={(e) => setGhRepo(e.target.value)}
1021
1029
  placeholder="owner/repo"
1022
- className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
1030
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
1023
1031
  />
1024
1032
  <p className="mt-1 text-xs text-gray-500">
1025
1033
  e.g.{' '}
1026
- <code className="font-mono bg-gray-100 px-1 rounded">
1034
+ <code className="rounded bg-gray-100 px-1 font-mono">
1027
1035
  actuate-media/my-client-site
1028
1036
  </code>
1029
1037
  </p>
@@ -1044,19 +1052,19 @@ function UpdatesPanel() {
1044
1052
  placeholder={
1045
1053
  updateInfo?.hasGithubToken ? '••••••••••••••••' : 'ghp_... or github_pat_...'
1046
1054
  }
1047
- className="w-full rounded-lg border border-gray-300 px-3 py-2 pr-10 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
1055
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 pr-10 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
1048
1056
  />
1049
1057
  <button
1050
1058
  type="button"
1051
1059
  onClick={() => setShowGhToken(!showGhToken)}
1052
- className="absolute right-2 top-1/2 -translate-y-1/2 p-1 text-gray-400 hover:text-gray-600"
1060
+ className="absolute top-1/2 right-2 -translate-y-1/2 p-1 text-gray-400 hover:text-gray-600"
1053
1061
  >
1054
- {showGhToken ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
1062
+ {showGhToken ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
1055
1063
  </button>
1056
1064
  </div>
1057
1065
  </div>
1058
1066
  <p className="mt-1 text-xs text-gray-500">
1059
- Needs <code className="font-mono bg-gray-100 px-1 rounded">repo</code> scope. Create
1067
+ Needs <code className="rounded bg-gray-100 px-1 font-mono">repo</code> scope. Create
1060
1068
  at{' '}
1061
1069
  <a
1062
1070
  href="https://github.com/settings/tokens"
@@ -1077,7 +1085,7 @@ function UpdatesPanel() {
1077
1085
  >
1078
1086
  {savingConfig ? (
1079
1087
  <>
1080
- <Loader2 className="w-4 h-4 animate-spin" />
1088
+ <Loader2 className="h-4 w-4 animate-spin" />
1081
1089
  Encrypting &amp; Saving...
1082
1090
  </>
1083
1091
  ) : (
@@ -1089,10 +1097,10 @@ function UpdatesPanel() {
1089
1097
 
1090
1098
  {/* Help Text */}
1091
1099
  <div className="rounded-lg border border-gray-200 bg-gray-50 p-4">
1092
- <h3 className="text-sm font-semibold text-gray-700 mb-2">How Updates Work</h3>
1100
+ <h3 className="mb-2 text-sm font-semibold text-gray-700">How Updates Work</h3>
1093
1101
  <ul className="space-y-1.5 text-xs text-gray-600">
1094
1102
  <li className="flex items-start gap-2">
1095
- <span className="w-4 h-4 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center text-[10px] font-bold shrink-0 mt-0.5">
1103
+ <span className="mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-blue-100 text-[10px] font-bold text-blue-600">
1096
1104
  1
1097
1105
  </span>
1098
1106
  <span>
@@ -1100,7 +1108,7 @@ function UpdatesPanel() {
1100
1108
  </span>
1101
1109
  </li>
1102
1110
  <li className="flex items-start gap-2">
1103
- <span className="w-4 h-4 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center text-[10px] font-bold shrink-0 mt-0.5">
1111
+ <span className="mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-blue-100 text-[10px] font-bold text-blue-600">
1104
1112
  2
1105
1113
  </span>
1106
1114
  <span>
@@ -1109,7 +1117,7 @@ function UpdatesPanel() {
1109
1117
  </span>
1110
1118
  </li>
1111
1119
  <li className="flex items-start gap-2">
1112
- <span className="w-4 h-4 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center text-[10px] font-bold shrink-0 mt-0.5">
1120
+ <span className="mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-blue-100 text-[10px] font-bold text-blue-600">
1113
1121
  3
1114
1122
  </span>
1115
1123
  <span>
@@ -1118,12 +1126,12 @@ function UpdatesPanel() {
1118
1126
  </span>
1119
1127
  </li>
1120
1128
  <li className="flex items-start gap-2">
1121
- <span className="w-4 h-4 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center text-[10px] font-bold shrink-0 mt-0.5">
1129
+ <span className="mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-blue-100 text-[10px] font-bold text-blue-600">
1122
1130
  4
1123
1131
  </span>
1124
1132
  <span>
1125
1133
  Review and merge the PR, then deploy. Database migrations run automatically via{' '}
1126
- <code className="font-mono bg-gray-200 px-1 rounded">prisma migrate deploy</code>.
1134
+ <code className="rounded bg-gray-200 px-1 font-mono">prisma migrate deploy</code>.
1127
1135
  </span>
1128
1136
  </li>
1129
1137
  </ul>