@cat-factory/app 0.308.0 → 0.309.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/README.md +21 -0
  2. package/app/assets/css/main.css +22 -0
  3. package/app/assets/css/prose.css +4 -4
  4. package/app/assets/css/type.css +24 -0
  5. package/app/components/assistant/AssistantModal.vue +3 -2
  6. package/app/components/auth/UserMenu.vue +1 -1
  7. package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +15 -15
  8. package/app/components/binaryOutput/BinaryOutputReport.vue +10 -14
  9. package/app/components/binaryOutput/StoredAssetView.vue +5 -5
  10. package/app/components/board/AddTaskModal.vue +16 -14
  11. package/app/components/board/AgentFailureCard.vue +9 -9
  12. package/app/components/board/AgentFailureHistory.vue +1 -1
  13. package/app/components/board/CreateInitiativeModal.vue +2 -2
  14. package/app/components/board/FailureDetail.vue +1 -1
  15. package/app/components/board/FailureHistoryList.vue +5 -5
  16. package/app/components/board/RecurringPipelineModal.vue +12 -11
  17. package/app/components/board/ReviewFrictionDialog.vue +4 -3
  18. package/app/components/board/StepExecutionHistory.vue +8 -8
  19. package/app/components/board/nodes/AgentChip.vue +1 -1
  20. package/app/components/board/nodes/BlockNode.vue +8 -9
  21. package/app/components/board/nodes/EpicNode.vue +4 -4
  22. package/app/components/board/nodes/FrameSwimlanes.vue +4 -7
  23. package/app/components/board/nodes/InitiativeCard.vue +4 -4
  24. package/app/components/board/nodes/LaneGroup.vue +3 -5
  25. package/app/components/board/nodes/TaskCard.vue +8 -8
  26. package/app/components/board/nodes/TaskLane.vue +3 -3
  27. package/app/components/board/nodes/TaskPipelineMini.vue +13 -12
  28. package/app/components/bootstrap/AdoptionReviewModal.vue +7 -6
  29. package/app/components/bootstrap/BootstrapModal.vue +11 -10
  30. package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
  31. package/app/components/brainstorm/BrainstormWindow.vue +8 -7
  32. package/app/components/bugFishing/BugFishingWindow.vue +37 -36
  33. package/app/components/clarity/ClarityReviewWindow.vue +8 -7
  34. package/app/components/common/AsyncViewError.vue +1 -1
  35. package/app/components/common/ClarificationItem.vue +6 -6
  36. package/app/components/common/DescriptorFields.vue +1 -1
  37. package/app/components/common/EmptyState.vue +1 -1
  38. package/app/components/common/InterviewGateNotice.vue +4 -4
  39. package/app/components/common/MarkdownProse.vue +8 -2
  40. package/app/components/common/SectionLabel.vue +38 -0
  41. package/app/components/consensus/ConsensusSessionWindow.vue +10 -9
  42. package/app/components/context/ContextAttachmentFields.vue +9 -8
  43. package/app/components/docs/DocInterviewWindow.vue +10 -9
  44. package/app/components/documents/ContextDocumentPicker.vue +10 -12
  45. package/app/components/documents/DocumentImportModal.vue +3 -2
  46. package/app/components/documents/DocumentSourceConnectModal.vue +2 -2
  47. package/app/components/documents/DocumentSyncState.vue +1 -1
  48. package/app/components/documents/DocumentTemplatesModal.vue +5 -4
  49. package/app/components/documents/RepoContextDocPicker.vue +3 -6
  50. package/app/components/documents/StartFromDesignModal.vue +4 -4
  51. package/app/components/documents/TaskContextDocs.vue +1 -1
  52. package/app/components/environments/EnvSetupStepper.vue +3 -3
  53. package/app/components/environments/EnvironmentStatusPanel.vue +11 -10
  54. package/app/components/environments/steps/EnvPreflightStep.vue +8 -8
  55. package/app/components/environments/steps/EnvReviewStep.vue +23 -22
  56. package/app/components/environments/steps/EnvSaveStep.vue +5 -5
  57. package/app/components/focus/BlockFocusView.vue +11 -10
  58. package/app/components/followUp/FollowUpWindow.vue +10 -10
  59. package/app/components/forkDecision/ForkDecisionWindow.vue +23 -26
  60. package/app/components/foundational/FoundationalContractSummary.vue +2 -2
  61. package/app/components/foundational/FoundationalServiceCatalogList.vue +3 -3
  62. package/app/components/foundational/FoundationalServiceRegistry.vue +3 -3
  63. package/app/components/foundational/FoundationalSuppressions.vue +2 -2
  64. package/app/components/fragments/FragmentLibraryManager.vue +3 -3
  65. package/app/components/fragments/FragmentSelector.vue +10 -11
  66. package/app/components/gates/GateFailingCheckList.vue +3 -3
  67. package/app/components/gates/GateResultView.vue +39 -38
  68. package/app/components/github/AddServiceFromRepoModal.vue +5 -4
  69. package/app/components/github/BranchProtectionPreflight.vue +5 -5
  70. package/app/components/github/GitHubConnect.vue +5 -3
  71. package/app/components/github/GitHubPanel.vue +14 -13
  72. package/app/components/github/RepoTreeBrowser.vue +1 -1
  73. package/app/components/humanTest/HumanTestWindow.vue +18 -17
  74. package/app/components/initiative/InitiativePlanNotice.vue +3 -3
  75. package/app/components/initiative/InitiativePlanReview.vue +19 -21
  76. package/app/components/initiative/InitiativePlanningWindow.vue +5 -5
  77. package/app/components/initiative/InitiativeTrackerWindow.vue +54 -53
  78. package/app/components/judge/JudgeResultView.vue +24 -25
  79. package/app/components/kaizen/KaizenPanel.vue +4 -4
  80. package/app/components/kaizen/KaizenStepStatus.vue +7 -6
  81. package/app/components/layout/AccountAuditLog.vue +1 -1
  82. package/app/components/layout/AccountDeploymentSettings.vue +10 -10
  83. package/app/components/layout/AccountFailureKindRules.vue +13 -13
  84. package/app/components/layout/AccountFoundationalSettings.vue +1 -1
  85. package/app/components/layout/AccountFragmentSettings.vue +1 -1
  86. package/app/components/layout/AccountModelPolicySettings.vue +7 -7
  87. package/app/components/layout/AccountPlatformAlertSettings.vue +8 -8
  88. package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
  89. package/app/components/layout/AccountRunCredentialSettings.vue +3 -3
  90. package/app/components/layout/AccountSkillSettings.vue +1 -1
  91. package/app/components/layout/AccountTeamSettings.vue +4 -0
  92. package/app/components/layout/AiProvidersBanner.vue +1 -1
  93. package/app/components/layout/AppearanceSwitcher.vue +1 -1
  94. package/app/components/layout/BoardSwitcher.vue +3 -2
  95. package/app/components/layout/BoardToolbar.vue +6 -2
  96. package/app/components/layout/CommandBar.vue +4 -2
  97. package/app/components/layout/DefaultTestEnvBanner.vue +2 -2
  98. package/app/components/layout/IntegrationsHub.vue +4 -3
  99. package/app/components/layout/LanguageSwitcher.vue +1 -1
  100. package/app/components/layout/ModelProvidersHub.vue +6 -4
  101. package/app/components/layout/NotificationsInbox.vue +8 -7
  102. package/app/components/layout/PersonalSetupModal.vue +5 -3
  103. package/app/components/layout/RolePrompt.vue +1 -1
  104. package/app/components/layout/SideBar.vue +3 -5
  105. package/app/components/layout/SpendWarningBanner.vue +3 -3
  106. package/app/components/layout/TranslationWarningBanner.vue +1 -1
  107. package/app/components/layout/UiModeSwitcher.vue +7 -6
  108. package/app/components/layout/UiRoleSwitcher.vue +2 -2
  109. package/app/components/media/ArtifactLightbox.vue +6 -6
  110. package/app/components/media/ImageCompare.vue +16 -16
  111. package/app/components/merge/MergeEffortChips.vue +4 -6
  112. package/app/components/notifications/NotificationSettingsPanel.vue +6 -5
  113. package/app/components/observability/OutcomeFilterChips.vue +1 -1
  114. package/app/components/observability/RunFailureSummary.vue +14 -17
  115. package/app/components/observability/StepMetricsBar.vue +9 -8
  116. package/app/components/observability/StepModelActivity.vue +4 -3
  117. package/app/components/observability/ToolCallList.vue +15 -18
  118. package/app/components/outcome/OutcomeSummaryWindow.vue +43 -42
  119. package/app/components/palettes/AgentPalette.vue +7 -5
  120. package/app/components/palettes/AgentTierSelect.vue +1 -1
  121. package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
  122. package/app/components/panels/AgentStepDetail.vue +27 -30
  123. package/app/components/panels/AttemptEntryHeader.vue +2 -2
  124. package/app/components/panels/DecisionModal.vue +1 -1
  125. package/app/components/panels/GenericStructuredResultView.vue +6 -5
  126. package/app/components/panels/InspectorPanel.vue +15 -13
  127. package/app/components/panels/MergerResultView.vue +10 -9
  128. package/app/components/panels/ObservabilityPanel.vue +66 -76
  129. package/app/components/panels/OperatorDashboardPanel.vue +27 -26
  130. package/app/components/panels/ReportsPanel.vue +26 -25
  131. package/app/components/panels/ReportsSpendBreakdown.vue +2 -2
  132. package/app/components/panels/ResultWindowShell.vue +19 -18
  133. package/app/components/panels/RunDetailLoadState.vue +1 -1
  134. package/app/components/panels/StepContainerStatus.vue +8 -7
  135. package/app/components/panels/StepDelegatedStatus.vue +13 -12
  136. package/app/components/panels/StepEffortReport.vue +12 -17
  137. package/app/components/panels/StepFragmentAdherence.vue +9 -10
  138. package/app/components/panels/StepMetadataCard.vue +41 -43
  139. package/app/components/panels/StepReproductionReport.vue +18 -20
  140. package/app/components/panels/StepRunMeta.vue +27 -26
  141. package/app/components/panels/StepTestReport.vue +16 -15
  142. package/app/components/panels/StepToolServers.vue +7 -8
  143. package/app/components/panels/StepValidationReport.vue +5 -5
  144. package/app/components/panels/inspector/ContainerSummary.vue +4 -4
  145. package/app/components/panels/inspector/DocReferenceRepos.vue +5 -4
  146. package/app/components/panels/inspector/EnvProbeReport.vue +16 -13
  147. package/app/components/panels/inspector/EpicChildren.vue +8 -7
  148. package/app/components/panels/inspector/FrontendBindingsResolved.vue +5 -4
  149. package/app/components/panels/inspector/FrontendConfig.vue +26 -34
  150. package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
  151. package/app/components/panels/inspector/InspectorSection.vue +7 -4
  152. package/app/components/panels/inspector/RecurringScheduleSettings.vue +9 -8
  153. package/app/components/panels/inspector/ServiceConnections.vue +2 -2
  154. package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
  155. package/app/components/panels/inspector/ServiceSelfTests.vue +9 -13
  156. package/app/components/panels/inspector/ServiceTestConfig.vue +41 -45
  157. package/app/components/panels/inspector/ServiceTestSecrets.vue +3 -3
  158. package/app/components/panels/inspector/ServiceTestingContext.vue +2 -2
  159. package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
  160. package/app/components/panels/inspector/TaskAgentConfig.vue +2 -2
  161. package/app/components/panels/inspector/TaskAprioriBranches.vue +6 -5
  162. package/app/components/panels/inspector/TaskDependencies.vue +1 -1
  163. package/app/components/panels/inspector/TaskEstimateBadge.vue +3 -7
  164. package/app/components/panels/inspector/TaskExecution.vue +13 -12
  165. package/app/components/panels/inspector/TaskRunSettings.vue +35 -38
  166. package/app/components/panels/inspector/TaskStructure.vue +5 -4
  167. package/app/components/pipeline/AgentPromptEditor.vue +15 -14
  168. package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -52
  169. package/app/components/pipeline/EstimateThresholdFields.vue +2 -2
  170. package/app/components/pipeline/GateConfigFields.vue +6 -6
  171. package/app/components/pipeline/IterationCapPrompt.vue +1 -1
  172. package/app/components/pipeline/PipelineBuilder.vue +28 -27
  173. package/app/components/pipeline/PipelineHealthModal.vue +7 -7
  174. package/app/components/pipeline/PipelinePicker.vue +3 -3
  175. package/app/components/pipeline/PipelinePreview.vue +6 -7
  176. package/app/components/pipeline/PipelineProgress.vue +23 -24
  177. package/app/components/prReview/PrReviewWindow.vue +42 -41
  178. package/app/components/providers/AiPresetMismatchDialog.vue +4 -3
  179. package/app/components/providers/AiProviderOnboardingModal.vue +2 -2
  180. package/app/components/providers/ApiKeysSection.vue +7 -6
  181. package/app/components/providers/PersonalSubscriptionSection.vue +4 -3
  182. package/app/components/providers/VendorCredentialsModal.vue +5 -4
  183. package/app/components/provisioning/ProvisioningLogsDrawer.vue +10 -9
  184. package/app/components/ralph/RalphLoopResultView.vue +25 -26
  185. package/app/components/requirements/RequirementsReviewWindow.vue +13 -12
  186. package/app/components/riskPolicy/RiskPolicyPicker.vue +5 -5
  187. package/app/components/riskPolicy/RiskPolicyPreview.vue +16 -15
  188. package/app/components/sandbox/SandboxPanel.vue +21 -20
  189. package/app/components/settings/ApiTokensPanel.vue +1 -1
  190. package/app/components/settings/BudgetSettings.vue +18 -17
  191. package/app/components/settings/CapabilityCredentialsPanel.vue +5 -5
  192. package/app/components/settings/CloudflareHandlerSection.vue +16 -16
  193. package/app/components/settings/ComposeEnvironmentSetupSection.vue +14 -12
  194. package/app/components/settings/ConnectionTestVerdict.vue +1 -1
  195. package/app/components/settings/ConsensusGroupsSection.vue +21 -20
  196. package/app/components/settings/CustomManifestTypeEditor.vue +8 -7
  197. package/app/components/settings/DefaultProvisionTypeSection.vue +5 -5
  198. package/app/components/settings/InfraHandlersConfigurator.vue +14 -15
  199. package/app/components/settings/InfrastructureBackendPicker.vue +2 -2
  200. package/app/components/settings/IssueTrackerPanel.vue +9 -15
  201. package/app/components/settings/KubernetesEngineForm.vue +9 -8
  202. package/app/components/settings/KubernetesEnvironmentForm.vue +4 -3
  203. package/app/components/settings/LocalContainerPoolSettings.vue +2 -2
  204. package/app/components/settings/LocalModelEndpointsPanel.vue +10 -9
  205. package/app/components/settings/MergeClassRulesEditor.vue +6 -5
  206. package/app/components/settings/MergeRolePolicyEditor.vue +13 -12
  207. package/app/components/settings/ModelConfigurationPanel.vue +8 -11
  208. package/app/components/settings/ModelPresetHealthModal.vue +3 -3
  209. package/app/components/settings/ObservabilityConnectionPanel.vue +1 -1
  210. package/app/components/settings/OpenRouterCatalogPanel.vue +6 -5
  211. package/app/components/settings/PackageRegistriesPanel.vue +4 -4
  212. package/app/components/settings/ProviderConnectionTab.vue +5 -4
  213. package/app/components/settings/ProviderManifestEditor.vue +9 -8
  214. package/app/components/settings/ProviderPreferenceEditor.vue +8 -7
  215. package/app/components/settings/RiskPolicyCreateForm.vue +40 -26
  216. package/app/components/settings/RiskPolicyEditorRow.vue +18 -17
  217. package/app/components/settings/RiskPolicyHealthModal.vue +3 -3
  218. package/app/components/settings/RiskPolicyPanel.vue +11 -13
  219. package/app/components/settings/ServiceFragmentDefaultsPanel.vue +5 -4
  220. package/app/components/settings/SharedStacksPanel.vue +5 -5
  221. package/app/components/settings/TaskSourceCard.vue +2 -2
  222. package/app/components/settings/TaskTypeSuppressionsPanel.vue +4 -4
  223. package/app/components/settings/ToolServerChecklist.vue +22 -22
  224. package/app/components/settings/UsageSettings.vue +13 -13
  225. package/app/components/settings/UserSecretsSection.vue +4 -3
  226. package/app/components/settings/WorkspaceMetadataSettings.vue +6 -5
  227. package/app/components/settings/WorkspaceSettingsPanel.vue +72 -58
  228. package/app/components/skills/ReviewSkillQueue.vue +8 -7
  229. package/app/components/skills/SkillLibraryManager.vue +2 -2
  230. package/app/components/slack/SlackPanel.vue +8 -7
  231. package/app/components/spec/ServiceSpecWindow.vue +15 -16
  232. package/app/components/tasks/BugHuntModal.vue +1 -1
  233. package/app/components/tasks/ContextIssuePicker.vue +4 -6
  234. package/app/components/tasks/TaskContextIssues.vue +1 -1
  235. package/app/components/tasks/TaskImportModal.vue +3 -2
  236. package/app/components/tasks/TaskSourceConnectModal.vue +5 -5
  237. package/app/components/testing/TestReportWindow.vue +54 -53
  238. package/app/components/tutorial/TutorialNudge.vue +3 -2
  239. package/app/components/tutorial/TutorialOverlay.vue +3 -2
  240. package/app/components/vcs/GitLabConnect.vue +1 -1
  241. package/app/components/visualConfirm/VisualConfirmationWindow.vue +23 -25
  242. package/app/utils/theme/builtins.ts +7 -1
  243. package/package.json +1 -1
@@ -19,6 +19,7 @@ import {
19
19
  trendMagnitude,
20
20
  } from './ReportsPanel.logic'
21
21
  import ReportsSpendBreakdown from '~/components/panels/ReportsSpendBreakdown.vue'
22
+ import SectionLabel from '~/components/common/SectionLabel.vue'
22
23
 
23
24
  // Reports: cross-cutting usage analytics for the active account — where the spend and the
24
25
  // work actually go. Spend per model and agent kind, spend + run activity per workspace /
@@ -206,7 +207,7 @@ watch(
206
207
  <!-- Filters in ONE row above the charts: window, then board scope. -->
207
208
  <div class="ms-auto flex flex-wrap items-center gap-1.5">
208
209
  <select
209
- class="rounded-lg border border-default bg-default px-2.5 py-1.5 text-[12px] text-default"
210
+ class="rounded-lg border border-default bg-default px-2.5 py-1.5 text-xs text-default"
210
211
  :value="reports.workspaceFilter ?? ''"
211
212
  :aria-label="t('reports.filter.board')"
212
213
  data-testid="reports-board-filter"
@@ -219,7 +220,7 @@ watch(
219
220
  {{ board.name }}
220
221
  </option>
221
222
  </select>
222
- <div class="me-1 flex rounded-lg border border-default p-0.5 text-[12px]">
223
+ <div class="me-1 flex rounded-lg border border-default p-0.5 text-xs">
223
224
  <button
224
225
  v-for="opt in WINDOWS"
225
226
  :key="opt.value"
@@ -277,7 +278,7 @@ watch(
277
278
  </div>
278
279
 
279
280
  <div v-else-if="view" class="mx-auto flex max-w-5xl flex-col gap-6">
280
- <p class="text-[11px] text-dimmed">
281
+ <p class="text-2xs text-dimmed">
281
282
  {{
282
283
  t('reports.period', {
283
284
  from: d(new Date(view.since), 'short'),
@@ -308,7 +309,7 @@ watch(
308
309
  </p>
309
310
  <p
310
311
  v-else-if="rollupState === 'current'"
311
- class="text-[11px] text-dimmed"
312
+ class="text-2xs text-dimmed"
312
313
  data-testid="reports-rollup-current"
313
314
  >
314
315
  {{
@@ -320,9 +321,9 @@ watch(
320
321
 
321
322
  <!-- Headline totals. A stat tile, not a chart: these are single numbers. -->
322
323
  <section>
323
- <h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
324
+ <SectionLabel as="h2" class="mb-2">
324
325
  {{ t('reports.totals.title') }}
325
- </h2>
326
+ </SectionLabel>
326
327
  <div class="grid grid-cols-2 gap-3 sm:grid-cols-4">
327
328
  <div class="rounded-lg border border-default bg-default/40 p-3">
328
329
  <p
@@ -352,16 +353,16 @@ watch(
352
353
  <p class="text-xs text-dimmed">{{ t('reports.totals.tokens') }}</p>
353
354
  </div>
354
355
  </div>
355
- <p class="mt-1.5 text-[10px] text-dimmed">
356
+ <p class="mt-1.5 text-3xs text-dimmed">
356
357
  {{ t('reports.totals.illustrative') }}
357
358
  </p>
358
359
  </section>
359
360
 
360
361
  <!-- Spend over time. One axis, two stacked series, legend always present. -->
361
362
  <section>
362
- <h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
363
+ <SectionLabel as="h2" class="mb-2">
363
364
  {{ t('reports.trend.title') }}
364
- </h2>
365
+ </SectionLabel>
365
366
  <div class="rounded-lg border border-default bg-default/40 p-4">
366
367
  <div v-if="!hasSpend" class="py-6 text-center text-xs text-dimmed">
367
368
  {{ t('reports.trend.empty') }}
@@ -383,7 +384,7 @@ watch(
383
384
  />
384
385
  </div>
385
386
  </div>
386
- <div class="mt-2 flex items-center gap-4 text-[11px] text-dimmed">
387
+ <div class="mt-2 flex items-center gap-4 text-2xs text-dimmed">
387
388
  <span class="flex items-center gap-1" :title="t('reports.legend.meteredHint')">
388
389
  <span class="h-2 w-2 rounded-sm bg-app-secondary-500" />{{
389
390
  t('reports.legend.metered')
@@ -404,9 +405,9 @@ watch(
404
405
  <!-- Spend by model + by agent kind: the two axes a run has no single value for. -->
405
406
  <div class="grid gap-6 md:grid-cols-2">
406
407
  <section>
407
- <h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
408
+ <SectionLabel as="h2" class="mb-2">
408
409
  {{ t('reports.spend.byModel') }}
409
- </h2>
410
+ </SectionLabel>
410
411
  <ReportsSpendBreakdown
411
412
  :rows="view.spend.byModel"
412
413
  :currency="currency"
@@ -415,9 +416,9 @@ watch(
415
416
  />
416
417
  </section>
417
418
  <section>
418
- <h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
419
+ <SectionLabel as="h2" class="mb-2">
419
420
  {{ t('reports.spend.byAgentKind') }}
420
- </h2>
421
+ </SectionLabel>
421
422
  <ReportsSpendBreakdown
422
423
  :rows="view.spend.byAgentKind"
423
424
  :currency="currency"
@@ -434,9 +435,9 @@ watch(
434
435
  breakdowns the projection caps, and each says so under its own card. -->
435
436
  <div class="grid gap-6 md:grid-cols-2">
436
437
  <section>
437
- <h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
438
+ <SectionLabel as="h2" class="mb-2">
438
439
  {{ t('reports.spend.byTicket') }}
439
- </h2>
440
+ </SectionLabel>
440
441
  <ReportsSpendBreakdown
441
442
  :rows="view.spend.byTicket"
442
443
  :currency="currency"
@@ -446,9 +447,9 @@ watch(
446
447
  />
447
448
  </section>
448
449
  <section>
449
- <h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
450
+ <SectionLabel as="h2" class="mb-2">
450
451
  {{ t('reports.spend.byRun') }}
451
- </h2>
452
+ </SectionLabel>
452
453
  <ReportsSpendBreakdown
453
454
  :rows="view.spend.byRun"
454
455
  :currency="currency"
@@ -462,10 +463,10 @@ watch(
462
463
  <!-- The shared axis: spend AND activity for the same grouping, side by side. -->
463
464
  <section class="flex flex-col gap-3">
464
465
  <div class="flex flex-wrap items-center gap-2">
465
- <h2 class="text-xs font-semibold uppercase tracking-wide text-dimmed">
466
+ <SectionLabel as="h2">
466
467
  {{ t('reports.breakdown.title') }}
467
- </h2>
468
- <div class="flex rounded-lg border border-default p-0.5 text-[12px]">
468
+ </SectionLabel>
469
+ <div class="flex rounded-lg border border-default p-0.5 text-xs">
469
470
  <button
470
471
  v-for="opt in DIMENSIONS"
471
472
  :key="opt.value"
@@ -484,7 +485,7 @@ watch(
484
485
  </div>
485
486
  <div class="grid gap-6 md:grid-cols-2">
486
487
  <div>
487
- <h3 class="mb-2 text-[11px] text-dimmed">
488
+ <h3 class="mb-2 text-2xs text-dimmed">
488
489
  {{ t('reports.spend.heading') }}
489
490
  </h3>
490
491
  <ReportsSpendBreakdown
@@ -495,7 +496,7 @@ watch(
495
496
  />
496
497
  </div>
497
498
  <div>
498
- <h3 class="mb-2 text-[11px] text-dimmed">
499
+ <h3 class="mb-2 text-2xs text-dimmed">
499
500
  {{ t('reports.activity.heading') }}
500
501
  </h3>
501
502
  <div class="rounded-lg border border-default bg-default/40 p-4">
@@ -532,7 +533,7 @@ watch(
532
533
  </div>
533
534
  <!-- The status counts in text: the reserved status hues are
534
535
  red-green adjacent, so identity is never colour alone. -->
535
- <p class="mt-1 flex flex-wrap gap-x-2 text-[10px] text-dimmed">
536
+ <p class="mt-1 flex flex-wrap gap-x-2 text-3xs text-dimmed">
536
537
  <span v-for="segment in activitySegments(row)" :key="segment.status">
537
538
  {{ n(segment.count, 'decimal') }} {{ statusLabel(segment.status) }}
538
539
  </span>
@@ -545,7 +546,7 @@ watch(
545
546
  </p>
546
547
  </li>
547
548
  </ul>
548
- <div class="mt-3 flex flex-wrap items-center gap-3 text-[11px] text-dimmed">
549
+ <div class="mt-3 flex flex-wrap items-center gap-3 text-2xs text-dimmed">
549
550
  <span
550
551
  v-for="status in ['done', 'failed', 'running', 'other'] as const"
551
552
  :key="status"
@@ -66,7 +66,7 @@ const max = computed(() => maxOf(props.rows, spendMagnitude))
66
66
  :style="{ width: `${segmentPct(row.subscriptionCost, max)}%` }"
67
67
  />
68
68
  </div>
69
- <p class="mt-1 text-[10px] text-dimmed">
69
+ <p class="mt-1 text-3xs text-dimmed">
70
70
  {{ t('reports.spend.calls', { count: row.calls }, row.calls) }} ·
71
71
  {{
72
72
  t('reports.spend.tokens', {
@@ -77,7 +77,7 @@ const max = computed(() => maxOf(props.rows, spendMagnitude))
77
77
  </p>
78
78
  </li>
79
79
  </ul>
80
- <p v-if="cap" class="mt-3 text-[10px] text-dimmed" :data-testid="`${testId}-capped`">
80
+ <p v-if="cap" class="mt-3 text-3xs text-dimmed" :data-testid="`${testId}-capped`">
81
81
  {{
82
82
  t('reports.spend.capped', { shown: n(cap.returned), omitted: n(cap.omitted) }, cap.omitted)
83
83
  }}
@@ -39,6 +39,7 @@ import {
39
39
  RESULT_WINDOW_WIDTH_CLASS,
40
40
  type ResultWindowWidth,
41
41
  } from '~/components/panels/ResultWindowShell.logic'
42
+ import SectionLabel from '~/components/common/SectionLabel.vue'
42
43
 
43
44
  /** A pipeline step reference — passed by step-result windows to surface the shared
44
45
  * "restart from here" control. `StepRestartControl` self-hides for an off-path open
@@ -68,8 +69,8 @@ const props = withDefaults(
68
69
  * worse, not better.
69
70
  *
70
71
  * The obligation that comes with it: CONTINUOUS PROSE inside a `full` window carries its
71
- * own reading measure (`PROSE_MEASURE_CLASS`, the step reader's own, over the same 13px
72
- * `.reader-prose`), or the width lands as 200-character lines.
72
+ * own reading measure (`PROSE_MEASURE_CLASS`, the step reader's own, over the same
73
+ * `text-sm` `.reader-prose`), or the width lands as 200-character lines.
73
74
  *
74
75
  * The unit that obligation attaches to is the PARAGRAPH, not the section — which is the
75
76
  * distinction to get right, because "a findings list reads better at the full span" is
@@ -289,7 +290,7 @@ const panelClass = computed(() => [
289
290
  </span>
290
291
  <div class="min-w-0 flex-1">
291
292
  <h2 class="truncate text-sm font-semibold text-app-100">{{ title }}</h2>
292
- <p v-if="subtitle" class="truncate text-[11px] text-muted">{{ subtitle }}</p>
293
+ <p v-if="subtitle" class="truncate text-2xs text-muted">{{ subtitle }}</p>
293
294
  </div>
294
295
  <!-- Window-specific header content (status badges, counts). -->
295
296
  <slot name="header-extras" />
@@ -329,16 +330,16 @@ const panelClass = computed(() => [
329
330
  @click="effortOpen = !effortOpen"
330
331
  >
331
332
  <UIcon name="i-lucide-gauge" class="h-3.5 w-3.5 shrink-0 text-muted" />
332
- <span class="text-[11px] font-semibold uppercase tracking-wide text-muted">
333
+ <SectionLabel as="span">
333
334
  {{ t('panels.stepDetail.effort.heading') }}
334
- </span>
335
+ </SectionLabel>
335
336
  <span
336
- class="shrink-0 rounded px-1.5 py-0.5 text-[11px] font-medium tabular-nums"
337
+ class="shrink-0 rounded-sm px-1.5 py-0.5 text-2xs font-medium tabular-nums"
337
338
  :class="chipClass"
338
339
  >
339
340
  {{ t('panels.stepDetail.effort.outOfTen', { value: effortReport.difficulty }) }}
340
341
  </span>
341
- <span v-if="hint" class="min-w-0 flex-1 truncate text-[12px] text-muted">
342
+ <span v-if="hint" class="min-w-0 flex-1 truncate text-xs text-muted">
342
343
  {{ hint }}
343
344
  </span>
344
345
  <UIcon
@@ -371,11 +372,11 @@ const panelClass = computed(() => [
371
372
  class="h-3.5 w-3.5 shrink-0"
372
373
  :class="validationReport.passed ? 'text-app-success-400' : 'text-app-error-400'"
373
374
  />
374
- <span class="text-[11px] font-semibold uppercase tracking-wide text-muted">
375
+ <SectionLabel as="span">
375
376
  {{ t('panels.stepDetail.validation.heading') }}
376
- </span>
377
+ </SectionLabel>
377
378
  <span
378
- class="shrink-0 rounded px-1.5 py-0.5 text-[11px] font-medium tabular-nums"
379
+ class="shrink-0 rounded-sm px-1.5 py-0.5 text-2xs font-medium tabular-nums"
379
380
  :class="
380
381
  validationReport.passed
381
382
  ? 'bg-app-success-500/15 text-app-success-300'
@@ -388,7 +389,7 @@ const panelClass = computed(() => [
388
389
  : t('panels.stepDetail.validation.failed')
389
390
  }}
390
391
  </span>
391
- <span class="min-w-0 flex-1 truncate text-[12px] text-muted">
392
+ <span class="min-w-0 flex-1 truncate text-xs text-muted">
392
393
  {{
393
394
  t('panels.stepDetail.validation.attempts', {
394
395
  attempts: validationReport.attempts,
@@ -427,11 +428,11 @@ const panelClass = computed(() => [
427
428
  class="h-3.5 w-3.5 shrink-0"
428
429
  :class="reproductionKeys!.proven ? 'text-app-success-400' : 'text-app-warning-400'"
429
430
  />
430
- <span class="text-[11px] font-semibold uppercase tracking-wide text-muted">
431
+ <SectionLabel as="span">
431
432
  {{ t('panels.stepDetail.reproduction.heading') }}
432
- </span>
433
+ </SectionLabel>
433
434
  <span
434
- class="shrink-0 rounded px-1.5 py-0.5 text-[11px] font-medium"
435
+ class="shrink-0 rounded-sm px-1.5 py-0.5 text-2xs font-medium"
435
436
  :class="
436
437
  reproductionKeys!.proven
437
438
  ? 'bg-app-success-500/15 text-app-success-300'
@@ -440,7 +441,7 @@ const panelClass = computed(() => [
440
441
  >
441
442
  {{ t(reproductionKeys!.chip) }}
442
443
  </span>
443
- <span class="min-w-0 flex-1 truncate text-[12px] text-muted">
444
+ <span class="min-w-0 flex-1 truncate text-xs text-muted">
444
445
  {{ t(reproductionKeys!.verdict) }}
445
446
  </span>
446
447
  <UIcon
@@ -471,10 +472,10 @@ const panelClass = computed(() => [
471
472
  @click="binaryOutputsOpen = !binaryOutputsOpen"
472
473
  >
473
474
  <UIcon name="i-lucide-image" class="h-3.5 w-3.5 shrink-0 text-muted" />
474
- <span class="text-[11px] font-semibold uppercase tracking-wide text-muted">
475
+ <SectionLabel as="span">
475
476
  {{ t('binaryOutput.heading') }}
476
- </span>
477
- <span class="min-w-0 flex-1 truncate text-[12px] text-muted">
477
+ </SectionLabel>
478
+ <span class="min-w-0 flex-1 truncate text-xs text-muted">
478
479
  {{ binaryOutputSummary }}
479
480
  </span>
480
481
  <UIcon
@@ -25,7 +25,7 @@ const error = computed(() => execution.fullError(props.instanceId))
25
25
  <template>
26
26
  <div
27
27
  v-if="loading || error"
28
- class="flex items-center gap-2 border-b border-default px-4 py-2 text-[11px]"
28
+ class="flex items-center gap-2 border-b border-default px-4 py-2 text-2xs"
29
29
  :class="error ? 'text-app-error-300' : 'text-muted'"
30
30
  data-testid="run-detail-load-state"
31
31
  >
@@ -2,6 +2,7 @@
2
2
  import { computed } from 'vue'
3
3
  import type { PipelineStep, RunContainerStatus } from '~/types/execution'
4
4
  import { containerPhaseLabel } from '~/utils/pipelineRender'
5
+ import SectionLabel from '~/components/common/SectionLabel.vue'
5
6
 
6
7
  // The per-run container lifecycle for a container-backed step: its status (spinning up /
7
8
  // running / errored / reclaimed), the live phase (preparing the checkout vs the agent
@@ -94,7 +95,7 @@ const { copy: copyText } = useCopyToClipboard()
94
95
  live phase (preparing the checkout vs the agent making calls), and the
95
96
  container's id + reachable URL once up. -->
96
97
  <div
97
- class="rounded-lg border px-3 py-2 text-[12px]"
98
+ class="rounded-lg border px-3 py-2 text-xs"
98
99
  :class="CONTAINER_STATUS_META[containerStatus].cls"
99
100
  >
100
101
  <div class="flex items-center gap-2">
@@ -111,10 +112,10 @@ const { copy: copyText } = useCopyToClipboard()
111
112
  </div>
112
113
  <dl v-if="step.container?.id || step.container?.url" class="mt-2 space-y-1">
113
114
  <div v-if="step.container?.id" class="flex items-center gap-2">
114
- <dt class="shrink-0 text-[11px] uppercase tracking-wide text-dimmed">
115
+ <SectionLabel as="dt" class="shrink-0">
115
116
  {{ t('panels.stepMeta.container.id') }}
116
- </dt>
117
- <dd class="truncate font-mono text-[11px] text-toned" :title="step.container.id">
117
+ </SectionLabel>
118
+ <dd class="truncate font-mono text-2xs text-toned" :title="step.container.id">
118
119
  {{ step.container.id }}
119
120
  </dd>
120
121
  <UButton
@@ -129,10 +130,10 @@ const { copy: copyText } = useCopyToClipboard()
129
130
  />
130
131
  </div>
131
132
  <div v-if="step.container?.url" class="flex items-center gap-2">
132
- <dt class="shrink-0 text-[11px] uppercase tracking-wide text-dimmed">
133
+ <SectionLabel as="dt" class="shrink-0">
133
134
  {{ t('panels.stepMeta.container.url') }}
134
- </dt>
135
- <dd class="truncate font-mono text-[11px] text-toned">
135
+ </SectionLabel>
136
+ <dd class="truncate font-mono text-2xs text-toned">
136
137
  <a
137
138
  :href="step.container.url"
138
139
  target="_blank"
@@ -6,6 +6,7 @@ import {
6
6
  externalRunHref,
7
7
  } from './StepDelegatedStatus.logic'
8
8
  import type { PipelineStep } from '~/types/execution'
9
+ import SectionLabel from '~/components/common/SectionLabel.vue'
9
10
 
10
11
  // The EXTERNAL work a delegated step dispatched: which registered executor is running it, what it
11
12
  // is doing, and the link to that system's own logs, which is the affordance everything else here
@@ -77,7 +78,7 @@ const { copy: copyText } = useCopyToClipboard()
77
78
  <!-- Single conditional root so a passed-through `class` (e.g. layout margin) applies cleanly.
78
79
  Renders nothing for a step that dispatched nowhere external. -->
79
80
  <div v-if="record" data-testid="step-delegated-status">
80
- <div class="rounded-lg border px-3 py-2 text-[12px]" :class="statusView.meta.cls">
81
+ <div class="rounded-lg border px-3 py-2 text-xs" :class="statusView.meta.cls">
81
82
  <div class="flex items-center gap-2">
82
83
  <UIcon
83
84
  :name="statusView.meta.icon"
@@ -98,13 +99,13 @@ const { copy: copyText } = useCopyToClipboard()
98
99
  <!-- The PRIMARY affordance: the executor's own logs. It is the only place the detail of
99
100
  what happened exists, which is why a failed delegated step without it is a dead end. -->
100
101
  <div v-if="record.url" class="mt-2 flex items-center gap-2">
101
- <dt class="shrink-0 text-[11px] uppercase tracking-wide text-dimmed">
102
+ <SectionLabel as="dt" class="shrink-0">
102
103
  {{ t('panels.stepMeta.delegated.run') }}
103
- </dt>
104
+ </SectionLabel>
104
105
  <!-- Linked only when the executor's URL is `http(s)`. Anything else is shown as the text
105
106
  it is: refusing to follow it is right, and hiding it would report a run that named
106
107
  no link at all. -->
107
- <dd class="truncate font-mono text-[11px] text-toned">
108
+ <dd class="truncate font-mono text-2xs text-toned">
108
109
  <a
109
110
  v-if="runHref"
110
111
  :href="runHref"
@@ -132,35 +133,35 @@ const { copy: copyText } = useCopyToClipboard()
132
133
  request. Rendered here because the platform holds nothing else about that run's
133
134
  product. -->
134
135
  <div v-if="landedBranch" class="mt-2 flex items-center gap-2">
135
- <dt class="shrink-0 text-[11px] uppercase tracking-wide text-dimmed">
136
+ <SectionLabel as="dt" class="shrink-0">
136
137
  {{ t('panels.stepMeta.delegated.branch') }}
137
- </dt>
138
- <dd class="truncate font-mono text-[11px] text-toned">{{ landedBranch }}</dd>
138
+ </SectionLabel>
139
+ <dd class="truncate font-mono text-2xs text-toned">{{ landedBranch }}</dd>
139
140
  </div>
140
141
 
141
142
  <!-- What the platform could not do, stated rather than left to read as a clean outcome:
142
143
  a cancelled run whose executor declares no cancel is still going. -->
143
- <p v-if="record.note" class="mt-2 text-[11px] text-toned">{{ record.note }}</p>
144
+ <p v-if="record.note" class="mt-2 text-2xs text-toned">{{ record.note }}</p>
144
145
  </div>
145
146
 
146
147
  <!-- "Absent" and "zero" must never render the same. Without this line a delegated step shows
147
148
  no tokens beside a container step that shows some, and the only available reading is that
148
149
  it was free. -->
149
- <p v-if="usageUnreported" class="mt-2 text-[11px] text-dimmed">
150
+ <p v-if="usageUnreported" class="mt-2 text-2xs text-dimmed">
150
151
  {{ t('panels.stepMeta.delegated.usageNotReported', { executor: executorName }) }}
151
152
  </p>
152
153
 
153
154
  <!-- Earlier attempts. Kept across a re-run on purpose: the previous run's logs are the
154
155
  evidence for why this step is being run again, and the platform holds nothing else. -->
155
156
  <div v-if="priorAttempts.length" class="mt-3">
156
- <div class="text-[11px] uppercase tracking-wide text-dimmed">
157
+ <SectionLabel>
157
158
  {{ t('panels.stepMeta.delegated.earlierAttempts') }}
158
- </div>
159
+ </SectionLabel>
159
160
  <ul class="mt-1 space-y-1">
160
161
  <li
161
162
  v-for="(attempt, index) in priorAttempts"
162
163
  :key="`${attempt.startedAt}-${index}`"
163
- class="flex items-center gap-2 text-[11px] text-muted"
164
+ class="flex items-center gap-2 text-2xs text-muted"
164
165
  >
165
166
  <span class="truncate">{{
166
167
  attempt.outcome || t('panels.stepMeta.delegated.noOutcome')
@@ -10,6 +10,7 @@
10
10
  // second one plus a nested border would just be chrome inside chrome.
11
11
  import type { AgentEffortReport } from '~/types/execution'
12
12
  import { effortBand } from '~/utils/effort'
13
+ import SectionLabel from '~/components/common/SectionLabel.vue'
13
14
 
14
15
  const props = withDefaults(
15
16
  defineProps<{ report: AgentEffortReport; variant?: 'card' | 'flat' }>(),
@@ -37,16 +38,13 @@ const difficultyClass = computed(() => BAR_CLASS[effortBand(props.report.difficu
37
38
  variant === 'card' ? 'scroll-mt-4 rounded-xl border border-default bg-default/50 p-4' : ''
38
39
  "
39
40
  >
40
- <div
41
- v-if="variant === 'card'"
42
- class="mb-2 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted"
43
- >
41
+ <SectionLabel v-if="variant === 'card'" class="mb-2 flex items-center gap-1.5">
44
42
  <UIcon name="i-lucide-gauge" class="h-3.5 w-3.5" />
45
43
  <span>{{ t('panels.stepDetail.effort.heading') }}</span>
46
- </div>
44
+ </SectionLabel>
47
45
 
48
46
  <div class="flex items-center gap-2">
49
- <span class="text-[12px] text-toned" :title="t('panels.stepDetail.effort.difficultyHint')">
47
+ <span class="text-xs text-toned" :title="t('panels.stepDetail.effort.difficultyHint')">
50
48
  {{ t('panels.stepDetail.effort.difficulty') }}
51
49
  </span>
52
50
  <div class="h-1.5 flex-1 overflow-hidden rounded-full bg-accented/60">
@@ -58,38 +56,35 @@ const difficultyClass = computed(() => BAR_CLASS[effortBand(props.report.difficu
58
56
  </div>
59
57
  <span
60
58
  data-testid="step-effort-difficulty"
61
- class="text-[12px] font-medium text-default"
59
+ class="text-xs font-medium text-default"
62
60
  :title="t('panels.stepDetail.effort.difficultyHint')"
63
61
  >
64
62
  {{ t('panels.stepDetail.effort.outOfTen', { value: report.difficulty }) }}
65
63
  </span>
66
64
  </div>
67
65
 
68
- <p
69
- v-if="report.summary"
70
- class="mt-2 whitespace-pre-wrap text-[13px] leading-relaxed text-toned"
71
- >
66
+ <p v-if="report.summary" class="mt-2 whitespace-pre-wrap text-sm leading-relaxed text-toned">
72
67
  {{ report.summary }}
73
68
  </p>
74
69
 
75
70
  <div v-if="report.reducedEffectiveness" class="mt-3">
76
- <p class="text-[11px] font-semibold uppercase tracking-wide text-dimmed">
71
+ <SectionLabel as="p">
77
72
  {{ t('panels.stepDetail.effort.reduced') }}
78
- </p>
79
- <p class="mt-0.5 whitespace-pre-wrap text-[12px] text-toned">
73
+ </SectionLabel>
74
+ <p class="mt-0.5 whitespace-pre-wrap text-xs text-toned">
80
75
  {{ report.reducedEffectiveness }}
81
76
  </p>
82
77
  </div>
83
78
 
84
79
  <div v-if="report.obstacles?.length" class="mt-3">
85
- <p class="text-[11px] font-semibold uppercase tracking-wide text-dimmed">
80
+ <SectionLabel as="p">
86
81
  {{ t('panels.stepDetail.effort.obstacles') }}
87
- </p>
82
+ </SectionLabel>
88
83
  <ul class="mt-0.5 space-y-1">
89
84
  <li
90
85
  v-for="(obstacle, i) in report.obstacles"
91
86
  :key="i"
92
- class="flex items-start gap-1.5 text-[12px] text-toned"
87
+ class="flex items-start gap-1.5 text-xs text-toned"
93
88
  >
94
89
  <UIcon
95
90
  name="i-lucide-alert-triangle"
@@ -7,6 +7,7 @@
7
7
  // summary instead (so there is nothing to show here).
8
8
  import type { FragmentAdherence } from '~/types/execution'
9
9
  import MarkdownProse from '~/components/common/MarkdownProse.vue'
10
+ import SectionLabel from '~/components/common/SectionLabel.vue'
10
11
 
11
12
  const props = defineProps<{ items: FragmentAdherence }>()
12
13
  const { t } = useI18n()
@@ -34,14 +35,12 @@ function label(item: FragmentAdherence[number]): string {
34
35
  data-testid="step-fragment-adherence"
35
36
  class="scroll-mt-4 rounded-xl border border-default bg-default/50 p-4"
36
37
  >
37
- <div
38
- class="mb-2 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted"
39
- >
38
+ <SectionLabel class="mb-2 flex items-center gap-1.5">
40
39
  <UIcon name="i-lucide-clipboard-check" class="h-3.5 w-3.5" />
41
40
  <span :title="t('panels.stepDetail.adherence.headingHint')">
42
41
  {{ t('panels.stepDetail.adherence.heading') }}
43
42
  </span>
44
- </div>
43
+ </SectionLabel>
45
44
 
46
45
  <div class="space-y-2.5">
47
46
  <article
@@ -51,7 +50,7 @@ function label(item: FragmentAdherence[number]): string {
51
50
  class="rounded-lg border border-default bg-default/60 px-3 py-2"
52
51
  >
53
52
  <div class="flex items-center gap-2">
54
- <span class="min-w-0 flex-1 truncate text-[13px] font-medium text-app-100">{{
53
+ <span class="min-w-0 flex-1 truncate text-sm font-medium text-app-100">{{
55
54
  label(item)
56
55
  }}</span>
57
56
  <div class="h-1.5 w-16 shrink-0 overflow-hidden rounded-full bg-accented/60">
@@ -62,7 +61,7 @@ function label(item: FragmentAdherence[number]): string {
62
61
  />
63
62
  </div>
64
63
  <span
65
- class="shrink-0 text-[12px] font-medium text-default"
64
+ class="shrink-0 text-xs font-medium text-default"
66
65
  :title="t('panels.stepDetail.adherence.ratingHint')"
67
66
  >
68
67
  {{ t('panels.stepDetail.adherence.outOfTen', { value: item.rating }) }}
@@ -71,17 +70,17 @@ function label(item: FragmentAdherence[number]): string {
71
70
  <MarkdownProse
72
71
  v-if="item.assessment"
73
72
  :text="item.assessment"
74
- class="mt-1 text-[12px] leading-relaxed text-toned"
73
+ class="mt-1 text-xs leading-relaxed text-toned"
75
74
  />
76
75
  <div v-if="item.relatedFindings.length" class="mt-1.5">
77
- <p class="text-[10px] font-semibold uppercase tracking-wide text-dimmed">
76
+ <SectionLabel as="p">
78
77
  {{ t('panels.stepDetail.adherence.relatedFindings') }}
79
- </p>
78
+ </SectionLabel>
80
79
  <ul class="mt-0.5 space-y-0.5">
81
80
  <li
82
81
  v-for="(finding, fi) in item.relatedFindings"
83
82
  :key="fi"
84
- class="flex items-start gap-1.5 text-[11px] text-muted"
83
+ class="flex items-start gap-1.5 text-2xs text-muted"
85
84
  >
86
85
  <UIcon name="i-lucide-dot" class="mt-0.5 h-3.5 w-3.5 shrink-0" />
87
86
  <span>{{ finding }}</span>