@cat-factory/app 0.308.0 → 0.309.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 (243) hide show
  1. package/README.md +21 -0
  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 +3 -2
  6. package/app/components/auth/UserMenu.vue +1 -1
  7. package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +15 -15
  8. package/app/components/binaryOutput/BinaryOutputReport.vue +10 -14
  9. package/app/components/binaryOutput/StoredAssetView.vue +5 -5
  10. package/app/components/board/AddTaskModal.vue +16 -14
  11. package/app/components/board/AgentFailureCard.vue +9 -9
  12. package/app/components/board/AgentFailureHistory.vue +1 -1
  13. package/app/components/board/CreateInitiativeModal.vue +2 -2
  14. package/app/components/board/FailureDetail.vue +1 -1
  15. package/app/components/board/FailureHistoryList.vue +5 -5
  16. package/app/components/board/RecurringPipelineModal.vue +12 -11
  17. package/app/components/board/ReviewFrictionDialog.vue +4 -3
  18. package/app/components/board/StepExecutionHistory.vue +8 -8
  19. package/app/components/board/nodes/AgentChip.vue +1 -1
  20. package/app/components/board/nodes/BlockNode.vue +8 -9
  21. package/app/components/board/nodes/EpicNode.vue +4 -4
  22. package/app/components/board/nodes/FrameSwimlanes.vue +4 -7
  23. package/app/components/board/nodes/InitiativeCard.vue +4 -4
  24. package/app/components/board/nodes/LaneGroup.vue +3 -5
  25. package/app/components/board/nodes/TaskCard.vue +8 -8
  26. package/app/components/board/nodes/TaskLane.vue +3 -3
  27. package/app/components/board/nodes/TaskPipelineMini.vue +13 -12
  28. package/app/components/bootstrap/AdoptionReviewModal.vue +7 -6
  29. package/app/components/bootstrap/BootstrapModal.vue +11 -10
  30. package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
  31. package/app/components/brainstorm/BrainstormWindow.vue +8 -7
  32. package/app/components/bugFishing/BugFishingWindow.vue +37 -36
  33. package/app/components/clarity/ClarityReviewWindow.vue +8 -7
  34. package/app/components/common/AsyncViewError.vue +1 -1
  35. package/app/components/common/ClarificationItem.vue +6 -6
  36. package/app/components/common/DescriptorFields.vue +1 -1
  37. package/app/components/common/EmptyState.vue +1 -1
  38. package/app/components/common/InterviewGateNotice.vue +4 -4
  39. package/app/components/common/MarkdownProse.vue +8 -2
  40. package/app/components/common/SectionLabel.vue +38 -0
  41. package/app/components/consensus/ConsensusSessionWindow.vue +10 -9
  42. package/app/components/context/ContextAttachmentFields.vue +9 -8
  43. package/app/components/docs/DocInterviewWindow.vue +10 -9
  44. package/app/components/documents/ContextDocumentPicker.vue +10 -12
  45. package/app/components/documents/DocumentImportModal.vue +3 -2
  46. package/app/components/documents/DocumentSourceConnectModal.vue +2 -2
  47. package/app/components/documents/DocumentSyncState.vue +1 -1
  48. package/app/components/documents/DocumentTemplatesModal.vue +5 -4
  49. package/app/components/documents/RepoContextDocPicker.vue +3 -6
  50. package/app/components/documents/StartFromDesignModal.vue +4 -4
  51. package/app/components/documents/TaskContextDocs.vue +1 -1
  52. package/app/components/environments/EnvSetupStepper.vue +3 -3
  53. package/app/components/environments/EnvironmentStatusPanel.vue +11 -10
  54. package/app/components/environments/steps/EnvPreflightStep.vue +8 -8
  55. package/app/components/environments/steps/EnvReviewStep.vue +23 -22
  56. package/app/components/environments/steps/EnvSaveStep.vue +5 -5
  57. package/app/components/focus/BlockFocusView.vue +11 -10
  58. package/app/components/followUp/FollowUpWindow.vue +10 -10
  59. package/app/components/forkDecision/ForkDecisionWindow.vue +23 -26
  60. package/app/components/foundational/FoundationalContractSummary.vue +2 -2
  61. package/app/components/foundational/FoundationalServiceCatalogList.vue +3 -3
  62. package/app/components/foundational/FoundationalServiceRegistry.vue +3 -3
  63. package/app/components/foundational/FoundationalSuppressions.vue +2 -2
  64. package/app/components/fragments/FragmentLibraryManager.vue +3 -3
  65. package/app/components/fragments/FragmentSelector.vue +10 -11
  66. package/app/components/gates/GateFailingCheckList.vue +3 -3
  67. package/app/components/gates/GateResultView.vue +39 -38
  68. package/app/components/github/AddServiceFromRepoModal.vue +5 -4
  69. package/app/components/github/BranchProtectionPreflight.vue +5 -5
  70. package/app/components/github/GitHubConnect.vue +5 -3
  71. package/app/components/github/GitHubPanel.vue +14 -13
  72. package/app/components/github/RepoTreeBrowser.vue +1 -1
  73. package/app/components/humanTest/HumanTestWindow.vue +18 -17
  74. package/app/components/initiative/InitiativePlanNotice.vue +3 -3
  75. package/app/components/initiative/InitiativePlanReview.vue +19 -21
  76. package/app/components/initiative/InitiativePlanningWindow.vue +5 -5
  77. package/app/components/initiative/InitiativeTrackerWindow.vue +54 -53
  78. package/app/components/judge/JudgeResultView.vue +24 -25
  79. package/app/components/kaizen/KaizenPanel.vue +4 -4
  80. package/app/components/kaizen/KaizenStepStatus.vue +7 -6
  81. package/app/components/layout/AccountAuditLog.vue +1 -1
  82. package/app/components/layout/AccountDeploymentSettings.vue +10 -10
  83. package/app/components/layout/AccountFailureKindRules.vue +13 -13
  84. package/app/components/layout/AccountFoundationalSettings.vue +1 -1
  85. package/app/components/layout/AccountFragmentSettings.vue +1 -1
  86. package/app/components/layout/AccountModelPolicySettings.vue +7 -7
  87. package/app/components/layout/AccountPlatformAlertSettings.vue +8 -8
  88. package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
  89. package/app/components/layout/AccountRunCredentialSettings.vue +3 -3
  90. package/app/components/layout/AccountSkillSettings.vue +1 -1
  91. package/app/components/layout/AccountTeamSettings.vue +4 -0
  92. package/app/components/layout/AiProvidersBanner.vue +1 -1
  93. package/app/components/layout/AppearanceSwitcher.vue +1 -1
  94. package/app/components/layout/BoardSwitcher.vue +3 -2
  95. package/app/components/layout/BoardToolbar.vue +6 -2
  96. package/app/components/layout/CommandBar.vue +4 -2
  97. package/app/components/layout/DefaultTestEnvBanner.vue +2 -2
  98. package/app/components/layout/IntegrationsHub.vue +4 -3
  99. package/app/components/layout/LanguageSwitcher.vue +1 -1
  100. package/app/components/layout/ModelProvidersHub.vue +6 -4
  101. package/app/components/layout/NotificationsInbox.vue +8 -7
  102. package/app/components/layout/PersonalSetupModal.vue +5 -3
  103. package/app/components/layout/RolePrompt.vue +1 -1
  104. package/app/components/layout/SideBar.vue +3 -5
  105. package/app/components/layout/SpendWarningBanner.vue +3 -3
  106. package/app/components/layout/TranslationWarningBanner.vue +1 -1
  107. package/app/components/layout/UiModeSwitcher.vue +7 -6
  108. package/app/components/layout/UiRoleSwitcher.vue +2 -2
  109. package/app/components/media/ArtifactLightbox.vue +6 -6
  110. package/app/components/media/ImageCompare.vue +16 -16
  111. package/app/components/merge/MergeEffortChips.vue +4 -6
  112. package/app/components/notifications/NotificationSettingsPanel.vue +6 -5
  113. package/app/components/observability/OutcomeFilterChips.vue +1 -1
  114. package/app/components/observability/RunFailureSummary.vue +14 -17
  115. package/app/components/observability/StepMetricsBar.vue +9 -8
  116. package/app/components/observability/StepModelActivity.vue +4 -3
  117. package/app/components/observability/ToolCallList.vue +15 -18
  118. package/app/components/outcome/OutcomeSummaryWindow.vue +43 -42
  119. package/app/components/palettes/AgentPalette.vue +7 -5
  120. package/app/components/palettes/AgentTierSelect.vue +1 -1
  121. package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
  122. package/app/components/panels/AgentStepDetail.vue +27 -30
  123. package/app/components/panels/AttemptEntryHeader.vue +2 -2
  124. package/app/components/panels/DecisionModal.vue +1 -1
  125. package/app/components/panels/GenericStructuredResultView.vue +6 -5
  126. package/app/components/panels/InspectorPanel.vue +15 -13
  127. package/app/components/panels/MergerResultView.vue +10 -9
  128. package/app/components/panels/ObservabilityPanel.vue +66 -76
  129. package/app/components/panels/OperatorDashboardPanel.vue +27 -26
  130. package/app/components/panels/ReportsPanel.vue +26 -25
  131. package/app/components/panels/ReportsSpendBreakdown.vue +2 -2
  132. package/app/components/panels/ResultWindowShell.vue +19 -18
  133. package/app/components/panels/RunDetailLoadState.vue +1 -1
  134. package/app/components/panels/StepContainerStatus.vue +8 -7
  135. package/app/components/panels/StepDelegatedStatus.vue +13 -12
  136. package/app/components/panels/StepEffortReport.vue +12 -17
  137. package/app/components/panels/StepFragmentAdherence.vue +9 -10
  138. package/app/components/panels/StepMetadataCard.vue +41 -43
  139. package/app/components/panels/StepReproductionReport.vue +18 -20
  140. package/app/components/panels/StepRunMeta.vue +27 -26
  141. package/app/components/panels/StepTestReport.vue +16 -15
  142. package/app/components/panels/StepToolServers.vue +7 -8
  143. package/app/components/panels/StepValidationReport.vue +5 -5
  144. package/app/components/panels/inspector/ContainerSummary.vue +4 -4
  145. package/app/components/panels/inspector/DocReferenceRepos.vue +5 -4
  146. package/app/components/panels/inspector/EnvProbeReport.vue +16 -13
  147. package/app/components/panels/inspector/EpicChildren.vue +8 -7
  148. package/app/components/panels/inspector/FrontendBindingsResolved.vue +5 -4
  149. package/app/components/panels/inspector/FrontendConfig.vue +26 -34
  150. package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
  151. package/app/components/panels/inspector/InspectorSection.vue +7 -4
  152. package/app/components/panels/inspector/RecurringScheduleSettings.vue +9 -8
  153. package/app/components/panels/inspector/ServiceConnections.vue +2 -2
  154. package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
  155. package/app/components/panels/inspector/ServiceSelfTests.vue +9 -13
  156. package/app/components/panels/inspector/ServiceTestConfig.vue +41 -45
  157. package/app/components/panels/inspector/ServiceTestSecrets.vue +3 -3
  158. package/app/components/panels/inspector/ServiceTestingContext.vue +2 -2
  159. package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
  160. package/app/components/panels/inspector/TaskAgentConfig.vue +2 -2
  161. package/app/components/panels/inspector/TaskAprioriBranches.vue +6 -5
  162. package/app/components/panels/inspector/TaskDependencies.vue +1 -1
  163. package/app/components/panels/inspector/TaskEstimateBadge.vue +3 -7
  164. package/app/components/panels/inspector/TaskExecution.vue +13 -12
  165. package/app/components/panels/inspector/TaskRunSettings.vue +35 -38
  166. package/app/components/panels/inspector/TaskStructure.vue +5 -4
  167. package/app/components/pipeline/AgentPromptEditor.vue +15 -14
  168. package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -52
  169. package/app/components/pipeline/EstimateThresholdFields.vue +2 -2
  170. package/app/components/pipeline/GateConfigFields.vue +6 -6
  171. package/app/components/pipeline/IterationCapPrompt.vue +1 -1
  172. package/app/components/pipeline/PipelineBuilder.vue +28 -27
  173. package/app/components/pipeline/PipelineHealthModal.vue +7 -7
  174. package/app/components/pipeline/PipelinePicker.vue +3 -3
  175. package/app/components/pipeline/PipelinePreview.vue +6 -7
  176. package/app/components/pipeline/PipelineProgress.vue +23 -24
  177. package/app/components/prReview/PrReviewWindow.vue +42 -41
  178. package/app/components/providers/AiPresetMismatchDialog.vue +4 -3
  179. package/app/components/providers/AiProviderOnboardingModal.vue +2 -2
  180. package/app/components/providers/ApiKeysSection.vue +7 -6
  181. package/app/components/providers/PersonalSubscriptionSection.vue +4 -3
  182. package/app/components/providers/VendorCredentialsModal.vue +5 -4
  183. package/app/components/provisioning/ProvisioningLogsDrawer.vue +10 -9
  184. package/app/components/ralph/RalphLoopResultView.vue +25 -26
  185. package/app/components/requirements/RequirementsReviewWindow.vue +13 -12
  186. package/app/components/riskPolicy/RiskPolicyPicker.vue +5 -5
  187. package/app/components/riskPolicy/RiskPolicyPreview.vue +16 -15
  188. package/app/components/sandbox/SandboxPanel.vue +21 -20
  189. package/app/components/settings/ApiTokensPanel.vue +1 -1
  190. package/app/components/settings/BudgetSettings.vue +18 -17
  191. package/app/components/settings/CapabilityCredentialsPanel.vue +5 -5
  192. package/app/components/settings/CloudflareHandlerSection.vue +16 -16
  193. package/app/components/settings/ComposeEnvironmentSetupSection.vue +14 -12
  194. package/app/components/settings/ConnectionTestVerdict.vue +1 -1
  195. package/app/components/settings/ConsensusGroupsSection.vue +21 -20
  196. package/app/components/settings/CustomManifestTypeEditor.vue +8 -7
  197. package/app/components/settings/DefaultProvisionTypeSection.vue +5 -5
  198. package/app/components/settings/InfraHandlersConfigurator.vue +14 -15
  199. package/app/components/settings/InfrastructureBackendPicker.vue +2 -2
  200. package/app/components/settings/IssueTrackerPanel.vue +9 -15
  201. package/app/components/settings/KubernetesEngineForm.vue +9 -8
  202. package/app/components/settings/KubernetesEnvironmentForm.vue +4 -3
  203. package/app/components/settings/LocalContainerPoolSettings.vue +2 -2
  204. package/app/components/settings/LocalModelEndpointsPanel.vue +10 -9
  205. package/app/components/settings/MergeClassRulesEditor.vue +6 -5
  206. package/app/components/settings/MergeRolePolicyEditor.vue +13 -12
  207. package/app/components/settings/ModelConfigurationPanel.vue +8 -11
  208. package/app/components/settings/ModelPresetHealthModal.vue +3 -3
  209. package/app/components/settings/ObservabilityConnectionPanel.vue +1 -1
  210. package/app/components/settings/OpenRouterCatalogPanel.vue +6 -5
  211. package/app/components/settings/PackageRegistriesPanel.vue +4 -4
  212. package/app/components/settings/ProviderConnectionTab.vue +5 -4
  213. package/app/components/settings/ProviderManifestEditor.vue +9 -8
  214. package/app/components/settings/ProviderPreferenceEditor.vue +8 -7
  215. package/app/components/settings/RiskPolicyCreateForm.vue +40 -26
  216. package/app/components/settings/RiskPolicyEditorRow.vue +18 -17
  217. package/app/components/settings/RiskPolicyHealthModal.vue +3 -3
  218. package/app/components/settings/RiskPolicyPanel.vue +11 -13
  219. package/app/components/settings/ServiceFragmentDefaultsPanel.vue +5 -4
  220. package/app/components/settings/SharedStacksPanel.vue +5 -5
  221. package/app/components/settings/TaskSourceCard.vue +2 -2
  222. package/app/components/settings/TaskTypeSuppressionsPanel.vue +4 -4
  223. package/app/components/settings/ToolServerChecklist.vue +22 -22
  224. package/app/components/settings/UsageSettings.vue +13 -13
  225. package/app/components/settings/UserSecretsSection.vue +4 -3
  226. package/app/components/settings/WorkspaceMetadataSettings.vue +6 -5
  227. package/app/components/settings/WorkspaceSettingsPanel.vue +72 -58
  228. package/app/components/skills/ReviewSkillQueue.vue +8 -7
  229. package/app/components/skills/SkillLibraryManager.vue +2 -2
  230. package/app/components/slack/SlackPanel.vue +8 -7
  231. package/app/components/spec/ServiceSpecWindow.vue +15 -16
  232. package/app/components/tasks/BugHuntModal.vue +1 -1
  233. package/app/components/tasks/ContextIssuePicker.vue +4 -6
  234. package/app/components/tasks/TaskContextIssues.vue +1 -1
  235. package/app/components/tasks/TaskImportModal.vue +3 -2
  236. package/app/components/tasks/TaskSourceConnectModal.vue +5 -5
  237. package/app/components/testing/TestReportWindow.vue +54 -53
  238. package/app/components/tutorial/TutorialNudge.vue +3 -2
  239. package/app/components/tutorial/TutorialOverlay.vue +3 -2
  240. package/app/components/vcs/GitLabConnect.vue +1 -1
  241. package/app/components/visualConfirm/VisualConfirmationWindow.vue +23 -25
  242. package/app/utils/theme/builtins.ts +7 -1
  243. package/package.json +1 -1
@@ -204,7 +204,7 @@ async function checkSetup(source: TaskSourceKind) {
204
204
  <h3 class="text-sm font-semibold text-default">
205
205
  {{ t('settings.issueTracker.filing.heading') }}
206
206
  </h3>
207
- <p class="mt-1 text-[11px] text-muted">
207
+ <p class="mt-1 text-2xs text-muted">
208
208
  <i18n-t keypath="settings.issueTracker.filing.description" tag="span" scope="global">
209
209
  <template #none>
210
210
  <span class="text-toned">{{ t('settings.issueTracker.filing.none') }}</span>
@@ -269,10 +269,7 @@ async function checkSetup(source: TaskSourceKind) {
269
269
  </div>
270
270
 
271
271
  <!-- Inline readiness hints for the picked tracker. -->
272
- <p
273
- v-if="trackerKind === 'github' && !githubAvailable"
274
- class="text-[11px] text-app-warning-400"
275
- >
272
+ <p v-if="trackerKind === 'github' && !githubAvailable" class="text-2xs text-app-warning-400">
276
273
  <i18n-t keypath="settings.issueTracker.filing.githubHint" tag="span" scope="global">
277
274
  <template #link>
278
275
  <button class="underline" @click="ui.openGitHub()">
@@ -281,10 +278,7 @@ async function checkSetup(source: TaskSourceKind) {
281
278
  </template>
282
279
  </i18n-t>
283
280
  </p>
284
- <p
285
- v-else-if="trackerKind === 'jira' && !jiraConnected"
286
- class="text-[11px] text-app-warning-400"
287
- >
281
+ <p v-else-if="trackerKind === 'jira' && !jiraConnected" class="text-2xs text-app-warning-400">
288
282
  <i18n-t keypath="settings.issueTracker.filing.jiraHint" tag="span" scope="global">
289
283
  <template #link>
290
284
  <button class="underline" @click="ui.openTaskConnect('jira')">
@@ -295,7 +289,7 @@ async function checkSetup(source: TaskSourceKind) {
295
289
  </p>
296
290
  <p
297
291
  v-else-if="trackerKind === 'linear' && !linearConnected"
298
- class="text-[11px] text-app-warning-400"
292
+ class="text-2xs text-app-warning-400"
299
293
  >
300
294
  <i18n-t keypath="settings.issueTracker.filing.linearHint" tag="span" scope="global">
301
295
  <template #link>
@@ -313,7 +307,7 @@ async function checkSetup(source: TaskSourceKind) {
313
307
  >
314
308
  <UInput v-model="jiraProjectKey" placeholder="ENG" size="sm" class="w-full" />
315
309
  <template #help>
316
- <span class="text-[11px] text-dimmed">
310
+ <span class="text-2xs text-dimmed">
317
311
  {{ t('settings.issueTracker.filing.jiraProjectKeyHelp') }}
318
312
  </span>
319
313
  </template>
@@ -340,7 +334,7 @@ async function checkSetup(source: TaskSourceKind) {
340
334
  />
341
335
  <UInput v-else v-model="linearTeamId" placeholder="team_…" size="sm" class="w-full" />
342
336
  <template #help>
343
- <span class="text-[11px] text-dimmed">
337
+ <span class="text-2xs text-dimmed">
344
338
  {{ t('settings.issueTracker.filing.linearTeamIdHelp') }}
345
339
  </span>
346
340
  </template>
@@ -353,7 +347,7 @@ async function checkSetup(source: TaskSourceKind) {
353
347
  <h3 class="text-sm font-semibold text-default">
354
348
  {{ t('settings.issueTracker.linking.heading') }}
355
349
  </h3>
356
- <p class="mt-1 text-[11px] text-muted">
350
+ <p class="mt-1 text-2xs text-muted">
357
351
  {{ t('settings.issueTracker.linking.description') }}
358
352
  </p>
359
353
  </div>
@@ -370,7 +364,7 @@ async function checkSetup(source: TaskSourceKind) {
370
364
  @remedy="openRemedy(source)"
371
365
  />
372
366
 
373
- <p v-if="tasks.sources.length === 0" class="text-[11px] text-dimmed">
367
+ <p v-if="tasks.sources.length === 0" class="text-2xs text-dimmed">
374
368
  {{ t('settings.issueTracker.linking.none') }}
375
369
  </p>
376
370
  </section>
@@ -381,7 +375,7 @@ async function checkSetup(source: TaskSourceKind) {
381
375
  <h3 class="text-sm font-semibold text-default">
382
376
  {{ t('settings.issueTracker.writeback.heading') }}
383
377
  </h3>
384
- <p class="mt-1 text-[11px] text-muted">
378
+ <p class="mt-1 text-2xs text-muted">
385
379
  <i18n-t keypath="settings.issueTracker.writeback.description" tag="span" scope="global">
386
380
  <template #done>
387
381
  <span class="text-toned">{{ t('settings.issueTracker.writeback.done') }}</span>
@@ -17,6 +17,7 @@ import type {
17
17
  } from '@cat-factory/contracts'
18
18
  import { isKubernetesUrlSource } from '@cat-factory/contracts'
19
19
  import type { K3sSetupPrefill } from '~/stores/ui'
20
+ import SectionLabel from '~/components/common/SectionLabel.vue'
20
21
 
21
22
  // The kube branch of the discriminated handler config this form produces (the `local-k3s` /
22
23
  // `remote-kubernetes` engines share `kubernetesEngineConfigSchema`). Emitting this typed
@@ -369,17 +370,17 @@ async function copyAutoSetupCommand() {
369
370
 
370
371
  <template>
371
372
  <div class="rounded-lg border border-dashed border-muted p-3 space-y-3">
372
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
373
+ <SectionLabel as="p">
373
374
  {{
374
375
  connected
375
376
  ? t('settings.providerConnection.form.updateConfiguration')
376
377
  : t('settings.providerConnection.form.connect')
377
378
  }}
378
- </p>
379
+ </SectionLabel>
379
380
 
380
381
  <p
381
382
  v-if="engine === 'local-k3s'"
382
- class="rounded-md border border-app-info-500/30 bg-app-info-500/10 p-2 text-[11px] text-app-info-200"
383
+ class="rounded-md border border-app-info-500/30 bg-app-info-500/10 p-2 text-2xs text-app-info-200"
383
384
  >
384
385
  {{ t('settings.infrastructure.kubernetesEngine.localK3sHint') }}
385
386
  </p>
@@ -391,16 +392,16 @@ async function copyAutoSetupCommand() {
391
392
  v-if="engine === 'local-k3s'"
392
393
  class="rounded-md border border-muted bg-default/40 p-2 space-y-1.5"
393
394
  >
394
- <p class="flex items-center gap-1.5 text-[11px] font-semibold text-toned">
395
+ <p class="flex items-center gap-1.5 text-2xs font-semibold text-toned">
395
396
  <UIcon name="i-lucide-wand-2" class="h-3.5 w-3.5 text-muted" />
396
397
  {{ t('settings.infrastructure.kubernetesEngine.autoSetup.title') }}
397
398
  </p>
398
- <p class="text-[11px] text-muted">
399
+ <p class="text-2xs text-muted">
399
400
  {{ t('settings.infrastructure.kubernetesEngine.autoSetup.description') }}
400
401
  </p>
401
402
  <div class="flex items-center gap-1.5">
402
403
  <code
403
- class="flex-1 rounded bg-app-950 px-2 py-1 font-mono text-[11px] text-default select-all"
404
+ class="flex-1 rounded-sm bg-app-950 px-2 py-1 font-mono text-2xs text-default select-all"
404
405
  >
405
406
  {{ AUTO_SETUP_COMMAND }}
406
407
  </code>
@@ -438,7 +439,7 @@ async function copyAutoSetupCommand() {
438
439
  "
439
440
  >
440
441
  <template v-if="tokenStored" #hint>
441
- <span class="inline-flex items-center gap-1 text-[11px] text-app-success-400">
442
+ <span class="inline-flex items-center gap-1 text-2xs text-app-success-400">
442
443
  <UIcon name="i-lucide-check-circle-2" class="h-3.5 w-3.5" />
443
444
  {{ t('settings.infrastructure.kubernetesEngine.tokenSaved') }}
444
445
  </span>
@@ -457,7 +458,7 @@ async function copyAutoSetupCommand() {
457
458
  and the operator may legitimately overrule it. -->
458
459
  <p
459
460
  v-if="tokenProblem"
460
- class="mt-1 text-[11px]"
461
+ class="mt-1 text-2xs"
461
462
  :class="tokenBlocking ? 'text-app-error-400' : 'text-app-warning-400'"
462
463
  data-testid="service-account-token-problem"
463
464
  >
@@ -15,6 +15,7 @@ import ConnectionWarnings from '~/components/settings/ConnectionWarnings.vue'
15
15
  import ConnectionTestVerdict from '~/components/settings/ConnectionTestVerdict.vue'
16
16
  import SecretInput from '~/components/common/SecretInput.vue'
17
17
  import type { ProviderConnection } from '~/types/providerConnections'
18
+ import SectionLabel from '~/components/common/SectionLabel.vue'
18
19
 
19
20
  const props = defineProps<{
20
21
  connection: ProviderConnection | null
@@ -264,13 +265,13 @@ function optional(label: string): string {
264
265
 
265
266
  <template>
266
267
  <div class="rounded-lg border border-dashed border-muted p-3 space-y-3">
267
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
268
+ <SectionLabel as="p">
268
269
  {{
269
270
  connection?.kind === 'kubernetes'
270
271
  ? t('settings.providerConnection.form.updateConfiguration')
271
272
  : t('settings.providerConnection.form.connect')
272
273
  }}
273
- </p>
274
+ </SectionLabel>
274
275
 
275
276
  <UFormField :label="t('settings.providerConnection.kubernetesEnv.label')">
276
277
  <UInput
@@ -295,7 +296,7 @@ function optional(label: string): string {
295
296
  and the operator may legitimately overrule it. -->
296
297
  <p
297
298
  v-if="tokenProblem"
298
- class="mt-1 text-[11px]"
299
+ class="mt-1 text-2xs"
299
300
  :class="tokenBlocking ? 'text-app-error-400' : 'text-app-warning-400'"
300
301
  data-testid="service-account-token-problem"
301
302
  >
@@ -93,7 +93,7 @@ async function save() {
93
93
  <i18n-t
94
94
  keypath="settings.localMode.pool.description"
95
95
  tag="p"
96
- class="text-[11px] text-muted"
96
+ class="text-2xs text-muted"
97
97
  scope="global"
98
98
  >
99
99
  <template #appleContainer>
@@ -141,7 +141,7 @@ async function save() {
141
141
  <h4 class="text-sm font-semibold text-default">
142
142
  {{ t('settings.localMode.checkout.heading') }}
143
143
  </h4>
144
- <p class="text-[11px] text-muted">
144
+ <p class="text-2xs text-muted">
145
145
  {{ t('settings.localMode.checkout.description') }}
146
146
  </p>
147
147
  </div>
@@ -17,6 +17,7 @@ import {
17
17
  } from '~/types/localModels'
18
18
  import IntegrationBackTitle from '~/components/layout/IntegrationBackTitle.vue'
19
19
  import SecretInput from '~/components/common/SecretInput.vue'
20
+ import SectionLabel from '~/components/common/SectionLabel.vue'
20
21
 
21
22
  const { t } = useI18n()
22
23
  const ui = useUiStore()
@@ -301,7 +302,7 @@ async function remove(p: LocalRunner) {
301
302
  <div>
302
303
  <span class="font-medium text-default">{{ e.label }}</span>
303
304
  <span class="ms-2 text-xs text-dimmed">{{ LOCAL_RUNNER_LABELS[e.provider] }}</span>
304
- <div class="text-[11px] text-dimmed">
305
+ <div class="text-2xs text-dimmed">
305
306
  {{ e.baseUrl }} ·
306
307
  {{
307
308
  t(
@@ -316,7 +317,7 @@ async function remove(p: LocalRunner) {
316
317
  </div>
317
318
  <!-- A row whose URL the deployment no longer permits: its models are withheld
318
319
  from the picker, so this is the only place that can say why. -->
319
- <div v-if="e.urlBlockedReason" class="mt-1 text-[11px] text-app-warning-400">
320
+ <div v-if="e.urlBlockedReason" class="mt-1 text-2xs text-app-warning-400">
320
321
  {{ t('settings.localModelEndpoints.blocked') }}
321
322
  <span class="block text-app-warning-300/70">{{
322
323
  urlReasonText(e.urlBlockedReason)
@@ -325,7 +326,7 @@ async function remove(p: LocalRunner) {
325
326
  <!-- Part of the stored model list could not be read and was discarded. Without this
326
327
  the shortened list reads exactly like a runner nothing was ever enabled on, and
327
328
  only one of those is fixed by re-ticking. -->
328
- <div v-if="e.unreadableModels" class="mt-1 text-[11px] text-app-warning-400">
329
+ <div v-if="e.unreadableModels" class="mt-1 text-2xs text-app-warning-400">
329
330
  {{ t('settings.localModelEndpoints.modelsDiscarded') }}
330
331
  </div>
331
332
  </div>
@@ -352,13 +353,13 @@ async function remove(p: LocalRunner) {
352
353
 
353
354
  <!-- add / edit form -->
354
355
  <div class="rounded-lg border border-dashed border-muted p-3 space-y-3">
355
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
356
+ <SectionLabel as="p">
356
357
  {{
357
358
  existing
358
359
  ? t('settings.localModelEndpoints.editRunner')
359
360
  : t('settings.localModelEndpoints.addRunner')
360
361
  }}
361
- </p>
362
+ </SectionLabel>
362
363
 
363
364
  <div class="flex flex-wrap items-end gap-3">
364
365
  <UFormField :label="t('settings.localModelEndpoints.runnerType')">
@@ -415,7 +416,7 @@ async function remove(p: LocalRunner) {
415
416
  </UButton>
416
417
  <span v-if="testError" class="text-xs text-app-error-400">
417
418
  {{ testError }}
418
- <span v-if="testErrorDetail" class="block text-[11px] text-app-error-300/70">{{
419
+ <span v-if="testErrorDetail" class="block text-2xs text-app-error-300/70">{{
419
420
  testErrorDetail
420
421
  }}</span>
421
422
  </span>
@@ -435,10 +436,10 @@ async function remove(p: LocalRunner) {
435
436
 
436
437
  <!-- discovered models multi-select, each with its declared image support -->
437
438
  <div v-if="discovered.length" class="space-y-1.5">
438
- <span class="block text-[10px] uppercase tracking-wide text-dimmed">
439
+ <SectionLabel as="span" class="block">
439
440
  {{ t('settings.localModelEndpoints.enableModels') }}
440
- </span>
441
- <p class="text-[11px] text-dimmed">
441
+ </SectionLabel>
442
+ <p class="text-2xs text-dimmed">
442
443
  {{ t('settings.localModelEndpoints.imageInputHint') }}
443
444
  </p>
444
445
  <div class="space-y-1.5">
@@ -10,6 +10,7 @@
10
10
  import { computed } from 'vue'
11
11
  import { autoMergeShare, frictionlessShare, RULEABLE_CHANGE_CLASSES } from '@cat-factory/contracts'
12
12
  import type { MergeClassRule, MergeClassRules } from '~/types/merge'
13
+ import SectionLabel from '~/components/common/SectionLabel.vue'
13
14
 
14
15
  const props = defineProps<{
15
16
  /** The preset's current rules; an absent class means "use the score ceilings". */
@@ -83,13 +84,13 @@ function setRule(changeClass: (typeof RULEABLE_CHANGE_CLASSES)[number], rule: Me
83
84
  <template>
84
85
  <div data-testid="merge-class-rules" class="space-y-2">
85
86
  <div>
86
- <span class="block text-[10px] uppercase tracking-wide text-dimmed">
87
+ <SectionLabel as="span" class="block">
87
88
  {{ t('settings.riskPolicy.classRules.heading') }}
88
- </span>
89
- <p class="mt-0.5 text-[11px] leading-snug text-dimmed">
89
+ </SectionLabel>
90
+ <p class="mt-0.5 text-2xs leading-snug text-dimmed">
90
91
  {{ t('settings.riskPolicy.classRules.help') }}
91
92
  </p>
92
- <p v-if="!autoMergeEnabled" class="mt-1 text-[11px] leading-snug text-app-warning-400/90">
93
+ <p v-if="!autoMergeEnabled" class="mt-1 text-2xs leading-snug text-app-warning-400/90">
93
94
  {{ t('settings.riskPolicy.classRules.autoMergeOffWarning') }}
94
95
  </p>
95
96
  </div>
@@ -111,7 +112,7 @@ function setRule(changeClass: (typeof RULEABLE_CHANGE_CLASSES)[number], rule: Me
111
112
  :data-testid="`merge-class-rule-${row.changeClass}`"
112
113
  @update:model-value="setRule(row.changeClass, $event as MergeClassRule)"
113
114
  />
114
- <span class="text-[11px] text-dimmed" :data-testid="`merge-class-record-${row.changeClass}`">
115
+ <span class="text-2xs text-dimmed" :data-testid="`merge-class-record-${row.changeClass}`">
115
116
  <template v-if="row.merged === 0">
116
117
  {{ t('settings.riskPolicy.classRules.noData') }}
117
118
  </template>
@@ -34,6 +34,7 @@ import {
34
34
  toggleSubmissionClass,
35
35
  type RoleRuleSelection,
36
36
  } from '~/components/settings/MergeRolePolicyEditor.logic'
37
+ import SectionLabel from '~/components/common/SectionLabel.vue'
37
38
 
38
39
  const props = defineProps<{
39
40
  /** The preset's per-role narrowing map; a role with no entry is exactly the base rules. */
@@ -162,10 +163,10 @@ function setSubmissionClass(
162
163
  <template>
163
164
  <div data-testid="merge-role-policy" class="space-y-2">
164
165
  <div>
165
- <span class="block text-[10px] uppercase tracking-wide text-dimmed">
166
+ <SectionLabel as="span" class="block">
166
167
  {{ t('settings.riskPolicy.roleRules.heading') }}
167
- </span>
168
- <p class="mt-0.5 text-[11px] leading-snug text-dimmed">
168
+ </SectionLabel>
169
+ <p class="mt-0.5 text-2xs leading-snug text-dimmed">
169
170
  {{ t('settings.riskPolicy.roleRules.help') }}
170
171
  </p>
171
172
  <!-- Auto-merge off already sends every pull request to a human, so the per-class narrowing
@@ -173,7 +174,7 @@ function setSubmissionClass(
173
174
  MANUAL merge as well, which is the one thing the master switch leaves open. -->
174
175
  <p
175
176
  v-if="!autoMergeEnabled"
176
- class="mt-1 text-[11px] leading-snug text-app-warning-400/90"
177
+ class="mt-1 text-2xs leading-snug text-app-warning-400/90"
177
178
  data-testid="merge-role-auto-merge-off"
178
179
  >
179
180
  {{ t('settings.riskPolicy.roleRules.autoMergeOffWarning') }}
@@ -218,7 +219,7 @@ function setSubmissionClass(
218
219
  only, and a role can land nothing at all while showing "No class limits". -->
219
220
  <span
220
221
  v-if="group.submissionScoped"
221
- class="text-[11px] text-app-warning-400/90"
222
+ class="text-2xs text-app-warning-400/90"
222
223
  :data-testid="`merge-role-submission-badge-${group.role}`"
223
224
  >
224
225
  {{ t('settings.riskPolicy.roleRules.submissionBadge') }}
@@ -230,7 +231,7 @@ function setSubmissionClass(
230
231
  row says which of the three is actually governing. -->
231
232
  <p
232
233
  v-if="group.sandboxed"
233
- class="mt-1 text-[11px] leading-snug text-app-warning-400/90"
234
+ class="mt-1 text-2xs leading-snug text-app-warning-400/90"
234
235
  :data-testid="`merge-role-sandbox-note-${group.role}`"
235
236
  >
236
237
  {{ t('settings.riskPolicy.roleRules.sandboxNote') }}
@@ -249,7 +250,7 @@ function setSubmissionClass(
249
250
  :data-testid="`merge-role-submission-${group.role}`"
250
251
  @update:model-value="setSubmissionScoped(group.role, $event)"
251
252
  />
252
- <p class="text-[11px] leading-snug text-dimmed">
253
+ <p class="text-2xs leading-snug text-dimmed">
253
254
  {{ t('settings.riskPolicy.roleRules.submissionHelp') }}
254
255
  </p>
255
256
  <div v-if="group.submissionScoped" class="flex flex-wrap gap-x-4 gap-y-1">
@@ -268,7 +269,7 @@ function setSubmissionClass(
268
269
  does rather than reading as a switch somebody forgot to fill in. -->
269
270
  <p
270
271
  v-if="group.submissionScoped && !group.submissionRows.some((r) => r.allowed)"
271
- class="text-[11px] leading-snug text-app-warning-400/90"
272
+ class="text-2xs leading-snug text-app-warning-400/90"
272
273
  :data-testid="`merge-role-submission-none-${group.role}`"
273
274
  >
274
275
  {{ t('settings.riskPolicy.roleRules.submissionNone') }}
@@ -276,10 +277,10 @@ function setSubmissionClass(
276
277
  </div>
277
278
 
278
279
  <div class="space-y-1.5 border-t border-default/70 pt-2">
279
- <p class="text-[11px] leading-snug text-dimmed">
280
+ <p class="text-2xs leading-snug text-dimmed">
280
281
  {{ t('settings.riskPolicy.roleRules.classHeading') }}
281
282
  </p>
282
- <p v-if="!anyBaseRule" class="text-[11px] leading-snug text-dimmed">
283
+ <p v-if="!anyBaseRule" class="text-2xs leading-snug text-dimmed">
283
284
  {{ t('settings.riskPolicy.roleRules.baseHint') }}
284
285
  </p>
285
286
  <div
@@ -302,12 +303,12 @@ function setSubmissionClass(
302
303
  "
303
304
  />
304
305
  <!-- Nothing left to narrow: the base rule already routes this class to a human. -->
305
- <span v-if="row.items.length === 1" class="text-[11px] text-dimmed">
306
+ <span v-if="row.items.length === 1" class="text-2xs text-dimmed">
306
307
  {{ t('settings.riskPolicy.roleRules.alreadyStrictest') }}
307
308
  </span>
308
309
  <span
309
310
  v-else-if="row.redundant"
310
- class="text-[11px] text-app-warning-400/90"
311
+ class="text-2xs text-app-warning-400/90"
311
312
  :data-testid="`merge-role-redundant-${group.role}-${row.changeClass}`"
312
313
  >
313
314
  {{ t('settings.riskPolicy.roleRules.redundant') }}
@@ -22,6 +22,7 @@ import { cachingLabel, contextLabel, costLabel, displayFlavor, isSelectable } fr
22
22
  import ConsensusGroupsSection from '~/components/settings/ConsensusGroupsSection.vue'
23
23
  import ProviderPreferenceEditor from '~/components/settings/ProviderPreferenceEditor.vue'
24
24
  import { showOverrideField } from '~/utils/uiMode'
25
+ import SectionLabel from '~/components/common/SectionLabel.vue'
25
26
 
26
27
  const { t } = useI18n()
27
28
  const ui = useUiStore()
@@ -424,7 +425,7 @@ async function save() {
424
425
  />
425
426
  </div>
426
427
  </div>
427
- <div class="mt-1.5 text-[11px] text-muted">
428
+ <div class="mt-1.5 text-2xs text-muted">
428
429
  {{ t('settings.modelConfiguration.list.basePrefix') }}
429
430
  <span class="text-toned">{{ modelLabel(p.baseModelId) }}</span>
430
431
  <span v-if="Object.keys(p.overrides).length">
@@ -460,11 +461,9 @@ async function save() {
460
461
  <template v-else>
461
462
  <div class="space-y-4 rounded-xl border border-default bg-default/50 p-4">
462
463
  <div>
463
- <label
464
- class="mb-1 block text-[11px] font-semibold uppercase tracking-wide text-muted"
465
- >
464
+ <SectionLabel as="label" class="mb-1 block">
466
465
  {{ t('settings.modelConfiguration.editor.nameLabel') }}
467
- </label>
466
+ </SectionLabel>
468
467
  <UInput
469
468
  v-model="editor.name"
470
469
  :placeholder="t('settings.modelConfiguration.editor.namePlaceholder')"
@@ -474,11 +473,9 @@ async function save() {
474
473
  </div>
475
474
 
476
475
  <div>
477
- <label
478
- class="mb-1 block text-[11px] font-semibold uppercase tracking-wide text-muted"
479
- >
476
+ <SectionLabel as="label" class="mb-1 block">
480
477
  {{ t('settings.modelConfiguration.editor.baseModelLabel') }}
481
- </label>
478
+ </SectionLabel>
482
479
  <UDropdownMenu
483
480
  :items="baseMenu"
484
481
  :ui="{ content: 'max-h-80 overflow-y-auto z-[60]' }"
@@ -514,9 +511,9 @@ async function save() {
514
511
 
515
512
  <div>
516
513
  <div class="mb-1 flex items-start justify-between gap-3">
517
- <span class="text-[11px] font-semibold uppercase tracking-wide text-muted">
514
+ <SectionLabel as="span">
518
515
  {{ t('settings.modelConfiguration.editor.perAgentOverrides') }}
519
- </span>
516
+ </SectionLabel>
520
517
  <AgentTierSelect class="w-56 shrink-0" :hidden-count="hiddenByTier" />
521
518
  </div>
522
519
  <UInput
@@ -73,7 +73,7 @@ const reseedableCount = computed(
73
73
  {{ t('modelPreset.health.newHeading') }}
74
74
  </h3>
75
75
  </div>
76
- <p class="text-[11px] text-dimmed">{{ t('modelPreset.health.newDescription') }}</p>
76
+ <p class="text-2xs text-dimmed">{{ t('modelPreset.health.newDescription') }}</p>
77
77
  <ul class="space-y-2">
78
78
  <li
79
79
  v-for="i in newPresets"
@@ -108,7 +108,7 @@ const reseedableCount = computed(
108
108
  {{ t('modelPreset.health.updatesHeading') }}
109
109
  </h3>
110
110
  </div>
111
- <p class="text-[11px] text-dimmed">
111
+ <p class="text-2xs text-dimmed">
112
112
  {{ t('modelPreset.health.updatesDescription') }}
113
113
  </p>
114
114
  <ul class="space-y-2">
@@ -119,7 +119,7 @@ const reseedableCount = computed(
119
119
  >
120
120
  <div class="min-w-0">
121
121
  <span class="truncate text-sm font-medium text-app-100">{{ i.name }}</span>
122
- <p class="text-[11px] text-app-warning-400/80">
122
+ <p class="text-2xs text-app-warning-400/80">
123
123
  {{
124
124
  t('modelPreset.health.versionAvailable', {
125
125
  from: i.fromVersion ?? 0,
@@ -236,7 +236,7 @@ const connectedLabel = computed(() => {
236
236
  }}
237
237
  </UBadge>
238
238
  </div>
239
- <p class="text-[11px] text-muted">
239
+ <p class="text-2xs text-muted">
240
240
  {{ t('settings.observabilityConnection.incident.description') }}
241
241
  </p>
242
242
 
@@ -11,6 +11,7 @@ import { computed, ref, watch } from 'vue'
11
11
  import type { OpenRouterModelMeta } from '~/types/openrouter'
12
12
  import IntegrationBackTitle from '~/components/layout/IntegrationBackTitle.vue'
13
13
  import SecretInput from '~/components/common/SecretInput.vue'
14
+ import SectionLabel from '~/components/common/SectionLabel.vue'
14
15
 
15
16
  const { t } = useI18n()
16
17
  const ui = useUiStore()
@@ -239,9 +240,9 @@ function manageKeys() {
239
240
  v-if="!keyConnected"
240
241
  class="space-y-3 rounded-lg border border-muted bg-default/60 p-4"
241
242
  >
242
- <h4 class="text-xs font-semibold uppercase tracking-wide text-dimmed">
243
+ <SectionLabel as="h4">
243
244
  {{ t('settings.openRouterCatalog.connectHeading') }}
244
- </h4>
245
+ </SectionLabel>
245
246
  <ol class="list-decimal space-y-1 ps-5 text-sm text-toned">
246
247
  <li>
247
248
  <i18n-t keypath="settings.openRouterCatalog.step1" tag="span" scope="global">
@@ -363,7 +364,7 @@ function manageKeys() {
363
364
  />
364
365
  <span class="min-w-0 flex-1">
365
366
  <span class="block truncate text-default">{{ m.name }}</span>
366
- <span class="block truncate font-mono text-[11px] text-dimmed">{{ m.id }}</span>
367
+ <span class="block truncate font-mono text-2xs text-dimmed">{{ m.id }}</span>
367
368
  <!--
368
369
  A withdrawal date is the one fact about a model that fails SILENTLY: past it the
369
370
  route simply stops answering and the run falls through to whatever the picker
@@ -371,11 +372,11 @@ function manageKeys() {
371
372
  -->
372
373
  <span
373
374
  v-if="m.expirationDate"
374
- class="block truncate text-[11px] text-app-warning-400"
375
+ class="block truncate text-2xs text-app-warning-400"
375
376
  >{{ t('settings.openRouterCatalog.retiresOn', { date: m.expirationDate }) }}</span
376
377
  >
377
378
  </span>
378
- <span class="shrink-0 text-end text-[11px] text-dimmed">
379
+ <span class="shrink-0 text-end text-2xs text-dimmed">
379
380
  <span v-if="m.contextLength" class="block">{{
380
381
  contextLabel(m.contextLength)
381
382
  }}</span>
@@ -115,7 +115,7 @@ async function removeEntry(entryId: string) {
115
115
  <div class="min-w-0 space-y-1">
116
116
  <div class="flex items-center gap-2">
117
117
  <span class="text-sm font-medium">{{ vendorLabel(entry.vendor) }}</span>
118
- <span class="text-[11px] text-dimmed">
118
+ <span class="text-2xs text-dimmed">
119
119
  {{ t('settings.packageRegistries.list.tokenTail', { tail: entry.tokenTail }) }}
120
120
  </span>
121
121
  </div>
@@ -132,7 +132,7 @@ async function removeEntry(entryId: string) {
132
132
  <!-- An entry with no scopes authenticates its host without routing any scope to
133
133
  it (the deliberate mixed public/private setup) — say so, or the row reads as
134
134
  half-configured. -->
135
- <span v-if="!entry.scopes.length" class="text-[11px] text-dimmed">
135
+ <span v-if="!entry.scopes.length" class="text-2xs text-dimmed">
136
136
  {{ t('settings.packageRegistries.list.noScopes') }}
137
137
  </span>
138
138
  </div>
@@ -164,7 +164,7 @@ async function removeEntry(entryId: string) {
164
164
  data-testid="package-registry-vendor"
165
165
  />
166
166
  </UFormField>
167
- <p class="text-[11px] text-dimmed">
167
+ <p class="text-2xs text-dimmed">
168
168
  {{ t('settings.packageRegistries.add.host', { host: vendorHost }) }}
169
169
  </p>
170
170
 
@@ -197,7 +197,7 @@ async function removeEntry(entryId: string) {
197
197
  </div>
198
198
  <!-- Why leaving this empty is often the RIGHT answer — a scope mapping is all-or-nothing,
199
199
  so an org publishing some of its `@org` packages publicly breaks under one. -->
200
- <p class="text-[11px] text-dimmed">
200
+ <p class="text-2xs text-dimmed">
201
201
  {{ t('settings.packageRegistries.add.scopesNote') }}
202
202
  </p>
203
203
 
@@ -19,6 +19,7 @@ import ConnectionTestVerdict from '~/components/settings/ConnectionTestVerdict.v
19
19
  import ProvisioningLogsDrawer from '~/components/provisioning/ProvisioningLogsDrawer.vue'
20
20
  import ProviderManifestEditor from '~/components/settings/ProviderManifestEditor.vue'
21
21
  import KubernetesEnvironmentForm from '~/components/settings/KubernetesEnvironmentForm.vue'
22
+ import SectionLabel from '~/components/common/SectionLabel.vue'
22
23
 
23
24
  const props = defineProps<{
24
25
  kind: ProviderConnectionKind
@@ -383,7 +384,7 @@ function fieldHelp(key: string): string | undefined {
383
384
  >
384
385
  <div>
385
386
  <span class="font-medium text-default">{{ connection.label }}</span>
386
- <div class="text-[11px] text-app-success-400">
387
+ <div class="text-2xs text-app-success-400">
387
388
  {{ t('settings.providerConnection.connectedAt', { baseUrl: connection.baseUrl }) }}
388
389
  </div>
389
390
  </div>
@@ -426,14 +427,14 @@ function fieldHelp(key: string): string | undefined {
426
427
 
427
428
  <!-- NATIVE provider: the friendly, descriptor-driven flat field form. -->
428
429
  <div v-else-if="isNative" class="rounded-lg border border-dashed border-muted p-3 space-y-3">
429
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
430
+ <SectionLabel as="p">
430
431
  {{
431
432
  connection
432
433
  ? t('settings.providerConnection.form.updateConfiguration')
433
434
  : t('settings.providerConnection.form.connect')
434
435
  }}
435
- </p>
436
- <p v-if="connection && hasSecretFields" class="text-[11px] text-app-warning-300/80">
436
+ </SectionLabel>
437
+ <p v-if="connection && hasSecretFields" class="text-2xs text-app-warning-300/80">
437
438
  {{
438
439
  t(
439
440
  'settings.providerConnection.form.reenterSecrets',