@cat-factory/app 0.308.0 → 0.310.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/README.md +32 -2
  2. package/app/assets/css/main.css +22 -0
  3. package/app/assets/css/prose.css +4 -4
  4. package/app/assets/css/type.css +24 -0
  5. package/app/components/assistant/AssistantModal.vue +8 -6
  6. package/app/components/auth/BackendMisconfiguredScreen.vue +4 -3
  7. package/app/components/auth/LoginScreen.vue +40 -26
  8. package/app/components/auth/ResetPasswordScreen.vue +9 -4
  9. package/app/components/auth/UserMenu.vue +5 -4
  10. package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +48 -37
  11. package/app/components/binaryOutput/BinaryOutputReport.vue +10 -14
  12. package/app/components/binaryOutput/StoredAssetView.vue +13 -11
  13. package/app/components/board/AddTaskModal.vue +30 -27
  14. package/app/components/board/AgentFailureCard.vue +21 -18
  15. package/app/components/board/AgentFailureHistory.vue +18 -9
  16. package/app/components/board/CreateInitiativeModal.vue +7 -6
  17. package/app/components/board/FailureDetail.vue +22 -12
  18. package/app/components/board/FailureHistoryList.vue +5 -5
  19. package/app/components/board/RecurringPipelineModal.vue +12 -11
  20. package/app/components/board/ReviewFrictionDialog.vue +8 -6
  21. package/app/components/board/StepExecutionHistory.vue +8 -8
  22. package/app/components/board/nodes/AgentChip.vue +1 -1
  23. package/app/components/board/nodes/BlockNode.vue +25 -24
  24. package/app/components/board/nodes/DecisionBadge.vue +4 -3
  25. package/app/components/board/nodes/EpicNode.vue +4 -4
  26. package/app/components/board/nodes/FrameSwimlanes.vue +8 -10
  27. package/app/components/board/nodes/InitiativeCard.vue +4 -4
  28. package/app/components/board/nodes/LaneGroup.vue +3 -5
  29. package/app/components/board/nodes/TaskCard.vue +20 -15
  30. package/app/components/board/nodes/TaskLane.vue +3 -3
  31. package/app/components/board/nodes/TaskPipelineMini.vue +21 -18
  32. package/app/components/bootstrap/AdoptionReviewModal.vue +36 -26
  33. package/app/components/bootstrap/BootstrapModal.vue +14 -13
  34. package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
  35. package/app/components/brainstorm/BrainstormWindow.vue +13 -10
  36. package/app/components/bugFishing/BugFishingWindow.vue +81 -58
  37. package/app/components/clarity/ClarityReviewWindow.vue +13 -10
  38. package/app/components/common/AsyncViewError.vue +1 -1
  39. package/app/components/common/ClarificationItem.vue +6 -6
  40. package/app/components/common/CopyButton.vue +12 -11
  41. package/app/components/common/DescriptorFields.vue +1 -1
  42. package/app/components/common/EmptyState.vue +1 -1
  43. package/app/components/common/IconButton.vue +34 -9
  44. package/app/components/common/InterviewGateNotice.vue +4 -4
  45. package/app/components/common/MarkdownProse.vue +8 -2
  46. package/app/components/common/SectionLabel.vue +38 -0
  47. package/app/components/consensus/ConsensusSessionWindow.vue +10 -9
  48. package/app/components/context/ContextAttachmentFields.vue +32 -20
  49. package/app/components/docs/DocInterviewWindow.vue +10 -9
  50. package/app/components/documents/ContextDocumentPicker.vue +22 -21
  51. package/app/components/documents/DocumentImportModal.vue +7 -5
  52. package/app/components/documents/DocumentOriginLink.vue +12 -9
  53. package/app/components/documents/DocumentSourceConnectModal.vue +2 -2
  54. package/app/components/documents/DocumentSyncState.vue +4 -4
  55. package/app/components/documents/DocumentTemplatesModal.vue +5 -4
  56. package/app/components/documents/RepoContextDocPicker.vue +7 -9
  57. package/app/components/documents/StartFromDesignModal.vue +4 -4
  58. package/app/components/documents/TaskContextDocs.vue +1 -1
  59. package/app/components/environments/EnvSetupStepper.vue +3 -3
  60. package/app/components/environments/EnvironmentStatusPanel.vue +15 -13
  61. package/app/components/environments/steps/EnvPreflightStep.vue +8 -8
  62. package/app/components/environments/steps/EnvReviewStep.vue +23 -22
  63. package/app/components/environments/steps/EnvSaveStep.vue +5 -5
  64. package/app/components/focus/BlockFocusView.vue +11 -10
  65. package/app/components/followUp/FollowUpWindow.vue +18 -15
  66. package/app/components/forkDecision/ForkDecisionWindow.vue +85 -97
  67. package/app/components/foundational/FoundationalContractSummary.vue +2 -2
  68. package/app/components/foundational/FoundationalServiceCatalogList.vue +6 -5
  69. package/app/components/foundational/FoundationalServiceRegistry.vue +10 -9
  70. package/app/components/foundational/FoundationalServiceSources.vue +7 -6
  71. package/app/components/foundational/FoundationalSuppressions.vue +2 -2
  72. package/app/components/fragments/FragmentLibraryManager.vue +8 -7
  73. package/app/components/fragments/FragmentSelector.vue +22 -20
  74. package/app/components/gates/GateFailingCheckList.vue +7 -6
  75. package/app/components/gates/GateResultView.vue +55 -49
  76. package/app/components/github/AddServiceFromRepoModal.vue +16 -11
  77. package/app/components/github/BranchProtectionPreflight.vue +5 -5
  78. package/app/components/github/GitHubConnect.vue +5 -3
  79. package/app/components/github/GitHubOnboarding.vue +7 -2
  80. package/app/components/github/GitHubPanel.vue +23 -19
  81. package/app/components/github/RepoTreeBrowser.vue +16 -13
  82. package/app/components/humanTest/HumanTestWindow.vue +29 -24
  83. package/app/components/initiative/InitiativePlanNotice.vue +3 -3
  84. package/app/components/initiative/InitiativePlanReview.vue +46 -38
  85. package/app/components/initiative/InitiativePlanningWindow.vue +5 -5
  86. package/app/components/initiative/InitiativeTrackerWindow.vue +213 -165
  87. package/app/components/judge/JudgeResultView.vue +28 -27
  88. package/app/components/kaizen/KaizenPanel.vue +70 -56
  89. package/app/components/kaizen/KaizenStepStatus.vue +7 -6
  90. package/app/components/layout/AccountAuditLog.vue +1 -1
  91. package/app/components/layout/AccountDeploymentSettings.vue +10 -10
  92. package/app/components/layout/AccountFailureKindRules.vue +13 -13
  93. package/app/components/layout/AccountFoundationalSettings.vue +1 -1
  94. package/app/components/layout/AccountFragmentSettings.vue +1 -1
  95. package/app/components/layout/AccountModelPolicySettings.vue +7 -7
  96. package/app/components/layout/AccountPlatformAlertSettings.vue +8 -8
  97. package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
  98. package/app/components/layout/AccountRunCredentialSettings.vue +3 -3
  99. package/app/components/layout/AccountSkillSettings.vue +1 -1
  100. package/app/components/layout/AccountTeamSettings.vue +13 -9
  101. package/app/components/layout/AiProvidersBanner.vue +1 -1
  102. package/app/components/layout/AppearanceSwitcher.vue +5 -4
  103. package/app/components/layout/BoardSwitcher.vue +13 -10
  104. package/app/components/layout/BoardToolbar.vue +10 -5
  105. package/app/components/layout/CommandBar.vue +8 -5
  106. package/app/components/layout/DefaultTestEnvBanner.vue +6 -5
  107. package/app/components/layout/IntegrationsHub.vue +12 -9
  108. package/app/components/layout/LanguageSwitcher.vue +5 -4
  109. package/app/components/layout/ModelProvidersHub.vue +10 -7
  110. package/app/components/layout/NotificationsInbox.vue +47 -36
  111. package/app/components/layout/PersonalSetupModal.vue +9 -6
  112. package/app/components/layout/RolePrompt.vue +5 -4
  113. package/app/components/layout/SideBar.vue +7 -8
  114. package/app/components/layout/SpendWarningBanner.vue +3 -3
  115. package/app/components/layout/TranslationWarningBanner.vue +5 -4
  116. package/app/components/layout/UiModeSwitcher.vue +15 -12
  117. package/app/components/layout/UiRoleSwitcher.vue +10 -8
  118. package/app/components/layout/WorkspaceMembersSettings.vue +2 -2
  119. package/app/components/media/ArtifactLightbox.vue +74 -44
  120. package/app/components/media/ImageCompare.vue +80 -85
  121. package/app/components/merge/MergeEffortChips.vue +4 -6
  122. package/app/components/notifications/NotificationSettingsPanel.vue +6 -5
  123. package/app/components/observability/OutcomeFilterChips.vue +6 -5
  124. package/app/components/observability/RunFailureSummary.vue +22 -23
  125. package/app/components/observability/StepMetricsBar.vue +9 -8
  126. package/app/components/observability/StepModelActivity.vue +8 -5
  127. package/app/components/observability/ToolCallList.vue +19 -20
  128. package/app/components/outcome/OutcomeSummaryWindow.vue +48 -46
  129. package/app/components/palettes/AgentPalette.vue +21 -15
  130. package/app/components/palettes/AgentTierSelect.vue +1 -1
  131. package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
  132. package/app/components/panels/AgentStepDetail.vue +57 -49
  133. package/app/components/panels/AttemptEntryHeader.vue +2 -2
  134. package/app/components/panels/DecisionModal.vue +1 -1
  135. package/app/components/panels/GenericStructuredResultView.vue +6 -5
  136. package/app/components/panels/InspectorPanel.vue +15 -13
  137. package/app/components/panels/MergerResultView.vue +10 -9
  138. package/app/components/panels/ObservabilityPanel.vue +211 -186
  139. package/app/components/panels/OperatorDashboardPanel.vue +124 -115
  140. package/app/components/panels/ReportsPanel.vue +87 -83
  141. package/app/components/panels/ReportsSpendBreakdown.vue +2 -2
  142. package/app/components/panels/ResultWindowShell.vue +152 -137
  143. package/app/components/panels/RunDetailLoadState.vue +1 -1
  144. package/app/components/panels/StepContainerStatus.vue +17 -16
  145. package/app/components/panels/StepDelegatedStatus.vue +24 -21
  146. package/app/components/panels/StepEffortReport.vue +12 -17
  147. package/app/components/panels/StepFragmentAdherence.vue +9 -10
  148. package/app/components/panels/StepMetadataCard.vue +41 -43
  149. package/app/components/panels/StepReproductionReport.vue +18 -20
  150. package/app/components/panels/StepRestartControl.vue +3 -2
  151. package/app/components/panels/StepRunMeta.vue +27 -26
  152. package/app/components/panels/StepTestReport.vue +16 -15
  153. package/app/components/panels/StepToolServers.vue +7 -8
  154. package/app/components/panels/StepValidationReport.vue +5 -5
  155. package/app/components/panels/inspector/ContainerSummary.vue +4 -4
  156. package/app/components/panels/inspector/DocReferenceRepos.vue +5 -4
  157. package/app/components/panels/inspector/EnvProbeReport.vue +16 -13
  158. package/app/components/panels/inspector/EpicChildren.vue +12 -10
  159. package/app/components/panels/inspector/FrontendBindingsResolved.vue +5 -4
  160. package/app/components/panels/inspector/FrontendConfig.vue +29 -36
  161. package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
  162. package/app/components/panels/inspector/InspectorSection.vue +25 -17
  163. package/app/components/panels/inspector/RecurringScheduleSettings.vue +9 -8
  164. package/app/components/panels/inspector/ServiceConnections.vue +5 -4
  165. package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
  166. package/app/components/panels/inspector/ServiceSelfTests.vue +9 -13
  167. package/app/components/panels/inspector/ServiceTestConfig.vue +46 -49
  168. package/app/components/panels/inspector/ServiceTestSecrets.vue +3 -3
  169. package/app/components/panels/inspector/ServiceTestingContext.vue +2 -2
  170. package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
  171. package/app/components/panels/inspector/TaskAgentConfig.vue +2 -2
  172. package/app/components/panels/inspector/TaskAprioriBranches.vue +6 -5
  173. package/app/components/panels/inspector/TaskDependencies.vue +1 -1
  174. package/app/components/panels/inspector/TaskEstimateBadge.vue +3 -7
  175. package/app/components/panels/inspector/TaskExecution.vue +18 -16
  176. package/app/components/panels/inspector/TaskRunSettings.vue +45 -44
  177. package/app/components/panels/inspector/TaskStructure.vue +5 -4
  178. package/app/components/pipeline/AgentPromptEditor.vue +15 -14
  179. package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -52
  180. package/app/components/pipeline/EstimateThresholdFields.vue +14 -11
  181. package/app/components/pipeline/GateConfigFields.vue +19 -23
  182. package/app/components/pipeline/IterationCapPrompt.vue +1 -1
  183. package/app/components/pipeline/PipelineBuilder.vue +113 -99
  184. package/app/components/pipeline/PipelineHealthModal.vue +7 -7
  185. package/app/components/pipeline/PipelinePicker.vue +11 -9
  186. package/app/components/pipeline/PipelinePreview.vue +6 -7
  187. package/app/components/pipeline/PipelineProgress.vue +49 -45
  188. package/app/components/prReview/PrReviewWindow.vue +87 -65
  189. package/app/components/providers/AiPresetMismatchDialog.vue +4 -3
  190. package/app/components/providers/AiProviderOnboardingModal.vue +2 -2
  191. package/app/components/providers/ApiKeysSection.vue +11 -9
  192. package/app/components/providers/PersonalSubscriptionSection.vue +4 -3
  193. package/app/components/providers/VendorCredentialsModal.vue +5 -4
  194. package/app/components/provisioning/ProvisioningLogsDrawer.vue +10 -9
  195. package/app/components/ralph/RalphLoopResultView.vue +29 -29
  196. package/app/components/requirements/RequirementsReviewWindow.vue +22 -17
  197. package/app/components/riskPolicy/RiskPolicyPicker.vue +13 -11
  198. package/app/components/riskPolicy/RiskPolicyPreview.vue +16 -15
  199. package/app/components/sandbox/SandboxPanel.vue +93 -73
  200. package/app/components/settings/ApiTokensPanel.vue +1 -1
  201. package/app/components/settings/BudgetSettings.vue +18 -17
  202. package/app/components/settings/CapabilityCredentialsPanel.vue +5 -5
  203. package/app/components/settings/CloudflareHandlerSection.vue +44 -41
  204. package/app/components/settings/ComposeEnvironmentSetupSection.vue +14 -12
  205. package/app/components/settings/ConnectionTestVerdict.vue +1 -1
  206. package/app/components/settings/ConsensusGroupsSection.vue +58 -47
  207. package/app/components/settings/CustomManifestTypeEditor.vue +8 -7
  208. package/app/components/settings/DefaultProvisionTypeSection.vue +5 -5
  209. package/app/components/settings/InfraHandlersConfigurator.vue +26 -24
  210. package/app/components/settings/InfrastructureBackendPicker.vue +18 -18
  211. package/app/components/settings/IssueTrackerPanel.vue +30 -21
  212. package/app/components/settings/KubernetesEngineForm.vue +9 -8
  213. package/app/components/settings/KubernetesEnvironmentForm.vue +4 -3
  214. package/app/components/settings/LocalContainerPoolSettings.vue +2 -2
  215. package/app/components/settings/LocalModelEndpointsPanel.vue +13 -11
  216. package/app/components/settings/MergeClassRulesEditor.vue +6 -5
  217. package/app/components/settings/MergeRolePolicyEditor.vue +13 -12
  218. package/app/components/settings/ModelConfigurationPanel.vue +17 -19
  219. package/app/components/settings/ModelPresetHealthModal.vue +3 -3
  220. package/app/components/settings/ObservabilityConnectionPanel.vue +1 -1
  221. package/app/components/settings/OpenRouterCatalogPanel.vue +10 -8
  222. package/app/components/settings/PackageRegistriesPanel.vue +4 -4
  223. package/app/components/settings/ProviderConnectionTab.vue +5 -4
  224. package/app/components/settings/ProviderManifestEditor.vue +9 -8
  225. package/app/components/settings/ProviderPreferenceEditor.vue +13 -13
  226. package/app/components/settings/RiskPolicyCreateForm.vue +40 -26
  227. package/app/components/settings/RiskPolicyEditorRow.vue +21 -19
  228. package/app/components/settings/RiskPolicyHealthModal.vue +3 -3
  229. package/app/components/settings/RiskPolicyPanel.vue +11 -13
  230. package/app/components/settings/ServiceFragmentDefaultsPanel.vue +15 -12
  231. package/app/components/settings/SharedStacksPanel.vue +5 -5
  232. package/app/components/settings/TaskSourceCard.vue +2 -2
  233. package/app/components/settings/TaskTypeSuppressionsPanel.vue +4 -4
  234. package/app/components/settings/ToolServerChecklist.vue +22 -22
  235. package/app/components/settings/UsageSettings.vue +13 -13
  236. package/app/components/settings/UserSecretsSection.vue +4 -3
  237. package/app/components/settings/WorkspaceMetadataSettings.vue +6 -5
  238. package/app/components/settings/WorkspaceSettingsPanel.vue +72 -58
  239. package/app/components/skills/ReviewSkillQueue.vue +12 -10
  240. package/app/components/skills/SkillLibraryManager.vue +9 -8
  241. package/app/components/slack/SlackPanel.vue +17 -12
  242. package/app/components/spec/ServiceSpecWindow.vue +19 -19
  243. package/app/components/tasks/BugHuntModal.vue +1 -1
  244. package/app/components/tasks/ContextIssuePicker.vue +16 -15
  245. package/app/components/tasks/TaskContextIssues.vue +5 -4
  246. package/app/components/tasks/TaskImportModal.vue +3 -2
  247. package/app/components/tasks/TaskSourceConnectModal.vue +5 -5
  248. package/app/components/testing/TestReportWindow.vue +67 -60
  249. package/app/components/theme/ThemeImportModal.vue +2 -2
  250. package/app/components/tutorial/TutorialNudge.vue +3 -2
  251. package/app/components/tutorial/TutorialOverlay.vue +3 -2
  252. package/app/components/vcs/GitLabConnect.vue +1 -1
  253. package/app/components/visualConfirm/VisualConfirmationWindow.vue +79 -54
  254. package/app/utils/theme/builtins.ts +7 -1
  255. package/i18n/locales/de.json +7 -3
  256. package/i18n/locales/en.json +7 -3
  257. package/i18n/locales/es.json +7 -3
  258. package/i18n/locales/fr.json +7 -3
  259. package/i18n/locales/he.json +7 -3
  260. package/i18n/locales/it.json +7 -3
  261. package/i18n/locales/ja.json +7 -3
  262. package/i18n/locales/pl.json +7 -3
  263. package/i18n/locales/tr.json +7 -3
  264. package/i18n/locales/uk.json +7 -3
  265. package/package.json +1 -1
@@ -30,6 +30,7 @@ import ResultWindowShell from '~/components/panels/ResultWindowShell.vue'
30
30
  import StepRunMeta from '~/components/panels/StepRunMeta.vue'
31
31
  import StepFragmentAdherence from '~/components/panels/StepFragmentAdherence.vue'
32
32
  import MarkdownProse from '~/components/common/MarkdownProse.vue'
33
+ import SectionLabel from '~/components/common/SectionLabel.vue'
33
34
 
34
35
  const execution = useExecutionStore()
35
36
  const board = useBoardStore()
@@ -291,14 +292,15 @@ const { requestClose } = useUnsavedGuard({
291
292
  @close="requestClose"
292
293
  >
293
294
  <template v-if="state?.prUrl" #header-extras>
294
- <a
295
- :href="state.prUrl"
295
+ <ULink
296
+ raw
297
+ :to="state.prUrl"
296
298
  target="_blank"
297
299
  rel="noopener"
298
- class="rounded-md px-2 py-1 text-[11px] text-primary hover:bg-elevated"
300
+ class="rounded-md px-2 py-1 text-2xs text-primary hover:bg-elevated"
299
301
  >
300
302
  {{ t('prReview.openPr') }}
301
- </a>
303
+ </ULink>
302
304
  </template>
303
305
 
304
306
  <div class="flex min-h-0 flex-1">
@@ -320,7 +322,7 @@ const { requestClose } = useUnsavedGuard({
320
322
  >
321
323
  <UIcon name="i-lucide-loader-circle" class="h-8 w-8 animate-spin opacity-60" />
322
324
  <p class="text-sm text-default">{{ t('prReview.reviewing.planning.title') }}</p>
323
- <p class="max-w-sm text-[11px] text-dimmed">
325
+ <p class="max-w-sm text-2xs text-dimmed">
324
326
  {{ t('prReview.reviewing.planning.hint') }}
325
327
  </p>
326
328
  </div>
@@ -334,11 +336,11 @@ const { requestClose } = useUnsavedGuard({
334
336
  />
335
337
  <span>{{ t('prReview.reviewing.reviewingChunks.title') }}</span>
336
338
  </div>
337
- <p class="mb-3 text-[11px] text-dimmed">
339
+ <p class="mb-3 text-2xs text-dimmed">
338
340
  {{ t('prReview.reviewing.reviewingChunks.hint') }}
339
341
  </p>
340
342
 
341
- <div class="flex items-center justify-between text-[11px] text-muted">
343
+ <div class="flex items-center justify-between text-2xs text-muted">
342
344
  <span data-testid="pr-review-chunk-count">
343
345
  {{
344
346
  t('prReview.reviewing.chunks', {
@@ -372,7 +374,7 @@ const { requestClose } = useUnsavedGuard({
372
374
  "
373
375
  >
374
376
  <p
375
- class="mb-1 text-[10px] font-semibold uppercase tracking-wide"
377
+ class="mb-1 text-3xs font-semibold uppercase tracking-wide"
376
378
  :class="activeChunks.length ? 'text-primary' : 'text-dimmed'"
377
379
  >
378
380
  {{ t('prReview.reviewing.activeHeading') }}
@@ -381,7 +383,7 @@ const { requestClose } = useUnsavedGuard({
381
383
  <li
382
384
  v-for="(label, i) in activeChunks"
383
385
  :key="i"
384
- class="flex items-start gap-1.5 text-[12px] text-app-100"
386
+ class="flex items-start gap-1.5 text-xs text-app-100"
385
387
  >
386
388
  <UIcon
387
389
  name="i-lucide-loader-circle"
@@ -390,22 +392,22 @@ const { requestClose } = useUnsavedGuard({
390
392
  <span class="min-w-0">{{ label }}</span>
391
393
  </li>
392
394
  </ul>
393
- <p v-else data-testid="pr-review-active-idle" class="text-[12px] text-muted">
395
+ <p v-else data-testid="pr-review-active-idle" class="text-xs text-muted">
394
396
  {{ t('prReview.reviewing.activeIdle') }}
395
397
  </p>
396
398
  </div>
397
399
 
398
400
  <!-- Every chunk with its explicit status (Reviewed / Reviewing… / Queued). -->
399
401
  <template v-if="subtasks!.items?.length">
400
- <p class="mb-1.5 mt-3 text-[10px] font-semibold uppercase tracking-wide text-muted">
402
+ <SectionLabel as="p" class="mb-1.5 mt-3">
401
403
  {{ t('prReview.reviewing.chunksHeading') }}
402
- </p>
404
+ </SectionLabel>
403
405
  <ul class="space-y-1.5" data-testid="pr-review-chunks">
404
406
  <li
405
407
  v-for="(item, i) in subtasks!.items"
406
408
  :key="i"
407
409
  data-testid="pr-review-chunk"
408
- class="flex items-center gap-1.5 text-[12px]"
410
+ class="flex items-center gap-1.5 text-xs"
409
411
  :class="
410
412
  item.status === 'completed'
411
413
  ? 'text-dimmed'
@@ -427,7 +429,7 @@ const { requestClose } = useUnsavedGuard({
427
429
  </span>
428
430
  <span
429
431
  data-testid="pr-review-chunk-status"
430
- class="shrink-0 rounded px-1.5 py-0.5 text-[10px] font-medium uppercase"
432
+ class="shrink-0 rounded-sm px-1.5 py-0.5 text-3xs font-medium uppercase"
431
433
  :class="CHUNK_STATUS_CLASS[item.status]"
432
434
  >
433
435
  {{ chunkStatusLabel(item.status) }}
@@ -446,12 +448,12 @@ const { requestClose } = useUnsavedGuard({
446
448
  <p
447
449
  v-if="prReview.error"
448
450
  data-testid="pr-review-resume-error"
449
- class="mb-2 rounded-md bg-app-error-500/10 px-3 py-2 text-[12px] text-app-error-300"
451
+ class="mb-2 rounded-md bg-app-error-500/10 px-3 py-2 text-xs text-app-error-300"
450
452
  >
451
453
  {{ prReview.error }}
452
454
  </p>
453
455
  <div class="flex items-start justify-between gap-3">
454
- <p class="min-w-0 text-[11px] text-dimmed">{{ t('prReview.resume.hint') }}</p>
456
+ <p class="min-w-0 text-2xs text-dimmed">{{ t('prReview.resume.hint') }}</p>
455
457
  <UButton
456
458
  data-testid="pr-review-resume"
457
459
  size="xs"
@@ -479,7 +481,7 @@ const { requestClose } = useUnsavedGuard({
479
481
  <p class="text-sm">
480
482
  {{ status === 'fixing' ? t('prReview.fixing.title') : t('prReview.posting.title') }}
481
483
  </p>
482
- <p class="max-w-sm text-[11px] text-dimmed">
484
+ <p class="max-w-sm text-2xs text-dimmed">
483
485
  {{ status === 'fixing' ? t('prReview.fixing.hint') : t('prReview.posting.hint') }}
484
486
  </p>
485
487
  </div>
@@ -487,7 +489,7 @@ const { requestClose } = useUnsavedGuard({
487
489
  <template v-else>
488
490
  <p
489
491
  v-if="prReview.error"
490
- class="mb-3 rounded-md bg-app-error-500/10 px-3 py-2 text-[12px] text-app-error-300"
492
+ class="mb-3 rounded-md bg-app-error-500/10 px-3 py-2 text-xs text-app-error-300"
491
493
  >
492
494
  {{ prReview.error }}
493
495
  </p>
@@ -498,7 +500,7 @@ const { requestClose } = useUnsavedGuard({
498
500
  <div
499
501
  v-if="postReport"
500
502
  data-testid="pr-review-post-report"
501
- class="mb-3 rounded-lg border px-3 py-2 text-[12px]"
503
+ class="mb-3 rounded-lg border px-3 py-2 text-xs"
502
504
  :class="
503
505
  postReport.failures.length > 0 || postReport.bodyPosted === false
504
506
  ? 'border-app-warning-500/40 bg-app-warning-500/10 text-app-warning-200'
@@ -547,7 +549,7 @@ const { requestClose } = useUnsavedGuard({
547
549
  shell's `width` prop) — this window is `full`-width. -->
548
550
  <div
549
551
  v-if="state?.summary"
550
- class="mb-3 max-w-3xl rounded-md bg-elevated/50 px-3 py-2 text-[12px] text-toned"
552
+ class="mb-3 max-w-3xl rounded-md bg-elevated/50 px-3 py-2 text-xs text-toned"
551
553
  >
552
554
  <span class="mb-1 block text-dimmed">{{ t('prReview.summaryLabel') }}</span>
553
555
  <MarkdownProse :text="state.summary" />
@@ -564,7 +566,7 @@ const { requestClose } = useUnsavedGuard({
564
566
  <!-- A clean PR / resolved review with no findings. -->
565
567
  <div
566
568
  v-if="findings.length === 0"
567
- class="rounded-xl border border-default bg-default/60 px-4 py-6 text-center text-[13px] text-toned"
569
+ class="rounded-xl border border-default bg-default/60 px-4 py-6 text-center text-sm text-toned"
568
570
  >
569
571
  {{ t('prReview.noFindings') }}
570
572
  </div>
@@ -574,31 +576,41 @@ const { requestClose } = useUnsavedGuard({
574
576
  <div
575
577
  v-if="challenging"
576
578
  data-testid="pr-review-challenging"
577
- class="mb-3 flex items-center gap-2 rounded-md border border-primary/40 bg-primary/10 px-3 py-2 text-[12px] text-primary"
579
+ class="mb-3 flex items-center gap-2 rounded-md border border-primary/40 bg-primary/10 px-3 py-2 text-xs text-primary"
578
580
  >
579
581
  <UIcon name="i-lucide-loader-circle" class="h-4 w-4 shrink-0 animate-spin" />
580
582
  <span>{{ t('prReview.challenge.investigatingBanner') }}</span>
581
583
  </div>
582
584
 
583
585
  <!-- Selection toolbar -->
584
- <div v-if="awaiting" class="mb-2 flex items-center gap-3 text-[11px] text-muted">
586
+ <div v-if="awaiting" class="mb-2 flex items-center gap-3 text-2xs text-muted">
585
587
  <span data-testid="pr-review-selected-count">
586
588
  {{ t('prReview.selectedCount', { count: activeSelectedIds.length }) }}
587
589
  </span>
588
- <button class="text-primary hover:underline" @click="selectAll">
590
+ <UButton
591
+ color="primary"
592
+ variant="link"
593
+ class="p-0 text-2xs text-primary hover:underline"
594
+ @click="selectAll"
595
+ >
589
596
  {{ t('prReview.selectAll') }}
590
- </button>
591
- <button class="text-primary hover:underline" @click="clearAll">
597
+ </UButton>
598
+ <UButton
599
+ color="primary"
600
+ variant="link"
601
+ class="p-0 text-2xs text-primary hover:underline"
602
+ @click="clearAll"
603
+ >
592
604
  {{ t('prReview.clear') }}
593
- </button>
605
+ </UButton>
594
606
  </div>
595
607
 
596
608
  <!-- Findings grouped by slice -->
597
609
  <section v-for="g in groups" :key="g.id" class="mb-4">
598
- <h3 class="mb-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted">
610
+ <SectionLabel as="h3" class="mb-1.5">
599
611
  {{ g.title }}
600
- </h3>
601
- <p v-if="g.rationale" class="mb-1.5 max-w-3xl text-[11px] text-dimmed">
612
+ </SectionLabel>
613
+ <p v-if="g.rationale" class="mb-1.5 max-w-3xl text-2xs text-dimmed">
602
614
  {{ g.rationale }}
603
615
  </p>
604
616
  <article
@@ -614,30 +626,30 @@ const { requestClose } = useUnsavedGuard({
614
626
  ]"
615
627
  >
616
628
  <div class="flex items-start gap-2">
617
- <input
629
+ <UCheckbox
618
630
  v-if="awaiting || challenging"
619
- type="checkbox"
620
- class="mt-1 accent-primary"
631
+ size="xs"
632
+ class="mt-1"
621
633
  data-testid="pr-review-finding-toggle"
622
- :checked="selected.has(f.id) && !isRetracted(f)"
634
+ :model-value="selected.has(f.id) && !isRetracted(f)"
623
635
  :disabled="!awaiting || isRetracted(f)"
624
- @change="toggle(f.id)"
636
+ @update:model-value="toggle(f.id)"
625
637
  />
626
638
  <div class="min-w-0 flex-1">
627
639
  <div class="flex flex-wrap items-center gap-1.5">
628
640
  <span
629
- class="rounded px-1.5 py-0.5 text-[10px] font-semibold uppercase ring-1"
641
+ class="rounded-sm px-1.5 py-0.5 text-3xs font-semibold uppercase ring-1"
630
642
  :class="SEVERITY_CLASS[f.severity]"
631
643
  >
632
644
  {{ t(`prReview.severity.${f.severity}`) }}
633
645
  </span>
634
- <span class="rounded bg-elevated px-1.5 py-0.5 text-[10px] text-toned">
646
+ <span class="rounded-sm bg-elevated px-1.5 py-0.5 text-3xs text-toned">
635
647
  {{ t(`prReview.category.${f.category}`) }}
636
648
  </span>
637
649
  <span
638
650
  v-if="postedIds.has(f.id)"
639
651
  data-testid="pr-review-finding-posted"
640
- class="rounded bg-app-success-500/15 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-app-success-300 ring-1 ring-app-success-500/30"
652
+ class="rounded-sm bg-app-success-500/15 px-1.5 py-0.5 text-3xs font-semibold uppercase text-app-success-300 ring-1 ring-app-success-500/30"
641
653
  >
642
654
  {{ t('prReview.postReport.postedBadge') }}
643
655
  </span>
@@ -645,47 +657,47 @@ const { requestClose } = useUnsavedGuard({
645
657
  <span
646
658
  v-if="isRetracted(f)"
647
659
  data-testid="pr-review-finding-retracted"
648
- class="rounded bg-app-error-500/15 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-app-error-300 ring-1 ring-app-error-500/30"
660
+ class="rounded-sm bg-app-error-500/15 px-1.5 py-0.5 text-3xs font-semibold uppercase text-app-error-300 ring-1 ring-app-error-500/30"
649
661
  >
650
662
  {{ t('prReview.challenge.retractedBadge') }}
651
663
  </span>
652
664
  <span
653
665
  v-else-if="isAmended(f)"
654
666
  data-testid="pr-review-finding-amended"
655
- class="rounded bg-app-info-500/15 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-app-info-300 ring-1 ring-app-info-500/30"
667
+ class="rounded-sm bg-app-info-500/15 px-1.5 py-0.5 text-3xs font-semibold uppercase text-app-info-300 ring-1 ring-app-info-500/30"
656
668
  >
657
669
  {{ t('prReview.challenge.strengthenedBadge') }}
658
670
  </span>
659
671
  <span
660
672
  v-else-if="isUpheld(f)"
661
673
  data-testid="pr-review-finding-upheld"
662
- class="rounded bg-app-success-500/15 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-app-success-300 ring-1 ring-app-success-500/30"
674
+ class="rounded-sm bg-app-success-500/15 px-1.5 py-0.5 text-3xs font-semibold uppercase text-app-success-300 ring-1 ring-app-success-500/30"
663
675
  >
664
676
  {{ t('prReview.challenge.upheldBadge') }}
665
677
  </span>
666
678
  <span
667
679
  v-else-if="isChallengeFailed(f)"
668
680
  data-testid="pr-review-finding-challenge-failed"
669
- class="rounded bg-app-warning-500/15 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-app-warning-300 ring-1 ring-app-warning-500/30"
681
+ class="rounded-sm bg-app-warning-500/15 px-1.5 py-0.5 text-3xs font-semibold uppercase text-app-warning-300 ring-1 ring-app-warning-500/30"
670
682
  >
671
683
  {{ t('prReview.challenge.failedBadge') }}
672
684
  </span>
673
685
  <span
674
686
  v-else-if="isInvestigating(f)"
675
687
  data-testid="pr-review-finding-investigating"
676
- class="flex items-center gap-1 rounded bg-primary/15 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-primary ring-1 ring-primary/30"
688
+ class="flex items-center gap-1 rounded-sm bg-primary/15 px-1.5 py-0.5 text-3xs font-semibold uppercase text-primary ring-1 ring-primary/30"
677
689
  >
678
690
  <UIcon name="i-lucide-loader-circle" class="h-3 w-3 animate-spin" />
679
691
  {{ t('prReview.challenge.investigatingBadge') }}
680
692
  </span>
681
693
  <h4
682
- class="min-w-0 flex-1 text-[13px] font-medium text-app-100"
694
+ class="min-w-0 flex-1 text-sm font-medium text-app-100"
683
695
  :class="isRetracted(f) ? 'line-through' : ''"
684
696
  >
685
697
  {{ f.title }}
686
698
  </h4>
687
699
  </div>
688
- <p class="mt-0.5 text-[11px] text-dimmed">
700
+ <p class="mt-0.5 text-2xs text-dimmed">
689
701
  {{ f.path
690
702
  }}<template v-if="f.line != null">
691
703
  · {{ t('prReview.line', { line: f.line }) }}</template
@@ -701,7 +713,7 @@ const { requestClose } = useUnsavedGuard({
701
713
  <MarkdownProse
702
714
  v-if="f.detail"
703
715
  :text="f.detail"
704
- class="mt-1 max-w-3xl text-[12px] text-toned"
716
+ class="mt-1 max-w-3xl text-xs text-toned"
705
717
  :class="isRetracted(f) ? 'line-through' : ''"
706
718
  />
707
719
  <!-- The suggested fix is a VALUE a human copies (a patch line, a command, a
@@ -711,7 +723,7 @@ const { requestClose } = useUnsavedGuard({
711
723
  failure summary is left alone. -->
712
724
  <p
713
725
  v-if="f.suggestedFix"
714
- class="mt-1 max-w-3xl whitespace-pre-wrap rounded-md bg-elevated/50 px-2 py-1 text-[11px] text-toned"
726
+ class="mt-1 max-w-3xl whitespace-pre-wrap rounded-md bg-elevated/50 px-2 py-1 text-2xs text-toned"
715
727
  >
716
728
  <span class="text-dimmed">{{ t('prReview.suggestedFix') }}</span>
717
729
  {{ f.suggestedFix }}
@@ -722,7 +734,7 @@ const { requestClose } = useUnsavedGuard({
722
734
  <div
723
735
  v-if="f.challenge?.justification"
724
736
  data-testid="pr-review-finding-justification"
725
- class="mt-1.5 max-w-3xl rounded-md px-2 py-1 text-[11px]"
737
+ class="mt-1.5 max-w-3xl rounded-md px-2 py-1 text-2xs"
726
738
  :class="
727
739
  isRetracted(f)
728
740
  ? 'bg-app-error-500/10 text-app-error-200'
@@ -745,12 +757,14 @@ const { requestClose } = useUnsavedGuard({
745
757
  <!-- Per-finding actions: Challenge + Dismiss (only while awaiting a selection). -->
746
758
  <div
747
759
  v-if="awaiting && !isInvestigating(f)"
748
- class="mt-1.5 flex items-center gap-3 text-[11px]"
760
+ class="mt-1.5 flex items-center gap-3 text-2xs"
749
761
  >
750
- <button
762
+ <UButton
763
+ color="primary"
764
+ variant="link"
751
765
  v-if="!isRetracted(f)"
752
766
  data-testid="pr-review-finding-challenge"
753
- class="flex items-center gap-1 text-primary hover:underline disabled:opacity-50"
767
+ class="p-0 text-2xs flex items-center gap-1 text-primary hover:underline disabled:opacity-50"
754
768
  :disabled="!canResolve || !access.canExecuteRuns.value"
755
769
  @click="openChallenge(f.id)"
756
770
  >
@@ -760,16 +774,18 @@ const { requestClose } = useUnsavedGuard({
760
774
  ? t('prReview.challenge.reChallenge')
761
775
  : t('prReview.challenge.action')
762
776
  }}
763
- </button>
764
- <button
777
+ </UButton>
778
+ <UButton
779
+ color="neutral"
780
+ variant="link"
765
781
  data-testid="pr-review-finding-dismiss"
766
- class="flex items-center gap-1 text-muted hover:text-app-error-300 hover:underline disabled:opacity-50"
782
+ class="p-0 text-xs flex items-center gap-1 text-muted hover:text-app-error-300 hover:underline disabled:opacity-50"
767
783
  :disabled="!canResolve || !access.canExecuteRuns.value"
768
784
  @click="onDismiss(f.id)"
769
785
  >
770
786
  <UIcon name="i-lucide-trash-2" class="h-3.5 w-3.5" />
771
787
  {{ t('prReview.challenge.dismiss') }}
772
- </button>
788
+ </UButton>
773
789
  </div>
774
790
 
775
791
  <!-- The inline challenge box: an OPTIONAL specific concern for the investigator. -->
@@ -778,31 +794,37 @@ const { requestClose } = useUnsavedGuard({
778
794
  data-testid="pr-review-challenge-box"
779
795
  class="mt-2 rounded-md border border-primary/40 bg-default/80 p-2"
780
796
  >
781
- <textarea
797
+ <UTextarea
782
798
  v-model="challengeText"
783
799
  data-testid="pr-review-challenge-input"
784
- rows="2"
800
+ :rows="2"
785
801
  :placeholder="t('prReview.challenge.placeholder')"
786
- class="w-full resize-y rounded border border-muted bg-app-950/60 px-2 py-1 text-[12px] text-default outline-none focus:border-primary"
802
+ size="xs"
803
+ class="w-full"
804
+ :ui="{ base: 'resize-y' }"
787
805
  />
788
- <p class="mt-1 text-[10px] text-dimmed">
806
+ <p class="mt-1 text-3xs text-dimmed">
789
807
  {{ t('prReview.challenge.hint') }}
790
808
  </p>
791
809
  <div class="mt-1.5 flex justify-end gap-2">
792
- <button
793
- class="rounded px-2 py-1 text-[11px] text-muted hover:text-default"
810
+ <UButton
811
+ color="neutral"
812
+ variant="ghost"
813
+ class="rounded-sm px-2 py-1 text-2xs text-muted hover:text-default"
794
814
  @click="cancelChallenge"
795
815
  >
796
816
  {{ t('common.cancel') }}
797
- </button>
798
- <button
817
+ </UButton>
818
+ <UButton
819
+ color="neutral"
820
+ variant="ghost"
799
821
  data-testid="pr-review-challenge-submit"
800
- class="rounded bg-primary/80 px-2 py-1 text-[11px] font-medium text-inverted hover:bg-primary/90 disabled:opacity-50"
822
+ class="rounded-sm bg-primary/80 px-2 py-1 text-2xs font-medium text-inverted hover:bg-primary/90 disabled:opacity-50"
801
823
  :disabled="!canResolve"
802
824
  @click="submitChallenge(f.id)"
803
825
  >
804
826
  {{ t('prReview.challenge.submit') }}
805
- </button>
827
+ </UButton>
806
828
  </div>
807
829
  </div>
808
830
  </div>
@@ -7,6 +7,7 @@
7
7
  // auto-opens once per session (driven from pages/index.vue) and clears once the preset is
8
8
  // fixed (or all its models become available).
9
9
  import { computed } from 'vue'
10
+ import SectionLabel from '~/components/common/SectionLabel.vue'
10
11
 
11
12
  const { t } = useI18n()
12
13
  const ui = useUiStore()
@@ -54,9 +55,9 @@ function go(action: () => void) {
54
55
  </i18n-t>
55
56
 
56
57
  <div class="rounded-lg border border-muted bg-default/50 p-3">
57
- <p class="mb-1.5 text-[11px] font-semibold uppercase tracking-wide text-dimmed">
58
+ <SectionLabel as="p" class="mb-1.5">
58
59
  {{ t('providers.presetMismatch.unavailable') }}
59
- </p>
60
+ </SectionLabel>
60
61
  <div class="flex flex-wrap gap-1.5">
61
62
  <UBadge
62
63
  v-for="label in unavailableLabels"
@@ -70,7 +71,7 @@ function go(action: () => void) {
70
71
  </div>
71
72
  </div>
72
73
 
73
- <p class="text-[13px] text-muted">
74
+ <p class="text-sm text-muted">
74
75
  {{ t('providers.presetMismatch.advice') }}
75
76
  </p>
76
77
 
@@ -104,7 +104,7 @@ const routes = computed<Route[]>(() => [
104
104
  {{ r.badge }}
105
105
  </UBadge>
106
106
  </div>
107
- <p class="mt-0.5 text-[13px] leading-relaxed text-muted">{{ r.body }}</p>
107
+ <p class="mt-0.5 text-sm leading-relaxed text-muted">{{ r.body }}</p>
108
108
  </div>
109
109
  <UButton
110
110
  size="sm"
@@ -118,7 +118,7 @@ const routes = computed<Route[]>(() => [
118
118
  </div>
119
119
  </div>
120
120
 
121
- <p class="text-[11px] leading-relaxed text-dimmed">
121
+ <p class="text-2xs leading-relaxed text-dimmed">
122
122
  {{ t('providers.onboarding.operatorNote') }}
123
123
  </p>
124
124
  </div>
@@ -19,6 +19,7 @@ import { computed, ref, watch } from 'vue'
19
19
  import { providerCachesPrompts } from '@cat-factory/contracts'
20
20
  import type { ApiKey, ApiKeyProvider } from '~/types/domain'
21
21
  import SecretInput from '~/components/common/SecretInput.vue'
22
+ import SectionLabel from '~/components/common/SectionLabel.vue'
22
23
 
23
24
  const props = withDefaults(defineProps<{ accountId?: string; category?: 'direct' | 'proxy' }>(), {
24
25
  category: 'direct',
@@ -264,13 +265,13 @@ async function remove(k: ApiKey) {
264
265
  <template>
265
266
  <div class="space-y-4">
266
267
  <div>
267
- <h4 class="text-xs font-semibold uppercase tracking-wide text-dimmed">
268
+ <SectionLabel as="h4">
268
269
  {{
269
270
  category === 'proxy'
270
271
  ? t('providers.apiKeys.proxyHeading')
271
272
  : t('providers.apiKeys.directHeading')
272
273
  }}
273
- </h4>
274
+ </SectionLabel>
274
275
  <template v-if="category === 'proxy'">
275
276
  <p v-if="isAccount" class="mt-1 text-sm text-muted">
276
277
  {{ t('providers.apiKeys.proxyAccountIntro') }}
@@ -328,14 +329,15 @@ async function remove(k: ApiKey) {
328
329
  >
329
330
  <li v-for="(step, i) in selected.steps" :key="i">{{ step }}</li>
330
331
  <li>
331
- <a
332
- :href="selected.url"
332
+ <ULink
333
+ raw
334
+ :to="selected.url"
333
335
  target="_blank"
334
336
  rel="noopener noreferrer"
335
337
  class="text-primary underline"
336
338
  >
337
339
  {{ t('providers.apiKeys.openKeys', { provider: selected.label }) }}
338
- </a>
340
+ </ULink>
339
341
  </li>
340
342
  </ol>
341
343
 
@@ -343,7 +345,7 @@ async function remove(k: ApiKey) {
343
345
  the caching flavour, so long agentic runs stop re-billing the whole prompt. -->
344
346
  <p
345
347
  v-if="cachesPrompts(selected.value)"
346
- class="flex items-center gap-1.5 text-[12px] text-app-success-400/90"
348
+ class="flex items-center gap-1.5 text-xs text-app-success-400/90"
347
349
  >
348
350
  <UIcon name="i-lucide-zap" class="h-3.5 w-3.5 shrink-0" />
349
351
  {{ t('providers.apiKeys.cachingNote', { provider: selected.label }) }}
@@ -380,9 +382,9 @@ async function remove(k: ApiKey) {
380
382
 
381
383
  <!-- connected keys for the selected scope -->
382
384
  <div v-if="connected.length" class="space-y-2">
383
- <h5 class="text-xs font-semibold uppercase tracking-wide text-dimmed">
385
+ <SectionLabel as="h5">
384
386
  {{ t('providers.apiKeys.connected', { count: connected.length }) }}
385
- </h5>
387
+ </SectionLabel>
386
388
  <div
387
389
  v-for="k in connected"
388
390
  :key="k.id"
@@ -395,7 +397,7 @@ async function remove(k: ApiKey) {
395
397
  <UBadge v-if="!k.enabled" color="neutral" variant="subtle" size="sm" class="ms-2">
396
398
  {{ t('providers.apiKeys.disabledBadge') }}
397
399
  </UBadge>
398
- <div class="text-[11px] tabular-nums text-dimmed">
400
+ <div class="text-2xs tabular-nums text-dimmed">
399
401
  {{
400
402
  t(
401
403
  'providers.apiKeys.usage',
@@ -7,6 +7,7 @@
7
7
  import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
8
8
  import type { SubscriptionVendor } from '~/types/domain'
9
9
  import SecretInput from '~/components/common/SecretInput.vue'
10
+ import SectionLabel from '~/components/common/SectionLabel.vue'
10
11
 
11
12
  const personal = usePersonalSubscriptionsStore()
12
13
  const auth = useAuthStore()
@@ -208,9 +209,9 @@ async function disconnect(v: SubscriptionVendor) {
208
209
  <template>
209
210
  <div class="space-y-3">
210
211
  <div>
211
- <h4 class="text-xs font-semibold uppercase tracking-wide text-dimmed">
212
+ <SectionLabel as="h4">
212
213
  {{ t('personalSubscriptions.heading') }}
213
- </h4>
214
+ </SectionLabel>
214
215
  <p class="mt-1 text-sm text-muted">{{ t('personalSubscriptions.intro') }}</p>
215
216
  </div>
216
217
 
@@ -228,7 +229,7 @@ async function disconnect(v: SubscriptionVendor) {
228
229
  <div>
229
230
  <span class="font-medium text-default">{{ sub.label }}</span>
230
231
  <span class="ms-2 text-xs text-dimmed">{{ vendorLabel(sub.vendor) }}</span>
231
- <div class="text-[11px] text-dimmed">
232
+ <div class="text-2xs text-dimmed">
232
233
  <template v-if="sub.expiresAt">
233
234
  {{ t('personalSubscriptions.expires', { date: d(new Date(sub.expiresAt), 'short') }) }}
234
235
  </template>
@@ -9,6 +9,7 @@ import { computed, ref, watch } from 'vue'
9
9
  import type { SubscriptionVendor } from '~/types/domain'
10
10
  import IntegrationBackTitle from '~/components/layout/IntegrationBackTitle.vue'
11
11
  import SecretInput from '~/components/common/SecretInput.vue'
12
+ import SectionLabel from '~/components/common/SectionLabel.vue'
12
13
 
13
14
  const { t, n } = useI18n()
14
15
  const ui = useUiStore()
@@ -202,7 +203,7 @@ function vendorLabel(v: SubscriptionVendor): string {
202
203
  class="flex items-center gap-3 rounded-lg border border-primary/30 bg-primary/10 px-3 py-2.5"
203
204
  >
204
205
  <UIcon name="i-lucide-user" class="h-5 w-5 shrink-0 text-primary" />
205
- <p class="min-w-0 flex-1 text-[13px] text-toned">
206
+ <p class="min-w-0 flex-1 text-sm text-toned">
206
207
  {{ t('providers.vendorCredentials.personalCallout.text') }}
207
208
  </p>
208
209
  <UButton
@@ -267,11 +268,11 @@ function vendorLabel(v: SubscriptionVendor): string {
267
268
 
268
269
  <!-- connected pool -->
269
270
  <div v-if="creds.credentials.length" class="space-y-2">
270
- <h4 class="text-xs font-semibold uppercase tracking-wide text-dimmed">
271
+ <SectionLabel as="h4">
271
272
  {{
272
273
  t('providers.vendorCredentials.connected', { count: creds.credentials.length })
273
274
  }}
274
- </h4>
275
+ </SectionLabel>
275
276
  <div
276
277
  v-for="c in creds.credentials"
277
278
  :key="c.id"
@@ -284,7 +285,7 @@ function vendorLabel(v: SubscriptionVendor): string {
284
285
  <UBadge v-if="!c.enabled" color="neutral" variant="subtle" size="sm" class="ms-2">
285
286
  {{ t('providers.vendorCredentials.disabledBadge') }}
286
287
  </UBadge>
287
- <div class="text-[11px] tabular-nums text-dimmed">
288
+ <div class="text-2xs tabular-nums text-dimmed">
288
289
  {{
289
290
  t(
290
291
  'providers.vendorCredentials.usage',