@cat-factory/app 0.307.1 → 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 (255) 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 +2 -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/composables/usePipelineErrorToast.ts +2 -0
  243. package/app/utils/catalog.ts +8 -0
  244. package/app/utils/theme/builtins.ts +7 -1
  245. package/i18n/locales/de.json +6 -3
  246. package/i18n/locales/en.json +6 -3
  247. package/i18n/locales/es.json +6 -3
  248. package/i18n/locales/fr.json +6 -3
  249. package/i18n/locales/he.json +6 -3
  250. package/i18n/locales/it.json +6 -3
  251. package/i18n/locales/ja.json +6 -3
  252. package/i18n/locales/pl.json +6 -3
  253. package/i18n/locales/tr.json +6 -3
  254. package/i18n/locales/uk.json +6 -3
  255. package/package.json +2 -2
@@ -173,7 +173,7 @@ async function removeKey(key: string) {
173
173
  </li>
174
174
  </ul>
175
175
 
176
- <p v-if="entry.stored && entry.updatedAt" class="text-[11px] text-dimmed">
176
+ <p v-if="entry.stored && entry.updatedAt" class="text-2xs text-dimmed">
177
177
  {{
178
178
  t('settings.capabilityCredentials.storedAt', {
179
179
  date: d(new Date(entry.updatedAt), 'short'),
@@ -191,13 +191,13 @@ async function removeKey(key: string) {
191
191
  usual one, but a facade that wired the store and dropped the flag lands here too, and
192
192
  blaming a custom resolver would make that wiring bug read as a deliberate configuration
193
193
  and send the operator to the one place that cannot explain it. -->
194
- <p v-else-if="view?.environmentFallback === true" class="text-[11px] text-dimmed">
194
+ <p v-else-if="view?.environmentFallback === true" class="text-2xs text-dimmed">
195
195
  {{ t('settings.capabilityCredentials.notStoredWithFallback') }}
196
196
  </p>
197
- <p v-else-if="view?.environmentFallback === false" class="text-[11px] text-app-warning-400">
197
+ <p v-else-if="view?.environmentFallback === false" class="text-2xs text-app-warning-400">
198
198
  {{ t('settings.capabilityCredentials.notStored') }}
199
199
  </p>
200
- <p v-else class="text-[11px] text-dimmed">
200
+ <p v-else class="text-2xs text-dimmed">
201
201
  {{ t('settings.capabilityCredentials.notStoredUnknownFallback') }}
202
202
  </p>
203
203
 
@@ -268,7 +268,7 @@ async function removeKey(key: string) {
268
268
  >
269
269
  <div class="min-w-0">
270
270
  <code class="font-mono text-sm">{{ orphan.key }}</code>
271
- <span class="block text-[11px] text-dimmed">
271
+ <span class="block text-2xs text-dimmed">
272
272
  {{
273
273
  t('settings.capabilityCredentials.storedAt', {
274
274
  date: d(new Date(orphan.updatedAt), 'short'),
@@ -147,7 +147,7 @@ async function remove() {
147
147
  <h3 class="text-sm font-semibold text-default">
148
148
  {{ t('inspector.testConfig.provisionTypes.cloudflare') }}
149
149
  </h3>
150
- <p class="text-[11px] text-muted">
150
+ <p class="text-2xs text-muted">
151
151
  {{ t('settings.infrastructure.cloudflare.intro') }}
152
152
  </p>
153
153
 
@@ -162,7 +162,7 @@ async function remove() {
162
162
  disabled
163
163
  size="lg"
164
164
  :label="t('settings.infrastructure.handler.connectionEstablished')"
165
- :ui="{ label: 'text-[13px] font-semibold text-app-success-300' }"
165
+ :ui="{ label: 'text-sm font-semibold text-app-success-300' }"
166
166
  />
167
167
  <div class="flex items-center gap-1">
168
168
  <UButton
@@ -185,31 +185,31 @@ async function remove() {
185
185
  />
186
186
  </div>
187
187
  </div>
188
- <p class="pl-7 text-[11px] text-toned">
188
+ <p class="pl-7 text-2xs text-toned">
189
189
  {{ t('settings.infrastructure.cloudflare.connectedAs', { subdomain: workersSubdomain }) }}
190
190
  </p>
191
191
  </div>
192
192
 
193
193
  <div v-else class="space-y-2" data-testid="cloudflare-handler-form">
194
194
  <div class="space-y-1">
195
- <label class="text-[11px] text-muted">{{
195
+ <label class="text-2xs text-muted">{{
196
196
  t('settings.infrastructure.cloudflare.label')
197
197
  }}</label>
198
198
  <UInput v-model="label" size="xs" />
199
199
  </div>
200
200
 
201
201
  <div class="space-y-1">
202
- <label class="text-[11px] text-muted">{{
202
+ <label class="text-2xs text-muted">{{
203
203
  t('settings.infrastructure.cloudflare.subdomain')
204
204
  }}</label>
205
205
  <UInput v-model="workersSubdomain" size="xs" placeholder="my-account" />
206
- <p class="text-[11px] text-dimmed">
206
+ <p class="text-2xs text-dimmed">
207
207
  {{ t('settings.infrastructure.cloudflare.subdomainHint') }}
208
208
  </p>
209
209
  </div>
210
210
 
211
211
  <div class="space-y-1">
212
- <label class="text-[11px] text-muted">{{
212
+ <label class="text-2xs text-muted">{{
213
213
  t('settings.infrastructure.cloudflare.token')
214
214
  }}</label>
215
215
  <UInput
@@ -222,28 +222,28 @@ async function remove() {
222
222
  : t('settings.infrastructure.cloudflare.tokenPlaceholder')
223
223
  "
224
224
  />
225
- <p class="text-[11px] text-dimmed">
225
+ <p class="text-2xs text-dimmed">
226
226
  {{ t('settings.infrastructure.cloudflare.tokenHint') }}
227
227
  </p>
228
228
  </div>
229
229
 
230
230
  <div class="space-y-1">
231
- <label class="text-[11px] text-muted">{{
231
+ <label class="text-2xs text-muted">{{
232
232
  t('settings.infrastructure.cloudflare.repo')
233
233
  }}</label>
234
234
  <UInput v-model="repo" size="xs" placeholder="owner/repo" />
235
- <p class="text-[11px] text-dimmed">
235
+ <p class="text-2xs text-dimmed">
236
236
  {{ t('settings.infrastructure.cloudflare.repoHint') }}
237
237
  </p>
238
238
  </div>
239
239
 
240
240
  <details class="rounded-md border border-muted/70 p-2">
241
- <summary class="cursor-pointer text-[11px] text-muted">
241
+ <summary class="cursor-pointer text-2xs text-muted">
242
242
  {{ t('settings.infrastructure.cloudflare.advanced') }}
243
243
  </summary>
244
244
  <div class="mt-2 space-y-2">
245
245
  <div class="space-y-1">
246
- <label class="text-[11px] text-muted">{{
246
+ <label class="text-2xs text-muted">{{
247
247
  t('settings.infrastructure.cloudflare.workerTemplate')
248
248
  }}</label>
249
249
  <!-- The placeholder is a FORMAT EXAMPLE containing vue-i18n metacharacters, so it
@@ -255,16 +255,16 @@ async function remove() {
255
255
  />
256
256
  </div>
257
257
  <div class="space-y-1">
258
- <label class="text-[11px] text-muted">{{
258
+ <label class="text-2xs text-muted">{{
259
259
  t('settings.infrastructure.cloudflare.environmentTemplate')
260
260
  }}</label>
261
261
  <UInput v-model="environmentNameTemplate" size="xs" placeholder="pr-{{pullNumber}}" />
262
262
  </div>
263
- <p class="text-[11px] text-dimmed">
263
+ <p class="text-2xs text-dimmed">
264
264
  {{ t('settings.infrastructure.cloudflare.templateHint') }}
265
265
  </p>
266
266
  <div class="space-y-1">
267
- <label class="text-[11px] text-muted">{{
267
+ <label class="text-2xs text-muted">{{
268
268
  t('settings.infrastructure.cloudflare.apiBaseUrl')
269
269
  }}</label>
270
270
  <UInput v-model="apiBaseUrl" size="xs" placeholder="https://api.github.com" />
@@ -300,7 +300,7 @@ async function remove() {
300
300
 
301
301
  <p
302
302
  v-if="testResult"
303
- class="text-[11px]"
303
+ class="text-2xs"
304
304
  :class="testResult.ok ? 'text-app-success-300' : 'text-app-error-300'"
305
305
  >
306
306
  {{ testResult.message }}
@@ -13,6 +13,8 @@
13
13
  // is a five-minute flow that touches a repo and can trial-provision a stack, so "when you need
14
14
  // this / when you don't" has to be answerable BEFORE opening it — most services on most boards
15
15
  // never need it at all.
16
+ import SectionLabel from '~/components/common/SectionLabel.vue'
17
+
16
18
  const { t } = useI18n()
17
19
  const ui = useUiStore()
18
20
 
@@ -52,34 +54,34 @@ function start() {
52
54
  </p>
53
55
  </div>
54
56
 
55
- <div class="rounded border border-default bg-default/40 p-3">
56
- <p class="text-[11px] font-medium uppercase tracking-wide text-muted">
57
+ <div class="rounded-sm border border-default bg-default/40 p-3">
58
+ <SectionLabel as="p">
57
59
  {{ t('settings.composeEnvSetup.how.title') }}
58
- </p>
59
- <ol class="mt-2 list-decimal space-y-1 ps-4 text-[11px] leading-relaxed text-muted">
60
+ </SectionLabel>
61
+ <ol class="mt-2 list-decimal space-y-1 ps-4 text-2xs leading-relaxed text-muted">
60
62
  <li v-for="(step, i) in steps" :key="`how-${i}`">{{ step }}</li>
61
63
  </ol>
62
- <p class="mt-2 text-[11px] leading-relaxed text-dimmed">
64
+ <p class="mt-2 text-2xs leading-relaxed text-dimmed">
63
65
  {{ t('settings.composeEnvSetup.how.outcome') }}
64
66
  </p>
65
67
  </div>
66
68
 
67
69
  <div class="grid gap-2 sm:grid-cols-2">
68
- <div class="rounded border border-app-success-900/50 bg-app-success-950/20 p-3">
69
- <p class="flex items-center gap-1.5 text-[11px] font-medium text-app-success-200/90">
70
+ <div class="rounded-sm border border-app-success-900/50 bg-app-success-950/20 p-3">
71
+ <p class="flex items-center gap-1.5 text-2xs font-medium text-app-success-200/90">
70
72
  <UIcon name="i-lucide-check" class="h-3.5 w-3.5 shrink-0" />
71
73
  {{ t('settings.composeEnvSetup.needed.title') }}
72
74
  </p>
73
- <ul class="mt-1.5 list-disc space-y-1 ps-4 text-[11px] leading-relaxed text-muted">
75
+ <ul class="mt-1.5 list-disc space-y-1 ps-4 text-2xs leading-relaxed text-muted">
74
76
  <li v-for="(item, i) in needed" :key="`need-${i}`">{{ item }}</li>
75
77
  </ul>
76
78
  </div>
77
- <div class="rounded border border-default bg-default/40 p-3">
78
- <p class="flex items-center gap-1.5 text-[11px] font-medium text-toned">
79
+ <div class="rounded-sm border border-default bg-default/40 p-3">
80
+ <p class="flex items-center gap-1.5 text-2xs font-medium text-toned">
79
81
  <UIcon name="i-lucide-minus" class="h-3.5 w-3.5 shrink-0" />
80
82
  {{ t('settings.composeEnvSetup.notNeeded.title') }}
81
83
  </p>
82
- <ul class="mt-1.5 list-disc space-y-1 ps-4 text-[11px] leading-relaxed text-muted">
84
+ <ul class="mt-1.5 list-disc space-y-1 ps-4 text-2xs leading-relaxed text-muted">
83
85
  <li v-for="(item, i) in notNeeded" :key="`skip-${i}`">{{ item }}</li>
84
86
  </ul>
85
87
  </div>
@@ -96,7 +98,7 @@ function start() {
96
98
  >
97
99
  {{ t('settings.composeEnvSetup.start') }}
98
100
  </UButton>
99
- <span class="text-[11px] text-dimmed">{{ t('settings.composeEnvSetup.rerunHint') }}</span>
101
+ <span class="text-2xs text-dimmed">{{ t('settings.composeEnvSetup.rerunHint') }}</span>
100
102
  </div>
101
103
  </section>
102
104
  </template>
@@ -57,6 +57,6 @@ const detail = computed(() => (causeKey.value ? (props.result?.message ?? '') :
57
57
  </p>
58
58
  <div v-else-if="result" class="space-y-0.5" data-testid="connection-test-result">
59
59
  <p class="text-xs text-app-error-400 break-words">{{ headline }}</p>
60
- <p v-if="detail" class="text-[11px] text-muted break-words">{{ detail }}</p>
60
+ <p v-if="detail" class="text-2xs text-muted break-words">{{ detail }}</p>
61
61
  </div>
62
62
  </template>
@@ -13,6 +13,7 @@ import { computed, ref } from 'vue'
13
13
  import type { ConsensusGroup, ConsensusStrategy } from '~/types/consensus'
14
14
  import { isSelectable } from '~/stores/models'
15
15
  import { uid } from '~/utils/catalog'
16
+ import SectionLabel from '~/components/common/SectionLabel.vue'
16
17
 
17
18
  const { t } = useI18n()
18
19
  const groups = useConsensusGroupsStore()
@@ -264,8 +265,8 @@ async function remove(group: ConsensusGroup) {
264
265
  />
265
266
  </div>
266
267
  </div>
267
- <p v-if="g.description" class="mt-1 text-[11px] text-muted">{{ g.description }}</p>
268
- <div class="mt-1.5 text-[11px] text-muted">
268
+ <p v-if="g.description" class="mt-1 text-2xs text-muted">{{ g.description }}</p>
269
+ <div class="mt-1.5 text-2xs text-muted">
269
270
  {{ t(`pipeline.builder.strategyOption.${g.strategy}`) }}
270
271
  ·
271
272
  {{
@@ -287,9 +288,9 @@ async function remove(group: ConsensusGroup) {
287
288
  <div v-else class="space-y-4 rounded-xl border border-default bg-default/50 p-4">
288
289
  <div class="grid gap-3 sm:grid-cols-2">
289
290
  <div>
290
- <label class="mb-1 block text-[11px] font-semibold uppercase tracking-wide text-muted">
291
+ <SectionLabel as="label" class="mb-1 block">
291
292
  {{ t('settings.consensusGroups.editor.nameLabel') }}
292
- </label>
293
+ </SectionLabel>
293
294
  <UInput
294
295
  v-model="editor.name"
295
296
  size="sm"
@@ -298,12 +299,12 @@ async function remove(group: ConsensusGroup) {
298
299
  />
299
300
  </div>
300
301
  <div>
301
- <label class="mb-1 block text-[11px] font-semibold uppercase tracking-wide text-muted">
302
+ <SectionLabel as="label" class="mb-1 block">
302
303
  {{ t('settings.consensusGroups.editor.strategyLabel') }}
303
- </label>
304
+ </SectionLabel>
304
305
  <select
305
306
  v-model="editor.strategy"
306
- class="w-full rounded border border-muted bg-default px-2 py-1.5 text-sm text-app-100"
307
+ class="w-full rounded-sm border border-muted bg-default px-2 py-1.5 text-sm text-app-100"
307
308
  >
308
309
  <option v-for="s in STRATEGIES" :key="s.value" :value="s.value">{{ s.label }}</option>
309
310
  </select>
@@ -311,9 +312,9 @@ async function remove(group: ConsensusGroup) {
311
312
  </div>
312
313
 
313
314
  <div>
314
- <label class="mb-1 block text-[11px] font-semibold uppercase tracking-wide text-muted">
315
+ <SectionLabel as="label" class="mb-1 block">
315
316
  {{ t('settings.consensusGroups.editor.descriptionLabel') }}
316
- </label>
317
+ </SectionLabel>
317
318
  <UInput
318
319
  v-model="editor.description"
319
320
  size="sm"
@@ -325,9 +326,9 @@ async function remove(group: ConsensusGroup) {
325
326
  <!-- participants -->
326
327
  <div class="space-y-2">
327
328
  <div class="flex items-center justify-between">
328
- <span class="text-[11px] font-semibold uppercase tracking-wide text-muted">
329
+ <SectionLabel as="span">
329
330
  {{ t('settings.consensusGroups.editor.participantsLabel') }}
330
- </span>
331
+ </SectionLabel>
331
332
  <UButton
332
333
  icon="i-lucide-plus"
333
334
  color="neutral"
@@ -337,7 +338,7 @@ async function remove(group: ConsensusGroup) {
337
338
  @click="addParticipant"
338
339
  />
339
340
  </div>
340
- <p class="text-[11px] text-dimmed">
341
+ <p class="text-2xs text-dimmed">
341
342
  {{ t('settings.consensusGroups.editor.participantsHint') }}
342
343
  </p>
343
344
  <div
@@ -359,7 +360,7 @@ async function remove(group: ConsensusGroup) {
359
360
  />
360
361
  <select
361
362
  v-model="p.modelId"
362
- class="w-44 rounded border border-muted bg-default px-1.5 py-1 text-xs text-toned"
363
+ class="w-44 rounded-sm border border-muted bg-default px-1.5 py-1 text-xs text-toned"
363
364
  >
364
365
  <option :value="undefined">{{ t('settings.consensusGroups.editor.stepModel') }}</option>
365
366
  <option v-for="m in selectableModelIds" :key="m.id" :value="m.id">{{ m.label }}</option>
@@ -378,21 +379,21 @@ async function remove(group: ConsensusGroup) {
378
379
 
379
380
  <div class="grid gap-3 sm:grid-cols-2">
380
381
  <div>
381
- <label class="mb-1 block text-[11px] font-semibold uppercase tracking-wide text-muted">
382
+ <SectionLabel as="label" class="mb-1 block">
382
383
  {{ t('settings.consensusGroups.editor.synthesizerLabel') }}
383
- </label>
384
+ </SectionLabel>
384
385
  <select
385
386
  v-model="editor.synthesizerModelId"
386
- class="w-full rounded border border-muted bg-default px-2 py-1.5 text-sm text-app-100"
387
+ class="w-full rounded-sm border border-muted bg-default px-2 py-1.5 text-sm text-app-100"
387
388
  >
388
389
  <option value="">{{ t('settings.consensusGroups.editor.stepModel') }}</option>
389
390
  <option v-for="m in selectableModelIds" :key="m.id" :value="m.id">{{ m.label }}</option>
390
391
  </select>
391
392
  </div>
392
393
  <div v-if="editor.strategy === 'debate'">
393
- <label class="mb-1 block text-[11px] font-semibold uppercase tracking-wide text-muted">
394
+ <SectionLabel as="label" class="mb-1 block">
394
395
  {{ t('pipeline.builder.rounds') }}
395
- </label>
396
+ </SectionLabel>
396
397
  <UInput v-model.number="editor.rounds" type="number" min="1" max="5" size="sm" />
397
398
  </div>
398
399
  </div>
@@ -403,7 +404,7 @@ async function remove(group: ConsensusGroup) {
403
404
  <input v-model="editor.gated" type="checkbox" class="accent-app-success-500" />
404
405
  {{ t('settings.consensusGroups.editor.gatedLabel') }}
405
406
  </label>
406
- <p class="text-[11px] text-dimmed">
407
+ <p class="text-2xs text-dimmed">
407
408
  {{ t('settings.consensusGroups.editor.gatedHint') }}
408
409
  </p>
409
410
  <div v-if="editor.gated" class="flex flex-wrap items-center gap-3 text-xs">
@@ -453,7 +454,7 @@ async function remove(group: ConsensusGroup) {
453
454
  />
454
455
  </label>
455
456
  </div>
456
- <p v-if="gatingIncomplete" class="text-[11px] text-app-warning-400">
457
+ <p v-if="gatingIncomplete" class="text-2xs text-app-warning-400">
457
458
  {{ t('settings.consensusGroups.editor.gatingIncomplete') }}
458
459
  </p>
459
460
  </div>
@@ -6,6 +6,7 @@
6
6
  // infraConfig store (`PUT|DELETE /environments/custom-types/:manifestId`).
7
7
  import { computed, reactive, ref } from 'vue'
8
8
  import type { CustomManifestType } from '@cat-factory/contracts'
9
+ import SectionLabel from '~/components/common/SectionLabel.vue'
9
10
 
10
11
  const { t } = useI18n()
11
12
  const infra = useInfraConfigStore()
@@ -95,7 +96,7 @@ async function remove(type: CustomManifestType) {
95
96
  <h3 class="text-sm font-semibold text-default">
96
97
  {{ t('settings.infrastructure.customType.title') }}
97
98
  </h3>
98
- <p class="text-[11px] text-dimmed">{{ t('settings.infrastructure.customType.hint') }}</p>
99
+ <p class="text-2xs text-dimmed">{{ t('settings.infrastructure.customType.hint') }}</p>
99
100
  </div>
100
101
 
101
102
  <!-- The catalog: registered (read-only) + workspace (editable). -->
@@ -107,7 +108,7 @@ async function remove(type: CustomManifestType) {
107
108
  >
108
109
  <div class="min-w-0">
109
110
  <div class="flex items-center gap-1.5">
110
- <span class="truncate text-[13px] text-default">{{ type.label }}</span>
111
+ <span class="truncate text-sm text-default">{{ type.label }}</span>
111
112
  <UBadge
112
113
  :color="type.source === 'workspace' ? 'primary' : 'neutral'"
113
114
  variant="subtle"
@@ -116,8 +117,8 @@ async function remove(type: CustomManifestType) {
116
117
  {{ t(`settings.infrastructure.customType.source.${type.source}`) }}
117
118
  </UBadge>
118
119
  </div>
119
- <code class="text-[11px] text-dimmed">{{ type.manifestId }}</code>
120
- <p v-if="type.description" class="text-[11px] text-muted">{{ type.description }}</p>
120
+ <code class="text-2xs text-dimmed">{{ type.manifestId }}</code>
121
+ <p v-if="type.description" class="text-2xs text-muted">{{ type.description }}</p>
121
122
  </div>
122
123
  <div v-if="type.source === 'workspace'" class="flex shrink-0 items-center gap-0.5">
123
124
  <UButton
@@ -139,19 +140,19 @@ async function remove(type: CustomManifestType) {
139
140
  </div>
140
141
  </li>
141
142
  </ul>
142
- <p v-else class="text-[11px] text-dimmed">
143
+ <p v-else class="text-2xs text-dimmed">
143
144
  {{ t('settings.infrastructure.customType.empty') }}
144
145
  </p>
145
146
 
146
147
  <!-- Add / edit a workspace-defined type. -->
147
148
  <div class="space-y-2 border-t border-default pt-3">
148
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
149
+ <SectionLabel as="p">
149
150
  {{
150
151
  editing
151
152
  ? t('settings.infrastructure.customType.editTitle', { id: draft.manifestId })
152
153
  : t('settings.infrastructure.customType.addTitle')
153
154
  }}
154
- </p>
155
+ </SectionLabel>
155
156
  <UFormField
156
157
  v-if="!editing"
157
158
  :label="t('settings.infrastructure.customType.manifestId')"
@@ -105,7 +105,7 @@ async function save() {
105
105
  <h3 class="text-sm font-semibold text-default">
106
106
  {{ t('settings.defaultProvision.title') }}
107
107
  </h3>
108
- <p class="mt-1 text-[11px] leading-snug text-dimmed">
108
+ <p class="mt-1 text-2xs leading-snug text-dimmed">
109
109
  {{ t('settings.defaultProvision.hint') }}
110
110
  </p>
111
111
  </div>
@@ -125,7 +125,7 @@ async function save() {
125
125
  </div>
126
126
 
127
127
  <div v-if="selection.type === 'custom'" class="space-y-1">
128
- <label class="text-[11px] text-muted">
128
+ <label class="text-2xs text-muted">
129
129
  {{ t('inspector.testConfig.customManifestId') }}
130
130
  </label>
131
131
  <USelect
@@ -138,7 +138,7 @@ async function save() {
138
138
  :placeholder="t('inspector.testConfig.customManifestIdPlaceholder')"
139
139
  @update:model-value="(v: string) => setManifestId(v)"
140
140
  />
141
- <p v-else class="text-[11px] leading-snug text-app-warning-300/80">
141
+ <p v-else class="text-2xs leading-snug text-app-warning-300/80">
142
142
  {{ t('inspector.testConfig.customNoTypes') }}
143
143
  </p>
144
144
  </div>
@@ -147,7 +147,7 @@ async function save() {
147
147
  the workspace still has nothing stored. -->
148
148
  <p
149
149
  v-if="unset && selection.type"
150
- class="text-[11px] leading-snug text-app-warning-300/80"
150
+ class="text-2xs leading-snug text-app-warning-300/80"
151
151
  data-testid="default-provision-suggestion-hint"
152
152
  >
153
153
  {{ t('settings.defaultProvision.suggestionHint') }}
@@ -165,7 +165,7 @@ async function save() {
165
165
  >
166
166
  {{ t('settings.defaultProvision.save') }}
167
167
  </UButton>
168
- <span v-if="!unset && !dirty" class="text-[11px] text-dimmed">
168
+ <span v-if="!unset && !dirty" class="text-2xs text-dimmed">
169
169
  {{ t('settings.defaultProvision.savedState') }}
170
170
  </span>
171
171
  </div>
@@ -30,6 +30,7 @@ import CustomManifestTypeEditor from '~/components/settings/CustomManifestTypeEd
30
30
  import CloudflareHandlerSection from '~/components/settings/CloudflareHandlerSection.vue'
31
31
  import ConnectionTestVerdict from '~/components/settings/ConnectionTestVerdict.vue'
32
32
  import { consumeKubernetesScrollAnchor } from '~/components/settings/InfraHandlersConfigurator.logic'
33
+ import SectionLabel from '~/components/common/SectionLabel.vue'
33
34
 
34
35
  const { t } = useI18n()
35
36
  const infra = useInfraConfigStore()
@@ -442,7 +443,7 @@ function toastRemoved() {
442
443
  disabled
443
444
  size="lg"
444
445
  :label="t('settings.infrastructure.handler.connectionEstablished')"
445
- :ui="{ label: 'text-[13px] font-semibold text-app-success-300' }"
446
+ :ui="{ label: 'text-sm font-semibold text-app-success-300' }"
446
447
  />
447
448
  <UButton
448
449
  icon="i-lucide-trash-2"
@@ -454,7 +455,7 @@ function toastRemoved() {
454
455
  @click="removeKube"
455
456
  />
456
457
  </div>
457
- <p class="pl-7 text-[11px] text-toned">
458
+ <p class="pl-7 text-2xs text-toned">
458
459
  {{ t('settings.infrastructure.handler.activeEngine') }}
459
460
  <span class="text-default">{{ kubeHandlerEngineLabel }}</span>
460
461
  </p>
@@ -472,13 +473,13 @@ function toastRemoved() {
472
473
  <ConnectionTestVerdict :result="kubeSavedTestResult" />
473
474
  </div>
474
475
  </div>
475
- <p v-else class="flex items-center gap-1.5 text-[12px] text-dimmed">
476
+ <p v-else class="flex items-center gap-1.5 text-xs text-dimmed">
476
477
  <UIcon name="i-lucide-circle-dashed" class="h-3.5 w-3.5" />
477
478
  {{ t('settings.infrastructure.handler.notConnected') }}
478
479
  </p>
479
480
 
480
481
  <div class="space-y-1">
481
- <span class="text-[11px] text-muted">{{
482
+ <span class="text-2xs text-muted">{{
482
483
  t('settings.infrastructure.handler.engineLabel')
483
484
  }}</span>
484
485
  <div class="flex flex-wrap gap-1">
@@ -513,9 +514,10 @@ function toastRemoved() {
513
514
 
514
515
  <!-- Local mode: a personal override for THIS machine, layered over the workspace handler. -->
515
516
  <div v-if="userOverridesOn" class="border-t border-default pt-2">
516
- <button
517
+ <SectionLabel
518
+ as="button"
517
519
  type="button"
518
- class="flex w-full items-center gap-1.5 text-start text-[11px] font-semibold uppercase tracking-wide text-dimmed hover:text-toned"
520
+ class="flex w-full items-center gap-1.5 text-start hover:text-default"
519
521
  @click="showKubeOverride = !showKubeOverride"
520
522
  >
521
523
  <UIcon
@@ -526,9 +528,9 @@ function toastRemoved() {
526
528
  <UBadge v-if="kubeUserHandler" color="primary" variant="subtle" size="sm">
527
529
  {{ t('settings.infrastructure.handler.overrideActive') }}
528
530
  </UBadge>
529
- </button>
531
+ </SectionLabel>
530
532
  <div v-if="showKubeOverride" class="mt-2 space-y-2">
531
- <p class="text-[11px] text-dimmed">
533
+ <p class="text-2xs text-dimmed">
532
534
  {{ t('settings.infrastructure.handler.personalOverrideHint') }}
533
535
  </p>
534
536
  <p v-if="kubeUserHandler" class="flex justify-end">
@@ -562,7 +564,7 @@ function toastRemoved() {
562
564
  <h3 class="text-sm font-semibold text-default">
563
565
  {{ t('inspector.testConfig.provisionTypes.docker-compose') }}
564
566
  </h3>
565
- <p class="text-[12px] text-muted">
567
+ <p class="text-xs text-muted">
566
568
  {{ t('settings.infrastructure.dockerComposeInfo') }}
567
569
  </p>
568
570
  </section>
@@ -580,9 +582,9 @@ function toastRemoved() {
580
582
  <CustomManifestTypeEditor />
581
583
 
582
584
  <div v-if="infra.customTypes.length" class="space-y-2 border-t border-default pt-3">
583
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
585
+ <SectionLabel as="p">
584
586
  {{ t('settings.infrastructure.handler.customHandlerTitle') }}
585
- </p>
587
+ </SectionLabel>
586
588
  <UFormField :label="t('settings.infrastructure.handler.customTypeLabel')">
587
589
  <USelect v-model="selectedCustomId" :items="customTypeItems" />
588
590
  </UFormField>
@@ -595,10 +597,7 @@ function toastRemoved() {
595
597
  >
596
598
  <USelect v-model="selectedBackendKind" :items="customBackendOptions" />
597
599
  </UFormField>
598
- <p
599
- v-if="customHandler"
600
- class="flex items-center justify-between gap-2 text-[12px] text-toned"
601
- >
600
+ <p v-if="customHandler" class="flex items-center justify-between gap-2 text-xs text-toned">
602
601
  <span class="text-app-success-400">{{
603
602
  t('settings.infrastructure.handler.customConnected')
604
603
  }}</span>
@@ -288,12 +288,12 @@ const labelKey = computed(() =>
288
288
  />
289
289
  <span class="min-w-0">
290
290
  <span class="text-sm text-default">{{ item.label }}</span>
291
- <span v-if="item.desc" class="block text-[11px] text-muted">{{ item.desc }}</span>
291
+ <span v-if="item.desc" class="block text-2xs text-muted">{{ item.desc }}</span>
292
292
  </span>
293
293
  </label>
294
294
  </div>
295
295
 
296
- <p v-if="showRegisterHint" class="text-[11px] text-app-warning-300/80">
296
+ <p v-if="showRegisterHint" class="text-2xs text-app-warning-300/80">
297
297
  {{ t('settings.infrastructure.registerHint') }}
298
298
  </p>
299
299