@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
@@ -229,10 +229,10 @@ function openSpawnedTask(taskId: string): void {
229
229
  }
230
230
 
231
231
  const SEVERITY_CLASS: Record<BugFishingSeverity, string> = {
232
- critical: 'bg-red-500/15 text-red-300 border-red-500/30',
233
- high: 'bg-orange-500/15 text-orange-300 border-orange-500/30',
234
- medium: 'bg-amber-500/15 text-amber-200 border-amber-500/30',
235
- low: 'bg-slate-500/15 text-slate-300 border-slate-600/40',
232
+ critical: 'bg-app-error-500/15 text-app-error-300 border-app-error-500/30',
233
+ high: 'bg-app-hue-orange/15 text-app-hue-orange border-app-hue-orange/30',
234
+ medium: 'bg-app-warning-500/15 text-app-warning-200 border-app-warning-500/30',
235
+ low: 'bg-app-500/15 text-toned border-app-600/40',
236
236
  }
237
237
 
238
238
  const PHASE_ICON: Record<string, string> = {
@@ -247,7 +247,7 @@ const PHASE_ICON: Record<string, string> = {
247
247
  <ResultWindowShell
248
248
  :open="open"
249
249
  icon="i-lucide-fish"
250
- icon-class="bg-sky-500/15 text-sky-300"
250
+ icon-class="bg-app-info-500/15 text-app-info-300"
251
251
  :title="block ? t('bugFishing.titleWithBlock', { title: block.title }) : t('bugFishing.title')"
252
252
  :subtitle="t('bugFishing.subtitle')"
253
253
  width="full"
@@ -261,9 +261,9 @@ const PHASE_ICON: Record<string, string> = {
261
261
  phase that found nothing from one that has not run yet. -->
262
262
  <aside
263
263
  data-testid="bug-fishing-phases"
264
- class="w-60 shrink-0 overflow-y-auto border-r border-slate-800 px-3 py-4"
264
+ class="w-60 shrink-0 overflow-y-auto border-r border-default px-3 py-4"
265
265
  >
266
- <p class="mb-2 px-1 text-[10px] font-semibold uppercase tracking-wide text-slate-500">
266
+ <p class="mb-2 px-1 text-[10px] font-semibold uppercase tracking-wide text-dimmed">
267
267
  {{ t('bugFishing.phases.heading') }}
268
268
  </p>
269
269
  <button
@@ -271,8 +271,8 @@ const PHASE_ICON: Record<string, string> = {
271
271
  class="mb-1 w-full rounded-md px-2 py-1.5 text-left text-[12px]"
272
272
  :class="
273
273
  selectedPassKey === null
274
- ? 'bg-slate-800 text-slate-100'
275
- : 'text-slate-400 hover:bg-slate-800/60'
274
+ ? 'bg-elevated text-app-100'
275
+ : 'text-muted hover:bg-elevated/60'
276
276
  "
277
277
  @click="selectedPassKey = null"
278
278
  >
@@ -283,7 +283,7 @@ const PHASE_ICON: Record<string, string> = {
283
283
  <div v-for="group in territoryGroups" :key="group.id ?? 'whole'" class="mb-2">
284
284
  <p
285
285
  v-if="group.label"
286
- class="mb-1 mt-2 truncate px-1 text-[10px] font-semibold uppercase tracking-wide text-sky-400/80"
286
+ class="mb-1 mt-2 truncate px-1 text-[10px] font-semibold uppercase tracking-wide text-app-info-400/80"
287
287
  :title="group.label"
288
288
  >
289
289
  {{ group.label }}
@@ -295,8 +295,8 @@ const PHASE_ICON: Record<string, string> = {
295
295
  class="flex w-full items-start gap-2 rounded-md px-2 py-1.5 text-left"
296
296
  :class="
297
297
  selectedPassKey === passKey(phase)
298
- ? 'bg-slate-800 text-slate-100'
299
- : 'text-slate-400 hover:bg-slate-800/60'
298
+ ? 'bg-elevated text-app-100'
299
+ : 'text-muted hover:bg-elevated/60'
300
300
  "
301
301
  :data-testid="`bug-fishing-phase-${phase.id}`"
302
302
  @click="selectedPassKey = passKey(phase)"
@@ -305,15 +305,15 @@ const PHASE_ICON: Record<string, string> = {
305
305
  :name="PHASE_ICON[phase.status] ?? 'i-lucide-circle-dashed'"
306
306
  class="mt-0.5 h-3.5 w-3.5 shrink-0"
307
307
  :class="{
308
- 'animate-spin text-sky-300': phase.status === 'fishing',
309
- 'text-emerald-400': phase.status === 'completed',
310
- 'text-amber-400': phase.status === 'failed',
311
- 'text-slate-600': phase.status === 'pending',
308
+ 'animate-spin text-app-info-300': phase.status === 'fishing',
309
+ 'text-app-success-400': phase.status === 'completed',
310
+ 'text-app-warning-400': phase.status === 'failed',
311
+ 'text-app-600': phase.status === 'pending',
312
312
  }"
313
313
  />
314
314
  <span class="min-w-0 flex-1">
315
315
  <span class="block truncate text-[12px]">{{ phase.title }}</span>
316
- <span class="block text-[10px] text-slate-500">
316
+ <span class="block text-[10px] text-dimmed">
317
317
  {{
318
318
  phase.status === 'completed' || phase.status === 'failed'
319
319
  ? t('bugFishing.phases.found', { count: phaseFindingCount(phase) })
@@ -329,13 +329,13 @@ const PHASE_ICON: Record<string, string> = {
329
329
  :data-testid="`bug-fishing-coverage-${phase.id}`"
330
330
  :title="t('bugFishing.coverage.tooltip', { percent: coverageShare(phase) })"
331
331
  >
332
- <span class="block h-0.5 w-full rounded-full bg-slate-700">
332
+ <span class="block h-0.5 w-full rounded-full bg-accented">
333
333
  <span
334
- class="block h-0.5 rounded-full bg-sky-500/70"
334
+ class="block h-0.5 rounded-full bg-app-info-500/70"
335
335
  :style="{ width: `${coverageShare(phase)}%` }"
336
336
  />
337
337
  </span>
338
- <span class="mt-0.5 block text-[10px] text-slate-600">
338
+ <span class="mt-0.5 block text-[10px] text-app-600">
339
339
  {{ t('bugFishing.coverage.share', { percent: coverageShare(phase) }) }}
340
340
  </span>
341
341
  </span>
@@ -352,13 +352,13 @@ const PHASE_ICON: Record<string, string> = {
352
352
  that reported nothing because it found nothing are different facts. -->
353
353
  <div
354
354
  v-if="selectedPhase"
355
- class="mb-4 rounded-lg border border-slate-800 bg-slate-900/40 px-3 py-2.5"
355
+ class="mb-4 rounded-lg border border-default bg-default/40 px-3 py-2.5"
356
356
  >
357
- <p class="text-[11px] text-slate-400">{{ selectedPhase.goal }}</p>
357
+ <p class="text-[11px] text-muted">{{ selectedPhase.goal }}</p>
358
358
  <p
359
359
  v-if="selectedPhase.status === 'failed'"
360
360
  data-testid="bug-fishing-phase-failed"
361
- class="mt-2 text-[12px] text-amber-300"
361
+ class="mt-2 text-[12px] text-app-warning-300"
362
362
  >
363
363
  {{ t('bugFishing.phases.failedNote', { reason: selectedPhase.failureReason ?? '' }) }}
364
364
  </p>
@@ -374,7 +374,7 @@ const PHASE_ICON: Record<string, string> = {
374
374
  <div
375
375
  v-if="fishing"
376
376
  data-testid="bug-fishing-in-progress"
377
- class="mb-4 flex items-center gap-2 rounded-lg border border-sky-500/25 bg-sky-500/5 px-3 py-2 text-[12px] text-sky-200"
377
+ class="mb-4 flex items-center gap-2 rounded-lg border border-app-info-500/25 bg-app-info-500/5 px-3 py-2 text-[12px] text-app-info-200"
378
378
  >
379
379
  <UIcon name="i-lucide-loader-circle" class="h-4 w-4 shrink-0 animate-spin" />
380
380
  <span>
@@ -395,7 +395,7 @@ const PHASE_ICON: Record<string, string> = {
395
395
  <div
396
396
  v-if="plan && (unfished.length > 0 || plan.treeTruncated || plan.surveyUnavailableReason)"
397
397
  data-testid="bug-fishing-plan"
398
- class="mb-4 rounded-lg border border-amber-500/25 bg-amber-500/5 px-3 py-2 text-[12px] text-amber-200"
398
+ class="mb-4 rounded-lg border border-app-warning-500/25 bg-app-warning-500/5 px-3 py-2 text-[12px] text-app-warning-200"
399
399
  >
400
400
  <p v-if="plan.surveyUnavailableReason" data-testid="bug-fishing-survey-unavailable">
401
401
  {{ t('bugFishing.plan.surveyUnavailable', { reason: plan.surveyUnavailableReason }) }}
@@ -412,7 +412,7 @@ const PHASE_ICON: Record<string, string> = {
412
412
  })
413
413
  }}
414
414
  </p>
415
- <ul class="mt-1 space-y-0.5 text-[11px] text-amber-200/80">
415
+ <ul class="mt-1 space-y-0.5 text-[11px] text-app-warning-200/80">
416
416
  <li v-for="cell in unfished" :key="`${cell.territoryId}::${cell.phaseId}`">
417
417
  {{
418
418
  t('bugFishing.plan.unfishedCell', {
@@ -430,9 +430,9 @@ const PHASE_ICON: Record<string, string> = {
430
430
  <div
431
431
  v-if="canAct"
432
432
  data-testid="bug-fishing-pipeline"
433
- class="mb-4 flex flex-wrap items-center gap-2 rounded-lg border border-slate-800 bg-slate-900/40 px-3 py-2"
433
+ class="mb-4 flex flex-wrap items-center gap-2 rounded-lg border border-default bg-default/40 px-3 py-2"
434
434
  >
435
- <span class="text-[11px] text-slate-400">{{ t('bugFishing.fixPipeline.label') }}</span>
435
+ <span class="text-[11px] text-muted">{{ t('bugFishing.fixPipeline.label') }}</span>
436
436
  <USelectMenu
437
437
  v-model="pipelineOverride"
438
438
  :items="pipelineOptions"
@@ -440,22 +440,22 @@ const PHASE_ICON: Record<string, string> = {
440
440
  size="xs"
441
441
  class="min-w-52"
442
442
  />
443
- <span class="text-[11px] text-slate-500">
443
+ <span class="text-[11px] text-dimmed">
444
444
  {{ t('bugFishing.fixPipeline.hint', { pipeline: effectivePipelineName ?? '—' }) }}
445
445
  </span>
446
446
  </div>
447
447
 
448
448
  <div class="mb-2 flex items-center justify-between">
449
- <p class="text-[11px] text-slate-400">
449
+ <p class="text-[11px] text-muted">
450
450
  {{ t('bugFishing.counts', { untriaged: untriagedCount, spawned: spawnedCount }) }}
451
451
  </p>
452
- <label class="flex items-center gap-1.5 text-[11px] text-slate-400">
453
- <input v-model="showTriaged" type="checkbox" class="accent-sky-500" />
452
+ <label class="flex items-center gap-1.5 text-[11px] text-muted">
453
+ <input v-model="showTriaged" type="checkbox" class="accent-app-info-500" />
454
454
  {{ t('bugFishing.showTriaged') }}
455
455
  </label>
456
456
  </div>
457
457
 
458
- <p v-if="bugFishing.error" class="mb-3 text-[12px] text-red-300">
458
+ <p v-if="bugFishing.error" class="mb-3 text-[12px] text-app-error-300">
459
459
  {{ bugFishing.error }}
460
460
  </p>
461
461
 
@@ -465,7 +465,7 @@ const PHASE_ICON: Record<string, string> = {
465
465
  <div
466
466
  v-if="visibleFindings.length === 0"
467
467
  data-testid="bug-fishing-empty"
468
- class="rounded-lg border border-slate-800 bg-slate-900/40 px-4 py-8 text-center text-[12px] text-slate-400"
468
+ class="rounded-lg border border-default bg-default/40 px-4 py-8 text-center text-[12px] text-muted"
469
469
  >
470
470
  {{
471
471
  findings.length === 0
@@ -479,7 +479,7 @@ const PHASE_ICON: Record<string, string> = {
479
479
  v-for="finding in visibleFindings"
480
480
  :key="finding.id"
481
481
  :data-testid="`bug-fishing-finding-${finding.id}`"
482
- class="rounded-lg border border-slate-800 bg-slate-900/40 px-3 py-2.5"
482
+ class="rounded-lg border border-default bg-default/40 px-3 py-2.5"
483
483
  :class="{ 'opacity-60': finding.dismissed }"
484
484
  >
485
485
  <div class="flex flex-wrap items-center gap-2">
@@ -489,28 +489,28 @@ const PHASE_ICON: Record<string, string> = {
489
489
  >
490
490
  {{ t(`bugFishing.severity.${finding.severity}`) }}
491
491
  </span>
492
- <span class="rounded bg-slate-800 px-1.5 py-0.5 text-[10px] text-slate-300">
492
+ <span class="rounded bg-elevated px-1.5 py-0.5 text-[10px] text-toned">
493
493
  {{ t(`bugFishing.kind.${finding.kind}`) }}
494
494
  </span>
495
- <span class="text-[10px] text-slate-500">
495
+ <span class="text-[10px] text-dimmed">
496
496
  {{ t(`bugFishing.confidence.${finding.confidence}`) }}
497
497
  </span>
498
498
  <span
499
- class="min-w-0 flex-1 text-[13px] text-slate-100"
499
+ class="min-w-0 flex-1 text-[13px] text-app-100"
500
500
  :class="{ 'line-through': finding.dismissed }"
501
501
  >
502
502
  {{ finding.title }}
503
503
  </span>
504
504
  </div>
505
505
 
506
- <p v-if="finding.path" class="mt-1 font-mono text-[11px] text-slate-500">
506
+ <p v-if="finding.path" class="mt-1 font-mono text-[11px] text-dimmed">
507
507
  {{ finding.path }}<span v-if="finding.line">:{{ finding.line }}</span>
508
508
  </p>
509
509
 
510
510
  <MarkdownProse :text="finding.detail" class="mt-2 max-w-3xl text-[12px]" />
511
511
 
512
- <div v-if="finding.failureScenario" class="mt-2 text-[12px] text-slate-300">
513
- <span class="text-[10px] font-semibold uppercase tracking-wide text-slate-500">
512
+ <div v-if="finding.failureScenario" class="mt-2 text-[12px] text-toned">
513
+ <span class="text-[10px] font-semibold uppercase tracking-wide text-dimmed">
514
514
  {{ t('bugFishing.finding.failureScenario') }}
515
515
  </span>
516
516
  <MarkdownProse :text="finding.failureScenario" class="mt-0.5 max-w-3xl" />
@@ -520,14 +520,14 @@ const PHASE_ICON: Record<string, string> = {
520
520
  apart: a finding that cannot point at the code it describes is speculating, and
521
521
  that should be visible without reading the prose for it. -->
522
522
  <details v-if="finding.evidence" class="mt-2">
523
- <summary class="cursor-pointer text-[11px] text-slate-400 hover:text-slate-200">
523
+ <summary class="cursor-pointer text-[11px] text-muted hover:text-default">
524
524
  {{ t('bugFishing.finding.evidence') }}
525
525
  </summary>
526
526
  <MarkdownProse :text="finding.evidence" class="mt-1 max-w-3xl text-[12px]" />
527
527
  </details>
528
528
 
529
529
  <details v-if="finding.suggestedFix" class="mt-1">
530
- <summary class="cursor-pointer text-[11px] text-slate-400 hover:text-slate-200">
530
+ <summary class="cursor-pointer text-[11px] text-muted hover:text-default">
531
531
  {{ t('bugFishing.finding.suggestedFix') }}
532
532
  </summary>
533
533
  <MarkdownProse :text="finding.suggestedFix" class="mt-1 max-w-3xl text-[12px]" />
@@ -540,7 +540,7 @@ const PHASE_ICON: Record<string, string> = {
540
540
  <div
541
541
  v-if="finding.spawn?.status === 'spawned'"
542
542
  data-testid="bug-fishing-finding-spawned"
543
- class="mt-2 flex flex-wrap items-center gap-2 text-[11px] text-emerald-300"
543
+ class="mt-2 flex flex-wrap items-center gap-2 text-[11px] text-app-success-300"
544
544
  >
545
545
  <UIcon name="i-lucide-check-circle-2" class="h-3.5 w-3.5" />
546
546
  <span>
@@ -554,7 +554,7 @@ const PHASE_ICON: Record<string, string> = {
554
554
  </span>
555
555
  <button
556
556
  type="button"
557
- class="underline hover:text-emerald-200"
557
+ class="underline hover:text-app-success-200"
558
558
  @click="openSpawnedTask(finding.spawn.taskId)"
559
559
  >
560
560
  {{ t('bugFishing.finding.openTask') }}
@@ -566,7 +566,7 @@ const PHASE_ICON: Record<string, string> = {
566
566
  <div
567
567
  v-else-if="finding.spawn?.status === 'pending'"
568
568
  data-testid="bug-fishing-finding-spawning"
569
- class="mt-2 flex flex-wrap items-center gap-2 text-[11px] text-slate-400"
569
+ class="mt-2 flex flex-wrap items-center gap-2 text-[11px] text-muted"
570
570
  >
571
571
  <UIcon name="i-lucide-loader-circle" class="h-3.5 w-3.5 animate-spin" />
572
572
  <span>{{ t('bugFishing.finding.spawning') }}</span>
@@ -577,7 +577,7 @@ const PHASE_ICON: Record<string, string> = {
577
577
  <p
578
578
  v-else-if="finding.spawn?.status === 'failed'"
579
579
  data-testid="bug-fishing-finding-spawn-failed"
580
- class="mt-2 max-w-3xl text-[11px] text-amber-300"
580
+ class="mt-2 max-w-3xl text-[11px] text-app-warning-300"
581
581
  >
582
582
  {{
583
583
  t('bugFishing.finding.spawnFailed', {
@@ -621,9 +621,9 @@ const PHASE_ICON: Record<string, string> = {
621
621
  (it is not — the run advances past the step and the remaining angles never run). -->
622
622
  <footer
623
623
  v-if="awaiting"
624
- class="flex items-center justify-between gap-3 border-t border-slate-800 px-5 py-3"
624
+ class="flex items-center justify-between gap-3 border-t border-default px-5 py-3"
625
625
  >
626
- <p class="text-[11px] text-slate-500">
626
+ <p class="text-[11px] text-dimmed">
627
627
  {{
628
628
  untriagedCount > 0
629
629
  ? t('bugFishing.footer.parkedWithUntriaged', { count: untriagedCount })
@@ -298,7 +298,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
298
298
  <ResultWindowShell
299
299
  :open="open"
300
300
  icon="i-lucide-bug"
301
- icon-class="bg-indigo-500/15 text-indigo-300"
301
+ icon-class="bg-primary/15 text-primary"
302
302
  :title="t('clarity.title')"
303
303
  :subtitle="block?.title"
304
304
  variant="centered"
@@ -314,14 +314,14 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
314
314
  <div class="flex min-h-0 flex-1 flex-col lg:flex-row">
315
315
  <!-- main column -->
316
316
  <div class="min-w-0 flex-1 overflow-y-auto px-6 py-5">
317
- <p class="mb-4 text-sm text-slate-400">
317
+ <p class="mb-4 text-sm text-muted">
318
318
  <i18n-t keypath="clarity.intro" tag="span" scope="global">
319
319
  <template #level>{{ block?.level ?? t('clarity.itemFallback') }}</template>
320
320
  <template #answer
321
- ><span class="text-slate-300">{{ t('clarity.introAnswer') }}</span></template
321
+ ><span class="text-toned">{{ t('clarity.introAnswer') }}</span></template
322
322
  >
323
323
  <template #dismiss
324
- ><span class="text-slate-300">{{ t('clarity.introDismiss') }}</span></template
324
+ ><span class="text-toned">{{ t('clarity.introDismiss') }}</span></template
325
325
  >
326
326
  </i18n-t>
327
327
  </p>
@@ -330,7 +330,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
330
330
  gate step, so there's nothing to do here until then -->
331
331
  <div
332
332
  v-if="!review && !busy && !loading"
333
- class="rounded-lg border border-dashed border-slate-700 p-8 text-center text-sm text-slate-500"
333
+ class="rounded-lg border border-dashed border-muted p-8 text-center text-sm text-dimmed"
334
334
  >
335
335
  {{ t('clarity.empty') }}
336
336
  </div>
@@ -338,7 +338,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
338
338
  <!-- working state (initial fetch on open, or a reviewer pass running) -->
339
339
  <div
340
340
  v-else-if="(busy || loading) && !review"
341
- class="flex items-center justify-center gap-2 p-8 text-sm text-slate-400"
341
+ class="flex items-center justify-center gap-2 p-8 text-sm text-muted"
342
342
  >
343
343
  <UIcon name="i-lucide-loader-circle" class="h-4 w-4 animate-spin" />
344
344
  {{ loading && !busy ? t('clarity.loadingReview') : t('clarity.triaging') }}
@@ -348,7 +348,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
348
348
  <!-- converged: reviewer satisfied -->
349
349
  <div
350
350
  v-if="incorporated"
351
- class="mb-4 flex items-center gap-2 rounded-lg border border-emerald-900/60 bg-emerald-950/30 p-4 text-sm text-emerald-300"
351
+ class="mb-4 flex items-center gap-2 rounded-lg border border-app-success-900/60 bg-app-success-950/30 p-4 text-sm text-app-success-300"
352
352
  >
353
353
  <UIcon name="i-lucide-circle-check" class="h-5 w-5 shrink-0" />
354
354
  {{ t('clarity.converged') }}
@@ -368,7 +368,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
368
368
  the human can see which of the two LLM calls is currently in progress. -->
369
369
  <div
370
370
  v-else-if="working"
371
- class="mb-4 flex items-center gap-2 rounded-lg border border-indigo-900/60 bg-indigo-950/30 p-4 text-sm text-indigo-200"
371
+ class="mb-4 flex items-center gap-2 rounded-lg border border-primary/60 bg-primary/10 p-4 text-sm text-primary"
372
372
  >
373
373
  <UIcon name="i-lucide-loader-circle" class="h-5 w-5 shrink-0 animate-spin" />
374
374
  <span v-if="incorporating">
@@ -384,17 +384,17 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
384
384
  <div
385
385
  v-for="item in sortedItems"
386
386
  :key="item.id"
387
- class="rounded-lg border border-slate-800 bg-slate-900/60 p-3"
387
+ class="rounded-lg border border-default bg-default/60 p-3"
388
388
  :class="{ 'opacity-60': item.status === 'dismissed' }"
389
389
  >
390
390
  <div class="flex items-start gap-2">
391
391
  <UIcon
392
392
  :name="CATEGORY_ICON[item.category]"
393
- class="mt-0.5 h-4 w-4 shrink-0 text-slate-400"
393
+ class="mt-0.5 h-4 w-4 shrink-0 text-muted"
394
394
  />
395
395
  <div class="min-w-0 flex-1">
396
396
  <div class="flex flex-wrap items-center gap-1.5">
397
- <span class="text-sm font-medium text-white">{{ item.title }}</span>
397
+ <span class="text-sm font-medium text-highlighted">{{ item.title }}</span>
398
398
  <UBadge size="xs" variant="subtle" :color="SEVERITY_COLOR[item.severity]">
399
399
  {{ t(SEVERITY_LABELS[item.severity]) }}
400
400
  </UBadge>
@@ -414,7 +414,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
414
414
  card around it takes the span (see the shell's `width` prop: the unit is the
415
415
  paragraph, not the section). The badge row above and the answer control
416
416
  below are what the full width is actually for. -->
417
- <p class="mt-1 max-w-3xl whitespace-pre-line text-sm text-slate-400">
417
+ <p class="mt-1 max-w-3xl whitespace-pre-line text-sm text-muted">
418
418
  {{ item.detail }}
419
419
  </p>
420
420
 
@@ -422,9 +422,9 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
422
422
  the answer lives in the textarea below, seeded from the reply) -->
423
423
  <div
424
424
  v-if="item.reply && item.status !== 'open' && item.status !== 'answered'"
425
- class="mt-2 max-w-3xl rounded-md border-s-2 border-slate-700 bg-slate-950/40 px-3 py-1.5 text-sm text-slate-300"
425
+ class="mt-2 max-w-3xl rounded-md border-s-2 border-muted bg-app-950/40 px-3 py-1.5 text-sm text-toned"
426
426
  >
427
- <span class="text-[10px] uppercase tracking-wide text-slate-500">
427
+ <span class="text-[10px] uppercase tracking-wide text-dimmed">
428
428
  {{ t('clarity.answerLabel') }}
429
429
  </span>
430
430
  <p class="whitespace-pre-line">{{ item.reply }}</p>
@@ -479,8 +479,8 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
479
479
  </div>
480
480
 
481
481
  <!-- clarified document: the standard-format bug report -->
482
- <section v-if="outline" class="mt-6 border-t border-slate-800 pt-5">
483
- <div class="mb-3 flex items-center gap-1.5 text-[11px] text-emerald-400">
482
+ <section v-if="outline" class="mt-6 border-t border-default pt-5">
483
+ <div class="mb-3 flex items-center gap-1.5 text-[11px] text-app-success-400">
484
484
  <UIcon name="i-lucide-file-check-2" class="h-3.5 w-3.5" />
485
485
  <span class="font-semibold uppercase tracking-wide">
486
486
  {{ incorporated ? t('clarity.docHeading') : t('clarity.docHeadingDraft') }}
@@ -497,18 +497,18 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
497
497
  >
498
498
  <UIcon
499
499
  name="i-lucide-chevron-right"
500
- class="h-3.5 w-3.5 shrink-0 text-slate-500 transition-transform"
500
+ class="h-3.5 w-3.5 shrink-0 text-dimmed transition-transform"
501
501
  :class="collapsed[s.id] ? '' : 'rotate-90'"
502
502
  />
503
503
  <span
504
- class="font-semibold text-white"
504
+ class="font-semibold text-highlighted"
505
505
  :class="s.depth <= 1 ? 'text-base' : s.depth === 2 ? 'text-sm' : 'text-xs'"
506
506
  v-html="s.titleHtml"
507
507
  />
508
508
  </button>
509
509
  <div
510
510
  v-show="!s.title || !collapsed[s.id]"
511
- class="reader-prose mt-1 ps-5.5 text-[13px] leading-relaxed text-slate-300"
511
+ class="reader-prose mt-1 ps-5.5 text-[13px] leading-relaxed text-toned"
512
512
  v-html="s.bodyHtml"
513
513
  />
514
514
  </div>
@@ -521,32 +521,32 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
521
521
  tablet, UX-32). The informational stats collapse away below `lg` to keep the
522
522
  bottom bar compact; the actions themselves always show. -->
523
523
  <aside
524
- class="flex w-full shrink-0 flex-col border-t border-slate-800 lg:w-72 lg:border-s lg:border-t-0"
524
+ class="flex w-full shrink-0 flex-col border-t border-default lg:w-72 lg:border-s lg:border-t-0"
525
525
  >
526
526
  <div class="flex flex-col gap-4 px-4 py-5">
527
- <div v-if="review" class="hidden space-y-2 text-xs text-slate-400 lg:block">
527
+ <div v-if="review" class="hidden space-y-2 text-xs text-muted lg:block">
528
528
  <div class="flex items-center justify-between">
529
529
  <span>{{ t('clarity.rail.findings') }}</span>
530
- <span class="text-slate-300">{{ review.items.length }}</span>
530
+ <span class="text-toned">{{ review.items.length }}</span>
531
531
  </div>
532
532
  <div class="flex items-center justify-between">
533
533
  <span>{{ t('clarity.rail.open') }}</span>
534
- <span class="text-slate-300">{{ openCount }}</span>
534
+ <span class="text-toned">{{ openCount }}</span>
535
535
  </div>
536
536
  <div class="flex items-center justify-between">
537
537
  <span>{{ t('clarity.rail.answered') }}</span>
538
- <span class="text-slate-300">{{ answeredCount }}</span>
538
+ <span class="text-toned">{{ answeredCount }}</span>
539
539
  </div>
540
540
  <div v-if="review.model" class="flex items-center justify-between">
541
541
  <span>{{ t('clarity.rail.model') }}</span>
542
- <span class="truncate ps-2 text-slate-500">{{
542
+ <span class="truncate ps-2 text-dimmed">{{
543
543
  models.labelForRef(review.model) ?? review.model
544
544
  }}</span>
545
545
  </div>
546
546
  </div>
547
547
 
548
548
  <!-- action: ready (answer → incorporate / proceed) -->
549
- <div v-if="review && status === 'ready'" class="space-y-2 border-t border-slate-800 pt-4">
549
+ <div v-if="review && status === 'ready'" class="space-y-2 border-t border-default pt-4">
550
550
  <UButton
551
551
  v-if="canProceed"
552
552
  color="primary"
@@ -574,7 +574,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
574
574
  >
575
575
  {{ t('clarity.incorporateAnswers') }}
576
576
  </UButton>
577
- <p class="text-[11px] leading-relaxed text-slate-500">
577
+ <p class="text-[11px] leading-relaxed text-dimmed">
578
578
  <template v-if="canProceed">
579
579
  {{ t('clarity.hint.proceed') }}
580
580
  </template>
@@ -586,7 +586,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
586
586
  </div>
587
587
 
588
588
  <!-- action: merged (inspect → re-review / redo) -->
589
- <div v-if="review && merged" class="space-y-2 border-t border-slate-800 pt-4">
589
+ <div v-if="review && merged" class="space-y-2 border-t border-default pt-4">
590
590
  <UButton
591
591
  color="primary"
592
592
  size="sm"
@@ -636,14 +636,14 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
636
636
  {{ t('clarity.redoWithDirection') }}
637
637
  </UButton>
638
638
  </div>
639
- <p class="text-[11px] leading-relaxed text-slate-500">
639
+ <p class="text-[11px] leading-relaxed text-dimmed">
640
640
  {{ t('clarity.redoHint') }}
641
641
  </p>
642
642
  </div>
643
643
 
644
644
  <div
645
645
  v-if="review && incorporated"
646
- class="border-t border-slate-800 pt-4 text-[11px] leading-relaxed text-slate-500"
646
+ class="border-t border-default pt-4 text-[11px] leading-relaxed text-dimmed"
647
647
  >
648
648
  {{ t('clarity.incorporatedFooter') }}
649
649
  </div>
@@ -11,15 +11,15 @@ function reload() {
11
11
  <template>
12
12
  <div
13
13
  data-testid="async-view-error"
14
- class="fixed inset-0 z-50 grid place-items-center bg-slate-950/80 p-6 backdrop-blur-sm"
14
+ class="fixed inset-0 z-50 grid place-items-center bg-app-950/80 p-6 backdrop-blur-sm"
15
15
  role="alert"
16
16
  >
17
- <div class="max-w-sm rounded-2xl border border-slate-700 bg-slate-900 p-5 shadow-2xl">
18
- <div class="flex items-center gap-2 text-sm font-semibold text-slate-100">
19
- <UIcon name="i-lucide-unplug" class="h-4 w-4 shrink-0 text-amber-400" />
17
+ <div class="max-w-sm rounded-2xl border border-muted bg-default p-5 shadow-2xl">
18
+ <div class="flex items-center gap-2 text-sm font-semibold text-app-100">
19
+ <UIcon name="i-lucide-unplug" class="h-4 w-4 shrink-0 text-app-warning-400" />
20
20
  {{ t('errors.asyncView.title') }}
21
21
  </div>
22
- <p class="mt-2 text-[12px] leading-relaxed text-slate-400">
22
+ <p class="mt-2 text-[12px] leading-relaxed text-muted">
23
23
  {{ t('errors.asyncView.body') }}
24
24
  </p>
25
25
  <UButton class="mt-4" color="primary" variant="soft" size="xs" @click="reload">
@@ -49,21 +49,18 @@ const draft = computed({
49
49
  </script>
50
50
 
51
51
  <template>
52
- <div
53
- class="rounded-lg border border-slate-800 bg-slate-950/40 p-3"
54
- data-testid="clarification-item"
55
- >
52
+ <div class="rounded-lg border border-default bg-app-950/40 p-3" data-testid="clarification-item">
56
53
  <div class="flex items-start justify-between gap-2">
57
- <p class="text-[13px] font-medium text-slate-200">{{ prompt }}</p>
54
+ <p class="text-[13px] font-medium text-default">{{ prompt }}</p>
58
55
  <slot name="badges" />
59
56
  </div>
60
- <p v-if="detail" class="mt-1 whitespace-pre-wrap text-[12px] leading-relaxed text-slate-400">
57
+ <p v-if="detail" class="mt-1 whitespace-pre-wrap text-[12px] leading-relaxed text-muted">
61
58
  {{ detail }}
62
59
  </p>
63
60
 
64
61
  <!-- dismissed: a "not relevant" chip + reopen -->
65
62
  <div v-if="dismissed" class="mt-2 flex items-center justify-between gap-2">
66
- <span class="inline-flex items-center gap-1 text-[11px] text-slate-500">
63
+ <span class="inline-flex items-center gap-1 text-[11px] text-dimmed">
67
64
  <UIcon name="i-lucide-x" class="h-3.5 w-3.5" />{{ t('clarification.dismissed') }}
68
65
  </span>
69
66
  <UButton
@@ -82,7 +79,7 @@ const draft = computed({
82
79
  <!-- a recommendation is being requested/generated: a working chip, no answer box -->
83
80
  <div
84
81
  v-else-if="requested"
85
- class="mt-2 inline-flex items-center gap-1 text-[11px] text-indigo-300"
82
+ class="mt-2 inline-flex items-center gap-1 text-[11px] text-primary"
86
83
  data-testid="clarification-requested"
87
84
  >
88
85
  <UIcon name="i-lucide-loader-circle" class="h-3.5 w-3.5 animate-spin" />
@@ -131,15 +128,13 @@ const draft = computed({
131
128
  <!-- inline AI suggestion + "use this answer" -->
132
129
  <div
133
130
  v-if="recommendation"
134
- class="mt-2 rounded-md border border-indigo-800/50 bg-indigo-950/30 p-2"
131
+ class="mt-2 rounded-md border border-primary/50 bg-primary/10 p-2"
135
132
  data-testid="clarification-recommendation"
136
133
  >
137
- <div
138
- class="mb-1 flex items-center gap-1 text-[10px] uppercase tracking-wide text-indigo-300"
139
- >
134
+ <div class="mb-1 flex items-center gap-1 text-[10px] uppercase tracking-wide text-primary">
140
135
  <UIcon name="i-lucide-wand-2" class="h-3 w-3" />{{ t('clarification.suggestion') }}
141
136
  </div>
142
- <p class="whitespace-pre-wrap text-[12px] text-slate-200">{{ recommendation }}</p>
137
+ <p class="whitespace-pre-wrap text-[12px] text-default">{{ recommendation }}</p>
143
138
  <UButton
144
139
  class="mt-1.5"
145
140
  size="xs"
@@ -60,11 +60,13 @@ const isDestructive = computed(() => current.value?.variant === 'destructive')
60
60
  <div
61
61
  v-if="current?.icon"
62
62
  class="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg"
63
- :class="isDestructive ? 'bg-red-500/10 text-red-400' : 'bg-slate-700/40 text-slate-300'"
63
+ :class="
64
+ isDestructive ? 'bg-app-error-500/10 text-app-error-400' : 'bg-accented/40 text-toned'
65
+ "
64
66
  >
65
67
  <UIcon :name="current.icon" class="h-5 w-5" />
66
68
  </div>
67
- <p v-if="current?.description" class="text-sm text-slate-300">
69
+ <p v-if="current?.description" class="text-sm text-toned">
68
70
  {{ current.description }}
69
71
  </p>
70
72
  </div>
@@ -112,7 +112,7 @@ function selectItems(field: DescriptorField) {
112
112
  testid that would have to be slugified to be selectable. -->
113
113
  <p
114
114
  v-if="caption"
115
- class="-mb-1 text-[11px] font-semibold uppercase tracking-wide text-slate-400"
115
+ class="-mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted"
116
116
  :class="{ 'pt-2': startsGroup }"
117
117
  :data-testid="`${testidPrefix}-section`"
118
118
  >
@@ -17,12 +17,12 @@ withDefaults(
17
17
 
18
18
  <template>
19
19
  <div
20
- class="flex flex-col items-center justify-center text-center text-slate-500"
20
+ class="flex flex-col items-center justify-center text-center text-dimmed"
21
21
  :class="compact ? 'gap-1 py-4' : 'gap-2 py-10'"
22
22
  data-testid="empty-state"
23
23
  >
24
- <UIcon :name="icon" :class="compact ? 'h-5 w-5' : 'h-8 w-8'" class="text-slate-600" />
25
- <p :class="compact ? 'text-xs' : 'text-sm'" class="font-medium text-slate-400">
24
+ <UIcon :name="icon" :class="compact ? 'h-5 w-5' : 'h-8 w-8'" class="text-app-600" />
25
+ <p :class="compact ? 'text-xs' : 'text-sm'" class="font-medium text-muted">
26
26
  {{ title }}
27
27
  </p>
28
28
  <p v-if="description" :class="compact ? 'text-[11px]' : 'text-xs'" class="max-w-xs">