@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
@@ -14,6 +14,7 @@ import type {
14
14
  } from '@cat-factory/contracts'
15
15
  import JourneyStepNav from '~/components/environments/steps/JourneyStepNav.vue'
16
16
  import { useEnvironmentWizardTarget } from '~/modular/journeys/environmentSetup.frame'
17
+ import SectionLabel from '~/components/common/SectionLabel.vue'
17
18
 
18
19
  const props = defineProps<{
19
20
  input: { frameId: string | null }
@@ -114,7 +115,7 @@ const canLeaveReview = computed(
114
115
  <div class="flex items-center justify-between gap-2">
115
116
  <div class="min-w-0">
116
117
  <p class="text-sm font-medium text-default">{{ store.targetFrame?.title }}</p>
117
- <p class="text-[11px] text-dimmed">{{ t('environmentWizard.review.detectHint') }}</p>
118
+ <p class="text-2xs text-dimmed">{{ t('environmentWizard.review.detectHint') }}</p>
118
119
  </div>
119
120
  <UButton
120
121
  size="xs"
@@ -130,12 +131,12 @@ const canLeaveReview = computed(
130
131
  </UButton>
131
132
  </div>
132
133
 
133
- <p v-if="!store.hasRepo" class="text-[12px] text-app-warning-300/80">
134
+ <p v-if="!store.hasRepo" class="text-xs text-app-warning-300/80">
134
135
  {{ t('environmentWizard.review.noRepo') }}
135
136
  </p>
136
137
  <p
137
138
  v-else-if="store.detectError"
138
- class="text-[12px] text-app-error-300/80"
139
+ class="text-xs text-app-error-300/80"
139
140
  data-testid="env-setup-detect-error"
140
141
  >
141
142
  {{ t('environmentWizard.review.detectError') }}
@@ -149,7 +150,7 @@ const canLeaveReview = computed(
149
150
  >
150
151
  <p
151
152
  v-if="repoCliHint"
152
- class="mb-2 flex items-start gap-1.5 text-[11px] text-primary"
153
+ class="mb-2 flex items-start gap-1.5 text-2xs text-primary"
153
154
  data-testid="env-setup-cli-nudge"
154
155
  >
155
156
  <UIcon name="i-lucide-lightbulb" class="mt-0.5 h-3.5 w-3.5 shrink-0" />
@@ -157,10 +158,10 @@ const canLeaveReview = computed(
157
158
  </p>
158
159
  <div class="flex items-center justify-between gap-2">
159
160
  <div class="min-w-0">
160
- <p class="text-[12px] font-medium text-toned">
161
+ <p class="text-xs font-medium text-toned">
161
162
  {{ t('environmentWizard.analysis.title') }}
162
163
  </p>
163
- <p class="text-[11px] text-dimmed">{{ t('environmentWizard.analysis.hint') }}</p>
164
+ <p class="text-2xs text-dimmed">{{ t('environmentWizard.analysis.hint') }}</p>
164
165
  </div>
165
166
  <UButton
166
167
  size="xs"
@@ -177,14 +178,14 @@ const canLeaveReview = computed(
177
178
  </div>
178
179
  <p
179
180
  v-if="!store.canAnalyze"
180
- class="mt-2 text-[11px] text-dimmed"
181
+ class="mt-2 text-2xs text-dimmed"
181
182
  data-testid="env-setup-analysis-unavailable"
182
183
  >
183
184
  {{ t('environmentWizard.analysis.unavailable') }}
184
185
  </p>
185
186
  <p
186
187
  v-else-if="store.analysisStatus === 'failed'"
187
- class="mt-2 text-[11px] text-app-error-300/80"
188
+ class="mt-2 text-2xs text-app-error-300/80"
188
189
  >
189
190
  {{ t('environmentWizard.analysis.failed') }}
190
191
  </p>
@@ -193,7 +194,7 @@ const canLeaveReview = computed(
193
194
  class="mt-2 space-y-2"
194
195
  data-testid="env-setup-analysis-ready"
195
196
  >
196
- <p v-if="store.merged?.summary" class="text-[11px] leading-snug text-muted">
197
+ <p v-if="store.merged?.summary" class="text-2xs leading-snug text-muted">
197
198
  {{ store.merged.summary }}
198
199
  </p>
199
200
  <UButton
@@ -211,9 +212,9 @@ const canLeaveReview = computed(
211
212
 
212
213
  <!-- per-field provenance -->
213
214
  <div v-if="store.merged?.fields.length" class="space-y-1.5">
214
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
215
+ <SectionLabel as="p">
215
216
  {{ t('environmentWizard.review.provenanceTitle') }}
216
- </p>
217
+ </SectionLabel>
217
218
  <div class="flex flex-wrap gap-1.5">
218
219
  <UBadge
219
220
  v-for="f in store.merged.fields"
@@ -261,9 +262,9 @@ const canLeaveReview = computed(
261
262
 
262
263
  <!-- compose file layering -->
263
264
  <div v-if="composeFileCandidates.length" class="space-y-1.5">
264
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
265
+ <SectionLabel as="p">
265
266
  {{ t('environmentWizard.review.composeFiles') }}
266
- </p>
267
+ </SectionLabel>
267
268
  <div class="flex flex-wrap gap-1.5">
268
269
  <UButton
269
270
  v-for="c in composeFileCandidates"
@@ -275,16 +276,16 @@ const canLeaveReview = computed(
275
276
  :data-testid="`env-setup-file-${c.name}`"
276
277
  @click="store.toggleComposeFile(c.path)"
277
278
  >
278
- {{ c.name }}<span v-if="c.os" class="ms-1 text-[9px] opacity-70">{{ c.os }}</span>
279
+ {{ c.name }}<span v-if="c.os" class="ms-1 text-3xs opacity-70">{{ c.os }}</span>
279
280
  </UButton>
280
281
  </div>
281
282
  </div>
282
283
 
283
284
  <!-- compose profiles -->
284
285
  <div v-if="profileCandidates.length" class="space-y-1.5">
285
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
286
+ <SectionLabel as="p">
286
287
  {{ t('environmentWizard.review.profiles') }}
287
- </p>
288
+ </SectionLabel>
288
289
  <div class="flex flex-wrap gap-1.5">
289
290
  <UButton
290
291
  v-for="c in profileCandidates"
@@ -303,16 +304,16 @@ const canLeaveReview = computed(
303
304
 
304
305
  <!-- seed dumps -->
305
306
  <div v-if="seedDumpCandidates.length" class="space-y-1.5">
306
- <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
307
+ <SectionLabel as="p">
307
308
  {{ t('environmentWizard.review.seedDumps') }}
308
- </p>
309
+ </SectionLabel>
309
310
  <div class="space-y-1">
310
311
  <div
311
312
  v-for="c in seedDumpCandidates"
312
313
  :key="c.path"
313
- class="flex items-center justify-between gap-2 rounded border border-default bg-default/40 px-2 py-1"
314
+ class="flex items-center justify-between gap-2 rounded-sm border border-default bg-default/40 px-2 py-1"
314
315
  >
315
- <span class="truncate text-[11px] text-toned">{{ c.path }}</span>
316
+ <span class="truncate text-2xs text-toned">{{ c.path }}</span>
316
317
  <UButton
317
318
  size="xs"
318
319
  :color="seedAdded(c.path) ? 'success' : 'neutral'"
@@ -348,12 +349,12 @@ const canLeaveReview = computed(
348
349
  <UTextarea
349
350
  v-model="rawText"
350
351
  :rows="10"
351
- class="w-full font-mono text-[11px]"
352
+ class="w-full font-mono text-2xs"
352
353
  data-testid="env-setup-raw-text"
353
354
  />
354
355
  <p
355
356
  v-if="rawError"
356
- class="text-[11px] text-app-error-300/80"
357
+ class="text-2xs text-app-error-300/80"
357
358
  data-testid="env-setup-raw-error"
358
359
  >
359
360
  {{ rawError }}
@@ -31,7 +31,7 @@ useEnvironmentWizardTarget(() => props.input.frameId)
31
31
  <UInput v-model="store.handlerLabel" class="w-full" data-testid="env-setup-handler-label" />
32
32
  </UFormField>
33
33
 
34
- <div class="rounded-md border border-default bg-default/40 p-3 text-[12px] text-toned">
34
+ <div class="rounded-md border border-default bg-default/40 p-3 text-xs text-toned">
35
35
  <p>
36
36
  {{
37
37
  t('environmentWizard.save.summary', {
@@ -44,7 +44,7 @@ useEnvironmentWizardTarget(() => props.input.frameId)
44
44
 
45
45
  <p
46
46
  v-if="store.saveError"
47
- class="text-[12px] text-app-error-300/80"
47
+ class="text-xs text-app-error-300/80"
48
48
  data-testid="env-setup-save-error"
49
49
  >
50
50
  {{ store.saveError }}
@@ -66,7 +66,7 @@ useEnvironmentWizardTarget(() => props.input.frameId)
66
66
  <!-- saved: confirmation + optional trial provision -->
67
67
  <template v-else>
68
68
  <div
69
- class="flex items-center gap-2 rounded-md border border-app-success-800/50 bg-app-success-950/30 p-2 text-[12px] text-app-success-200"
69
+ class="flex items-center gap-2 rounded-md border border-app-success-800/50 bg-app-success-950/30 p-2 text-xs text-app-success-200"
70
70
  data-testid="env-setup-saved"
71
71
  >
72
72
  <UIcon name="i-lucide-check-circle" class="h-4 w-4" />
@@ -74,7 +74,7 @@ useEnvironmentWizardTarget(() => props.input.frameId)
74
74
  </div>
75
75
 
76
76
  <div class="flex items-center justify-between gap-2">
77
- <p class="text-[11px] text-dimmed">{{ t('environmentWizard.trial.hint') }}</p>
77
+ <p class="text-2xs text-dimmed">{{ t('environmentWizard.trial.hint') }}</p>
78
78
  <UButton
79
79
  size="xs"
80
80
  variant="soft"
@@ -88,7 +88,7 @@ useEnvironmentWizardTarget(() => props.input.frameId)
88
88
  {{ t('environmentWizard.trial.run') }}
89
89
  </UButton>
90
90
  </div>
91
- <p v-if="store.trialError" class="text-[11px] text-app-error-300/80">
91
+ <p v-if="store.trialError" class="text-2xs text-app-error-300/80">
92
92
  {{ store.trialError }}
93
93
  </p>
94
94
  <ProvisioningLogsDrawer v-if="store.trialStarted" subsystem="environment" />
@@ -6,6 +6,7 @@ import { pipelineAllowedForManualStart } from '~/utils/pipeline'
6
6
  import PipelineProgress from '~/components/pipeline/PipelineProgress.vue'
7
7
  import IconButton from '~/components/common/IconButton.vue'
8
8
  import { useInitiativePlanning } from '~/composables/useInitiativePlanning'
9
+ import SectionLabel from '~/components/common/SectionLabel.vue'
9
10
 
10
11
  const board = useBoardStore()
11
12
  const pipelines = usePipelinesStore()
@@ -203,9 +204,9 @@ function openApprovalFor(approvalId: string) {
203
204
  >
204
205
  <div class="mb-4 flex items-center gap-2">
205
206
  <UIcon name="i-lucide-workflow" class="h-4 w-4 text-dimmed" />
206
- <h2 class="text-sm font-semibold uppercase tracking-wide text-muted">
207
+ <SectionLabel as="h2">
207
208
  {{ instance ? instance.pipelineName : t('focus.noPipelineRunning') }}
208
- </h2>
209
+ </SectionLabel>
209
210
  </div>
210
211
 
211
212
  <PipelineProgress
@@ -226,30 +227,30 @@ function openApprovalFor(approvalId: string) {
226
227
  <!-- side: details -->
227
228
  <aside class="space-y-4 overflow-auto rounded-2xl border border-default bg-default/60 p-5">
228
229
  <div>
229
- <div class="mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted">
230
+ <SectionLabel class="mb-1">
230
231
  {{ t('focus.description') }}
231
- </div>
232
+ </SectionLabel>
232
233
  <p class="text-sm text-toned">{{ block.description }}</p>
233
234
  </div>
234
235
  <div v-if="instance">
235
- <div class="mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted">
236
+ <SectionLabel class="mb-1">
236
237
  {{ t('focus.overallProgress') }}
237
- </div>
238
+ </SectionLabel>
238
239
  <UProgress :model-value="Math.round(block.progress * 100)" />
239
- <div class="mt-1 text-[11px] text-muted">
240
+ <div class="mt-1 text-2xs text-muted">
240
241
  {{ n(block.progress, 'percent') }}
241
242
  </div>
242
243
  </div>
243
244
  <div>
244
- <div class="mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted">
245
+ <SectionLabel class="mb-1">
245
246
  {{ t('focus.dependencies') }}
246
- </div>
247
+ </SectionLabel>
247
248
  <div v-if="deps.length" class="flex flex-wrap gap-1">
248
249
  <UBadge v-for="d in deps" :key="d.id" color="neutral" variant="subtle" size="sm">
249
250
  {{ d.title }}
250
251
  </UBadge>
251
252
  </div>
252
- <div v-else class="text-[11px] text-dimmed">{{ t('focus.noDependencies') }}</div>
253
+ <div v-else class="text-2xs text-dimmed">{{ t('focus.noDependencies') }}</div>
253
254
  </div>
254
255
  </aside>
255
256
  </div>
@@ -162,7 +162,7 @@ function hasRecordedAnswer(item: FollowUpItem): boolean {
162
162
  >
163
163
  <UIcon :name="FOLLOW_UP_COMPANION_META.icon" class="h-8 w-8 opacity-40" />
164
164
  <p class="text-sm">{{ t('followUp.empty.title') }}</p>
165
- <p class="max-w-sm text-[11px] text-dimmed">
165
+ <p class="max-w-sm text-2xs text-dimmed">
166
166
  {{ t('followUp.empty.hint') }}
167
167
  </p>
168
168
  </div>
@@ -170,7 +170,7 @@ function hasRecordedAnswer(item: FollowUpItem): boolean {
170
170
  <div v-else class="space-y-3">
171
171
  <p
172
172
  v-if="followUps.error"
173
- class="rounded-md bg-app-error-500/10 px-3 py-2 text-[12px] text-app-error-300"
173
+ class="rounded-md bg-app-error-500/10 px-3 py-2 text-xs text-app-error-300"
174
174
  >
175
175
  {{ followUps.error }}
176
176
  </p>
@@ -189,21 +189,21 @@ function hasRecordedAnswer(item: FollowUpItem): boolean {
189
189
  />
190
190
  <div class="min-w-0 flex-1">
191
191
  <div class="flex items-center gap-2">
192
- <h3 class="min-w-0 flex-1 truncate text-[13px] font-medium text-app-100">
192
+ <h3 class="min-w-0 flex-1 truncate text-sm font-medium text-app-100">
193
193
  {{ item.title }}
194
194
  </h3>
195
195
  <UBadge :color="STATUS_META[item.status].badge" variant="subtle" size="sm">
196
196
  {{ t(STATUS_LABEL_KEYS[item.status]) }}
197
197
  </UBadge>
198
198
  </div>
199
- <p v-if="item.detail" class="mt-1 whitespace-pre-wrap text-[12px] text-toned">
199
+ <p v-if="item.detail" class="mt-1 whitespace-pre-wrap text-xs text-toned">
200
200
  {{ item.detail }}
201
201
  </p>
202
- <p v-if="item.suggestedAction" class="mt-1 text-[11px] text-muted">
202
+ <p v-if="item.suggestedAction" class="mt-1 text-2xs text-muted">
203
203
  <span class="text-dimmed">{{ t('followUp.suggested') }}</span>
204
204
  {{ item.suggestedAction }}
205
205
  </p>
206
- <p v-if="item.status === 'filed' && item.ticketUrl" class="mt-1 text-[11px]">
206
+ <p v-if="item.status === 'filed' && item.ticketUrl" class="mt-1 text-2xs">
207
207
  <a
208
208
  :href="item.ticketUrl"
209
209
  target="_blank"
@@ -213,7 +213,7 @@ function hasRecordedAnswer(item: FollowUpItem): boolean {
213
213
  {{ item.ticketExternalId ?? t('followUp.viewIssue') }}
214
214
  </a>
215
215
  </p>
216
- <p v-if="hasRecordedAnswer(item)" class="mt-1 text-[11px] text-toned">
216
+ <p v-if="hasRecordedAnswer(item)" class="mt-1 text-2xs text-toned">
217
217
  <span class="text-dimmed">
218
218
  {{
219
219
  item.status === 'closed' ? t('followUp.yourRuling') : t('followUp.yourAnswer')
@@ -223,7 +223,7 @@ function hasRecordedAnswer(item: FollowUpItem): boolean {
223
223
  </p>
224
224
  <!-- A decision that was made and then thrown away when the budget ran out. It must
225
225
  not read like one the Coder acted on. -->
226
- <p v-if="item.sendBackDropped" class="mt-1 text-[11px] text-app-warning-300">
226
+ <p v-if="item.sendBackDropped" class="mt-1 text-2xs text-app-warning-300">
227
227
  {{ t('followUp.sendBackDropped') }}
228
228
  </p>
229
229
 
@@ -235,7 +235,7 @@ function hasRecordedAnswer(item: FollowUpItem): boolean {
235
235
  v-model="drafts[item.id]"
236
236
  rows="2"
237
237
  :placeholder="t('followUp.answerPlaceholder')"
238
- class="w-full resize-y rounded-md border border-muted bg-app-950/60 px-2.5 py-1.5 text-[12px] text-app-100 placeholder:text-app-600 focus:border-app-info-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-app-info-500/60"
238
+ class="w-full resize-y rounded-md border border-muted bg-app-950/60 px-2.5 py-1.5 text-xs text-app-100 placeholder:text-app-600 focus:border-app-info-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-app-info-500/60"
239
239
  />
240
240
  <!-- Wraps, like the follow-up row below: three buttons whose labels are two
241
241
  words each in English are one long line in most of the other locales, and
@@ -323,7 +323,7 @@ function hasRecordedAnswer(item: FollowUpItem): boolean {
323
323
  </div>
324
324
 
325
325
  <footer
326
- class="flex items-center justify-between border-t border-default px-5 py-2.5 text-[11px] text-muted"
326
+ class="flex items-center justify-between border-t border-default px-5 py-2.5 text-2xs text-muted"
327
327
  >
328
328
  <span>
329
329
  {{
@@ -166,7 +166,7 @@ const { requestClose } = useUnsavedGuard({
166
166
  >
167
167
  <UIcon name="i-lucide-loader-circle" class="h-8 w-8 animate-spin opacity-60" />
168
168
  <p class="text-sm">{{ t('forkDecision.proposing.title') }}</p>
169
- <p class="max-w-sm text-[11px] text-dimmed">
169
+ <p class="max-w-sm text-2xs text-dimmed">
170
170
  {{ t('forkDecision.proposing.hint') }}
171
171
  </p>
172
172
  </div>
@@ -176,10 +176,10 @@ const { requestClose } = useUnsavedGuard({
176
176
  v-else-if="status === 'single_path'"
177
177
  class="rounded-xl border border-default bg-default/60 px-4 py-3 text-toned"
178
178
  >
179
- <p class="text-[13px] font-medium text-app-100">
179
+ <p class="text-sm font-medium text-app-100">
180
180
  {{ t('forkDecision.singlePath.title') }}
181
181
  </p>
182
- <p v-if="state?.singlePathReason" class="mt-1 text-[12px]">
182
+ <p v-if="state?.singlePathReason" class="mt-1 text-xs">
183
183
  {{ state.singlePathReason }}
184
184
  </p>
185
185
  </div>
@@ -189,16 +189,16 @@ const { requestClose } = useUnsavedGuard({
189
189
  v-else-if="status === 'chosen'"
190
190
  class="rounded-xl border border-app-secondary-500/40 bg-default/60 px-4 py-3 text-toned"
191
191
  >
192
- <p class="text-[13px] font-medium text-app-secondary-200">
192
+ <p class="text-sm font-medium text-app-secondary-200">
193
193
  {{ t('forkDecision.chosen.title') }}
194
194
  </p>
195
- <p v-if="state?.chosen?.custom" class="mt-1 whitespace-pre-wrap text-[12px]">
195
+ <p v-if="state?.chosen?.custom" class="mt-1 whitespace-pre-wrap text-xs">
196
196
  {{ state.chosen.custom }}
197
197
  </p>
198
- <p v-else-if="state?.chosen?.forkId" class="mt-1 text-[12px]">
198
+ <p v-else-if="state?.chosen?.forkId" class="mt-1 text-xs">
199
199
  {{ forks.find((f) => f.id === state?.chosen?.forkId)?.title }}
200
200
  </p>
201
- <p v-if="state?.chosen?.note" class="mt-1 text-[11px] text-muted">
201
+ <p v-if="state?.chosen?.note" class="mt-1 text-2xs text-muted">
202
202
  {{ t('forkDecision.chosen.note', { note: state.chosen.note }) }}
203
203
  </p>
204
204
  </div>
@@ -207,15 +207,12 @@ const { requestClose } = useUnsavedGuard({
207
207
  <div v-else-if="interactive" class="space-y-3">
208
208
  <p
209
209
  v-if="forkDecision.error"
210
- class="rounded-md bg-app-error-500/10 px-3 py-2 text-[12px] text-app-error-300"
210
+ class="rounded-md bg-app-error-500/10 px-3 py-2 text-xs text-app-error-300"
211
211
  >
212
212
  {{ forkDecision.error }}
213
213
  </p>
214
214
 
215
- <p
216
- v-if="state?.seamSummary"
217
- class="rounded-md bg-elevated/50 px-3 py-2 text-[12px] text-toned"
218
- >
215
+ <p v-if="state?.seamSummary" class="rounded-md bg-elevated/50 px-3 py-2 text-xs text-toned">
219
216
  <span class="text-dimmed">{{ t('forkDecision.seam') }}</span>
220
217
  {{ state.seamSummary }}
221
218
  </p>
@@ -242,29 +239,29 @@ const { requestClose } = useUnsavedGuard({
242
239
  />
243
240
  <div class="min-w-0 flex-1">
244
241
  <div class="flex items-center gap-2">
245
- <h3 class="min-w-0 flex-1 text-[13px] font-medium text-app-100">
242
+ <h3 class="min-w-0 flex-1 text-sm font-medium text-app-100">
246
243
  {{ fork.title }}
247
244
  </h3>
248
245
  <UBadge v-if="fork.recommended" color="primary" variant="subtle" size="sm">
249
246
  {{ t('forkDecision.recommended') }}
250
247
  </UBadge>
251
248
  </div>
252
- <p v-if="fork.summary" class="mt-0.5 text-[12px] text-muted">
249
+ <p v-if="fork.summary" class="mt-0.5 text-xs text-muted">
253
250
  {{ fork.summary }}
254
251
  </p>
255
- <p class="mt-1.5 whitespace-pre-wrap text-[12px] text-toned">
252
+ <p class="mt-1.5 whitespace-pre-wrap text-xs text-toned">
256
253
  {{ fork.approach }}
257
254
  </p>
258
255
  <ul v-if="fork.tradeoffs.length" class="mt-1.5 space-y-0.5">
259
256
  <li
260
257
  v-for="(tr, i) in fork.tradeoffs"
261
258
  :key="i"
262
- class="flex gap-1.5 text-[11px] text-muted"
259
+ class="flex gap-1.5 text-2xs text-muted"
263
260
  >
264
261
  <span class="text-app-600">•</span>{{ tr }}
265
262
  </li>
266
263
  </ul>
267
- <p v-if="fork.riskNotes" class="mt-1.5 text-[11px] text-app-warning-300/90">
264
+ <p v-if="fork.riskNotes" class="mt-1.5 text-2xs text-app-warning-300/90">
268
265
  <span class="text-app-warning-500/70">{{ t('forkDecision.riskNotes') }}</span>
269
266
  {{ fork.riskNotes }}
270
267
  </p>
@@ -283,7 +280,7 @@ const { requestClose } = useUnsavedGuard({
283
280
  >
284
281
  <label class="flex cursor-pointer items-center gap-2" @click="selected = 'custom'">
285
282
  <input type="radio" class="accent-app-secondary-500" :checked="selected === 'custom'" />
286
- <span class="text-[13px] font-medium text-app-100">{{
283
+ <span class="text-sm font-medium text-app-100">{{
287
284
  t('forkDecision.custom.title')
288
285
  }}</span>
289
286
  </label>
@@ -292,25 +289,25 @@ const { requestClose } = useUnsavedGuard({
292
289
  data-testid="fork-custom-input"
293
290
  rows="3"
294
291
  :placeholder="t('forkDecision.custom.placeholder')"
295
- class="mt-2 w-full resize-y rounded-md border border-muted bg-app-950/60 px-2.5 py-1.5 text-[12px] text-app-100 placeholder:text-app-600 focus:border-app-secondary-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-app-secondary-500/60"
292
+ class="mt-2 w-full resize-y rounded-md border border-muted bg-app-950/60 px-2.5 py-1.5 text-xs text-app-100 placeholder:text-app-600 focus:border-app-secondary-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-app-secondary-500/60"
296
293
  @focus="selected = 'custom'"
297
294
  />
298
295
  </article>
299
296
 
300
297
  <!-- Optional steering note -->
301
298
  <div>
302
- <label class="mb-1 block text-[11px] text-muted">{{ t('forkDecision.noteLabel') }}</label>
299
+ <label class="mb-1 block text-2xs text-muted">{{ t('forkDecision.noteLabel') }}</label>
303
300
  <input
304
301
  v-model="note"
305
302
  type="text"
306
303
  :placeholder="t('forkDecision.notePlaceholder')"
307
- class="w-full rounded-md border border-muted bg-app-950/60 px-2.5 py-1.5 text-[12px] text-app-100 placeholder:text-app-600 focus:border-app-secondary-500 focus:outline-none"
304
+ class="w-full rounded-md border border-muted bg-app-950/60 px-2.5 py-1.5 text-xs text-app-100 placeholder:text-app-600 focus:border-app-secondary-500 focus:outline-none"
308
305
  />
309
306
  </div>
310
307
 
311
308
  <!-- Grounded chat: ask about the forks before deciding. -->
312
309
  <section class="rounded-xl border border-default bg-default/40 px-4 py-3">
313
- <p class="text-[11px] font-medium text-muted">
310
+ <p class="text-2xs font-medium text-muted">
314
311
  {{ t('forkDecision.chat.title') }}
315
312
  </p>
316
313
  <div v-if="chat.length || answering" class="mt-2 max-h-64 space-y-2 overflow-y-auto pr-1">
@@ -322,7 +319,7 @@ const { requestClose } = useUnsavedGuard({
322
319
  :class="msg.role === 'human' ? 'justify-end' : 'justify-start'"
323
320
  >
324
321
  <p
325
- class="max-w-[85%] whitespace-pre-wrap rounded-lg px-3 py-1.5 text-[12px]"
322
+ class="max-w-[85%] whitespace-pre-wrap rounded-lg px-3 py-1.5 text-xs"
326
323
  :class="
327
324
  msg.role === 'human'
328
325
  ? 'bg-app-secondary-500/15 text-app-secondary-100'
@@ -334,14 +331,14 @@ const { requestClose } = useUnsavedGuard({
334
331
  </div>
335
332
  <div v-if="answering" class="flex justify-start">
336
333
  <p
337
- class="flex items-center gap-1.5 rounded-lg bg-elevated/70 px-3 py-1.5 text-[12px] text-muted"
334
+ class="flex items-center gap-1.5 rounded-lg bg-elevated/70 px-3 py-1.5 text-xs text-muted"
338
335
  >
339
336
  <UIcon name="i-lucide-loader-circle" class="h-3.5 w-3.5 animate-spin" />
340
337
  {{ t('forkDecision.chat.thinking') }}
341
338
  </p>
342
339
  </div>
343
340
  </div>
344
- <p v-else class="mt-1 text-[11px] text-dimmed">
341
+ <p v-else class="mt-1 text-2xs text-dimmed">
345
342
  {{ t('forkDecision.chat.hint') }}
346
343
  </p>
347
344
  <div class="mt-2 flex items-end gap-2">
@@ -355,7 +352,7 @@ const { requestClose } = useUnsavedGuard({
355
352
  ? t('forkDecision.chat.budgetSpent')
356
353
  : t('forkDecision.chat.placeholder')
357
354
  "
358
- class="min-h-0 flex-1 resize-y rounded-md border border-muted bg-app-950/60 px-2.5 py-1.5 text-[12px] text-app-100 placeholder:text-app-600 focus:border-app-secondary-500 focus:outline-none disabled:opacity-50"
355
+ class="min-h-0 flex-1 resize-y rounded-md border border-muted bg-app-950/60 px-2.5 py-1.5 text-xs text-app-100 placeholder:text-app-600 focus:border-app-secondary-500 focus:outline-none disabled:opacity-50"
359
356
  @keydown.enter.exact.prevent="onSend"
360
357
  />
361
358
  <UButton
@@ -25,7 +25,7 @@ const { t, n } = useI18n()
25
25
 
26
26
  <template>
27
27
  <div v-if="contracts.length" class="mt-1 flex flex-col gap-1">
28
- <div v-for="c in contracts" :key="c.contractId" class="text-[11px] text-dimmed">
28
+ <div v-for="c in contracts" :key="c.contractId" class="text-2xs text-dimmed">
29
29
  <span class="text-muted">{{ c.title }}</span>
30
30
  <span class="ms-1">({{ formatLabel[c.format] }}, {{ n(c.size) }})</span>
31
31
  <span v-if="c.operations.length" class="ms-1 font-mono text-dimmed">
@@ -42,7 +42,7 @@ const { t, n } = useI18n()
42
42
  </span>
43
43
  </div>
44
44
  </div>
45
- <p v-else class="mt-1 text-[11px] text-app-warning-500/80">
45
+ <p v-else class="mt-1 text-2xs text-app-warning-500/80">
46
46
  {{ t('foundational.contracts.none') }}
47
47
  </p>
48
48
  </template>
@@ -92,7 +92,7 @@ async function suppress(serviceId: string) {
92
92
  <div class="min-w-0 flex-1">
93
93
  <p class="truncate text-sm font-medium text-app-100">
94
94
  {{ s.name }}
95
- <code class="ms-1 text-[11px] text-dimmed">{{ s.id }}</code>
95
+ <code class="ms-1 text-2xs text-dimmed">{{ s.id }}</code>
96
96
  </p>
97
97
  <p class="text-xs text-muted">{{ s.summary }}</p>
98
98
  <div v-if="s.capabilities.length" class="mt-1 flex flex-wrap gap-1">
@@ -124,11 +124,11 @@ async function suppress(serviceId: string) {
124
124
  :key="doc.contractId"
125
125
  class="rounded-md border border-default bg-app-950/60 p-2"
126
126
  >
127
- <p class="mb-1 text-[11px] text-muted">
127
+ <p class="mb-1 text-2xs text-muted">
128
128
  {{ doc.title }}
129
129
  <span v-if="doc.path" class="ms-1 font-mono text-app-600">{{ doc.path }}</span>
130
130
  </p>
131
- <pre class="max-h-64 overflow-auto text-[11px] text-toned">{{ doc.body }}</pre>
131
+ <pre class="max-h-64 overflow-auto text-2xs text-toned">{{ doc.body }}</pre>
132
132
  </div>
133
133
  </div>
134
134
  </div>
@@ -189,7 +189,7 @@ async function remove(service: FoundationalService) {
189
189
  <div class="min-w-0 flex-1">
190
190
  <p class="truncate text-sm font-medium text-app-100">
191
191
  {{ s.name }}
192
- <code class="ms-1 text-[11px] text-dimmed">{{ s.id }}</code>
192
+ <code class="ms-1 text-2xs text-dimmed">{{ s.id }}</code>
193
193
  </p>
194
194
  <p class="text-xs text-muted">{{ s.summary }}</p>
195
195
  <div v-if="s.capabilities.length" class="mt-1 flex flex-wrap gap-1">
@@ -198,7 +198,7 @@ async function remove(service: FoundationalService) {
198
198
  </UBadge>
199
199
  </div>
200
200
  <FoundationalContractSummary :contracts="s.contracts" :format-label="formatLabel" />
201
- <p v-if="s.sourceId" class="mt-1 text-[11px] text-dimmed">
201
+ <p v-if="s.sourceId" class="mt-1 text-2xs text-dimmed">
202
202
  {{ t('foundational.registry.fromSource', { path: s.sourcePath ?? '' }) }}
203
203
  </p>
204
204
  </div>
@@ -274,7 +274,7 @@ async function remove(service: FoundationalService) {
274
274
  <p class="text-xs font-medium text-toned">
275
275
  {{ t('foundational.registry.contractsTitle') }}
276
276
  </p>
277
- <p class="mb-2 text-[11px] text-dimmed">
277
+ <p class="mb-2 text-2xs text-dimmed">
278
278
  {{
279
279
  draft.contractsTouched
280
280
  ? t('foundational.registry.contractsReplace')
@@ -73,10 +73,10 @@ async function restore(serviceId: string) {
73
73
  <div class="min-w-0 flex-1">
74
74
  <p class="truncate text-sm text-toned">
75
75
  {{ s.name || s.id }}
76
- <code v-if="s.name" class="ms-1 text-[11px] text-dimmed">{{ s.id }}</code>
76
+ <code v-if="s.name" class="ms-1 text-2xs text-dimmed">{{ s.id }}</code>
77
77
  </p>
78
78
  <p v-if="s.summary" class="text-xs text-dimmed">{{ s.summary }}</p>
79
- <p v-if="!s.inherited" class="text-[11px] text-dimmed">
79
+ <p v-if="!s.inherited" class="text-2xs text-dimmed">
80
80
  {{ t('foundational.suppressions.shadowsNothing') }}
81
81
  </p>
82
82
  </div>
@@ -654,7 +654,7 @@ async function unlinkSource(id: string) {
654
654
  >
655
655
  {{ t('fragments.catalog.live', { source: f.documentRef.source }) }}
656
656
  </UBadge>
657
- <span class="ms-auto font-mono text-[11px] text-dimmed">{{ f.id }}</span>
657
+ <span class="ms-auto font-mono text-2xs text-dimmed">{{ f.id }}</span>
658
658
  </div>
659
659
  <p class="mt-1 text-sm text-muted">{{ f.summary }}</p>
660
660
  <div v-if="f.tags?.length" class="mt-1 flex flex-wrap gap-1">
@@ -859,7 +859,7 @@ async function unlinkSource(id: string) {
859
859
  </UBadge>
860
860
  </div>
861
861
  <p class="text-sm text-muted">{{ f.summary }}</p>
862
- <p v-if="f.resolvedAt" class="text-[11px] text-dimmed">
862
+ <p v-if="f.resolvedAt" class="text-2xs text-dimmed">
863
863
  {{
864
864
  t('fragments.documents.lastResolved', { date: d(new Date(f.resolvedAt), 'long') })
865
865
  }}
@@ -942,7 +942,7 @@ async function unlinkSource(id: string) {
942
942
  <div
943
943
  v-for="staged in stagedDocRefs"
944
944
  :key="staged.path"
945
- class="flex items-center gap-1.5 rounded bg-elevated/60 px-2 py-1 text-xs text-toned"
945
+ class="flex items-center gap-1.5 rounded-sm bg-elevated/60 px-2 py-1 text-xs text-toned"
946
946
  >
947
947
  <UIcon name="i-lucide-file-code-2" class="h-3.5 w-3.5 shrink-0 text-primary" />
948
948
  <span class="truncate">{{ staged.path }}</span>