@cat-factory/app 0.302.1 → 0.303.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 (328) hide show
  1. package/README.md +16 -0
  2. package/app/app.config.ts +19 -10
  3. package/app/assets/css/main.css +13 -13
  4. package/app/assets/css/prose.css +22 -22
  5. package/app/assets/css/tokens.css +298 -0
  6. package/app/components/assistant/AssistantModal.vue +22 -22
  7. package/app/components/auth/AuthGate.vue +1 -1
  8. package/app/components/auth/BackendMisconfiguredScreen.vue +10 -10
  9. package/app/components/auth/LoginScreen.vue +34 -36
  10. package/app/components/auth/ResetPasswordScreen.vue +12 -12
  11. package/app/components/auth/UserMenu.vue +4 -4
  12. package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +27 -25
  13. package/app/components/binaryOutput/BinaryOutputReport.vue +15 -15
  14. package/app/components/binaryOutput/StoredAssetView.vue +5 -5
  15. package/app/components/board/AddTaskModal.vue +17 -20
  16. package/app/components/board/AgentFailureCard.vue +11 -11
  17. package/app/components/board/AgentFailureHistory.vue +2 -2
  18. package/app/components/board/BoardCanvas.vue +6 -5
  19. package/app/components/board/CreateInitiativeModal.vue +8 -10
  20. package/app/components/board/DependencyConnectOverlay.vue +1 -1
  21. package/app/components/board/FailureHistoryList.vue +7 -7
  22. package/app/components/board/RecurringPipelineModal.vue +17 -17
  23. package/app/components/board/ReviewFrictionDialog.vue +6 -6
  24. package/app/components/board/StepExecutionHistory.vue +13 -13
  25. package/app/components/board/TaskDependencyEdges.vue +8 -8
  26. package/app/components/board/nodes/AgentChip.vue +10 -10
  27. package/app/components/board/nodes/BlockNode.vue +29 -29
  28. package/app/components/board/nodes/DecisionBadge.vue +2 -2
  29. package/app/components/board/nodes/EpicNode.vue +14 -10
  30. package/app/components/board/nodes/FrameSwimlanes.vue +7 -9
  31. package/app/components/board/nodes/InitiativeCard.vue +8 -8
  32. package/app/components/board/nodes/LaneGroup.vue +1 -1
  33. package/app/components/board/nodes/LaneTask.vue +2 -2
  34. package/app/components/board/nodes/ResizeGrips.vue +4 -4
  35. package/app/components/board/nodes/TaskCard.vue +18 -18
  36. package/app/components/board/nodes/TaskLane.vue +5 -5
  37. package/app/components/board/nodes/TaskPipelineMini.vue +18 -18
  38. package/app/components/bootstrap/AdoptionReviewModal.vue +29 -26
  39. package/app/components/bootstrap/BootstrapModal.vue +21 -23
  40. package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
  41. package/app/components/brainstorm/BrainstormWindow.vue +30 -33
  42. package/app/components/bugFishing/BugFishingWindow.vue +49 -49
  43. package/app/components/clarity/ClarityReviewWindow.vue +30 -30
  44. package/app/components/common/AsyncViewError.vue +5 -5
  45. package/app/components/common/ClarificationItem.vue +8 -13
  46. package/app/components/common/ConfirmDialog.vue +4 -2
  47. package/app/components/common/DescriptorFields.vue +1 -1
  48. package/app/components/common/EmptyState.vue +3 -3
  49. package/app/components/common/InterviewGateNotice.vue +7 -7
  50. package/app/components/common/KeyboardShortcutsHelp.vue +1 -1
  51. package/app/components/common/MarkdownProse.vue +14 -13
  52. package/app/components/consensus/ConsensusSessionWindow.vue +26 -26
  53. package/app/components/context/ContextAttachmentFields.vue +17 -17
  54. package/app/components/docs/DocInterviewWindow.vue +14 -14
  55. package/app/components/documents/ContextDocumentPicker.vue +17 -17
  56. package/app/components/documents/DocumentImportModal.vue +7 -7
  57. package/app/components/documents/DocumentSourceConnectModal.vue +3 -3
  58. package/app/components/documents/DocumentSyncState.vue +5 -5
  59. package/app/components/documents/DocumentTemplatesModal.vue +15 -15
  60. package/app/components/documents/RepoContextDocPicker.vue +5 -5
  61. package/app/components/documents/SpawnPreviewModal.vue +12 -12
  62. package/app/components/documents/StartFromDesignModal.vue +11 -11
  63. package/app/components/documents/TaskContextDocs.vue +5 -5
  64. package/app/components/environments/EnvSetupStepper.vue +6 -6
  65. package/app/components/environments/EnvironmentStatusPanel.vue +17 -17
  66. package/app/components/environments/steps/EnvPickStep.vue +3 -3
  67. package/app/components/environments/steps/EnvPreflightStep.vue +9 -9
  68. package/app/components/environments/steps/EnvReviewStep.vue +25 -22
  69. package/app/components/environments/steps/EnvSaveStep.vue +7 -5
  70. package/app/components/environments/steps/JourneyStepNav.vue +1 -1
  71. package/app/components/focus/BlockFocusView.vue +17 -19
  72. package/app/components/followUp/FollowUpWindow.vue +23 -23
  73. package/app/components/forkDecision/ForkDecisionWindow.vue +37 -39
  74. package/app/components/foundational/FoundationalContractSummary.vue +7 -7
  75. package/app/components/foundational/FoundationalServiceCatalogList.vue +11 -11
  76. package/app/components/foundational/FoundationalServiceManager.vue +1 -1
  77. package/app/components/foundational/FoundationalServiceRegistry.vue +13 -13
  78. package/app/components/foundational/FoundationalServiceSources.vue +13 -13
  79. package/app/components/foundational/FoundationalSuppressions.vue +7 -7
  80. package/app/components/foundational/ServiceCatalogConnection.vue +10 -10
  81. package/app/components/fragments/FragmentLibraryManager.vue +41 -44
  82. package/app/components/fragments/FragmentSelector.vue +13 -13
  83. package/app/components/fragments/GitHubDocUrlImport.vue +1 -1
  84. package/app/components/gates/GateFailingCheckList.vue +5 -5
  85. package/app/components/gates/GateResultView.vue +50 -47
  86. package/app/components/github/AddServiceFromRepoModal.vue +14 -14
  87. package/app/components/github/BranchProtectionPreflight.vue +13 -13
  88. package/app/components/github/GitHubConnect.vue +7 -7
  89. package/app/components/github/GitHubOnboarding.vue +7 -7
  90. package/app/components/github/GitHubPanel.vue +37 -40
  91. package/app/components/github/RepoTreeBrowser.vue +18 -18
  92. package/app/components/humanTest/HumanTestWindow.vue +30 -33
  93. package/app/components/initiative/InitiativePlanNotice.vue +5 -5
  94. package/app/components/initiative/InitiativePlanReview.vue +27 -29
  95. package/app/components/initiative/InitiativePlanningWindow.vue +10 -10
  96. package/app/components/initiative/InitiativeTrackerWindow.vue +71 -65
  97. package/app/components/inputGate/InputGateNotice.vue +2 -4
  98. package/app/components/judge/JudgeResultView.vue +30 -32
  99. package/app/components/kaizen/KaizenPanel.vue +40 -36
  100. package/app/components/kaizen/KaizenStepStatus.vue +21 -21
  101. package/app/components/layout/AccountAuditLog.vue +10 -10
  102. package/app/components/layout/AccountDeploymentSettings.vue +20 -20
  103. package/app/components/layout/AccountFailureKindRules.vue +13 -13
  104. package/app/components/layout/AccountFoundationalSettings.vue +1 -1
  105. package/app/components/layout/AccountFragmentSettings.vue +1 -1
  106. package/app/components/layout/AccountModelPolicySettings.vue +9 -9
  107. package/app/components/layout/AccountPlatformAlertSettings.vue +11 -11
  108. package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
  109. package/app/components/layout/AccountRunCredentialSettings.vue +5 -5
  110. package/app/components/layout/AccountSkillSettings.vue +1 -1
  111. package/app/components/layout/AccountTeamSettings.vue +23 -15
  112. package/app/components/layout/AiProvidersBanner.vue +11 -8
  113. package/app/components/layout/AppearanceSwitcher.vue +108 -0
  114. package/app/components/layout/BoardSwitcher.vue +8 -11
  115. package/app/components/layout/BoardToolbar.vue +3 -3
  116. package/app/components/layout/CommandBar.vue +7 -9
  117. package/app/components/layout/ConnectionStatusBanner.vue +2 -2
  118. package/app/components/layout/DefaultTestEnvBanner.vue +5 -5
  119. package/app/components/layout/GitHubPatBanner.vue +5 -5
  120. package/app/components/layout/GitHubPatPermissionsBanner.vue +16 -10
  121. package/app/components/layout/InfraSetupBanner.vue +6 -6
  122. package/app/components/layout/IntegrationsHub.vue +15 -15
  123. package/app/components/layout/LanguageSwitcher.vue +5 -5
  124. package/app/components/layout/ModelProvidersHub.vue +13 -16
  125. package/app/components/layout/NotificationsInbox.vue +10 -10
  126. package/app/components/layout/PersonalSetupModal.vue +8 -8
  127. package/app/components/layout/ProviderConfigBanner.vue +4 -4
  128. package/app/components/layout/RolePrompt.vue +7 -7
  129. package/app/components/layout/SideBar.vue +6 -4
  130. package/app/components/layout/SpendWarningBanner.vue +17 -14
  131. package/app/components/layout/TranslationWarningBanner.vue +4 -4
  132. package/app/components/layout/UiModeSwitcher.vue +13 -13
  133. package/app/components/layout/UiRoleSwitcher.vue +8 -8
  134. package/app/components/layout/WorkspaceMembersSettings.vue +15 -11
  135. package/app/components/media/ArtifactLightbox.vue +13 -13
  136. package/app/components/media/ImageCompare.vue +31 -24
  137. package/app/components/merge/MergeEffortChips.vue +2 -2
  138. package/app/components/notifications/NotificationSettingsPanel.vue +14 -12
  139. package/app/components/observability/OutcomeFilterChips.vue +6 -6
  140. package/app/components/observability/RunFailureSummary.vue +28 -25
  141. package/app/components/observability/StepMetricsBar.vue +26 -28
  142. package/app/components/observability/StepModelActivity.vue +2 -2
  143. package/app/components/observability/ToolCallList.vue +24 -24
  144. package/app/components/outcome/OutcomeSummaryWindow.vue +47 -47
  145. package/app/components/palettes/AgentPalette.vue +8 -8
  146. package/app/components/palettes/AgentTierSelect.vue +1 -1
  147. package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
  148. package/app/components/panels/AgentStepDetail.vue +52 -51
  149. package/app/components/panels/AttemptEntryHeader.vue +4 -6
  150. package/app/components/panels/DecisionModal.vue +7 -7
  151. package/app/components/panels/GenericStructuredResultView.vue +7 -7
  152. package/app/components/panels/InspectorPanel.vue +17 -17
  153. package/app/components/panels/MergerResultView.vue +19 -19
  154. package/app/components/panels/ObservabilityPanel.vue +115 -123
  155. package/app/components/panels/OperatorDashboardPanel.vue +89 -97
  156. package/app/components/panels/ReportsPanel.vue +69 -66
  157. package/app/components/panels/ReportsSpendBreakdown.vue +9 -9
  158. package/app/components/panels/ResultWindowShell.vue +38 -38
  159. package/app/components/panels/RunDetailLoadState.vue +2 -2
  160. package/app/components/panels/StepContainerStatus.vue +9 -9
  161. package/app/components/panels/StepDelegatedStatus.logic.spec.ts +135 -0
  162. package/app/components/panels/StepDelegatedStatus.logic.ts +160 -0
  163. package/app/components/panels/StepDelegatedStatus.vue +181 -0
  164. package/app/components/panels/StepEffortReport.vue +16 -15
  165. package/app/components/panels/StepFragmentAdherence.vue +14 -10
  166. package/app/components/panels/StepMetadataCard.vue +74 -45
  167. package/app/components/panels/StepReproductionReport.vue +25 -21
  168. package/app/components/panels/StepRunMeta.vue +20 -20
  169. package/app/components/panels/StepTestReport.logic.spec.ts +8 -3
  170. package/app/components/panels/StepTestReport.logic.ts +4 -4
  171. package/app/components/panels/StepTestReport.vue +28 -28
  172. package/app/components/panels/StepToolServers.vue +14 -11
  173. package/app/components/panels/StepValidationReport.vue +7 -7
  174. package/app/components/panels/inspector/ContainerSummary.vue +9 -9
  175. package/app/components/panels/inspector/DocReferenceRepos.vue +3 -3
  176. package/app/components/panels/inspector/EnvProbeReport.vue +24 -27
  177. package/app/components/panels/inspector/EpicChildren.vue +8 -12
  178. package/app/components/panels/inspector/FrontendBindingsResolved.vue +11 -11
  179. package/app/components/panels/inspector/FrontendConfig.vue +37 -41
  180. package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
  181. package/app/components/panels/inspector/InspectorSection.vue +6 -6
  182. package/app/components/panels/inspector/RecurringScheduleSettings.vue +16 -19
  183. package/app/components/panels/inspector/ServiceConnections.vue +2 -2
  184. package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
  185. package/app/components/panels/inspector/ServiceSelfTests.vue +21 -17
  186. package/app/components/panels/inspector/ServiceTestConfig.vue +51 -59
  187. package/app/components/panels/inspector/ServiceTestSecrets.vue +5 -5
  188. package/app/components/panels/inspector/ServiceTestingContext.vue +3 -3
  189. package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
  190. package/app/components/panels/inspector/TaskAgentConfig.vue +3 -3
  191. package/app/components/panels/inspector/TaskAprioriBranches.vue +8 -5
  192. package/app/components/panels/inspector/TaskDependencies.vue +1 -1
  193. package/app/components/panels/inspector/TaskEstimateBadge.vue +11 -11
  194. package/app/components/panels/inspector/TaskExecution.vue +17 -17
  195. package/app/components/panels/inspector/TaskReviewTarget.vue +2 -2
  196. package/app/components/panels/inspector/TaskRunSettings.vue +35 -37
  197. package/app/components/panels/inspector/TaskStructure.vue +3 -3
  198. package/app/components/pipeline/AgentKindIcon.vue +1 -1
  199. package/app/components/pipeline/AgentPromptEditor.vue +17 -17
  200. package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -56
  201. package/app/components/pipeline/EstimateThresholdFields.vue +4 -4
  202. package/app/components/pipeline/GateConfigFields.vue +13 -10
  203. package/app/components/pipeline/IterationCapPrompt.vue +4 -2
  204. package/app/components/pipeline/PipelineBuilder.vue +47 -55
  205. package/app/components/pipeline/PipelineHealthModal.vue +27 -29
  206. package/app/components/pipeline/PipelinePicker.vue +10 -10
  207. package/app/components/pipeline/PipelinePreview.vue +10 -10
  208. package/app/components/pipeline/PipelineProgress.vue +64 -67
  209. package/app/components/prReview/PrReviewPhaseBadge.vue +7 -7
  210. package/app/components/prReview/PrReviewWindow.vue +75 -77
  211. package/app/components/providers/AiPresetMismatchDialog.vue +5 -5
  212. package/app/components/providers/AiProviderOnboardingModal.vue +9 -9
  213. package/app/components/providers/ApiKeysSection.vue +13 -13
  214. package/app/components/providers/PersonalCredentialModal.vue +2 -2
  215. package/app/components/providers/PersonalSubscriptionSection.vue +10 -10
  216. package/app/components/providers/SignInRequiredNotice.vue +1 -1
  217. package/app/components/providers/VendorCredentialsModal.vue +10 -10
  218. package/app/components/provisioning/ProvisioningLogsDrawer.vue +13 -13
  219. package/app/components/ralph/RalphLoopResultView.vue +28 -30
  220. package/app/components/recurring/RecurrenceEditor.vue +2 -2
  221. package/app/components/requirements/RequirementsReviewWindow.vue +51 -58
  222. package/app/components/riskPolicy/RiskPolicyPicker.vue +12 -15
  223. package/app/components/riskPolicy/RiskPolicyPreview.vue +14 -14
  224. package/app/components/sandbox/SandboxPanel.vue +58 -59
  225. package/app/components/settings/AccountSettingsPanel.vue +1 -1
  226. package/app/components/settings/ApiTokensPanel.vue +10 -10
  227. package/app/components/settings/BudgetSettings.vue +18 -22
  228. package/app/components/settings/CapabilityCredentialsPanel.vue +15 -15
  229. package/app/components/settings/CloudflareHandlerSection.vue +20 -20
  230. package/app/components/settings/ComposeEnvironmentSetupSection.vue +13 -13
  231. package/app/components/settings/ConnectionTestVerdict.vue +3 -3
  232. package/app/components/settings/ConnectionWarnings.vue +1 -1
  233. package/app/components/settings/ConsensusGroupsSection.vue +27 -35
  234. package/app/components/settings/CustomManifestTypeEditor.vue +10 -10
  235. package/app/components/settings/DefaultProvisionTypeSection.vue +6 -6
  236. package/app/components/settings/InfraHandlersConfigurator.vue +24 -22
  237. package/app/components/settings/InfrastructureBackendPicker.vue +6 -6
  238. package/app/components/settings/InfrastructureWindow.vue +5 -5
  239. package/app/components/settings/IssueTrackerPanel.vue +29 -23
  240. package/app/components/settings/KubernetesEngineForm.vue +11 -11
  241. package/app/components/settings/KubernetesEnvironmentForm.vue +4 -4
  242. package/app/components/settings/LocalContainerPoolSettings.vue +6 -11
  243. package/app/components/settings/LocalModelEndpointsPanel.vue +20 -18
  244. package/app/components/settings/McpAuthorizeScreen.vue +13 -15
  245. package/app/components/settings/McpOAuthCallbackScreen.vue +16 -10
  246. package/app/components/settings/MergeClassRulesEditor.vue +6 -9
  247. package/app/components/settings/MergeRolePolicyEditor.vue +16 -16
  248. package/app/components/settings/ModelConfigurationPanel.vue +23 -30
  249. package/app/components/settings/ModelPresetHealthModal.vue +15 -13
  250. package/app/components/settings/ObservabilityConnectionPanel.vue +4 -4
  251. package/app/components/settings/OpenRouterCatalogPanel.vue +23 -19
  252. package/app/components/settings/PackageRegistriesPanel.vue +8 -8
  253. package/app/components/settings/ProviderConnectionTab.vue +8 -11
  254. package/app/components/settings/ProviderManifestEditor.vue +9 -9
  255. package/app/components/settings/ProviderPreferenceEditor.vue +8 -8
  256. package/app/components/settings/RiskPolicyCreateForm.vue +10 -10
  257. package/app/components/settings/RiskPolicyEditorRow.vue +14 -14
  258. package/app/components/settings/RiskPolicyHealthModal.vue +15 -13
  259. package/app/components/settings/RiskPolicyInheritedRow.vue +1 -1
  260. package/app/components/settings/RiskPolicyPanel.vue +10 -15
  261. package/app/components/settings/ServiceFragmentDefaultsPanel.vue +7 -7
  262. package/app/components/settings/SharedStacksPanel.vue +9 -12
  263. package/app/components/settings/TaskSourceCard.vue +4 -4
  264. package/app/components/settings/TaskTypeSuppressionsPanel.vue +6 -6
  265. package/app/components/settings/ToolServerChecklist.vue +36 -29
  266. package/app/components/settings/UsageSettings.vue +15 -15
  267. package/app/components/settings/UserSecretsSection.vue +9 -12
  268. package/app/components/settings/WorkspaceMetadataSettings.vue +5 -5
  269. package/app/components/settings/WorkspaceSettingsPanel.vue +47 -47
  270. package/app/components/skills/ReviewSkillQueue.vue +10 -10
  271. package/app/components/skills/SkillLibraryManager.vue +23 -20
  272. package/app/components/slack/SlackPanel.vue +13 -17
  273. package/app/components/spec/ServiceSpecWindow.vue +45 -42
  274. package/app/components/tasks/BugHuntModal.vue +24 -27
  275. package/app/components/tasks/ContextIssuePicker.vue +11 -11
  276. package/app/components/tasks/TaskContextIssues.vue +3 -3
  277. package/app/components/tasks/TaskImportModal.vue +7 -7
  278. package/app/components/tasks/TaskSourceConnectModal.vue +10 -8
  279. package/app/components/testing/TestReportWindow.vue +99 -82
  280. package/app/components/theme/ThemeImportModal.vue +115 -0
  281. package/app/components/tutorial/TutorialCatalogue.vue +9 -9
  282. package/app/components/tutorial/TutorialNudge.vue +5 -5
  283. package/app/components/tutorial/TutorialOverlay.vue +12 -12
  284. package/app/components/tutorial/TutorialPrompt.vue +6 -9
  285. package/app/components/vcs/GitLabConnect.vue +4 -4
  286. package/app/components/vcs/VcsConnectSurfaces.vue +2 -2
  287. package/app/components/visualConfirm/VisualConfirmationWindow.vue +36 -36
  288. package/app/composables/api/client.ts +6 -1
  289. package/app/composables/usePipelineErrorToast.ts +17 -0
  290. package/app/modular/agent-kinds.ts +24 -0
  291. package/app/pages/index.vue +5 -5
  292. package/app/plugins/theme.client.ts +125 -0
  293. package/app/spa-loading-template.html +52 -14
  294. package/app/stores/agents.ts +1 -1
  295. package/app/stores/theme.spec.ts +56 -0
  296. package/app/stores/theme.ts +87 -0
  297. package/app/types/domain.ts +19 -0
  298. package/app/types/execution.ts +4 -0
  299. package/app/utils/agentOutput.ts +1 -1
  300. package/app/utils/binaryOutput.ts +6 -6
  301. package/app/utils/bootstrapSteps.ts +14 -14
  302. package/app/utils/catalog.ts +87 -83
  303. package/app/utils/colorTint.ts +10 -0
  304. package/app/utils/failureKinds.ts +1 -0
  305. package/app/utils/observability.ts +3 -3
  306. package/app/utils/pipelineRender.ts +13 -17
  307. package/app/utils/swimlanes.ts +4 -4
  308. package/app/utils/theme/bootPalette.spec.ts +54 -0
  309. package/app/utils/theme/bootPalette.ts +108 -0
  310. package/app/utils/theme/builtins.spec.ts +38 -0
  311. package/app/utils/theme/builtins.ts +55 -0
  312. package/app/utils/theme/css.ts +162 -0
  313. package/app/utils/theme/doc.ts +353 -0
  314. package/app/utils/theme/link.ts +93 -0
  315. package/app/utils/theme/presets.ts +509 -0
  316. package/app/utils/theme/theme.spec.ts +224 -0
  317. package/i18n/locales/de.json +61 -4
  318. package/i18n/locales/en.json +70 -4
  319. package/i18n/locales/es.json +61 -4
  320. package/i18n/locales/fr.json +61 -4
  321. package/i18n/locales/he.json +61 -4
  322. package/i18n/locales/it.json +61 -4
  323. package/i18n/locales/ja.json +61 -4
  324. package/i18n/locales/pl.json +61 -4
  325. package/i18n/locales/tr.json +61 -4
  326. package/i18n/locales/uk.json +61 -4
  327. package/nuxt.config.ts +37 -11
  328. package/package.json +10 -9
@@ -0,0 +1,509 @@
1
+ /**
2
+ * The Nuxt UI theme editor's presets (https://ui.nuxt.com/theme), copied from
3
+ * `docs/app/utils/theme/engine/presets.ts` in nuxt/ui (MIT). The editor collapses a share link
4
+ * whose document is EXACTLY a preset to `{ version: 1, preset: '<id>' }`, so the importer needs
5
+ * these documents to rebuild such a link. They are a DECODE TABLE, not menu entries: the switcher
6
+ * offers the app's built-ins (`builtins.ts`), and a user who wants a preset imports its link.
7
+ * Re-copy when the editor changes a preset; `theme.spec.ts` pins the ids the editor ships today.
8
+ *
9
+ * `icons` is carried for round-tripping and ignored on apply (the app ships one icon set).
10
+ */
11
+ import type { StyleOptions, ThemeDoc } from '~/utils/theme/doc'
12
+
13
+ export interface ThemePreset {
14
+ id: string
15
+ name: string
16
+ description: string
17
+ doc: ThemeDoc
18
+ }
19
+
20
+ /**
21
+ * The five tokens the library pins to white, routed through the neutral ramp
22
+ * the way picking a neutral in the editor does (selectPalette's remaps), so a
23
+ * tinted ramp reaches the page and the export reproduces the preview.
24
+ *
25
+ * The page moving to 50 takes the muted surface with it: the library sits it
26
+ * at 50 too, so it would land ON the page and every muted panel (a code
27
+ * block, a table head) would lose its shape.
28
+ */
29
+ const tintedNeutralBase = {
30
+ '--ui-bg': { light: 50 },
31
+ '--ui-bg-muted': { light: 100 },
32
+ '--ui-text-inverted': { light: 50 },
33
+ '--ui-text-highlighted': { dark: 50 },
34
+ '--ui-bg-inverted': { dark: 50 },
35
+ '--ui-border-inverted': { dark: 50 },
36
+ } satisfies StyleOptions['tokenShades']
37
+
38
+ /**
39
+ * A fresh copy per preset. `deriveStyle` puts these objects straight into
40
+ * reactive editor state, so a spread would hand six presets the same
41
+ * per-token object and one in-place write would corrupt all of them.
42
+ */
43
+ const tintedNeutral = () => structuredClone(tintedNeutralBase)
44
+
45
+ /**
46
+ * Presets are plain ThemeDocs: applying one replaces the current document.
47
+ */
48
+ export const presets: ThemePreset[] = [
49
+ {
50
+ id: 'default',
51
+ name: 'Default',
52
+ description: 'The stock theme, everything inherited.',
53
+ doc: {
54
+ version: 1,
55
+ },
56
+ },
57
+ {
58
+ id: 'mono',
59
+ name: 'Mono',
60
+ description: 'Black on a pure gray neutral, generous radius, quiet surfaces.',
61
+ doc: {
62
+ version: 1,
63
+ blackAsPrimary: true,
64
+ colors: {
65
+ neutral: 'neutral',
66
+ },
67
+ radius: 0.5,
68
+ font: { sans: 'Geist', mono: 'Geist Mono' },
69
+ style: {
70
+ defaults: {
71
+ variants: {
72
+ inputs: 'subtle',
73
+ },
74
+ },
75
+ tokenShades: {
76
+ '--ui-bg': { dark: 950 },
77
+ '--ui-bg-muted': { light: 100, dark: 900 },
78
+ '--ui-bg-elevated': { light: 100, dark: 900 },
79
+ '--ui-bg-accented': { light: 200, dark: 800 },
80
+ '--ui-text': { light: 900, dark: 100 },
81
+ '--ui-text-highlighted': { light: 950, dark: 50 },
82
+ },
83
+ },
84
+ },
85
+ },
86
+ {
87
+ id: 'cobalt',
88
+ name: 'Cobalt',
89
+ description: 'Utility blue on cool grays, tight corners, flat bordered surfaces.',
90
+ doc: {
91
+ version: 1,
92
+ // Prefixed names: a palette named plainly 'blue'/'gray' would override
93
+ // the same-named tailwind ramp app-wide while active.
94
+ palettes: {
95
+ cobalt: {
96
+ shades: {
97
+ 50: 'oklch(95.3% 0.022 260.723)',
98
+ 100: 'oklch(90.8% 0.045 258.763)',
99
+ 200: 'oklch(81.6% 0.091 257.776)',
100
+ 300: 'oklch(72.9% 0.14 258.068)',
101
+ 400: 'oklch(64.7% 0.186 258.256)',
102
+ 500: 'oklch(57.8% 0.228 260.025)',
103
+ 600: 'oklch(49.2% 0.19 259.799)',
104
+ 700: 'oklch(40.2% 0.152 259.656)',
105
+ 800: 'oklch(30.7% 0.109 258.934)',
106
+ 900: 'oklch(20.4% 0.063 257.52)',
107
+ 950: 'oklch(14.7% 0.037 249.929)',
108
+ },
109
+ },
110
+ // A flat cool gray, its mid stops lighter than tailwind's so borders
111
+ // and muted text stay soft against the tinted page.
112
+ 'cobalt-gray': {
113
+ shades: {
114
+ 50: 'oklch(99.1% 0 0)',
115
+ 100: 'oklch(98.2% 0.002 247.839)',
116
+ 200: 'oklch(94.2% 0.005 247.879)',
117
+ 300: 'oklch(91.1% 0.007 247.901)',
118
+ 400: 'oklch(86.7% 0.011 247.949)',
119
+ 500: 'oklch(76.9% 0.015 248.017)',
120
+ 600: 'oklch(55.8% 0.016 244.893)',
121
+ 700: 'oklch(42.8% 0.015 248.172)',
122
+ 800: 'oklch(34.5% 0.013 248.212)',
123
+ 900: 'oklch(26.2% 0.009 248.19)',
124
+ 950: 'oklch(20.7% 0.008 248.192)',
125
+ },
126
+ },
127
+ },
128
+ // The gray ramp serves as secondary too: a muted second button colour.
129
+ colors: {
130
+ primary: 'cobalt',
131
+ secondary: 'cobalt-gray',
132
+ info: 'cyan',
133
+ warning: 'amber',
134
+ neutral: 'cobalt-gray',
135
+ },
136
+ radius: 0.125,
137
+ // a point under stock, utility UIs run dense
138
+ fontSize: 15,
139
+ font: { sans: 'Roboto' },
140
+ icons: 'bootstrap',
141
+ // Light rides the gray ramp one step deeper than stock.
142
+ tokens: {
143
+ light: {
144
+ '--ui-secondary': 'var(--ui-color-secondary-600)',
145
+ '--ui-bg-muted': 'var(--ui-color-neutral-200)',
146
+ '--ui-text': 'var(--ui-color-neutral-800)',
147
+ '--ui-border': 'var(--ui-color-neutral-400)',
148
+ '--ui-border-muted': 'var(--ui-color-neutral-300)',
149
+ '--ui-bg': 'var(--ui-color-neutral-100)',
150
+ '--ui-text-toned': 'var(--ui-color-neutral-700)',
151
+ '--ui-text-muted': 'var(--ui-color-neutral-600)',
152
+ '--ui-text-dimmed': 'var(--ui-color-neutral-600)',
153
+ '--ui-bg-elevated': 'var(--ui-color-neutral-200)',
154
+ '--ui-bg-accented': 'var(--ui-color-neutral-300)',
155
+ },
156
+ // Dark keeps the same brand colours rather than lifting to the 400s.
157
+ dark: {
158
+ '--ui-primary': 'var(--ui-color-primary-500)',
159
+ '--ui-secondary': 'var(--ui-color-secondary-500)',
160
+ '--ui-success': 'var(--ui-color-success-500)',
161
+ '--ui-info': 'var(--ui-color-info-500)',
162
+ '--ui-warning': 'var(--ui-color-warning-500)',
163
+ '--ui-error': 'var(--ui-color-error-500)',
164
+ '--ui-bg-muted': 'var(--ui-color-neutral-700)',
165
+ '--ui-text': 'var(--ui-color-neutral-300)',
166
+ },
167
+ },
168
+ },
169
+ },
170
+ {
171
+ id: 'sky',
172
+ name: 'Sky',
173
+ description: 'Sky blue on a mist neutral, pastel fills everywhere, airy type.',
174
+ doc: {
175
+ version: 1,
176
+ colors: {
177
+ primary: 'sky',
178
+ neutral: 'mist',
179
+ },
180
+ radius: 0.75,
181
+ font: { sans: 'Figtree', lineHeight: 1.6 },
182
+ style: {
183
+ // nothing solid anywhere: one app-wide pastel fill
184
+ defaults: { variants: { buttons: 'soft', inputs: 'soft' } },
185
+ tokenShades: tintedNeutral(),
186
+ },
187
+ },
188
+ },
189
+ {
190
+ id: 'mint',
191
+ name: 'Mint',
192
+ description:
193
+ 'Teal on an olive neutral, pill buttons and fields, chunky rounded type, large controls.',
194
+ doc: {
195
+ version: 1,
196
+ colors: {
197
+ primary: 'teal',
198
+ neutral: 'olive',
199
+ },
200
+ radius: 0.75,
201
+ // a step heavier across the ladder, Nunito reads thin at stock weights
202
+ font: { sans: 'Nunito', weights: { normal: 500, medium: 600, semibold: 700, bold: 800 } },
203
+ icons: 'iconoir',
204
+ style: {
205
+ defaults: { size: 'lg', variants: { inputs: 'soft' } },
206
+ tokenShades: tintedNeutral(),
207
+ },
208
+ // the radius ladder stops at 0.75rem, the pill has to come from the slots
209
+ components: {
210
+ button: { slots: { base: 'rounded-full' } },
211
+ input: { slots: { base: 'rounded-full' } },
212
+ select: { slots: { base: 'rounded-full' } },
213
+ selectMenu: { slots: { base: 'rounded-full' } },
214
+ inputMenu: { slots: { base: 'rounded-full' } },
215
+ },
216
+ },
217
+ },
218
+ {
219
+ id: 'iris',
220
+ name: 'Iris',
221
+ description: 'Violet outlines on a mauve neutral, fuchsia secondary, tinted fields.',
222
+ doc: {
223
+ version: 1,
224
+ colors: {
225
+ primary: 'violet',
226
+ secondary: 'fuchsia',
227
+ neutral: 'mauve',
228
+ },
229
+ radius: 0.5,
230
+ font: { sans: 'Manrope', letterSpacing: -0.01 },
231
+ icons: 'remix',
232
+ style: {
233
+ // the violet stays a line: outlined actions over tinted fields
234
+ defaults: { variants: { buttons: 'outline', inputs: 'subtle' } },
235
+ tokenShades: tintedNeutral(),
236
+ },
237
+ },
238
+ },
239
+ {
240
+ id: 'crimson',
241
+ name: 'Crimson',
242
+ description: 'Cinema red on pure gray, square corners, filled fields, near-black in dark mode.',
243
+ doc: {
244
+ version: 1,
245
+ colors: {
246
+ primary: 'red',
247
+ neutral: 'neutral',
248
+ },
249
+ radius: 0,
250
+ font: { sans: 'Inter', weights: { semibold: 700, bold: 800 } },
251
+ icons: 'material',
252
+ style: {
253
+ defaults: { variants: { inputs: 'soft' } },
254
+ tokenShades: {
255
+ ...tintedNeutral(),
256
+ // 600 is the deep cinema red, 500 leans orange; dark holds it rather
257
+ // than lifting to the salmon 400
258
+ '--ui-primary': { light: 600, dark: 500 },
259
+ '--ui-bg': { light: 50, dark: 950 },
260
+ // light restates tintedNeutral's step: this key replaces it wholesale
261
+ '--ui-bg-muted': { light: 100, dark: 900 },
262
+ '--ui-bg-elevated': { dark: 900 },
263
+ '--ui-bg-accented': { dark: 800 },
264
+ },
265
+ },
266
+ },
267
+ },
268
+ {
269
+ id: 'coral',
270
+ name: 'Coral',
271
+ description:
272
+ 'Rose on warm stone, cards floating on shadows, teal for success, neutral focus rings.',
273
+ doc: {
274
+ version: 1,
275
+ colors: {
276
+ primary: 'rose',
277
+ success: 'teal',
278
+ neutral: 'stone',
279
+ },
280
+ radius: 0.5,
281
+ font: { sans: 'Plus Jakarta Sans' },
282
+ icons: 'phosphor',
283
+ style: {
284
+ // fields ring in neutral, the rose stays on actions
285
+ defaults: { colors: { inputs: 'neutral' } },
286
+ tokenShades: tintedNeutral(),
287
+ },
288
+ components: {
289
+ // Cards float on a shadow instead of sitting in a ring. Dark keeps the
290
+ // ring, a shadow has nothing to fall on there. A compound entry rather
291
+ // than the slot: the variant's own `ring` lands after the slot string
292
+ // and would win the merge.
293
+ card: {
294
+ compoundVariants: [
295
+ { variant: 'outline', class: { root: 'ring-0 dark:ring shadow-xl shadow-black/5' } },
296
+ ],
297
+ },
298
+ },
299
+ },
300
+ },
301
+ {
302
+ id: 'sunset',
303
+ name: 'Sunset',
304
+ description:
305
+ 'Orange on a warm taupe neutral, glowing actions, yellow secondary, subtle panels.',
306
+ doc: {
307
+ version: 1,
308
+ colors: {
309
+ primary: 'orange',
310
+ secondary: 'yellow',
311
+ neutral: 'taupe',
312
+ },
313
+ radius: 0.625,
314
+ font: { sans: 'Bricolage Grotesque' },
315
+ icons: 'tabler',
316
+ style: {
317
+ defaults: { variants: { panels: 'subtle' } },
318
+ tokenShades: {
319
+ ...tintedNeutral(),
320
+ // orange-500 is too light to carry white text, 600 is the burnt stop
321
+ '--ui-primary': { light: 600 },
322
+ },
323
+ },
324
+ components: {
325
+ // solid primary actions cast a warm glow
326
+ button: {
327
+ compoundVariants: [
328
+ { color: 'primary', variant: 'solid', class: 'shadow-md shadow-primary/30' },
329
+ ],
330
+ },
331
+ },
332
+ },
333
+ },
334
+ {
335
+ id: 'carbon',
336
+ name: 'Carbon',
337
+ description: 'Amber on a warm carbon neutral, with ink-dark borders throughout.',
338
+ doc: {
339
+ version: 1,
340
+ // Sculpted warm neutral: lilac-tinted paper into pure carbon.
341
+ palettes: {
342
+ carbon: {
343
+ shades: {
344
+ 50: 'oklch(98.5% 0.017 447.457)',
345
+ 100: 'oklch(95.9% 0.036 438.639)',
346
+ 200: 'oklch(92.6% 0.054 428.8)',
347
+ 300: 'oklch(87% 0.053 417.734)',
348
+ 400: 'oklch(70.5% 0.032 405.184)',
349
+ 500: 'oklch(55.3% 0.014 390.836)',
350
+ 600: 'oklch(44.7% 0.001 374.343)',
351
+ 700: 'oklch(35.9% 0 0)',
352
+ 800: 'oklch(28% 0 0)',
353
+ 900: 'oklch(20.8% 0 0)',
354
+ 950: 'oklch(14.1% 0.005 285.805)',
355
+ },
356
+ },
357
+ },
358
+ colors: {
359
+ primary: 'amber',
360
+ secondary: 'yellow',
361
+ neutral: 'carbon',
362
+ },
363
+ radius: 0.5,
364
+ font: { sans: 'Outfit' },
365
+ icons: 'tabler',
366
+ style: {
367
+ defaults: { variants: { buttons: 'solid', panels: 'subtle', inputs: 'subtle' } },
368
+ tokenShades: {
369
+ '--ui-bg': { light: 50, dark: 800 },
370
+ '--ui-bg-muted': { light: 300, dark: 700 },
371
+ '--ui-bg-elevated': { light: 300, dark: 700 },
372
+ '--ui-bg-accented': { light: 400, dark: 600 },
373
+ '--ui-bg-inverted': { light: 900, dark: 50 },
374
+ '--ui-text-inverted': { light: 50 },
375
+ '--ui-text-dimmed': { light: 500, dark: 400 },
376
+ '--ui-text-muted': { light: 800, dark: 300 },
377
+ '--ui-text-toned': { light: 900 },
378
+ '--ui-text': { light: 900 },
379
+ '--ui-text-highlighted': { light: 950, dark: 100 },
380
+ // Light keeps the ink hairline; dark has to run the other way, a
381
+ // border below the surface's own lightness just reads as a seam.
382
+ '--ui-border': { light: 950, dark: 600 },
383
+ // dark is left at the library's own neutral-700, restating it would
384
+ // only add a line the importer then has to recognise as generated
385
+ '--ui-border-muted': { light: 400 },
386
+ '--ui-border-accented': { light: 950, dark: 500 },
387
+ '--ui-border-inverted': { light: 500, dark: 50 },
388
+ },
389
+ },
390
+ },
391
+ },
392
+ {
393
+ id: 'bubblegum',
394
+ name: 'Bubblegum',
395
+ description: 'Pastel pink softness with mauve-tinted grays.',
396
+ doc: {
397
+ version: 1,
398
+ // Sculpted pink-mauve neutral, chroma peaks mid-ramp.
399
+ palettes: {
400
+ 'saturated-mauve': {
401
+ shades: {
402
+ 50: 'oklch(96.1% 0.021 325.68)',
403
+ 100: 'oklch(92.4% 0.039 325.829)',
404
+ 200: 'oklch(88% 0.057 325.83)',
405
+ 300: 'oklch(81.2% 0.073 325.398)',
406
+ 400: 'oklch(66.1% 0.084 323.292)',
407
+ 500: 'oklch(52.4% 0.079 322.443)',
408
+ 600: 'oklch(42.7% 0.064 322.128)',
409
+ 700: 'oklch(34.6% 0.048 322.004)',
410
+ 800: 'oklch(27.4% 0.034 321.983)',
411
+ 900: 'oklch(20.7% 0.02 322.028)',
412
+ 950: 'oklch(14.5% 0.008 322.12)',
413
+ },
414
+ },
415
+ },
416
+ colors: {
417
+ primary: 'pink',
418
+ secondary: 'violet',
419
+ neutral: 'saturated-mauve',
420
+ },
421
+ radius: 0.375,
422
+ font: { sans: 'Poppins' },
423
+ icons: 'phosphor',
424
+ tokens: {
425
+ light: {
426
+ '--ui-bg': 'var(--ui-color-neutral-50)',
427
+ '--ui-text-inverted': 'var(--ui-color-neutral-50)',
428
+ '--ui-bg-muted': 'var(--ui-color-neutral-100)',
429
+ },
430
+ dark: {
431
+ '--ui-bg-inverted': 'var(--ui-color-neutral-50)',
432
+ '--ui-text-highlighted': 'var(--ui-color-neutral-50)',
433
+ '--ui-border-inverted': 'var(--ui-color-neutral-50)',
434
+ },
435
+ },
436
+ },
437
+ },
438
+ {
439
+ id: 'parchment',
440
+ name: 'Parchment',
441
+ description: 'Warm parchment neutrals with a book-cloth clay primary.',
442
+ doc: {
443
+ version: 1,
444
+ palettes: {
445
+ // Book-cloth clay: the 500 anchors the ramp, the rest is fitted around it.
446
+ clay: {
447
+ shades: {
448
+ 50: 'oklch(97.4% 0.009 48.308)',
449
+ 100: 'oklch(94.2% 0.019 52.207)',
450
+ 200: 'oklch(88.5% 0.036 51.142)',
451
+ 300: 'oklch(82.1% 0.058 50.392)',
452
+ 400: 'oklch(74.1% 0.094 47.255)',
453
+ 500: 'oklch(67.2% 0.131 38.798)',
454
+ 600: 'oklch(58.9% 0.138 37.63)',
455
+ 700: 'oklch(51.4% 0.123 37.45)',
456
+ 800: 'oklch(44.4% 0.103 36.916)',
457
+ 900: 'oklch(38.8% 0.086 36.46)',
458
+ 950: 'oklch(25.9% 0.054 38.197)',
459
+ },
460
+ },
461
+ // Warm paper grays, the light end is cream rather than white: the page
462
+ // sits at 100, its surfaces a step below.
463
+ parchment: {
464
+ shades: {
465
+ 50: 'oklch(98% 0.006 100)',
466
+ 100: 'oklch(96.5% 0.011 99)',
467
+ 200: 'oklch(93.6% 0.014 97.348)',
468
+ 300: 'oklch(85.8% 0.018 100)',
469
+ 400: 'oklch(72.1% 0.015 102.54)',
470
+ 500: 'oklch(57.8% 0.008 88.877)',
471
+ 600: 'oklch(43.2% 0.006 91.526)',
472
+ 700: 'oklch(38.2% 0.003 84.572)',
473
+ 800: 'oklch(29.3% 0.003 106.588)',
474
+ 900: 'oklch(21.7% 0.002 106.561)',
475
+ 950: 'oklch(14.6% 0 0)',
476
+ },
477
+ },
478
+ },
479
+ colors: {
480
+ primary: 'clay',
481
+ neutral: 'parchment',
482
+ },
483
+ radius: 0.375,
484
+ font: { sans: 'DM Sans', serif: 'Source Serif 4' },
485
+ icons: 'heroicons',
486
+ // Surfaces and borders stepped one deeper to hold on the tinted cream
487
+ // page. Elevated has to stay below the page: the library's hover and
488
+ // highlight tints are bg-elevated at half opacity, a lighter elevated
489
+ // vanishes into it.
490
+ tokens: {
491
+ light: {
492
+ '--ui-bg': 'var(--ui-color-neutral-100)',
493
+ '--ui-bg-muted': 'var(--ui-color-neutral-200)',
494
+ '--ui-bg-elevated': 'var(--ui-color-neutral-200)',
495
+ '--ui-bg-accented': 'var(--ui-color-neutral-300)',
496
+ '--ui-border': 'var(--ui-color-neutral-300)',
497
+ // the library leaves this at 200, where the muted surface now sits:
498
+ // a code block's frame would land on its own background
499
+ '--ui-border-muted': 'var(--ui-color-neutral-300)',
500
+ '--ui-border-accented': 'var(--ui-color-neutral-400)',
501
+ },
502
+ dark: {
503
+ '--ui-primary': 'var(--ui-color-primary-500)',
504
+ '--ui-bg-accented': 'var(--ui-color-neutral-800)',
505
+ },
506
+ },
507
+ },
508
+ },
509
+ ] satisfies ThemePreset[]