@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
@@ -10,6 +10,7 @@ import type { RalphStepState } from '~/types/execution'
10
10
  import ResultWindowShell from '~/components/panels/ResultWindowShell.vue'
11
11
  import StepRunMeta from '~/components/panels/StepRunMeta.vue'
12
12
  import CopyButton from '~/components/common/CopyButton.vue'
13
+ import SectionLabel from '~/components/common/SectionLabel.vue'
13
14
 
14
15
  const board = useBoardStore()
15
16
  const execution = useExecutionStore()
@@ -145,26 +146,26 @@ const STATUS_META = computed<
145
146
 
146
147
  <template v-else>
147
148
  <!-- The completion criterion. -->
148
- <h3 class="mb-1.5 text-[11px] font-semibold uppercase tracking-wide text-dimmed">
149
+ <SectionLabel as="h3" class="mb-1.5">
149
150
  {{ t('ralph.validationCommand') }}
150
- </h3>
151
+ </SectionLabel>
151
152
  <div class="relative rounded-md border border-default bg-app-950/60 px-3 py-2">
152
153
  <CopyButton :text="ralph.validationCommand" class="absolute end-1 top-1" />
153
- <code class="block whitespace-pre-wrap pe-8 font-mono text-[12px] text-default">{{
154
+ <code class="block whitespace-pre-wrap pe-8 font-mono text-xs text-default">{{
154
155
  ralph.validationCommand
155
156
  }}</code>
156
157
  </div>
157
158
 
158
159
  <!-- The most recent validation output. -->
159
160
  <template v-if="ralph.lastValidationTail">
160
- <h3 class="mb-1.5 mt-4 text-[11px] font-semibold uppercase tracking-wide text-dimmed">
161
+ <SectionLabel as="h3" class="mb-1.5 mt-4">
161
162
  {{ t('ralph.lastOutput', { exit: ralph.lastExitCode ?? '?' }) }}
162
- </h3>
163
+ </SectionLabel>
163
164
  <div class="relative rounded-md border border-default bg-app-950/60 px-3 py-2">
164
165
  <CopyButton :text="ralph.lastValidationTail" class="absolute end-1 top-1" />
165
- <pre
166
- class="whitespace-pre-wrap pe-8 font-mono text-[11px] leading-relaxed text-muted"
167
- >{{ ralph.lastValidationTail }}</pre>
166
+ <pre class="whitespace-pre-wrap pe-8 font-mono text-2xs leading-relaxed text-muted">{{
167
+ ralph.lastValidationTail
168
+ }}</pre>
168
169
  </div>
169
170
  </template>
170
171
 
@@ -173,7 +174,7 @@ const STATUS_META = computed<
173
174
  :href="prUrl"
174
175
  target="_blank"
175
176
  rel="noopener"
176
- class="mt-3 inline-flex items-center gap-1 text-[12px] text-app-info-300 hover:text-app-info-200 hover:underline"
177
+ class="mt-3 inline-flex items-center gap-1 text-xs text-app-info-300 hover:text-app-info-200 hover:underline"
177
178
  >
178
179
  {{ t('ralph.viewPr') }}
179
180
  <UIcon name="i-lucide-external-link" class="h-3 w-3" />
@@ -183,7 +184,7 @@ const STATUS_META = computed<
183
184
  the sidebar (e.g. "3 of 20") reads as an unexplained abandonment. -->
184
185
  <p
185
186
  v-if="status === 'stalled'"
186
- class="mt-3 rounded-md border border-app-error-900/60 bg-app-error-950/30 px-3 py-2 text-[12px] leading-relaxed text-app-error-200"
187
+ class="mt-3 rounded-md border border-app-error-900/60 bg-app-error-950/30 px-3 py-2 text-xs leading-relaxed text-app-error-200"
187
188
  data-testid="ralph-stalled-note"
188
189
  >
189
190
  {{ t('ralph.stalledNote') }}
@@ -191,14 +192,14 @@ const STATUS_META = computed<
191
192
 
192
193
  <!-- Iteration history: what each pass produced and whether its validation passed. -->
193
194
  <section v-if="attempts.length" class="mt-5">
194
- <h3 class="mb-2 text-[11px] font-semibold uppercase tracking-wide text-dimmed">
195
+ <SectionLabel as="h3" class="mb-2">
195
196
  {{ t('ralph.iterationsHeading') }}
196
- </h3>
197
+ </SectionLabel>
197
198
  <!-- The log is capped (it rides the run's detail blob); say so rather than letting a
198
199
  long loop's partial history read as if those iterations never ran. -->
199
200
  <p
200
201
  v-if="droppedAttempts"
201
- class="mb-2 text-[11px] text-dimmed"
202
+ class="mb-2 text-2xs text-dimmed"
202
203
  data-testid="ralph-iterations-truncated"
203
204
  >
204
205
  {{ t('ralph.iterationsTruncated', { count: droppedAttempts }, droppedAttempts) }}
@@ -216,23 +217,21 @@ const STATUS_META = computed<
216
217
  class="h-3.5 w-3.5"
217
218
  :class="a.validationPassed ? 'text-app-success-400' : 'text-app-error-400'"
218
219
  />
219
- <span class="text-[12px] font-medium text-default">
220
+ <span class="text-xs font-medium text-default">
220
221
  {{ t('ralph.iteration', { number: a.attempt }) }}
221
222
  </span>
222
- <span class="text-[11px] text-dimmed">
223
+ <span class="text-2xs text-dimmed">
223
224
  {{
224
225
  a.validationPassed
225
226
  ? t('ralph.iterationPassed')
226
227
  : t('ralph.iterationFailed', { exit: a.exitCode ?? '?' })
227
228
  }}
228
229
  </span>
229
- <span class="ms-auto text-[10px] text-app-600">{{
230
- d(new Date(a.at), 'long')
231
- }}</span>
230
+ <span class="ms-auto text-3xs text-app-600">{{ d(new Date(a.at), 'long') }}</span>
232
231
  </div>
233
232
  <p
234
233
  v-if="a.summary"
235
- class="mt-1 whitespace-pre-wrap text-[12px] leading-relaxed text-muted"
234
+ class="mt-1 whitespace-pre-wrap text-xs leading-relaxed text-muted"
236
235
  >
237
236
  {{ a.summary }}
238
237
  </p>
@@ -246,10 +245,10 @@ const STATUS_META = computed<
246
245
  class="hidden w-60 shrink-0 flex-col gap-4 border-s border-default bg-default/50 px-4 py-4 lg:flex"
247
246
  >
248
247
  <div v-if="ralph">
249
- <h4 class="mb-2 text-[11px] font-semibold uppercase tracking-wide text-dimmed">
248
+ <SectionLabel as="h4" class="mb-2">
250
249
  {{ t('ralph.sidebar.state') }}
251
- </h4>
252
- <div class="flex items-center gap-2 text-[13px]">
250
+ </SectionLabel>
251
+ <div class="flex items-center gap-2 text-sm">
253
252
  <UIcon
254
253
  :name="STATUS_META[status].icon"
255
254
  class="h-4 w-4"
@@ -259,10 +258,10 @@ const STATUS_META = computed<
259
258
  </div>
260
259
  </div>
261
260
  <div v-if="ralph">
262
- <h4 class="mb-1 text-[11px] font-semibold uppercase tracking-wide text-dimmed">
261
+ <SectionLabel as="h4" class="mb-1">
263
262
  {{ t('ralph.sidebar.iterations') }}
264
- </h4>
265
- <p class="text-[12px] text-toned" data-testid="ralph-iteration-count">
263
+ </SectionLabel>
264
+ <p class="text-xs text-toned" data-testid="ralph-iteration-count">
266
265
  {{ t('ralph.sidebar.count', { attempts: ralph.attempts, max: ralph.maxIterations }) }}
267
266
  </p>
268
267
  </div>
@@ -275,7 +274,7 @@ const STATUS_META = computed<
275
274
  :run-failed="instance?.status === 'failed'"
276
275
  :failure-at="instance?.failure?.occurredAt"
277
276
  />
278
- <p class="mt-auto text-[10px] leading-relaxed text-app-600">
277
+ <p class="mt-auto text-3xs leading-relaxed text-app-600">
279
278
  {{ t('ralph.sidebar.footer') }}
280
279
  </p>
281
280
  </aside>
@@ -28,6 +28,7 @@ import type {
28
28
  ReviewItemSeverity,
29
29
  ReviewItemStatus,
30
30
  } from '~/types/requirements'
31
+ import SectionLabel from '~/components/common/SectionLabel.vue'
31
32
 
32
33
  const board = useBoardStore()
33
34
  const requirements = useRequirementsStore()
@@ -806,11 +807,11 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
806
807
  </span>
807
808
  <span class="h-px flex-1 bg-accented" />
808
809
  </div>
809
- <p class="mt-0.5 text-[11px] text-dimmed">{{ CLASS_HINTS[group] }}</p>
810
+ <p class="mt-0.5 text-2xs text-dimmed">{{ CLASS_HINTS[group] }}</p>
810
811
  </div>
811
812
  <div v-if="startsAttentionGroup(index)" class="flex items-center gap-2 pt-1">
812
813
  <span
813
- class="text-[11px] font-semibold uppercase tracking-wide"
814
+ class="text-2xs font-semibold uppercase tracking-wide"
814
815
  :class="ATTENTION_LABEL_COLOR[attention]"
815
816
  >
816
817
  {{ ATTENTION_LABELS[attention] }}
@@ -873,9 +874,9 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
873
874
  v-if="item.reply && item.status !== 'open' && item.status !== 'answered'"
874
875
  class="mt-2 max-w-3xl rounded-md border-s-2 border-muted bg-app-950/40 px-3 py-1.5 text-sm text-toned"
875
876
  >
876
- <span class="text-[10px] uppercase tracking-wide text-dimmed">
877
+ <SectionLabel as="span">
877
878
  {{ t('requirements.answerLabel') }}
878
- </span>
879
+ </SectionLabel>
879
880
  <p class="whitespace-pre-line">{{ item.reply }}</p>
880
881
  </div>
881
882
 
@@ -964,7 +965,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
964
965
  />
965
966
  <p
966
967
  v-if="isUserAnswered(item)"
967
- class="mt-1 flex items-center gap-1 text-[11px] text-app-success-400"
968
+ class="mt-1 flex items-center gap-1 text-2xs text-app-success-400"
968
969
  >
969
970
  <UIcon name="i-lucide-check" class="h-3 w-3 shrink-0" />
970
971
  {{ t('requirements.userAnswered') }}
@@ -1093,7 +1094,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
1093
1094
  :placeholder="t('requirements.guidancePlaceholder')"
1094
1095
  :disabled="frozen"
1095
1096
  />
1096
- <p class="mt-1 flex items-center gap-1 text-[11px] text-primary/80">
1097
+ <p class="mt-1 flex items-center gap-1 text-2xs text-primary/80">
1097
1098
  <UIcon name="i-lucide-wand-2" class="h-3 w-3 shrink-0" />
1098
1099
  {{ t('requirements.guidanceHint') }}
1099
1100
  </p>
@@ -1101,7 +1102,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
1101
1102
  </template>
1102
1103
 
1103
1104
  <!-- DISMISS: nothing to fill in — a short note explains the effect -->
1104
- <p v-else class="mt-2 text-[11px] text-dimmed">
1105
+ <p v-else class="mt-2 text-2xs text-dimmed">
1105
1106
  {{ t('requirements.dismissedHint') }}
1106
1107
  </p>
1107
1108
  </template>
@@ -1116,7 +1117,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
1116
1117
  off-screen); the per-heading toggles below still work when it's expanded. -->
1117
1118
  <section v-if="outline" class="mt-6 border-t border-default pt-5">
1118
1119
  <button
1119
- class="mb-3 flex w-full items-center gap-1.5 text-[11px] text-app-success-400"
1120
+ class="mb-3 flex w-full items-center gap-1.5 text-2xs text-app-success-400"
1120
1121
  @click="toggleDoc"
1121
1122
  >
1122
1123
  <UIcon
@@ -1157,7 +1158,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
1157
1158
  </button>
1158
1159
  <div
1159
1160
  v-show="!s.title || !collapsed[s.id]"
1160
- class="reader-prose mt-1 ps-5.5 text-[13px] leading-relaxed text-toned"
1161
+ class="reader-prose mt-1 ps-5.5 text-sm leading-relaxed text-toned"
1161
1162
  v-html="s.bodyHtml"
1162
1163
  />
1163
1164
  </div>
@@ -1277,7 +1278,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
1277
1278
  >
1278
1279
  {{ t('requirements.actions.incorporateAnswers') }}
1279
1280
  </UButton>
1280
- <p class="text-[11px] leading-relaxed text-dimmed">
1281
+ <p class="text-2xs leading-relaxed text-dimmed">
1281
1282
  <template v-if="canProceed">
1282
1283
  {{ t('requirements.help.canProceed') }}
1283
1284
  </template>
@@ -1341,14 +1342,14 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
1341
1342
  {{ t('requirements.actions.redoWithDirection') }}
1342
1343
  </UButton>
1343
1344
  </div>
1344
- <p class="text-[11px] leading-relaxed text-dimmed">
1345
+ <p class="text-2xs leading-relaxed text-dimmed">
1345
1346
  {{ t('requirements.help.merged') }}
1346
1347
  </p>
1347
1348
  </div>
1348
1349
 
1349
1350
  <div
1350
1351
  v-if="review && incorporated"
1351
- class="border-t border-default pt-4 text-[11px] leading-relaxed text-dimmed"
1352
+ class="border-t border-default pt-4 text-2xs leading-relaxed text-dimmed"
1352
1353
  >
1353
1354
  {{ t('requirements.settledFooter') }}
1354
1355
  </div>
@@ -142,7 +142,7 @@ function choose(id: string) {
142
142
  <li>
143
143
  <button
144
144
  type="button"
145
- class="flex w-full items-center gap-2 rounded px-2 py-1.5 text-start text-sm"
145
+ class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-start text-sm"
146
146
  :class="[
147
147
  refused.has('') ? 'cursor-not-allowed opacity-50' : 'hover:bg-elevated/60',
148
148
  modelValue ? 'text-toned' : 'text-app-100',
@@ -169,7 +169,7 @@ function choose(id: string) {
169
169
  <li v-for="p in options" :key="p.id">
170
170
  <button
171
171
  type="button"
172
- class="flex w-full items-center gap-2 rounded px-2 py-1.5 text-start text-sm"
172
+ class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-start text-sm"
173
173
  :class="[
174
174
  refused.has(p.id) ? 'cursor-not-allowed opacity-50' : 'hover:bg-elevated/60',
175
175
  modelValue === p.id ? 'text-app-100' : 'text-toned',
@@ -200,17 +200,17 @@ function choose(id: string) {
200
200
  <template v-if="preview.policy">
201
201
  <p
202
202
  v-if="previewRefusal"
203
- class="mb-2 text-[11px] leading-snug text-app-warning-400"
203
+ class="mb-2 text-2xs leading-snug text-app-warning-400"
204
204
  data-testid="risk-policy-refusal"
205
205
  >
206
206
  {{ t(`riskPolicy.picker.refused.${previewRefusal}`) }}
207
207
  </p>
208
- <p v-if="preview.viaWorkspaceDefault" class="mb-2 text-[11px] leading-snug text-dimmed">
208
+ <p v-if="preview.viaWorkspaceDefault" class="mb-2 text-2xs leading-snug text-dimmed">
209
209
  {{ t('riskPolicy.picker.workspaceDefaultCaption') }}
210
210
  </p>
211
211
  <RiskPolicyPreview :policy="preview.policy" />
212
212
  </template>
213
- <div v-else class="text-[12px] leading-snug text-dimmed">
213
+ <div v-else class="text-xs leading-snug text-dimmed">
214
214
  {{ t('riskPolicy.picker.noneHint') }}
215
215
  </div>
216
216
  </div>
@@ -10,6 +10,7 @@
10
10
  import { computed } from 'vue'
11
11
  import type { RiskPolicy, WorkspaceRole } from '~/types/merge'
12
12
  import { riskPolicyCeilings, rolePolicySummary, type RiskPolicyAxis } from '~/utils/riskPolicy'
13
+ import SectionLabel from '~/components/common/SectionLabel.vue'
13
14
 
14
15
  const props = defineProps<{ policy: RiskPolicy }>()
15
16
  const { t, n } = useI18n()
@@ -56,15 +57,15 @@ const ceilings = computed(() =>
56
57
 
57
58
  <!-- the three ceilings, grouped under one heading that names what they are -->
58
59
  <div v-if="policy.autoMergeEnabled">
59
- <div class="mb-1 flex items-center gap-1 text-[10px] uppercase tracking-wide text-dimmed">
60
+ <SectionLabel class="mb-1 flex items-center gap-1">
60
61
  <UIcon name="i-lucide-git-merge" class="h-3 w-3" />
61
62
  {{ t('riskPolicy.preview.autoMergeHeading') }}
62
- </div>
63
+ </SectionLabel>
63
64
  <dl class="space-y-1">
64
65
  <div
65
66
  v-for="c in ceilings"
66
67
  :key="c.axis"
67
- class="flex items-baseline justify-between gap-3 rounded bg-elevated/70 px-1.5 py-0.5 text-[12px]"
68
+ class="flex items-baseline justify-between gap-3 rounded-sm bg-elevated/70 px-1.5 py-0.5 text-xs"
68
69
  >
69
70
  <dt class="text-toned">{{ c.label }}</dt>
70
71
  <dd class="tabular-nums text-app-100">
@@ -72,43 +73,43 @@ const ceilings = computed(() =>
72
73
  </dd>
73
74
  </div>
74
75
  </dl>
75
- <p class="mt-1.5 text-[12px] leading-snug text-muted">
76
+ <p class="mt-1.5 text-xs leading-snug text-muted">
76
77
  {{ t('riskPolicy.preview.autoMergeExplainer') }}
77
78
  </p>
78
79
  </div>
79
80
  <div v-else>
80
- <div class="mb-1 flex items-center gap-1 text-[10px] uppercase tracking-wide text-dimmed">
81
+ <SectionLabel class="mb-1 flex items-center gap-1">
81
82
  <UIcon name="i-lucide-user-check" class="h-3 w-3" />
82
83
  {{ t('riskPolicy.preview.manualHeading') }}
83
- </div>
84
- <p class="text-[12px] leading-snug text-muted">
84
+ </SectionLabel>
85
+ <p class="text-xs leading-snug text-muted">
85
86
  {{ t('riskPolicy.preview.manualExplainer') }}
86
87
  </p>
87
88
  </div>
88
89
 
89
90
  <!-- Who started the run changes what may land, on a policy that says so. -->
90
91
  <div v-if="roleLayer.any" data-testid="risk-policy-preview-roles">
91
- <div class="mb-1 flex items-center gap-1 text-[10px] uppercase tracking-wide text-dimmed">
92
+ <SectionLabel class="mb-1 flex items-center gap-1">
92
93
  <UIcon name="i-lucide-users" class="h-3 w-3" />
93
94
  {{ t('riskPolicy.preview.roleHeading') }}
94
- </div>
95
- <p v-if="roleLayer.sandboxed" class="text-[12px] leading-snug text-muted">
95
+ </SectionLabel>
96
+ <p v-if="roleLayer.sandboxed" class="text-xs leading-snug text-muted">
96
97
  {{ t('riskPolicy.preview.roleSandboxed', { roles: roleLayer.sandboxed }) }}
97
98
  </p>
98
- <p v-if="roleLayer.scoped" class="text-[12px] leading-snug text-muted">
99
+ <p v-if="roleLayer.scoped" class="text-xs leading-snug text-muted">
99
100
  {{ t('riskPolicy.preview.roleScoped', { roles: roleLayer.scoped }) }}
100
101
  </p>
101
- <p v-if="roleLayer.narrowed" class="text-[12px] leading-snug text-muted">
102
+ <p v-if="roleLayer.narrowed" class="text-xs leading-snug text-muted">
102
103
  {{ t('riskPolicy.preview.roleNarrowed', { roles: roleLayer.narrowed }) }}
103
104
  </p>
104
105
  </div>
105
106
 
106
107
  <div>
107
- <div class="mb-1 flex items-center gap-1 text-[10px] uppercase tracking-wide text-dimmed">
108
+ <SectionLabel class="mb-1 flex items-center gap-1">
108
109
  <UIcon name="i-lucide-wrench" class="h-3 w-3" />
109
110
  {{ t('riskPolicy.preview.ciHeading') }}
110
- </div>
111
- <p class="text-[12px] leading-snug text-muted">
111
+ </SectionLabel>
112
+ <p class="text-xs leading-snug text-muted">
112
113
  {{
113
114
  t('riskPolicy.preview.ciAttempts', { count: policy.ciMaxAttempts }, policy.ciMaxAttempts)
114
115
  }}
@@ -15,6 +15,7 @@ import type {
15
15
  SandboxRun,
16
16
  SandboxUnsupportedReason,
17
17
  } from '~/types/sandbox'
18
+ import SectionLabel from '~/components/common/SectionLabel.vue'
18
19
 
19
20
  const ui = useUiStore()
20
21
  const store = useSandboxStore()
@@ -317,9 +318,9 @@ async function archive(prompt: SandboxPromptVersion) {
317
318
  <div v-if="tab === 'experiments'" class="grid gap-4 lg:grid-cols-2">
318
319
  <!-- builder -->
319
320
  <div class="space-y-3 rounded-lg border border-muted bg-default/40 p-3">
320
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
321
+ <SectionLabel as="p">
321
322
  {{ t('sandbox.builder.title') }}
322
- </p>
323
+ </SectionLabel>
323
324
 
324
325
  <UFormField :label="t('sandbox.builder.agent')">
325
326
  <USelect
@@ -331,7 +332,7 @@ async function archive(prompt: SandboxPromptVersion) {
331
332
  <p
332
333
  v-for="excluded in unrunnableAgentKinds"
333
334
  :key="excluded.agentKind"
334
- class="mt-1 text-[11px] leading-snug text-dimmed"
335
+ class="mt-1 text-2xs leading-snug text-dimmed"
335
336
  >
336
337
  <span class="font-medium text-muted">{{ excluded.label }}:</span>
337
338
  {{
@@ -343,9 +344,9 @@ async function archive(prompt: SandboxPromptVersion) {
343
344
  </UFormField>
344
345
 
345
346
  <div>
346
- <span class="mb-1 block text-[10px] uppercase tracking-wide text-dimmed">
347
+ <SectionLabel as="span" class="mb-1 block">
347
348
  {{ t('sandbox.builder.promptVersions') }}
348
- </span>
349
+ </SectionLabel>
349
350
  <div class="max-h-28 space-y-1 overflow-auto pe-1">
350
351
  <label
351
352
  v-for="p in kindPrompts"
@@ -375,9 +376,9 @@ async function archive(prompt: SandboxPromptVersion) {
375
376
  </div>
376
377
 
377
378
  <div>
378
- <span class="mb-1 block text-[10px] uppercase tracking-wide text-dimmed">
379
+ <SectionLabel as="span" class="mb-1 block">
379
380
  {{ t('sandbox.builder.models') }}
380
- </span>
381
+ </SectionLabel>
381
382
  <div class="max-h-28 space-y-1 overflow-auto pe-1">
382
383
  <label
383
384
  v-for="m in store.selectableModels"
@@ -399,9 +400,9 @@ async function archive(prompt: SandboxPromptVersion) {
399
400
  </div>
400
401
 
401
402
  <div>
402
- <span class="mb-1 block text-[10px] uppercase tracking-wide text-dimmed">
403
+ <SectionLabel as="span" class="mb-1 block">
403
404
  {{ t('sandbox.builder.fixtures') }}
404
- </span>
405
+ </SectionLabel>
405
406
  <div class="max-h-28 space-y-1 overflow-auto pe-1">
406
407
  <label
407
408
  v-for="f in kindFixtures"
@@ -486,7 +487,7 @@ async function archive(prompt: SandboxPromptVersion) {
486
487
  @click="selectedRun = run"
487
488
  >
488
489
  <td class="py-1 pe-2 text-toned">{{ run.promptLabel }}</td>
489
- <td class="py-1 pe-2 font-mono text-[11px] text-muted">
490
+ <td class="py-1 pe-2 font-mono text-2xs text-muted">
490
491
  {{ run.model }}
491
492
  </td>
492
493
  <td class="py-1 pe-2 text-muted">{{ fixtureName }}</td>
@@ -521,21 +522,21 @@ async function archive(prompt: SandboxPromptVersion) {
521
522
 
522
523
  <!-- selected cell output -->
523
524
  <div v-if="selectedRun" class="mt-3 border-t border-default pt-2">
524
- <p class="mb-1 text-[11px] uppercase tracking-wide text-dimmed">
525
+ <SectionLabel as="p" class="mb-1">
525
526
  {{ selectedRun.promptLabel }} · {{ selectedRun.model }}
526
- </p>
527
+ </SectionLabel>
527
528
  <p v-if="selectedRun.error" class="text-xs text-app-error-400">
528
529
  {{ selectedRun.error }}
529
530
  </p>
530
531
  <pre
531
532
  v-if="selectedRun.outputText"
532
- class="max-h-48 overflow-auto whitespace-pre-wrap rounded bg-app-950/60 p-2 text-[11px] text-toned"
533
+ class="max-h-48 overflow-auto whitespace-pre-wrap rounded-sm bg-app-950/60 p-2 text-2xs text-toned"
533
534
  >{{ selectedRun.outputText }}</pre>
534
535
  <div v-if="gradeByRun.get(selectedRun.id)" class="mt-2 space-y-0.5">
535
536
  <p
536
537
  v-for="d in gradeByRun.get(selectedRun.id)!.scores"
537
538
  :key="d.key"
538
- class="text-[11px] text-muted"
539
+ class="text-2xs text-muted"
539
540
  >
540
541
  <span :class="scoreColor(d.score)" class="font-semibold">{{ d.score }}</span>
541
542
  <span class="ms-1 text-toned">{{ d.key }}</span>
@@ -545,9 +546,9 @@ async function archive(prompt: SandboxPromptVersion) {
545
546
  </div>
546
547
  </div>
547
548
 
548
- <p class="text-[11px] uppercase tracking-wide text-dimmed">
549
+ <SectionLabel as="p">
549
550
  {{ t('sandbox.results.past') }}
550
- </p>
551
+ </SectionLabel>
551
552
  <div class="max-h-56 space-y-1 overflow-auto">
552
553
  <button
553
554
  v-for="x in store.experiments"
@@ -591,7 +592,7 @@ async function archive(prompt: SandboxPromptVersion) {
591
592
  }}
592
593
  </UBadge>
593
594
  </div>
594
- <span class="text-[11px] text-dimmed">{{ p.agentKind }}</span>
595
+ <span class="text-2xs text-dimmed">{{ p.agentKind }}</span>
595
596
  </div>
596
597
  <div class="flex items-center gap-1">
597
598
  <UButton
@@ -632,13 +633,13 @@ async function archive(prompt: SandboxPromptVersion) {
632
633
  </div>
633
634
 
634
635
  <div v-if="editing" class="space-y-2 rounded-lg border border-muted bg-default/40 p-3">
635
- <p class="text-[11px] uppercase tracking-wide text-dimmed">
636
+ <SectionLabel as="p">
636
637
  {{
637
638
  editing.origin === 'baseline'
638
639
  ? t('sandbox.prompts.forkOf', { name: editing.name })
639
640
  : t('sandbox.prompts.newVersionOf', { name: editing.name })
640
641
  }}
641
- </p>
642
+ </SectionLabel>
642
643
  <UTextarea v-model="editText" :rows="16" class="w-full font-mono text-xs" autoresize />
643
644
  <div class="flex justify-end gap-2">
644
645
  <UButton
@@ -690,7 +691,7 @@ async function archive(prompt: SandboxPromptVersion) {
690
691
  </UBadge>
691
692
  </div>
692
693
  </div>
693
- <p v-if="f.objective?.kind === 'findings'" class="mt-0.5 text-[11px] text-dimmed">
694
+ <p v-if="f.objective?.kind === 'findings'" class="mt-0.5 text-2xs text-dimmed">
694
695
  {{
695
696
  t(
696
697
  'sandbox.fixtures.expectations',
@@ -259,7 +259,7 @@ async function revokeToken(key: PublicApiKey) {
259
259
  {{ boundLabel(key) }}
260
260
  </UBadge>
261
261
  </div>
262
- <div class="text-[11px] text-dimmed">
262
+ <div class="text-2xs text-dimmed">
263
263
  {{
264
264
  t('settings.apiTokens.list.created', {
265
265
  date: d(new Date(key.createdAt), 'short'),
@@ -5,6 +5,7 @@
5
5
  // operator sets a hard cap env var, the account/user input cannot exceed it and the cap is
6
6
  // shown here. See docs/initiatives/tiered-budgets.md.
7
7
  import { computed, reactive, ref, watch, type Ref } from 'vue'
8
+ import SectionLabel from '~/components/common/SectionLabel.vue'
8
9
 
9
10
  const { t, n } = useI18n()
10
11
  const toast = useToast()
@@ -122,7 +123,7 @@ function saveUser() {
122
123
 
123
124
  <template>
124
125
  <div class="space-y-8">
125
- <p class="text-[11px] text-muted">
126
+ <p class="text-2xs text-muted">
126
127
  {{ t('settings.workspaceSettings.budget.body') }}
127
128
  </p>
128
129
 
@@ -133,9 +134,9 @@ function saveUser() {
133
134
  </h3>
134
135
  <div class="grid grid-cols-2 gap-3">
135
136
  <label class="block">
136
- <span class="mb-1 block text-[10px] uppercase tracking-wide text-dimmed">
137
+ <SectionLabel as="span" class="mb-1 block">
137
138
  {{ t('settings.workspaceSettings.budget.monthlyLimit') }}
138
- </span>
139
+ </SectionLabel>
139
140
  <UInput
140
141
  v-model="wsDraft.spendMonthlyLimit"
141
142
  type="number"
@@ -145,9 +146,9 @@ function saveUser() {
145
146
  />
146
147
  </label>
147
148
  <label class="block">
148
- <span class="mb-1 block text-[10px] uppercase tracking-wide text-dimmed">
149
+ <SectionLabel as="span" class="mb-1 block">
149
150
  {{ t('settings.workspaceSettings.budget.currency') }}
150
- </span>
151
+ </SectionLabel>
151
152
  <UInput
152
153
  v-model="wsDraft.spendCurrency"
153
154
  placeholder="EUR"
@@ -157,7 +158,7 @@ function saveUser() {
157
158
  />
158
159
  </label>
159
160
  </div>
160
- <div v-if="workspace.spend" class="text-[11px] text-muted">
161
+ <div v-if="workspace.spend" class="text-2xs text-muted">
161
162
  {{
162
163
  t('settings.workspaceSettings.budget.spent', {
163
164
  spent: money(workspace.spend.costSpent, workspace.spend.currency),
@@ -183,13 +184,13 @@ function saveUser() {
183
184
  <h3 class="text-sm font-semibold text-default">
184
185
  {{ t('settings.workspaceSettings.budget.account') }}
185
186
  </h3>
186
- <p class="text-[11px] text-muted">
187
+ <p class="text-2xs text-muted">
187
188
  {{ t('settings.workspaceSettings.budget.accountBody') }}
188
189
  </p>
189
190
  <label class="block">
190
- <span class="mb-1 block text-[10px] uppercase tracking-wide text-dimmed">
191
+ <SectionLabel as="span" class="mb-1 block">
191
192
  {{ t('settings.workspaceSettings.budget.monthlyLimit') }}
192
- </span>
193
+ </SectionLabel>
193
194
  <UInput
194
195
  v-model="accountDraft"
195
196
  type="number"
@@ -202,13 +203,13 @@ function saveUser() {
202
203
  </label>
203
204
  <p
204
205
  v-if="accountCap != null"
205
- class="text-[11px]"
206
+ class="text-2xs"
206
207
  :class="accountOverCap ? 'text-app-error-400' : 'text-app-warning-400'"
207
208
  >
208
209
  {{ t('settings.workspaceSettings.budget.hardCap', { amount: money(accountCap) }) }}
209
210
  <span class="text-dimmed">({{ t('settings.workspaceSettings.budget.hardCapHint') }})</span>
210
211
  </p>
211
- <div v-if="workspace.accountSpend" class="text-[11px] text-muted">
212
+ <div v-if="workspace.accountSpend" class="text-2xs text-muted">
212
213
  {{
213
214
  t('settings.workspaceSettings.budget.spent', {
214
215
  spent: money(workspace.accountSpend.costSpent),
@@ -216,7 +217,7 @@ function saveUser() {
216
217
  })
217
218
  }}
218
219
  </div>
219
- <p v-if="!canEditAccount" class="text-[11px] text-dimmed">
220
+ <p v-if="!canEditAccount" class="text-2xs text-dimmed">
220
221
  {{ t('settings.workspaceSettings.budget.adminOnly') }}
221
222
  </p>
222
223
  <div v-if="canEditAccount" class="flex justify-end">
@@ -238,13 +239,13 @@ function saveUser() {
238
239
  <h3 class="text-sm font-semibold text-default">
239
240
  {{ t('settings.workspaceSettings.budget.user') }}
240
241
  </h3>
241
- <p class="text-[11px] text-muted">
242
+ <p class="text-2xs text-muted">
242
243
  {{ t('settings.workspaceSettings.budget.userBody') }}
243
244
  </p>
244
245
  <label class="block">
245
- <span class="mb-1 block text-[10px] uppercase tracking-wide text-dimmed">
246
+ <SectionLabel as="span" class="mb-1 block">
246
247
  {{ t('settings.workspaceSettings.budget.monthlyLimit') }}
247
- </span>
248
+ </SectionLabel>
248
249
  <UInput
249
250
  v-model="userDraft"
250
251
  type="number"
@@ -256,13 +257,13 @@ function saveUser() {
256
257
  </label>
257
258
  <p
258
259
  v-if="userCap != null"
259
- class="text-[11px]"
260
+ class="text-2xs"
260
261
  :class="userOverCap ? 'text-app-error-400' : 'text-app-warning-400'"
261
262
  >
262
263
  {{ t('settings.workspaceSettings.budget.hardCap', { amount: money(userCap) }) }}
263
264
  <span class="text-dimmed">({{ t('settings.workspaceSettings.budget.hardCapHint') }})</span>
264
265
  </p>
265
- <div v-if="workspace.userSpend" class="text-[11px] text-muted">
266
+ <div v-if="workspace.userSpend" class="text-2xs text-muted">
266
267
  {{
267
268
  t('settings.workspaceSettings.budget.spent', {
268
269
  spent: money(workspace.userSpend.costSpent),