@cat-factory/app 0.302.2 → 0.303.1

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 (328) hide show
  1. package/README.md +99 -14
  2. package/app/app.config.ts +19 -10
  3. package/app/assets/css/main.css +13 -13
  4. package/app/assets/css/prose.css +22 -22
  5. package/app/assets/css/tokens.css +298 -0
  6. package/app/components/assistant/AssistantModal.vue +22 -22
  7. package/app/components/auth/AuthGate.vue +1 -1
  8. package/app/components/auth/BackendMisconfiguredScreen.vue +10 -10
  9. package/app/components/auth/LoginScreen.vue +34 -36
  10. package/app/components/auth/ResetPasswordScreen.vue +12 -12
  11. package/app/components/auth/UserMenu.vue +4 -4
  12. package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +27 -25
  13. package/app/components/binaryOutput/BinaryOutputReport.vue +15 -15
  14. package/app/components/binaryOutput/StoredAssetView.vue +5 -5
  15. package/app/components/board/AddTaskModal.vue +17 -20
  16. package/app/components/board/AgentFailureCard.vue +11 -11
  17. package/app/components/board/AgentFailureHistory.vue +2 -2
  18. package/app/components/board/BoardCanvas.vue +6 -5
  19. package/app/components/board/CreateInitiativeModal.vue +8 -10
  20. package/app/components/board/DependencyConnectOverlay.vue +1 -1
  21. package/app/components/board/FailureHistoryList.vue +7 -7
  22. package/app/components/board/RecurringPipelineModal.vue +17 -17
  23. package/app/components/board/ReviewFrictionDialog.vue +6 -6
  24. package/app/components/board/StepExecutionHistory.vue +13 -13
  25. package/app/components/board/TaskDependencyEdges.vue +8 -8
  26. package/app/components/board/nodes/AgentChip.vue +10 -10
  27. package/app/components/board/nodes/BlockNode.vue +29 -29
  28. package/app/components/board/nodes/DecisionBadge.vue +2 -2
  29. package/app/components/board/nodes/EpicNode.vue +14 -10
  30. package/app/components/board/nodes/FrameSwimlanes.vue +7 -9
  31. package/app/components/board/nodes/InitiativeCard.vue +8 -8
  32. package/app/components/board/nodes/LaneGroup.vue +1 -1
  33. package/app/components/board/nodes/LaneTask.vue +2 -2
  34. package/app/components/board/nodes/ResizeGrips.vue +4 -4
  35. package/app/components/board/nodes/TaskCard.vue +18 -18
  36. package/app/components/board/nodes/TaskLane.vue +5 -5
  37. package/app/components/board/nodes/TaskPipelineMini.vue +18 -18
  38. package/app/components/bootstrap/AdoptionReviewModal.vue +29 -26
  39. package/app/components/bootstrap/BootstrapModal.vue +21 -23
  40. package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
  41. package/app/components/brainstorm/BrainstormWindow.vue +30 -33
  42. package/app/components/bugFishing/BugFishingWindow.vue +49 -49
  43. package/app/components/clarity/ClarityReviewWindow.vue +30 -30
  44. package/app/components/common/AsyncViewError.vue +5 -5
  45. package/app/components/common/ClarificationItem.vue +8 -13
  46. package/app/components/common/ConfirmDialog.vue +4 -2
  47. package/app/components/common/DescriptorFields.vue +1 -1
  48. package/app/components/common/EmptyState.vue +3 -3
  49. package/app/components/common/InterviewGateNotice.vue +7 -7
  50. package/app/components/common/KeyboardShortcutsHelp.vue +1 -1
  51. package/app/components/common/MarkdownProse.vue +14 -13
  52. package/app/components/consensus/ConsensusSessionWindow.vue +26 -26
  53. package/app/components/context/ContextAttachmentFields.vue +17 -17
  54. package/app/components/docs/DocInterviewWindow.vue +14 -14
  55. package/app/components/documents/ContextDocumentPicker.vue +17 -17
  56. package/app/components/documents/DocumentImportModal.vue +7 -7
  57. package/app/components/documents/DocumentSourceConnectModal.vue +3 -3
  58. package/app/components/documents/DocumentSyncState.vue +5 -5
  59. package/app/components/documents/DocumentTemplatesModal.vue +15 -15
  60. package/app/components/documents/RepoContextDocPicker.vue +5 -5
  61. package/app/components/documents/SpawnPreviewModal.vue +12 -12
  62. package/app/components/documents/StartFromDesignModal.vue +11 -11
  63. package/app/components/documents/TaskContextDocs.vue +5 -5
  64. package/app/components/environments/EnvSetupStepper.vue +6 -6
  65. package/app/components/environments/EnvironmentStatusPanel.vue +17 -17
  66. package/app/components/environments/steps/EnvPickStep.vue +3 -3
  67. package/app/components/environments/steps/EnvPreflightStep.vue +9 -9
  68. package/app/components/environments/steps/EnvReviewStep.vue +25 -22
  69. package/app/components/environments/steps/EnvSaveStep.vue +7 -5
  70. package/app/components/environments/steps/JourneyStepNav.vue +1 -1
  71. package/app/components/focus/BlockFocusView.vue +17 -19
  72. package/app/components/followUp/FollowUpWindow.vue +23 -23
  73. package/app/components/forkDecision/ForkDecisionWindow.vue +37 -39
  74. package/app/components/foundational/FoundationalContractSummary.vue +7 -7
  75. package/app/components/foundational/FoundationalServiceCatalogList.vue +11 -11
  76. package/app/components/foundational/FoundationalServiceManager.vue +1 -1
  77. package/app/components/foundational/FoundationalServiceRegistry.vue +13 -13
  78. package/app/components/foundational/FoundationalServiceSources.vue +13 -13
  79. package/app/components/foundational/FoundationalSuppressions.vue +7 -7
  80. package/app/components/foundational/ServiceCatalogConnection.vue +10 -10
  81. package/app/components/fragments/FragmentLibraryManager.vue +41 -44
  82. package/app/components/fragments/FragmentSelector.vue +13 -13
  83. package/app/components/fragments/GitHubDocUrlImport.vue +1 -1
  84. package/app/components/gates/GateFailingCheckList.vue +5 -5
  85. package/app/components/gates/GateResultView.vue +50 -47
  86. package/app/components/github/AddServiceFromRepoModal.vue +14 -14
  87. package/app/components/github/BranchProtectionPreflight.vue +13 -13
  88. package/app/components/github/GitHubConnect.vue +7 -7
  89. package/app/components/github/GitHubOnboarding.vue +7 -7
  90. package/app/components/github/GitHubPanel.vue +37 -40
  91. package/app/components/github/RepoTreeBrowser.vue +18 -18
  92. package/app/components/humanTest/HumanTestWindow.vue +30 -33
  93. package/app/components/initiative/InitiativePlanNotice.vue +5 -5
  94. package/app/components/initiative/InitiativePlanReview.vue +27 -29
  95. package/app/components/initiative/InitiativePlanningWindow.vue +10 -10
  96. package/app/components/initiative/InitiativeTrackerWindow.vue +71 -65
  97. package/app/components/inputGate/InputGateNotice.vue +2 -4
  98. package/app/components/judge/JudgeResultView.vue +30 -32
  99. package/app/components/kaizen/KaizenPanel.vue +40 -36
  100. package/app/components/kaizen/KaizenStepStatus.vue +21 -21
  101. package/app/components/layout/AccountAuditLog.vue +10 -10
  102. package/app/components/layout/AccountDeploymentSettings.vue +20 -20
  103. package/app/components/layout/AccountFailureKindRules.vue +13 -13
  104. package/app/components/layout/AccountFoundationalSettings.vue +1 -1
  105. package/app/components/layout/AccountFragmentSettings.vue +1 -1
  106. package/app/components/layout/AccountModelPolicySettings.vue +9 -9
  107. package/app/components/layout/AccountPlatformAlertSettings.vue +11 -11
  108. package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
  109. package/app/components/layout/AccountRunCredentialSettings.vue +5 -5
  110. package/app/components/layout/AccountSkillSettings.vue +1 -1
  111. package/app/components/layout/AccountTeamSettings.vue +23 -15
  112. package/app/components/layout/AiProvidersBanner.vue +11 -8
  113. package/app/components/layout/AppearanceSwitcher.vue +108 -0
  114. package/app/components/layout/BoardSwitcher.vue +8 -11
  115. package/app/components/layout/BoardToolbar.vue +3 -3
  116. package/app/components/layout/CommandBar.vue +7 -9
  117. package/app/components/layout/ConnectionStatusBanner.vue +2 -2
  118. package/app/components/layout/DefaultTestEnvBanner.vue +5 -5
  119. package/app/components/layout/GitHubPatBanner.vue +5 -5
  120. package/app/components/layout/GitHubPatPermissionsBanner.vue +16 -10
  121. package/app/components/layout/InfraSetupBanner.vue +6 -6
  122. package/app/components/layout/IntegrationsHub.vue +15 -15
  123. package/app/components/layout/LanguageSwitcher.vue +5 -5
  124. package/app/components/layout/ModelProvidersHub.vue +13 -16
  125. package/app/components/layout/NotificationsInbox.vue +10 -10
  126. package/app/components/layout/PersonalSetupModal.vue +8 -8
  127. package/app/components/layout/ProviderConfigBanner.vue +4 -4
  128. package/app/components/layout/RolePrompt.vue +7 -7
  129. package/app/components/layout/SideBar.vue +6 -4
  130. package/app/components/layout/SpendWarningBanner.vue +17 -14
  131. package/app/components/layout/TranslationWarningBanner.vue +4 -4
  132. package/app/components/layout/UiModeSwitcher.vue +13 -13
  133. package/app/components/layout/UiRoleSwitcher.vue +8 -8
  134. package/app/components/layout/WorkspaceMembersSettings.vue +15 -11
  135. package/app/components/media/ArtifactLightbox.vue +13 -13
  136. package/app/components/media/ImageCompare.vue +31 -24
  137. package/app/components/merge/MergeEffortChips.vue +2 -2
  138. package/app/components/notifications/NotificationSettingsPanel.vue +14 -12
  139. package/app/components/observability/OutcomeFilterChips.vue +6 -6
  140. package/app/components/observability/RunFailureSummary.vue +28 -25
  141. package/app/components/observability/StepMetricsBar.vue +26 -28
  142. package/app/components/observability/StepModelActivity.vue +2 -2
  143. package/app/components/observability/ToolCallList.vue +24 -24
  144. package/app/components/outcome/OutcomeSummaryWindow.vue +47 -47
  145. package/app/components/palettes/AgentPalette.vue +8 -8
  146. package/app/components/palettes/AgentTierSelect.vue +1 -1
  147. package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
  148. package/app/components/panels/AgentStepDetail.vue +52 -51
  149. package/app/components/panels/AttemptEntryHeader.vue +4 -6
  150. package/app/components/panels/DecisionModal.vue +7 -7
  151. package/app/components/panels/GenericStructuredResultView.vue +7 -7
  152. package/app/components/panels/InspectorPanel.vue +17 -17
  153. package/app/components/panels/MergerResultView.vue +19 -19
  154. package/app/components/panels/ObservabilityPanel.vue +115 -123
  155. package/app/components/panels/OperatorDashboardPanel.vue +89 -97
  156. package/app/components/panels/ReportsPanel.vue +69 -66
  157. package/app/components/panels/ReportsSpendBreakdown.vue +9 -9
  158. package/app/components/panels/ResultWindowShell.vue +38 -38
  159. package/app/components/panels/RunDetailLoadState.vue +2 -2
  160. package/app/components/panels/StepContainerStatus.vue +9 -9
  161. package/app/components/panels/StepDelegatedStatus.logic.spec.ts +135 -0
  162. package/app/components/panels/StepDelegatedStatus.logic.ts +160 -0
  163. package/app/components/panels/StepDelegatedStatus.vue +181 -0
  164. package/app/components/panels/StepEffortReport.vue +16 -15
  165. package/app/components/panels/StepFragmentAdherence.vue +14 -10
  166. package/app/components/panels/StepMetadataCard.vue +74 -45
  167. package/app/components/panels/StepReproductionReport.vue +25 -21
  168. package/app/components/panels/StepRunMeta.vue +20 -20
  169. package/app/components/panels/StepTestReport.logic.spec.ts +8 -3
  170. package/app/components/panels/StepTestReport.logic.ts +4 -4
  171. package/app/components/panels/StepTestReport.vue +28 -28
  172. package/app/components/panels/StepToolServers.vue +14 -11
  173. package/app/components/panels/StepValidationReport.vue +7 -7
  174. package/app/components/panels/inspector/ContainerSummary.vue +9 -9
  175. package/app/components/panels/inspector/DocReferenceRepos.vue +3 -3
  176. package/app/components/panels/inspector/EnvProbeReport.vue +24 -27
  177. package/app/components/panels/inspector/EpicChildren.vue +8 -12
  178. package/app/components/panels/inspector/FrontendBindingsResolved.vue +11 -11
  179. package/app/components/panels/inspector/FrontendConfig.vue +37 -41
  180. package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
  181. package/app/components/panels/inspector/InspectorSection.vue +6 -6
  182. package/app/components/panels/inspector/RecurringScheduleSettings.vue +16 -19
  183. package/app/components/panels/inspector/ServiceConnections.vue +2 -2
  184. package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
  185. package/app/components/panels/inspector/ServiceSelfTests.vue +21 -17
  186. package/app/components/panels/inspector/ServiceTestConfig.vue +51 -59
  187. package/app/components/panels/inspector/ServiceTestSecrets.vue +5 -5
  188. package/app/components/panels/inspector/ServiceTestingContext.vue +3 -3
  189. package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
  190. package/app/components/panels/inspector/TaskAgentConfig.vue +3 -3
  191. package/app/components/panels/inspector/TaskAprioriBranches.vue +8 -5
  192. package/app/components/panels/inspector/TaskDependencies.vue +1 -1
  193. package/app/components/panels/inspector/TaskEstimateBadge.vue +11 -11
  194. package/app/components/panels/inspector/TaskExecution.vue +17 -17
  195. package/app/components/panels/inspector/TaskReviewTarget.vue +2 -2
  196. package/app/components/panels/inspector/TaskRunSettings.vue +35 -37
  197. package/app/components/panels/inspector/TaskStructure.vue +3 -3
  198. package/app/components/pipeline/AgentKindIcon.vue +1 -1
  199. package/app/components/pipeline/AgentPromptEditor.vue +17 -17
  200. package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -56
  201. package/app/components/pipeline/EstimateThresholdFields.vue +4 -4
  202. package/app/components/pipeline/GateConfigFields.vue +13 -10
  203. package/app/components/pipeline/IterationCapPrompt.vue +4 -2
  204. package/app/components/pipeline/PipelineBuilder.vue +47 -55
  205. package/app/components/pipeline/PipelineHealthModal.vue +27 -29
  206. package/app/components/pipeline/PipelinePicker.vue +10 -10
  207. package/app/components/pipeline/PipelinePreview.vue +10 -10
  208. package/app/components/pipeline/PipelineProgress.vue +64 -67
  209. package/app/components/prReview/PrReviewPhaseBadge.vue +7 -7
  210. package/app/components/prReview/PrReviewWindow.vue +75 -77
  211. package/app/components/providers/AiPresetMismatchDialog.vue +5 -5
  212. package/app/components/providers/AiProviderOnboardingModal.vue +9 -9
  213. package/app/components/providers/ApiKeysSection.vue +13 -13
  214. package/app/components/providers/PersonalCredentialModal.vue +2 -2
  215. package/app/components/providers/PersonalSubscriptionSection.vue +10 -10
  216. package/app/components/providers/SignInRequiredNotice.vue +1 -1
  217. package/app/components/providers/VendorCredentialsModal.vue +10 -10
  218. package/app/components/provisioning/ProvisioningLogsDrawer.vue +13 -13
  219. package/app/components/ralph/RalphLoopResultView.vue +28 -30
  220. package/app/components/recurring/RecurrenceEditor.vue +2 -2
  221. package/app/components/requirements/RequirementsReviewWindow.vue +51 -58
  222. package/app/components/riskPolicy/RiskPolicyPicker.vue +12 -15
  223. package/app/components/riskPolicy/RiskPolicyPreview.vue +14 -14
  224. package/app/components/sandbox/SandboxPanel.vue +58 -59
  225. package/app/components/settings/AccountSettingsPanel.vue +1 -1
  226. package/app/components/settings/ApiTokensPanel.vue +10 -10
  227. package/app/components/settings/BudgetSettings.vue +18 -22
  228. package/app/components/settings/CapabilityCredentialsPanel.vue +15 -15
  229. package/app/components/settings/CloudflareHandlerSection.vue +20 -20
  230. package/app/components/settings/ComposeEnvironmentSetupSection.vue +13 -13
  231. package/app/components/settings/ConnectionTestVerdict.vue +3 -3
  232. package/app/components/settings/ConnectionWarnings.vue +1 -1
  233. package/app/components/settings/ConsensusGroupsSection.vue +27 -35
  234. package/app/components/settings/CustomManifestTypeEditor.vue +10 -10
  235. package/app/components/settings/DefaultProvisionTypeSection.vue +6 -6
  236. package/app/components/settings/InfraHandlersConfigurator.vue +24 -22
  237. package/app/components/settings/InfrastructureBackendPicker.vue +6 -6
  238. package/app/components/settings/InfrastructureWindow.vue +5 -5
  239. package/app/components/settings/IssueTrackerPanel.vue +29 -23
  240. package/app/components/settings/KubernetesEngineForm.vue +11 -11
  241. package/app/components/settings/KubernetesEnvironmentForm.vue +4 -4
  242. package/app/components/settings/LocalContainerPoolSettings.vue +6 -11
  243. package/app/components/settings/LocalModelEndpointsPanel.vue +20 -18
  244. package/app/components/settings/McpAuthorizeScreen.vue +13 -15
  245. package/app/components/settings/McpOAuthCallbackScreen.vue +16 -10
  246. package/app/components/settings/MergeClassRulesEditor.vue +6 -9
  247. package/app/components/settings/MergeRolePolicyEditor.vue +16 -16
  248. package/app/components/settings/ModelConfigurationPanel.vue +23 -30
  249. package/app/components/settings/ModelPresetHealthModal.vue +15 -13
  250. package/app/components/settings/ObservabilityConnectionPanel.vue +4 -4
  251. package/app/components/settings/OpenRouterCatalogPanel.vue +26 -19
  252. package/app/components/settings/PackageRegistriesPanel.vue +8 -8
  253. package/app/components/settings/ProviderConnectionTab.vue +8 -11
  254. package/app/components/settings/ProviderManifestEditor.vue +9 -9
  255. package/app/components/settings/ProviderPreferenceEditor.vue +8 -8
  256. package/app/components/settings/RiskPolicyCreateForm.vue +10 -10
  257. package/app/components/settings/RiskPolicyEditorRow.vue +14 -14
  258. package/app/components/settings/RiskPolicyHealthModal.vue +15 -13
  259. package/app/components/settings/RiskPolicyInheritedRow.vue +1 -1
  260. package/app/components/settings/RiskPolicyPanel.vue +10 -15
  261. package/app/components/settings/ServiceFragmentDefaultsPanel.vue +7 -7
  262. package/app/components/settings/SharedStacksPanel.vue +9 -12
  263. package/app/components/settings/TaskSourceCard.vue +4 -4
  264. package/app/components/settings/TaskTypeSuppressionsPanel.vue +6 -6
  265. package/app/components/settings/ToolServerChecklist.vue +36 -29
  266. package/app/components/settings/UsageSettings.vue +15 -15
  267. package/app/components/settings/UserSecretsSection.vue +9 -12
  268. package/app/components/settings/WorkspaceMetadataSettings.vue +5 -5
  269. package/app/components/settings/WorkspaceSettingsPanel.vue +47 -47
  270. package/app/components/skills/ReviewSkillQueue.vue +10 -10
  271. package/app/components/skills/SkillLibraryManager.vue +23 -20
  272. package/app/components/slack/SlackPanel.vue +13 -17
  273. package/app/components/spec/ServiceSpecWindow.vue +45 -42
  274. package/app/components/tasks/BugHuntModal.vue +24 -27
  275. package/app/components/tasks/ContextIssuePicker.vue +11 -11
  276. package/app/components/tasks/TaskContextIssues.vue +3 -3
  277. package/app/components/tasks/TaskImportModal.vue +7 -7
  278. package/app/components/tasks/TaskSourceConnectModal.vue +10 -8
  279. package/app/components/testing/TestReportWindow.vue +99 -82
  280. package/app/components/theme/ThemeImportModal.vue +115 -0
  281. package/app/components/tutorial/TutorialCatalogue.vue +9 -9
  282. package/app/components/tutorial/TutorialNudge.vue +5 -5
  283. package/app/components/tutorial/TutorialOverlay.vue +12 -12
  284. package/app/components/tutorial/TutorialPrompt.vue +6 -9
  285. package/app/components/vcs/GitLabConnect.vue +4 -4
  286. package/app/components/vcs/VcsConnectSurfaces.vue +2 -2
  287. package/app/components/visualConfirm/VisualConfirmationWindow.vue +36 -36
  288. package/app/composables/api/client.ts +6 -1
  289. package/app/composables/usePipelineErrorToast.ts +17 -0
  290. package/app/modular/agent-kinds.ts +24 -0
  291. package/app/pages/index.vue +5 -5
  292. package/app/plugins/theme.client.ts +125 -0
  293. package/app/spa-loading-template.html +52 -14
  294. package/app/stores/agents.ts +1 -1
  295. package/app/stores/theme.spec.ts +56 -0
  296. package/app/stores/theme.ts +87 -0
  297. package/app/types/domain.ts +19 -0
  298. package/app/types/execution.ts +4 -0
  299. package/app/utils/agentOutput.ts +1 -1
  300. package/app/utils/binaryOutput.ts +6 -6
  301. package/app/utils/bootstrapSteps.ts +14 -14
  302. package/app/utils/catalog.ts +87 -83
  303. package/app/utils/colorTint.ts +10 -0
  304. package/app/utils/failureKinds.ts +1 -0
  305. package/app/utils/observability.ts +3 -3
  306. package/app/utils/pipelineRender.ts +13 -17
  307. package/app/utils/swimlanes.ts +4 -4
  308. package/app/utils/theme/bootPalette.spec.ts +54 -0
  309. package/app/utils/theme/bootPalette.ts +108 -0
  310. package/app/utils/theme/builtins.spec.ts +38 -0
  311. package/app/utils/theme/builtins.ts +55 -0
  312. package/app/utils/theme/css.ts +162 -0
  313. package/app/utils/theme/doc.ts +353 -0
  314. package/app/utils/theme/link.ts +93 -0
  315. package/app/utils/theme/presets.ts +509 -0
  316. package/app/utils/theme/theme.spec.ts +224 -0
  317. package/i18n/locales/de.json +61 -4
  318. package/i18n/locales/en.json +70 -4
  319. package/i18n/locales/es.json +61 -4
  320. package/i18n/locales/fr.json +61 -4
  321. package/i18n/locales/he.json +61 -4
  322. package/i18n/locales/it.json +61 -4
  323. package/i18n/locales/ja.json +61 -4
  324. package/i18n/locales/pl.json +61 -4
  325. package/i18n/locales/tr.json +61 -4
  326. package/i18n/locales/uk.json +61 -4
  327. package/nuxt.config.ts +37 -11
  328. package/package.json +10 -9
@@ -151,7 +151,7 @@ const { requestClose } = useUnsavedGuard({
151
151
  <ResultWindowShell
152
152
  :open="open"
153
153
  :icon="FORK_DECISION_META.icon"
154
- icon-class="bg-violet-500/15 text-violet-300"
154
+ icon-class="bg-app-secondary-500/15 text-app-secondary-300"
155
155
  :title="headerTitle"
156
156
  :subtitle="t('forkDecision.subtitle')"
157
157
  width="3xl"
@@ -162,11 +162,11 @@ const { requestClose } = useUnsavedGuard({
162
162
  <!-- Proposing: the read-only proposer is still working. -->
163
163
  <div
164
164
  v-if="status === 'proposing'"
165
- class="flex h-full flex-col items-center justify-center gap-2 py-10 text-center text-slate-400"
165
+ class="flex h-full flex-col items-center justify-center gap-2 py-10 text-center text-muted"
166
166
  >
167
167
  <UIcon name="i-lucide-loader-circle" class="h-8 w-8 animate-spin opacity-60" />
168
168
  <p class="text-sm">{{ t('forkDecision.proposing.title') }}</p>
169
- <p class="max-w-sm text-[11px] text-slate-500">
169
+ <p class="max-w-sm text-[11px] text-dimmed">
170
170
  {{ t('forkDecision.proposing.hint') }}
171
171
  </p>
172
172
  </div>
@@ -174,9 +174,9 @@ const { requestClose } = useUnsavedGuard({
174
174
  <!-- A single path (no materially different alternatives): a read-only record. -->
175
175
  <div
176
176
  v-else-if="status === 'single_path'"
177
- class="rounded-xl border border-slate-800 bg-slate-900/60 px-4 py-3 text-slate-300"
177
+ class="rounded-xl border border-default bg-default/60 px-4 py-3 text-toned"
178
178
  >
179
- <p class="text-[13px] font-medium text-slate-100">
179
+ <p class="text-[13px] font-medium text-app-100">
180
180
  {{ t('forkDecision.singlePath.title') }}
181
181
  </p>
182
182
  <p v-if="state?.singlePathReason" class="mt-1 text-[12px]">
@@ -187,9 +187,9 @@ const { requestClose } = useUnsavedGuard({
187
187
  <!-- Chosen: a read-only record of what was decided. -->
188
188
  <div
189
189
  v-else-if="status === 'chosen'"
190
- class="rounded-xl border border-violet-500/40 bg-slate-900/60 px-4 py-3 text-slate-300"
190
+ class="rounded-xl border border-app-secondary-500/40 bg-default/60 px-4 py-3 text-toned"
191
191
  >
192
- <p class="text-[13px] font-medium text-violet-200">
192
+ <p class="text-[13px] font-medium text-app-secondary-200">
193
193
  {{ t('forkDecision.chosen.title') }}
194
194
  </p>
195
195
  <p v-if="state?.chosen?.custom" class="mt-1 whitespace-pre-wrap text-[12px]">
@@ -198,7 +198,7 @@ const { requestClose } = useUnsavedGuard({
198
198
  <p v-else-if="state?.chosen?.forkId" class="mt-1 text-[12px]">
199
199
  {{ forks.find((f) => f.id === state?.chosen?.forkId)?.title }}
200
200
  </p>
201
- <p v-if="state?.chosen?.note" class="mt-1 text-[11px] text-slate-400">
201
+ <p v-if="state?.chosen?.note" class="mt-1 text-[11px] text-muted">
202
202
  {{ t('forkDecision.chosen.note', { note: state.chosen.note }) }}
203
203
  </p>
204
204
  </div>
@@ -207,16 +207,16 @@ const { requestClose } = useUnsavedGuard({
207
207
  <div v-else-if="interactive" class="space-y-3">
208
208
  <p
209
209
  v-if="forkDecision.error"
210
- class="rounded-md bg-rose-500/10 px-3 py-2 text-[12px] text-rose-300"
210
+ class="rounded-md bg-app-error-500/10 px-3 py-2 text-[12px] text-app-error-300"
211
211
  >
212
212
  {{ forkDecision.error }}
213
213
  </p>
214
214
 
215
215
  <p
216
216
  v-if="state?.seamSummary"
217
- class="rounded-md bg-slate-800/50 px-3 py-2 text-[12px] text-slate-300"
217
+ class="rounded-md bg-elevated/50 px-3 py-2 text-[12px] text-toned"
218
218
  >
219
- <span class="text-slate-500">{{ t('forkDecision.seam') }}</span>
219
+ <span class="text-dimmed">{{ t('forkDecision.seam') }}</span>
220
220
  {{ state.seamSummary }}
221
221
  </p>
222
222
 
@@ -228,44 +228,44 @@ const { requestClose } = useUnsavedGuard({
228
228
  class="cursor-pointer rounded-xl border px-4 py-3 transition"
229
229
  :class="
230
230
  selected === fork.id
231
- ? 'border-violet-500/70 bg-violet-500/5'
232
- : 'border-slate-800 bg-slate-900/60 hover:border-slate-700'
231
+ ? 'border-app-secondary-500/70 bg-app-secondary-500/5'
232
+ : 'border-default bg-default/60 hover:border-muted'
233
233
  "
234
234
  @click="selected = fork.id"
235
235
  >
236
236
  <div class="flex items-start gap-2">
237
237
  <input
238
238
  type="radio"
239
- class="mt-1 accent-violet-500"
239
+ class="mt-1 accent-app-secondary-500"
240
240
  :checked="selected === fork.id"
241
241
  @change="selected = fork.id"
242
242
  />
243
243
  <div class="min-w-0 flex-1">
244
244
  <div class="flex items-center gap-2">
245
- <h3 class="min-w-0 flex-1 text-[13px] font-medium text-slate-100">
245
+ <h3 class="min-w-0 flex-1 text-[13px] font-medium text-app-100">
246
246
  {{ fork.title }}
247
247
  </h3>
248
248
  <UBadge v-if="fork.recommended" color="primary" variant="subtle" size="sm">
249
249
  {{ t('forkDecision.recommended') }}
250
250
  </UBadge>
251
251
  </div>
252
- <p v-if="fork.summary" class="mt-0.5 text-[12px] text-slate-400">
252
+ <p v-if="fork.summary" class="mt-0.5 text-[12px] text-muted">
253
253
  {{ fork.summary }}
254
254
  </p>
255
- <p class="mt-1.5 whitespace-pre-wrap text-[12px] text-slate-300">
255
+ <p class="mt-1.5 whitespace-pre-wrap text-[12px] text-toned">
256
256
  {{ fork.approach }}
257
257
  </p>
258
258
  <ul v-if="fork.tradeoffs.length" class="mt-1.5 space-y-0.5">
259
259
  <li
260
260
  v-for="(tr, i) in fork.tradeoffs"
261
261
  :key="i"
262
- class="flex gap-1.5 text-[11px] text-slate-400"
262
+ class="flex gap-1.5 text-[11px] text-muted"
263
263
  >
264
- <span class="text-slate-600">•</span>{{ tr }}
264
+ <span class="text-app-600">•</span>{{ tr }}
265
265
  </li>
266
266
  </ul>
267
- <p v-if="fork.riskNotes" class="mt-1.5 text-[11px] text-amber-300/90">
268
- <span class="text-amber-500/70">{{ t('forkDecision.riskNotes') }}</span>
267
+ <p v-if="fork.riskNotes" class="mt-1.5 text-[11px] text-app-warning-300/90">
268
+ <span class="text-app-warning-500/70">{{ t('forkDecision.riskNotes') }}</span>
269
269
  {{ fork.riskNotes }}
270
270
  </p>
271
271
  </div>
@@ -277,13 +277,13 @@ const { requestClose } = useUnsavedGuard({
277
277
  class="rounded-xl border px-4 py-3 transition"
278
278
  :class="
279
279
  selected === 'custom'
280
- ? 'border-violet-500/70 bg-violet-500/5'
281
- : 'border-slate-800 bg-slate-900/60'
280
+ ? 'border-app-secondary-500/70 bg-app-secondary-500/5'
281
+ : 'border-default bg-default/60'
282
282
  "
283
283
  >
284
284
  <label class="flex cursor-pointer items-center gap-2" @click="selected = 'custom'">
285
- <input type="radio" class="accent-violet-500" :checked="selected === 'custom'" />
286
- <span class="text-[13px] font-medium text-slate-100">{{
285
+ <input type="radio" class="accent-app-secondary-500" :checked="selected === 'custom'" />
286
+ <span class="text-[13px] font-medium text-app-100">{{
287
287
  t('forkDecision.custom.title')
288
288
  }}</span>
289
289
  </label>
@@ -292,27 +292,25 @@ const { requestClose } = useUnsavedGuard({
292
292
  data-testid="fork-custom-input"
293
293
  rows="3"
294
294
  :placeholder="t('forkDecision.custom.placeholder')"
295
- class="mt-2 w-full resize-y rounded-md border border-slate-700 bg-slate-950/60 px-2.5 py-1.5 text-[12px] text-slate-100 placeholder:text-slate-600 focus:border-violet-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-violet-500/60"
295
+ class="mt-2 w-full resize-y rounded-md border border-muted bg-app-950/60 px-2.5 py-1.5 text-[12px] text-app-100 placeholder:text-app-600 focus:border-app-secondary-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-app-secondary-500/60"
296
296
  @focus="selected = 'custom'"
297
297
  />
298
298
  </article>
299
299
 
300
300
  <!-- Optional steering note -->
301
301
  <div>
302
- <label class="mb-1 block text-[11px] text-slate-400">{{
303
- t('forkDecision.noteLabel')
304
- }}</label>
302
+ <label class="mb-1 block text-[11px] text-muted">{{ t('forkDecision.noteLabel') }}</label>
305
303
  <input
306
304
  v-model="note"
307
305
  type="text"
308
306
  :placeholder="t('forkDecision.notePlaceholder')"
309
- class="w-full rounded-md border border-slate-700 bg-slate-950/60 px-2.5 py-1.5 text-[12px] text-slate-100 placeholder:text-slate-600 focus:border-violet-500 focus:outline-none"
307
+ class="w-full rounded-md border border-muted bg-app-950/60 px-2.5 py-1.5 text-[12px] text-app-100 placeholder:text-app-600 focus:border-app-secondary-500 focus:outline-none"
310
308
  />
311
309
  </div>
312
310
 
313
311
  <!-- Grounded chat: ask about the forks before deciding. -->
314
- <section class="rounded-xl border border-slate-800 bg-slate-900/40 px-4 py-3">
315
- <p class="text-[11px] font-medium text-slate-400">
312
+ <section class="rounded-xl border border-default bg-default/40 px-4 py-3">
313
+ <p class="text-[11px] font-medium text-muted">
316
314
  {{ t('forkDecision.chat.title') }}
317
315
  </p>
318
316
  <div v-if="chat.length || answering" class="mt-2 max-h-64 space-y-2 overflow-y-auto pr-1">
@@ -327,8 +325,8 @@ const { requestClose } = useUnsavedGuard({
327
325
  class="max-w-[85%] whitespace-pre-wrap rounded-lg px-3 py-1.5 text-[12px]"
328
326
  :class="
329
327
  msg.role === 'human'
330
- ? 'bg-violet-500/15 text-violet-100'
331
- : 'bg-slate-800/70 text-slate-200'
328
+ ? 'bg-app-secondary-500/15 text-app-secondary-100'
329
+ : 'bg-elevated/70 text-default'
332
330
  "
333
331
  >
334
332
  {{ msg.text }}
@@ -336,14 +334,14 @@ const { requestClose } = useUnsavedGuard({
336
334
  </div>
337
335
  <div v-if="answering" class="flex justify-start">
338
336
  <p
339
- class="flex items-center gap-1.5 rounded-lg bg-slate-800/70 px-3 py-1.5 text-[12px] text-slate-400"
337
+ class="flex items-center gap-1.5 rounded-lg bg-elevated/70 px-3 py-1.5 text-[12px] text-muted"
340
338
  >
341
339
  <UIcon name="i-lucide-loader-circle" class="h-3.5 w-3.5 animate-spin" />
342
340
  {{ t('forkDecision.chat.thinking') }}
343
341
  </p>
344
342
  </div>
345
343
  </div>
346
- <p v-else class="mt-1 text-[11px] text-slate-500">
344
+ <p v-else class="mt-1 text-[11px] text-dimmed">
347
345
  {{ t('forkDecision.chat.hint') }}
348
346
  </p>
349
347
  <div class="mt-2 flex items-end gap-2">
@@ -357,7 +355,7 @@ const { requestClose } = useUnsavedGuard({
357
355
  ? t('forkDecision.chat.budgetSpent')
358
356
  : t('forkDecision.chat.placeholder')
359
357
  "
360
- class="min-h-0 flex-1 resize-y rounded-md border border-slate-700 bg-slate-950/60 px-2.5 py-1.5 text-[12px] text-slate-100 placeholder:text-slate-600 focus:border-violet-500 focus:outline-none disabled:opacity-50"
358
+ class="min-h-0 flex-1 resize-y rounded-md border border-muted bg-app-950/60 px-2.5 py-1.5 text-[12px] text-app-100 placeholder:text-app-600 focus:border-app-secondary-500 focus:outline-none disabled:opacity-50"
361
359
  @keydown.enter.exact.prevent="onSend"
362
360
  />
363
361
  <UButton
@@ -380,7 +378,7 @@ const { requestClose } = useUnsavedGuard({
380
378
  <!-- Skipped / no state: nothing to decide. -->
381
379
  <div
382
380
  v-else
383
- class="flex h-full flex-col items-center justify-center gap-2 py-10 text-center text-slate-400"
381
+ class="flex h-full flex-col items-center justify-center gap-2 py-10 text-center text-muted"
384
382
  >
385
383
  <UIcon :name="FORK_DECISION_META.icon" class="h-8 w-8 opacity-40" />
386
384
  <p class="text-sm">{{ t('forkDecision.empty.title') }}</p>
@@ -389,7 +387,7 @@ const { requestClose } = useUnsavedGuard({
389
387
 
390
388
  <footer
391
389
  v-if="interactive"
392
- class="flex items-center justify-end gap-2 border-t border-slate-800 px-5 py-3"
390
+ class="flex items-center justify-end gap-2 border-t border-default px-5 py-3"
393
391
  >
394
392
  <UButton color="neutral" variant="ghost" size="sm" @click="requestClose">
395
393
  {{ t('common.cancel') }}
@@ -25,24 +25,24 @@ const { t, n } = useI18n()
25
25
 
26
26
  <template>
27
27
  <div v-if="contracts.length" class="mt-1 flex flex-col gap-1">
28
- <div v-for="c in contracts" :key="c.contractId" class="text-[11px] text-slate-500">
29
- <span class="text-slate-400">{{ c.title }}</span>
28
+ <div v-for="c in contracts" :key="c.contractId" class="text-[11px] text-dimmed">
29
+ <span class="text-muted">{{ c.title }}</span>
30
30
  <span class="ms-1">({{ formatLabel[c.format] }}, {{ n(c.size) }})</span>
31
- <span v-if="c.operations.length" class="ms-1 font-mono text-slate-500">
31
+ <span v-if="c.operations.length" class="ms-1 font-mono text-dimmed">
32
32
  {{ c.operations.join(' · ') }}
33
33
  </span>
34
- <span v-else-if="!operationsAreIndexable(c.format)" class="ms-1 text-slate-600">
34
+ <span v-else-if="!operationsAreIndexable(c.format)" class="ms-1 text-app-600">
35
35
  {{ t('foundational.contracts.notIndexed') }}
36
36
  </span>
37
- <span v-else-if="!c.omittedOperations" class="ms-1 text-slate-600">
37
+ <span v-else-if="!c.omittedOperations" class="ms-1 text-app-600">
38
38
  {{ t('foundational.contracts.noOperations') }}
39
39
  </span>
40
- <span v-if="c.omittedOperations > 0" class="ms-1 text-amber-500/80">
40
+ <span v-if="c.omittedOperations > 0" class="ms-1 text-app-warning-500/80">
41
41
  {{ t('foundational.contracts.omitted', { count: c.omittedOperations }) }}
42
42
  </span>
43
43
  </div>
44
44
  </div>
45
- <p v-else class="mt-1 text-[11px] text-amber-500/80">
45
+ <p v-else class="mt-1 text-[11px] text-app-warning-500/80">
46
46
  {{ t('foundational.contracts.none') }}
47
47
  </p>
48
48
  </template>
@@ -80,21 +80,21 @@ async function suppress(serviceId: string) {
80
80
 
81
81
  <template>
82
82
  <div class="flex flex-col gap-3" data-testid="foundational-catalog">
83
- <p class="text-xs text-slate-500">{{ t('foundational.catalog.intro') }}</p>
83
+ <p class="text-xs text-dimmed">{{ t('foundational.catalog.intro') }}</p>
84
84
 
85
85
  <div
86
86
  v-for="s in catalog.resolved"
87
87
  :key="s.id"
88
- class="rounded-md border border-slate-800 bg-slate-900/60 p-3"
88
+ class="rounded-md border border-default bg-default/60 p-3"
89
89
  >
90
90
  <div class="flex items-start gap-2">
91
- <UIcon name="i-lucide-boxes" class="mt-0.5 h-4 w-4 shrink-0 text-sky-400" />
91
+ <UIcon name="i-lucide-boxes" class="mt-0.5 h-4 w-4 shrink-0 text-app-info-400" />
92
92
  <div class="min-w-0 flex-1">
93
- <p class="truncate text-sm font-medium text-slate-100">
93
+ <p class="truncate text-sm font-medium text-app-100">
94
94
  {{ s.name }}
95
- <code class="ms-1 text-[11px] text-slate-500">{{ s.id }}</code>
95
+ <code class="ms-1 text-[11px] text-dimmed">{{ s.id }}</code>
96
96
  </p>
97
- <p class="text-xs text-slate-400">{{ s.summary }}</p>
97
+ <p class="text-xs text-muted">{{ s.summary }}</p>
98
98
  <div v-if="s.capabilities.length" class="mt-1 flex flex-wrap gap-1">
99
99
  <UBadge v-for="c in s.capabilities" :key="c" size="xs" variant="subtle" color="neutral">
100
100
  {{ c }}
@@ -122,13 +122,13 @@ async function suppress(serviceId: string) {
122
122
  <div
123
123
  v-for="doc in catalog.contractBodies[s.id] ?? []"
124
124
  :key="doc.contractId"
125
- class="rounded-md border border-slate-800 bg-slate-950/60 p-2"
125
+ class="rounded-md border border-default bg-app-950/60 p-2"
126
126
  >
127
- <p class="mb-1 text-[11px] text-slate-400">
127
+ <p class="mb-1 text-[11px] text-muted">
128
128
  {{ doc.title }}
129
- <span v-if="doc.path" class="ms-1 font-mono text-slate-600">{{ doc.path }}</span>
129
+ <span v-if="doc.path" class="ms-1 font-mono text-app-600">{{ doc.path }}</span>
130
130
  </p>
131
- <pre class="max-h-64 overflow-auto text-[11px] text-slate-300">{{ doc.body }}</pre>
131
+ <pre class="max-h-64 overflow-auto text-[11px] text-toned">{{ doc.body }}</pre>
132
132
  </div>
133
133
  </div>
134
134
  </div>
@@ -153,7 +153,7 @@ async function suppress(serviceId: string) {
153
153
  </div>
154
154
  </div>
155
155
 
156
- <p v-if="!catalog.resolved.length" class="text-sm text-slate-500">
156
+ <p v-if="!catalog.resolved.length" class="text-sm text-dimmed">
157
157
  {{ t('foundational.catalog.empty') }}
158
158
  </p>
159
159
  </div>
@@ -88,7 +88,7 @@ const activeTab = computed({
88
88
  forms that would fail with a raw 503. -->
89
89
  <div
90
90
  v-if="catalog.available === false"
91
- class="rounded-md border border-slate-800 bg-slate-900/40 p-3 text-sm text-slate-400"
91
+ class="rounded-md border border-default bg-default/40 p-3 text-sm text-muted"
92
92
  >
93
93
  {{ t('foundational.unavailable') }}
94
94
  </div>
@@ -182,23 +182,23 @@ async function remove(service: FoundationalService) {
182
182
  <div
183
183
  v-for="s in catalog.services"
184
184
  :key="s.id"
185
- class="rounded-md border border-slate-800 bg-slate-900/60 p-3"
185
+ class="rounded-md border border-default bg-default/60 p-3"
186
186
  >
187
187
  <div class="flex items-start gap-2">
188
- <UIcon name="i-lucide-boxes" class="mt-0.5 h-4 w-4 shrink-0 text-sky-400" />
188
+ <UIcon name="i-lucide-boxes" class="mt-0.5 h-4 w-4 shrink-0 text-app-info-400" />
189
189
  <div class="min-w-0 flex-1">
190
- <p class="truncate text-sm font-medium text-slate-100">
190
+ <p class="truncate text-sm font-medium text-app-100">
191
191
  {{ s.name }}
192
- <code class="ms-1 text-[11px] text-slate-500">{{ s.id }}</code>
192
+ <code class="ms-1 text-[11px] text-dimmed">{{ s.id }}</code>
193
193
  </p>
194
- <p class="text-xs text-slate-400">{{ s.summary }}</p>
194
+ <p class="text-xs text-muted">{{ s.summary }}</p>
195
195
  <div v-if="s.capabilities.length" class="mt-1 flex flex-wrap gap-1">
196
196
  <UBadge v-for="c in s.capabilities" :key="c" size="xs" variant="subtle" color="neutral">
197
197
  {{ c }}
198
198
  </UBadge>
199
199
  </div>
200
200
  <FoundationalContractSummary :contracts="s.contracts" :format-label="formatLabel" />
201
- <p v-if="s.sourceId" class="mt-1 text-[11px] text-slate-500">
201
+ <p v-if="s.sourceId" class="mt-1 text-[11px] text-dimmed">
202
202
  {{ t('foundational.registry.fromSource', { path: s.sourcePath ?? '' }) }}
203
203
  </p>
204
204
  </div>
@@ -222,7 +222,7 @@ async function remove(service: FoundationalService) {
222
222
  </div>
223
223
  </div>
224
224
  </div>
225
- <p v-if="!catalog.services.length" class="text-sm text-slate-500">
225
+ <p v-if="!catalog.services.length" class="text-sm text-dimmed">
226
226
  {{ t('foundational.registry.empty') }}
227
227
  </p>
228
228
 
@@ -238,7 +238,7 @@ async function remove(service: FoundationalService) {
238
238
  {{ t('foundational.registry.add') }}
239
239
  </UButton>
240
240
 
241
- <div v-else class="rounded-md border border-slate-800 p-3">
241
+ <div v-else class="rounded-md border border-default p-3">
242
242
  <p class="mb-2 text-sm font-medium">
243
243
  {{
244
244
  isCreating ? t('foundational.registry.addTitle') : t('foundational.registry.editTitle')
@@ -251,8 +251,8 @@ async function remove(service: FoundationalService) {
251
251
  v-model="draft.id"
252
252
  :placeholder="t('foundational.registry.idPlaceholder')"
253
253
  />
254
- <p v-else class="text-xs text-slate-500">
255
- <code class="text-slate-300">{{ draft.id }}</code>
254
+ <p v-else class="text-xs text-dimmed">
255
+ <code class="text-toned">{{ draft.id }}</code>
256
256
  — {{ t('foundational.registry.idFixed') }}
257
257
  </p>
258
258
  <UInput v-model="draft.name" :placeholder="t('foundational.registry.namePlaceholder')" />
@@ -270,11 +270,11 @@ async function remove(service: FoundationalService) {
270
270
  :placeholder="t('foundational.registry.capabilitiesPlaceholder')"
271
271
  />
272
272
 
273
- <div class="rounded-md border border-slate-800 p-2">
274
- <p class="text-xs font-medium text-slate-300">
273
+ <div class="rounded-md border border-default p-2">
274
+ <p class="text-xs font-medium text-toned">
275
275
  {{ t('foundational.registry.contractsTitle') }}
276
276
  </p>
277
- <p class="mb-2 text-[11px] text-slate-500">
277
+ <p class="mb-2 text-[11px] text-dimmed">
278
278
  {{
279
279
  draft.contractsTouched
280
280
  ? t('foundational.registry.contractsReplace')
@@ -245,14 +245,14 @@ async function unlink(id: string) {
245
245
  <div
246
246
  v-for="s in catalog.sources"
247
247
  :key="s.id"
248
- class="flex items-center gap-2 rounded-md border border-slate-800 bg-slate-900/60 p-3"
248
+ class="flex items-center gap-2 rounded-md border border-default bg-default/60 p-3"
249
249
  >
250
- <UIcon name="i-lucide-git-branch" class="h-4 w-4 shrink-0 text-slate-400" />
250
+ <UIcon name="i-lucide-git-branch" class="h-4 w-4 shrink-0 text-muted" />
251
251
  <div class="min-w-0">
252
- <span class="font-mono text-sm text-slate-100">
253
- {{ s.repoOwner }}/{{ s.repoName }}<span class="text-slate-500">/{{ s.dirPath }}</span>
252
+ <span class="font-mono text-sm text-app-100">
253
+ {{ s.repoOwner }}/{{ s.repoName }}<span class="text-dimmed">/{{ s.dirPath }}</span>
254
254
  </span>
255
- <p class="text-xs text-slate-500">
255
+ <p class="text-xs text-dimmed">
256
256
  <template v-if="s.mode === 'files'">
257
257
  {{
258
258
  t('foundational.sources.metaFiles', {
@@ -274,7 +274,7 @@ async function unlink(id: string) {
274
274
  </template>
275
275
  <template v-else>{{ t('foundational.sources.metaDirectory') }}</template>
276
276
  </p>
277
- <p class="text-xs text-slate-500">
277
+ <p class="text-xs text-dimmed">
278
278
  {{
279
279
  s.lastSyncedAt
280
280
  ? t('foundational.sources.metaSynced', {
@@ -322,29 +322,29 @@ async function unlink(id: string) {
322
322
  />
323
323
  </div>
324
324
  </div>
325
- <p v-if="!catalog.sources.length" class="text-sm text-slate-500">
325
+ <p v-if="!catalog.sources.length" class="text-sm text-dimmed">
326
326
  {{ t('foundational.sources.empty') }}
327
327
  </p>
328
328
 
329
329
  <!-- Linking needs the GitHub integration; say so rather than offering a form that 503s. -->
330
330
  <div
331
331
  v-if="!catalog.sourcesAvailable"
332
- class="rounded-md border border-slate-800 bg-slate-900/40 p-3 text-sm text-slate-500"
332
+ class="rounded-md border border-default bg-default/40 p-3 text-sm text-dimmed"
333
333
  >
334
334
  {{ t('foundational.sources.githubRequired') }}
335
335
  </div>
336
- <div v-else class="rounded-md border border-slate-800 p-3">
336
+ <div v-else class="rounded-md border border-default p-3">
337
337
  <p class="mb-2 text-sm font-medium">{{ t('foundational.sources.linkTitle') }}</p>
338
338
  <div class="flex flex-col gap-2">
339
339
  <URadioGroup v-model="mode" :items="modeItems" orientation="horizontal" size="sm" />
340
- <p class="text-xs text-slate-500">{{ modeHints[mode] }}</p>
340
+ <p class="text-xs text-dimmed">{{ modeHints[mode] }}</p>
341
341
 
342
342
  <!-- Connected: search a repo, then browse to the folder / pick the contract files -->
343
343
  <template v-if="githubReady">
344
344
  <GitHubRepoSearchSelect v-model="repoId" @update:repo="repo = $event" />
345
345
  <div
346
346
  v-if="repoId !== undefined"
347
- class="rounded-md border border-slate-800 bg-slate-900/40 p-2"
347
+ class="rounded-md border border-default bg-default/40 p-2"
348
348
  >
349
349
  <RepoTreeBrowser
350
350
  v-if="mode === 'files'"
@@ -355,13 +355,13 @@ async function unlink(id: string) {
355
355
  @toggle="toggleFile"
356
356
  />
357
357
  <RepoTreeBrowser v-else v-model="dirPath" :repo-github-id="repoId" mode="dir" />
358
- <p class="mt-2 truncate text-xs text-slate-400">
358
+ <p class="mt-2 truncate text-xs text-muted">
359
359
  <template v-if="mode === 'files'">
360
360
  {{ t('foundational.sources.selectedFiles', { count: filePaths.length }) }}
361
361
  </template>
362
362
  <template v-else-if="dirPath">
363
363
  {{ t('foundational.sources.selectedDir') }}
364
- <code class="text-slate-200">{{ dirPath }}</code>
364
+ <code class="text-default">{{ dirPath }}</code>
365
365
  </template>
366
366
  <template v-else>{{ t('foundational.sources.wholeRepo') }}</template>
367
367
  </p>
@@ -63,20 +63,20 @@ async function restore(serviceId: string) {
63
63
  data-testid="foundational-suppressions"
64
64
  >
65
65
  <p class="text-sm font-medium">{{ title[props.kind] }}</p>
66
- <p class="text-xs text-slate-500">{{ intro[props.kind] }}</p>
66
+ <p class="text-xs text-dimmed">{{ intro[props.kind] }}</p>
67
67
  <div
68
68
  v-for="s in catalog.suppressions"
69
69
  :key="s.id"
70
- class="flex items-center gap-2 rounded-md border border-slate-800 bg-slate-900/40 p-3"
70
+ class="flex items-center gap-2 rounded-md border border-default bg-default/40 p-3"
71
71
  >
72
- <UIcon name="i-lucide-eye-off" class="h-4 w-4 shrink-0 text-slate-500" />
72
+ <UIcon name="i-lucide-eye-off" class="h-4 w-4 shrink-0 text-dimmed" />
73
73
  <div class="min-w-0 flex-1">
74
- <p class="truncate text-sm text-slate-300">
74
+ <p class="truncate text-sm text-toned">
75
75
  {{ s.name || s.id }}
76
- <code v-if="s.name" class="ms-1 text-[11px] text-slate-500">{{ s.id }}</code>
76
+ <code v-if="s.name" class="ms-1 text-[11px] text-dimmed">{{ s.id }}</code>
77
77
  </p>
78
- <p v-if="s.summary" class="text-xs text-slate-500">{{ s.summary }}</p>
79
- <p v-if="!s.inherited" class="text-[11px] text-slate-500">
78
+ <p v-if="s.summary" class="text-xs text-dimmed">{{ s.summary }}</p>
79
+ <p v-if="!s.inherited" class="text-[11px] text-dimmed">
80
80
  {{ t('foundational.suppressions.shadowsNothing') }}
81
81
  </p>
82
82
  </div>
@@ -219,30 +219,30 @@ async function disconnect() {
219
219
  <!-- Unwired is stated, never offered as a form that would fail with a raw 503. -->
220
220
  <div
221
221
  v-if="catalog.serviceCatalogAvailable === false"
222
- class="rounded-md border border-slate-800 bg-slate-900/40 p-3 text-sm text-slate-400"
222
+ class="rounded-md border border-default bg-default/40 p-3 text-sm text-muted"
223
223
  >
224
224
  {{ t('serviceCatalog.unavailable') }}
225
225
  </div>
226
226
 
227
227
  <template v-else>
228
- <p class="text-sm text-slate-400">{{ t('serviceCatalog.intro') }}</p>
228
+ <p class="text-sm text-muted">{{ t('serviceCatalog.intro') }}</p>
229
229
 
230
230
  <!-- The CONNECTED state, with what the last import concluded. `lastSyncMessage` is the
231
231
  load-bearing line: it is what says a catalog is a PREFIX of the portal's estate. -->
232
232
  <div
233
233
  v-if="connection"
234
- class="flex flex-col gap-2 rounded-md border border-slate-800 bg-slate-900/40 p-3"
234
+ class="flex flex-col gap-2 rounded-md border border-default bg-default/40 p-3"
235
235
  data-testid="service-catalog-connected"
236
236
  >
237
237
  <div class="flex flex-wrap items-center gap-2">
238
238
  <UBadge :color="syncStatusColor" variant="subtle">{{ statusLabel }}</UBadge>
239
- <span class="font-mono text-xs text-slate-300">{{ connection.baseUrl }}</span>
240
- <span class="text-xs text-slate-500">{{ authModeLabel(connection.authMode) }}</span>
241
- <span v-if="connection.lastSyncedAt" class="text-xs text-slate-500">
239
+ <span class="font-mono text-xs text-toned">{{ connection.baseUrl }}</span>
240
+ <span class="text-xs text-dimmed">{{ authModeLabel(connection.authMode) }}</span>
241
+ <span v-if="connection.lastSyncedAt" class="text-xs text-dimmed">
242
242
  {{ d(new Date(connection.lastSyncedAt), 'short') }}
243
243
  </span>
244
244
  </div>
245
- <p class="text-xs text-slate-400">
245
+ <p class="text-xs text-muted">
246
246
  {{
247
247
  t('serviceCatalog.summary', {
248
248
  filter: connection.entityFilter.join(', '),
@@ -250,7 +250,7 @@ async function disconnect() {
250
250
  })
251
251
  }}
252
252
  </p>
253
- <p v-if="connection.lastSyncMessage" class="text-xs text-amber-400">
253
+ <p v-if="connection.lastSyncMessage" class="text-xs text-app-warning-400">
254
254
  {{ connection.lastSyncMessage }}
255
255
  </p>
256
256
  <div class="flex gap-2">
@@ -272,8 +272,8 @@ async function disconnect() {
272
272
 
273
273
  <!-- The connect / re-connect form. Shown alongside a live connection too, because rotating
274
274
  a token is the routine reason to come here. -->
275
- <div class="flex flex-col gap-3 rounded-md border border-slate-800 p-3">
276
- <h4 class="text-sm font-medium text-slate-200">
275
+ <div class="flex flex-col gap-3 rounded-md border border-default p-3">
276
+ <h4 class="text-sm font-medium text-default">
277
277
  {{ connection ? t('serviceCatalog.form.replace') : t('serviceCatalog.form.connect') }}
278
278
  </h4>
279
279