@cat-factory/app 0.302.2 → 0.303.1
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.
- package/README.md +99 -14
- package/app/app.config.ts +19 -10
- package/app/assets/css/main.css +13 -13
- package/app/assets/css/prose.css +22 -22
- package/app/assets/css/tokens.css +298 -0
- package/app/components/assistant/AssistantModal.vue +22 -22
- package/app/components/auth/AuthGate.vue +1 -1
- package/app/components/auth/BackendMisconfiguredScreen.vue +10 -10
- package/app/components/auth/LoginScreen.vue +34 -36
- package/app/components/auth/ResetPasswordScreen.vue +12 -12
- package/app/components/auth/UserMenu.vue +4 -4
- package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +27 -25
- package/app/components/binaryOutput/BinaryOutputReport.vue +15 -15
- package/app/components/binaryOutput/StoredAssetView.vue +5 -5
- package/app/components/board/AddTaskModal.vue +17 -20
- package/app/components/board/AgentFailureCard.vue +11 -11
- package/app/components/board/AgentFailureHistory.vue +2 -2
- package/app/components/board/BoardCanvas.vue +6 -5
- package/app/components/board/CreateInitiativeModal.vue +8 -10
- package/app/components/board/DependencyConnectOverlay.vue +1 -1
- package/app/components/board/FailureHistoryList.vue +7 -7
- package/app/components/board/RecurringPipelineModal.vue +17 -17
- package/app/components/board/ReviewFrictionDialog.vue +6 -6
- package/app/components/board/StepExecutionHistory.vue +13 -13
- package/app/components/board/TaskDependencyEdges.vue +8 -8
- package/app/components/board/nodes/AgentChip.vue +10 -10
- package/app/components/board/nodes/BlockNode.vue +29 -29
- package/app/components/board/nodes/DecisionBadge.vue +2 -2
- package/app/components/board/nodes/EpicNode.vue +14 -10
- package/app/components/board/nodes/FrameSwimlanes.vue +7 -9
- package/app/components/board/nodes/InitiativeCard.vue +8 -8
- package/app/components/board/nodes/LaneGroup.vue +1 -1
- package/app/components/board/nodes/LaneTask.vue +2 -2
- package/app/components/board/nodes/ResizeGrips.vue +4 -4
- package/app/components/board/nodes/TaskCard.vue +18 -18
- package/app/components/board/nodes/TaskLane.vue +5 -5
- package/app/components/board/nodes/TaskPipelineMini.vue +18 -18
- package/app/components/bootstrap/AdoptionReviewModal.vue +29 -26
- package/app/components/bootstrap/BootstrapModal.vue +21 -23
- package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
- package/app/components/brainstorm/BrainstormWindow.vue +30 -33
- package/app/components/bugFishing/BugFishingWindow.vue +49 -49
- package/app/components/clarity/ClarityReviewWindow.vue +30 -30
- package/app/components/common/AsyncViewError.vue +5 -5
- package/app/components/common/ClarificationItem.vue +8 -13
- package/app/components/common/ConfirmDialog.vue +4 -2
- package/app/components/common/DescriptorFields.vue +1 -1
- package/app/components/common/EmptyState.vue +3 -3
- package/app/components/common/InterviewGateNotice.vue +7 -7
- package/app/components/common/KeyboardShortcutsHelp.vue +1 -1
- package/app/components/common/MarkdownProse.vue +14 -13
- package/app/components/consensus/ConsensusSessionWindow.vue +26 -26
- package/app/components/context/ContextAttachmentFields.vue +17 -17
- package/app/components/docs/DocInterviewWindow.vue +14 -14
- package/app/components/documents/ContextDocumentPicker.vue +17 -17
- package/app/components/documents/DocumentImportModal.vue +7 -7
- package/app/components/documents/DocumentSourceConnectModal.vue +3 -3
- package/app/components/documents/DocumentSyncState.vue +5 -5
- package/app/components/documents/DocumentTemplatesModal.vue +15 -15
- package/app/components/documents/RepoContextDocPicker.vue +5 -5
- package/app/components/documents/SpawnPreviewModal.vue +12 -12
- package/app/components/documents/StartFromDesignModal.vue +11 -11
- package/app/components/documents/TaskContextDocs.vue +5 -5
- package/app/components/environments/EnvSetupStepper.vue +6 -6
- package/app/components/environments/EnvironmentStatusPanel.vue +17 -17
- package/app/components/environments/steps/EnvPickStep.vue +3 -3
- package/app/components/environments/steps/EnvPreflightStep.vue +9 -9
- package/app/components/environments/steps/EnvReviewStep.vue +25 -22
- package/app/components/environments/steps/EnvSaveStep.vue +7 -5
- package/app/components/environments/steps/JourneyStepNav.vue +1 -1
- package/app/components/focus/BlockFocusView.vue +17 -19
- package/app/components/followUp/FollowUpWindow.vue +23 -23
- package/app/components/forkDecision/ForkDecisionWindow.vue +37 -39
- package/app/components/foundational/FoundationalContractSummary.vue +7 -7
- package/app/components/foundational/FoundationalServiceCatalogList.vue +11 -11
- package/app/components/foundational/FoundationalServiceManager.vue +1 -1
- package/app/components/foundational/FoundationalServiceRegistry.vue +13 -13
- package/app/components/foundational/FoundationalServiceSources.vue +13 -13
- package/app/components/foundational/FoundationalSuppressions.vue +7 -7
- package/app/components/foundational/ServiceCatalogConnection.vue +10 -10
- package/app/components/fragments/FragmentLibraryManager.vue +41 -44
- package/app/components/fragments/FragmentSelector.vue +13 -13
- package/app/components/fragments/GitHubDocUrlImport.vue +1 -1
- package/app/components/gates/GateFailingCheckList.vue +5 -5
- package/app/components/gates/GateResultView.vue +50 -47
- package/app/components/github/AddServiceFromRepoModal.vue +14 -14
- package/app/components/github/BranchProtectionPreflight.vue +13 -13
- package/app/components/github/GitHubConnect.vue +7 -7
- package/app/components/github/GitHubOnboarding.vue +7 -7
- package/app/components/github/GitHubPanel.vue +37 -40
- package/app/components/github/RepoTreeBrowser.vue +18 -18
- package/app/components/humanTest/HumanTestWindow.vue +30 -33
- package/app/components/initiative/InitiativePlanNotice.vue +5 -5
- package/app/components/initiative/InitiativePlanReview.vue +27 -29
- package/app/components/initiative/InitiativePlanningWindow.vue +10 -10
- package/app/components/initiative/InitiativeTrackerWindow.vue +71 -65
- package/app/components/inputGate/InputGateNotice.vue +2 -4
- package/app/components/judge/JudgeResultView.vue +30 -32
- package/app/components/kaizen/KaizenPanel.vue +40 -36
- package/app/components/kaizen/KaizenStepStatus.vue +21 -21
- package/app/components/layout/AccountAuditLog.vue +10 -10
- package/app/components/layout/AccountDeploymentSettings.vue +20 -20
- package/app/components/layout/AccountFailureKindRules.vue +13 -13
- package/app/components/layout/AccountFoundationalSettings.vue +1 -1
- package/app/components/layout/AccountFragmentSettings.vue +1 -1
- package/app/components/layout/AccountModelPolicySettings.vue +9 -9
- package/app/components/layout/AccountPlatformAlertSettings.vue +11 -11
- package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
- package/app/components/layout/AccountRunCredentialSettings.vue +5 -5
- package/app/components/layout/AccountSkillSettings.vue +1 -1
- package/app/components/layout/AccountTeamSettings.vue +23 -15
- package/app/components/layout/AiProvidersBanner.vue +11 -8
- package/app/components/layout/AppearanceSwitcher.vue +108 -0
- package/app/components/layout/BoardSwitcher.vue +8 -11
- package/app/components/layout/BoardToolbar.vue +3 -3
- package/app/components/layout/CommandBar.vue +7 -9
- package/app/components/layout/ConnectionStatusBanner.vue +2 -2
- package/app/components/layout/DefaultTestEnvBanner.vue +5 -5
- package/app/components/layout/GitHubPatBanner.vue +5 -5
- package/app/components/layout/GitHubPatPermissionsBanner.vue +16 -10
- package/app/components/layout/InfraSetupBanner.vue +6 -6
- package/app/components/layout/IntegrationsHub.vue +15 -15
- package/app/components/layout/LanguageSwitcher.vue +5 -5
- package/app/components/layout/ModelProvidersHub.vue +13 -16
- package/app/components/layout/NotificationsInbox.vue +10 -10
- package/app/components/layout/PersonalSetupModal.vue +8 -8
- package/app/components/layout/ProviderConfigBanner.vue +4 -4
- package/app/components/layout/RolePrompt.vue +7 -7
- package/app/components/layout/SideBar.vue +6 -4
- package/app/components/layout/SpendWarningBanner.vue +17 -14
- package/app/components/layout/TranslationWarningBanner.vue +4 -4
- package/app/components/layout/UiModeSwitcher.vue +13 -13
- package/app/components/layout/UiRoleSwitcher.vue +8 -8
- package/app/components/layout/WorkspaceMembersSettings.vue +15 -11
- package/app/components/media/ArtifactLightbox.vue +13 -13
- package/app/components/media/ImageCompare.vue +31 -24
- package/app/components/merge/MergeEffortChips.vue +2 -2
- package/app/components/notifications/NotificationSettingsPanel.vue +14 -12
- package/app/components/observability/OutcomeFilterChips.vue +6 -6
- package/app/components/observability/RunFailureSummary.vue +28 -25
- package/app/components/observability/StepMetricsBar.vue +26 -28
- package/app/components/observability/StepModelActivity.vue +2 -2
- package/app/components/observability/ToolCallList.vue +24 -24
- package/app/components/outcome/OutcomeSummaryWindow.vue +47 -47
- package/app/components/palettes/AgentPalette.vue +8 -8
- package/app/components/palettes/AgentTierSelect.vue +1 -1
- package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
- package/app/components/panels/AgentStepDetail.vue +52 -51
- package/app/components/panels/AttemptEntryHeader.vue +4 -6
- package/app/components/panels/DecisionModal.vue +7 -7
- package/app/components/panels/GenericStructuredResultView.vue +7 -7
- package/app/components/panels/InspectorPanel.vue +17 -17
- package/app/components/panels/MergerResultView.vue +19 -19
- package/app/components/panels/ObservabilityPanel.vue +115 -123
- package/app/components/panels/OperatorDashboardPanel.vue +89 -97
- package/app/components/panels/ReportsPanel.vue +69 -66
- package/app/components/panels/ReportsSpendBreakdown.vue +9 -9
- package/app/components/panels/ResultWindowShell.vue +38 -38
- package/app/components/panels/RunDetailLoadState.vue +2 -2
- package/app/components/panels/StepContainerStatus.vue +9 -9
- package/app/components/panels/StepDelegatedStatus.logic.spec.ts +135 -0
- package/app/components/panels/StepDelegatedStatus.logic.ts +160 -0
- package/app/components/panels/StepDelegatedStatus.vue +181 -0
- package/app/components/panels/StepEffortReport.vue +16 -15
- package/app/components/panels/StepFragmentAdherence.vue +14 -10
- package/app/components/panels/StepMetadataCard.vue +74 -45
- package/app/components/panels/StepReproductionReport.vue +25 -21
- package/app/components/panels/StepRunMeta.vue +20 -20
- package/app/components/panels/StepTestReport.logic.spec.ts +8 -3
- package/app/components/panels/StepTestReport.logic.ts +4 -4
- package/app/components/panels/StepTestReport.vue +28 -28
- package/app/components/panels/StepToolServers.vue +14 -11
- package/app/components/panels/StepValidationReport.vue +7 -7
- package/app/components/panels/inspector/ContainerSummary.vue +9 -9
- package/app/components/panels/inspector/DocReferenceRepos.vue +3 -3
- package/app/components/panels/inspector/EnvProbeReport.vue +24 -27
- package/app/components/panels/inspector/EpicChildren.vue +8 -12
- package/app/components/panels/inspector/FrontendBindingsResolved.vue +11 -11
- package/app/components/panels/inspector/FrontendConfig.vue +37 -41
- package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
- package/app/components/panels/inspector/InspectorSection.vue +6 -6
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +16 -19
- package/app/components/panels/inspector/ServiceConnections.vue +2 -2
- package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
- package/app/components/panels/inspector/ServiceSelfTests.vue +21 -17
- package/app/components/panels/inspector/ServiceTestConfig.vue +51 -59
- package/app/components/panels/inspector/ServiceTestSecrets.vue +5 -5
- package/app/components/panels/inspector/ServiceTestingContext.vue +3 -3
- package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
- package/app/components/panels/inspector/TaskAgentConfig.vue +3 -3
- package/app/components/panels/inspector/TaskAprioriBranches.vue +8 -5
- package/app/components/panels/inspector/TaskDependencies.vue +1 -1
- package/app/components/panels/inspector/TaskEstimateBadge.vue +11 -11
- package/app/components/panels/inspector/TaskExecution.vue +17 -17
- package/app/components/panels/inspector/TaskReviewTarget.vue +2 -2
- package/app/components/panels/inspector/TaskRunSettings.vue +35 -37
- package/app/components/panels/inspector/TaskStructure.vue +3 -3
- package/app/components/pipeline/AgentKindIcon.vue +1 -1
- package/app/components/pipeline/AgentPromptEditor.vue +17 -17
- package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -56
- package/app/components/pipeline/EstimateThresholdFields.vue +4 -4
- package/app/components/pipeline/GateConfigFields.vue +13 -10
- package/app/components/pipeline/IterationCapPrompt.vue +4 -2
- package/app/components/pipeline/PipelineBuilder.vue +47 -55
- package/app/components/pipeline/PipelineHealthModal.vue +27 -29
- package/app/components/pipeline/PipelinePicker.vue +10 -10
- package/app/components/pipeline/PipelinePreview.vue +10 -10
- package/app/components/pipeline/PipelineProgress.vue +64 -67
- package/app/components/prReview/PrReviewPhaseBadge.vue +7 -7
- package/app/components/prReview/PrReviewWindow.vue +75 -77
- package/app/components/providers/AiPresetMismatchDialog.vue +5 -5
- package/app/components/providers/AiProviderOnboardingModal.vue +9 -9
- package/app/components/providers/ApiKeysSection.vue +13 -13
- package/app/components/providers/PersonalCredentialModal.vue +2 -2
- package/app/components/providers/PersonalSubscriptionSection.vue +10 -10
- package/app/components/providers/SignInRequiredNotice.vue +1 -1
- package/app/components/providers/VendorCredentialsModal.vue +10 -10
- package/app/components/provisioning/ProvisioningLogsDrawer.vue +13 -13
- package/app/components/ralph/RalphLoopResultView.vue +28 -30
- package/app/components/recurring/RecurrenceEditor.vue +2 -2
- package/app/components/requirements/RequirementsReviewWindow.vue +51 -58
- package/app/components/riskPolicy/RiskPolicyPicker.vue +12 -15
- package/app/components/riskPolicy/RiskPolicyPreview.vue +14 -14
- package/app/components/sandbox/SandboxPanel.vue +58 -59
- package/app/components/settings/AccountSettingsPanel.vue +1 -1
- package/app/components/settings/ApiTokensPanel.vue +10 -10
- package/app/components/settings/BudgetSettings.vue +18 -22
- package/app/components/settings/CapabilityCredentialsPanel.vue +15 -15
- package/app/components/settings/CloudflareHandlerSection.vue +20 -20
- package/app/components/settings/ComposeEnvironmentSetupSection.vue +13 -13
- package/app/components/settings/ConnectionTestVerdict.vue +3 -3
- package/app/components/settings/ConnectionWarnings.vue +1 -1
- package/app/components/settings/ConsensusGroupsSection.vue +27 -35
- package/app/components/settings/CustomManifestTypeEditor.vue +10 -10
- package/app/components/settings/DefaultProvisionTypeSection.vue +6 -6
- package/app/components/settings/InfraHandlersConfigurator.vue +24 -22
- package/app/components/settings/InfrastructureBackendPicker.vue +6 -6
- package/app/components/settings/InfrastructureWindow.vue +5 -5
- package/app/components/settings/IssueTrackerPanel.vue +29 -23
- package/app/components/settings/KubernetesEngineForm.vue +11 -11
- package/app/components/settings/KubernetesEnvironmentForm.vue +4 -4
- package/app/components/settings/LocalContainerPoolSettings.vue +6 -11
- package/app/components/settings/LocalModelEndpointsPanel.vue +20 -18
- package/app/components/settings/McpAuthorizeScreen.vue +13 -15
- package/app/components/settings/McpOAuthCallbackScreen.vue +16 -10
- package/app/components/settings/MergeClassRulesEditor.vue +6 -9
- package/app/components/settings/MergeRolePolicyEditor.vue +16 -16
- package/app/components/settings/ModelConfigurationPanel.vue +23 -30
- package/app/components/settings/ModelPresetHealthModal.vue +15 -13
- package/app/components/settings/ObservabilityConnectionPanel.vue +4 -4
- package/app/components/settings/OpenRouterCatalogPanel.vue +26 -19
- package/app/components/settings/PackageRegistriesPanel.vue +8 -8
- package/app/components/settings/ProviderConnectionTab.vue +8 -11
- package/app/components/settings/ProviderManifestEditor.vue +9 -9
- package/app/components/settings/ProviderPreferenceEditor.vue +8 -8
- package/app/components/settings/RiskPolicyCreateForm.vue +10 -10
- package/app/components/settings/RiskPolicyEditorRow.vue +14 -14
- package/app/components/settings/RiskPolicyHealthModal.vue +15 -13
- package/app/components/settings/RiskPolicyInheritedRow.vue +1 -1
- package/app/components/settings/RiskPolicyPanel.vue +10 -15
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +7 -7
- package/app/components/settings/SharedStacksPanel.vue +9 -12
- package/app/components/settings/TaskSourceCard.vue +4 -4
- package/app/components/settings/TaskTypeSuppressionsPanel.vue +6 -6
- package/app/components/settings/ToolServerChecklist.vue +36 -29
- package/app/components/settings/UsageSettings.vue +15 -15
- package/app/components/settings/UserSecretsSection.vue +9 -12
- package/app/components/settings/WorkspaceMetadataSettings.vue +5 -5
- package/app/components/settings/WorkspaceSettingsPanel.vue +47 -47
- package/app/components/skills/ReviewSkillQueue.vue +10 -10
- package/app/components/skills/SkillLibraryManager.vue +23 -20
- package/app/components/slack/SlackPanel.vue +13 -17
- package/app/components/spec/ServiceSpecWindow.vue +45 -42
- package/app/components/tasks/BugHuntModal.vue +24 -27
- package/app/components/tasks/ContextIssuePicker.vue +11 -11
- package/app/components/tasks/TaskContextIssues.vue +3 -3
- package/app/components/tasks/TaskImportModal.vue +7 -7
- package/app/components/tasks/TaskSourceConnectModal.vue +10 -8
- package/app/components/testing/TestReportWindow.vue +99 -82
- package/app/components/theme/ThemeImportModal.vue +115 -0
- package/app/components/tutorial/TutorialCatalogue.vue +9 -9
- package/app/components/tutorial/TutorialNudge.vue +5 -5
- package/app/components/tutorial/TutorialOverlay.vue +12 -12
- package/app/components/tutorial/TutorialPrompt.vue +6 -9
- package/app/components/vcs/GitLabConnect.vue +4 -4
- package/app/components/vcs/VcsConnectSurfaces.vue +2 -2
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +36 -36
- package/app/composables/api/client.ts +6 -1
- package/app/composables/usePipelineErrorToast.ts +17 -0
- package/app/modular/agent-kinds.ts +24 -0
- package/app/pages/index.vue +5 -5
- package/app/plugins/theme.client.ts +125 -0
- package/app/spa-loading-template.html +52 -14
- package/app/stores/agents.ts +1 -1
- package/app/stores/theme.spec.ts +56 -0
- package/app/stores/theme.ts +87 -0
- package/app/types/domain.ts +19 -0
- package/app/types/execution.ts +4 -0
- package/app/utils/agentOutput.ts +1 -1
- package/app/utils/binaryOutput.ts +6 -6
- package/app/utils/bootstrapSteps.ts +14 -14
- package/app/utils/catalog.ts +87 -83
- package/app/utils/colorTint.ts +10 -0
- package/app/utils/failureKinds.ts +1 -0
- package/app/utils/observability.ts +3 -3
- package/app/utils/pipelineRender.ts +13 -17
- package/app/utils/swimlanes.ts +4 -4
- package/app/utils/theme/bootPalette.spec.ts +54 -0
- package/app/utils/theme/bootPalette.ts +108 -0
- package/app/utils/theme/builtins.spec.ts +38 -0
- package/app/utils/theme/builtins.ts +55 -0
- package/app/utils/theme/css.ts +162 -0
- package/app/utils/theme/doc.ts +353 -0
- package/app/utils/theme/link.ts +93 -0
- package/app/utils/theme/presets.ts +509 -0
- package/app/utils/theme/theme.spec.ts +224 -0
- package/i18n/locales/de.json +61 -4
- package/i18n/locales/en.json +70 -4
- package/i18n/locales/es.json +61 -4
- package/i18n/locales/fr.json +61 -4
- package/i18n/locales/he.json +61 -4
- package/i18n/locales/it.json +61 -4
- package/i18n/locales/ja.json +61 -4
- package/i18n/locales/pl.json +61 -4
- package/i18n/locales/tr.json +61 -4
- package/i18n/locales/uk.json +61 -4
- package/nuxt.config.ts +37 -11
- package/package.json +10 -9
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ The SPA source lives under `app/` (the Nuxt srcDir).
|
|
|
15
15
|
- [What it is](#what-it-is)
|
|
16
16
|
- [Tech stack](#tech-stack)
|
|
17
17
|
- [Layout](#layout)
|
|
18
|
+
- [Nuxt UI: agent tooling and overrides](#nuxt-ui-agent-tooling-and-where-the-spa-overrides-the-skill)
|
|
18
19
|
- [Task swimlanes](#task-swimlanes)
|
|
19
20
|
- [Roles (engineer / product manager / designer)](#roles-engineer--product-manager--designer)
|
|
20
21
|
- [Interface modes (basic / advanced)](#interface-modes-basic--advanced)
|
|
@@ -41,7 +42,8 @@ over the WebSocket. How that sync works is written up in
|
|
|
41
42
|
|
|
42
43
|
## Tech stack
|
|
43
44
|
|
|
44
|
-
- **Nuxt 4 / Vue 3** SPA:
|
|
45
|
+
- **Nuxt 4 / Vue 3** SPA: the board is `pages/index.vue`, beside three standalone routes
|
|
46
|
+
(`mcp-authorize.vue`, `mcp-oauth-callback.vue`, `reset-password.vue`).
|
|
45
47
|
- **Pinia** (+ `pinia-plugin-persistedstate`): feature stores.
|
|
46
48
|
- **Vue Flow** (`core`, `background`, `controls`, `node-resizer`): the canvas.
|
|
47
49
|
- **Nuxt UI** + Tailwind: components and styling.
|
|
@@ -50,15 +52,15 @@ over the WebSocket. How that sync works is written up in
|
|
|
50
52
|
|
|
51
53
|
## Layout
|
|
52
54
|
|
|
53
|
-
| Path
|
|
54
|
-
|
|
|
55
|
-
| `app.vue`
|
|
56
|
-
| `pages
|
|
57
|
-
| `components/`
|
|
58
|
-
| `composables/`
|
|
59
|
-
| `stores/`
|
|
60
|
-
| `types/`
|
|
61
|
-
| `utils/`
|
|
55
|
+
| Path | Contents |
|
|
56
|
+
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
57
|
+
| `app.vue` | Root; wraps the page in `AuthGate`. |
|
|
58
|
+
| `pages/` | The board (`index.vue`: sidebar, canvas, toolbar, inspector, focus view, all modals), plus the standalone `mcp-authorize`, `mcp-oauth-callback` and `reset-password` routes. |
|
|
59
|
+
| `components/` | UI grouped by area (see [Key UI surfaces](#key-ui-surfaces)). |
|
|
60
|
+
| `composables/` | `useApi` (typed client), `useWorkspaceStream` (WebSocket sync), `useBlockDrag`, `useBlockQueries`, `useBoardFlow`, `useSemanticZoom`, `useDepLabels`. |
|
|
61
|
+
| `stores/` | Pinia stores, one per feature domain. |
|
|
62
|
+
| `types/` | TypeScript domain unions (`domain.ts`) and wire types mirroring the contracts. |
|
|
63
|
+
| `utils/` | Small pure helpers. |
|
|
62
64
|
|
|
63
65
|
### The board's top overlay region has ONE owner
|
|
64
66
|
|
|
@@ -288,6 +290,80 @@ it has nothing to do at mount, and running it there would announce a close that
|
|
|
288
290
|
|
|
289
291
|
A status → chip map feeding a `<UBadge :color="…">` types its values as `BadgeColor` (`utils/badge.ts`), which is derived from `UBadge`'s own prop type rather than restated as a literal union. Typed `string`, the binding does not compile and the reflex is `as any` at each call site: seven of them had accumulated. That cast also accepts a colour Nuxt UI does not define, which renders as an unstyled badge with nothing failing.
|
|
290
292
|
|
|
293
|
+
### Colour through theme tokens, never a fixed palette shade
|
|
294
|
+
|
|
295
|
+
Every colour in the SPA is a token that follows the THEME and the colour MODE. Three kinds exist:
|
|
296
|
+
|
|
297
|
+
- **Nuxt UI role tokens** for greys (`bg-default`, `bg-elevated`, `bg-accented`, `text-default`, `text-toned`, `text-muted`, `text-dimmed`, `text-highlighted`, `border-default`, `border-muted`) and the **bare aliases** for an accent at Nuxt UI's own shade (`text-primary`, `bg-warning/10`, `ring-error/25`).
|
|
298
|
+
- **The app's mirrored numbered tokens** (`app/assets/css/tokens.css`) for a STATUS surface painted in a specific ramp shade: `bg-app-950` / `text-app-100` / `text-app-600` / `bg-app-500` / `ring-app-400` for the five grey shades with no role token, `bg-app-canvas` for the board canvas (the one surface below the page background; in light the page surface `app-950` sits at neutral-100 rather than the mirror's 50 and the canvas at 200, so the ~350 translucent `bg-default/NN` panels keep an edge), and `text-app-warning-300` / `bg-app-error-950/40` / `border-app-success-800` for the five status ramps (`secondary`, `success`, `info`, `warning`, `error`). Each token's dark value is the exact ramp shade and its light value is the MIRRORED shade (`50↔950`, `100↔900`, `200↔800`, `300↔700`, `400↔600`, `500` its own midpoint), so a `300` text on a `950/40` fill reads on both surfaces from one class list. Every value is a reference into the `--ui-color-<alias>-<n>` ramps, so a theme that remaps `warning` recolours every warning surface. `primary` has NO numbered token: brand accents use the bare alias, which is what the editor's primary slider and `blackAsPrimary` address.
|
|
299
|
+
- **Category hues** (`text-app-hue-pink`, `var(--app-hue-teal)` in an inline style) for an IDENTITY colour: an agent kind, a task type, a pipeline step kind (`utils/catalog.ts`). One token per Tailwind hue, `400` in dark and `600` in light (Nuxt UI's own alias convention), referencing Tailwind's ramps because a category is not a status. A STATUS (task status, step state, test verdict, finding severity) is not a category and takes the alias directly (`var(--ui-warning)`, `var(--ui-success)`, `var(--ui-text-muted)` for planned / done / skipped), so the halo, the badge and the dot recolour together. A translucent tile behind a category glyph goes through `tint()` (`utils/colorTint.ts`), which also accepts the hex a deployment-registered kind may send. A theme recolours a hue through its `tokens` block.
|
|
300
|
+
- **Never** a raw Tailwind hue (`bg-slate-900`, `text-amber-300`, `text-pink-300`) nor a fixed numbered alias (`text-primary-400`, `bg-warning-950/40`): the first is welded to one palette and one mode, the second follows the palette but not the mode. `scripts/check-frontend-palette.mjs` (CI) bans both. `red` and `rose` both mean `error`.
|
|
301
|
+
- **Never** a fixed `white` / `black` utility (`bg-white`, `text-black`, `border-white/5`, `bg-white/[0.02]`): invisible or wrong in light mode. Use `border-inverted` (a selection ring), `border-default` / `bg-muted` (faint chrome) or `text-inverted` (text over a filled surface). A line that genuinely needs a fixed value says why with a `fixed-colour-ok:` comment, on that line or the one above it.
|
|
302
|
+
|
|
303
|
+
### Themes and colour mode
|
|
304
|
+
|
|
305
|
+
A **theme** is a Nuxt UI theme editor document (https://ui.nuxt.com/theme): the sparse `ThemeDoc` the editor edits and shares as a `?doc=` link, decoded by `utils/theme/link.ts` and typed in `utils/theme/doc.ts` (a port of the editor engine's tables). The app speaks THAT format rather than one of its own, so a theme built in the editor imports as-is and a built-in theme is a document a user could have exported. `utils/theme/builtins.ts` ships `Cat Factory` (the default; its `colors` MUST equal `app.config.ts`'s `ui.colors`, which paints the first frame) and the editor's own `Mono` preset, referenced from the preset table rather than copied. The `theme` store persists the pick and the user's imported documents in this browser; `plugins/theme.client.ts` applies the active document at runtime: aliases onto `appConfig.ui.colors` (Nuxt UI's own colours plugin re-emits the ramps), default variants and component overrides onto `appConfig.ui.<component>` merged INTO the layer's own overrides, and tokens / radius / fonts onto one `<style id="app-theme">` whose selectors anchor on the `data-theme` attribute on `<html>` (`utils/theme/css.ts`, which is also the write boundary for untrusted values). The faces the built-in themes name (Geist, Geist Mono) are self-hosted through `@nuxt/fonts` (`fonts.families` in `nuxt.config.ts`, pinned by `builtins.spec.ts`); a font an IMPORTED theme names is applied as a family name only, so it renders when the device or the deployment provides it. A editor link whose document equals one of the editor's presets collapses to `{ preset: 'mono' }`; `utils/theme/presets.ts` is a copy of the editor's preset table so such a link rebuilds (a decode table, not menu entries).
|
|
306
|
+
|
|
307
|
+
**Colour mode** (system / light / dark) is `@nuxtjs/color-mode`'s, registered by Nuxt UI, with its own persistence; `nuxt.config.ts` follows the system preference and falls back to dark. `AppearanceSwitcher` at the sidebar bottom is the one control for both axes. The pre-JS loading shell (`spa-loading-template.html`) cannot resolve a token (no stylesheet is loaded yet), so the plugin caches the computed colours of the four tokens the shell paints with, per colour mode, in `localStorage` (`utils/theme/bootPalette.ts`), and a two-line inline script in the shell applies the entry for the mode the `<head>` colour-mode script has already put on `<html>`. The hardcoded defaults are the default theme's, used only until a theme has been seen in that mode.
|
|
308
|
+
|
|
309
|
+
## Nuxt UI: agent tooling and where the SPA overrides the skill
|
|
310
|
+
|
|
311
|
+
The SPA runs on Nuxt UI 4. Two first-party sources carry the rules this repo does not restate:
|
|
312
|
+
|
|
313
|
+
- **The vendored [`nuxt-ui` skill](https://github.com/kibertoad/cat-factory/tree/main/.claude/skills/nuxt-ui)** teaches WHEN to reach for which
|
|
314
|
+
component (Modal vs Slideover vs Drawer, Tabs vs NavigationMenu, Toast vs Alert) and HOW to build
|
|
315
|
+
well (the variant-weight table, one solid primary per view, semantic utility roles). It is
|
|
316
|
+
vendored under `.claude/skills/nuxt-ui/`, beside the project's own skills, so the rules version
|
|
317
|
+
with the code and every contributor on Claude Code reads the same text. This is the Claude Code
|
|
318
|
+
surface: `.claude/skills/` auto-loads for a local Claude Code session, and the repo `.mcp.json` is
|
|
319
|
+
offered once for approval on the first session in the repo (re-offered when the file changes); a
|
|
320
|
+
decline is remembered, and `claude mcp reset-project-choices` un-sticks it. Another tool that reads
|
|
321
|
+
`AGENTS.md` (Codex, for one) gets the pointers below but not an auto-loaded skill or an auto-wired
|
|
322
|
+
server. Making the platform's OWN coder agents (Claude Code, Codex, Pi in
|
|
323
|
+
the runner image) apply the skill is a separate, backend change: they stage skills and tool
|
|
324
|
+
servers per run through the agent-capabilities system (ADR 0024 /
|
|
325
|
+
[`custom-agents.md`](https://github.com/kibertoad/cat-factory/blob/main/backend/docs/custom-agents.md)), not from these repo files. The `@nuxt/ui` npm
|
|
326
|
+
package does not ship the skill, so it cannot move with `pnpm update`: it is vendored from the
|
|
327
|
+
`v4` branch of `nuxt/ui` (which tracks the 4.x line) and pinned by convention to the Nuxt UI
|
|
328
|
+
major in [`package.json`](./package.json) (`@nuxt/ui@^4.11`). Refresh it by re-vendoring
|
|
329
|
+
`skills/nuxt-ui/` from that branch (or `npx skills add nuxt/ui`) when the major moves. The
|
|
330
|
+
vendored files are kept byte-for-byte as upstream: `.oxfmtrc.json` exempts them from the
|
|
331
|
+
formatter and `scripts/check-doc-links.mjs` skips them, so a refresh stays a clean diff even when
|
|
332
|
+
upstream ships a link this repo's own doc rules would reject.
|
|
333
|
+
- **The [`nuxt-ui` MCP server](https://github.com/kibertoad/cat-factory/blob/main/.mcp.json)** (`https://ui.nuxt.com/mcp`, declared repo-level)
|
|
334
|
+
answers WHAT a component accepts: props, slots, events, theme files and examples per component.
|
|
335
|
+
The skill defers to it for every API question.
|
|
336
|
+
|
|
337
|
+
The SPA's own rules win where they and the skill disagree. Each entry below links the rule it
|
|
338
|
+
protects, so the two never contradict silently:
|
|
339
|
+
|
|
340
|
+
- **Visible copy is an i18n key, never a literal string.** The skill's examples hard-code labels and
|
|
341
|
+
placeholders (`label="Email"`, `placeholder="you@example.com"`); here every user-facing string
|
|
342
|
+
goes through `@nuxtjs/i18n` and lands in the catalog. [Rule](#internationalization-i18n-authoring).
|
|
343
|
+
- **Schema validation goes through valibot, never zod.** The skill's `forms.md` recipe opens with
|
|
344
|
+
`import * as z from 'zod'` and validates through `z.object({...})`; this package depends on
|
|
345
|
+
`valibot` (and `@toad-contracts/valibot`) and has no `zod`, so a `zod` import fails typecheck and
|
|
346
|
+
"fixing" it pulls in a dependency the repo deliberately lacks (which then has to clear the 24h
|
|
347
|
+
`minimumReleaseAge` gate). Validate with valibot, mirroring the wire contracts
|
|
348
|
+
([`@cat-factory/contracts`](https://github.com/kibertoad/cat-factory/tree/main/backend/packages/contracts)).
|
|
349
|
+
- **A backend-declared form renders through `DescriptorFields.vue`, not a hand-built `UForm`.** The
|
|
350
|
+
skill teaches the hand-rolled `UForm` + `UFormField` shape for every form; when the backend
|
|
351
|
+
declares the fields and the SPA only collects them, that shape is forbidden here.
|
|
352
|
+
[Rule](#a-backend-declared-form-renders-through-descriptorfieldsvue).
|
|
353
|
+
- **Failure toasts go through the funnel, not a bare `toast.add`.** The skill uses `useToast()`
|
|
354
|
+
freely; here a failed backend call is reported with `usePipelineErrorToast().present(error, key)`.
|
|
355
|
+
[Rule](#every-failure-toast-goes-through-one-funnel).
|
|
356
|
+
- **Icon-only buttons carry an accessible name.** Use `common/IconButton.vue`
|
|
357
|
+
([source](./app/components/common/IconButton.vue)), which applies `label` as both `title` and
|
|
358
|
+
`aria-label`, rather than a bare `<UButton icon>`.
|
|
359
|
+
- **Colour goes through theme tokens, never a fixed palette shade.** The skill bans raw Tailwind
|
|
360
|
+
hues; this repo also bans fixed numbered aliases, enforced by
|
|
361
|
+
[`scripts/check-frontend-palette.mjs`](https://github.com/kibertoad/cat-factory/blob/main/scripts/check-frontend-palette.mjs).
|
|
362
|
+
[Rule](#colour-through-theme-tokens-never-a-fixed-palette-shade).
|
|
363
|
+
- **Confirmation dialogs use the shared `useConfirm`.** The skill shows `useOverlay()` per call
|
|
364
|
+
site; here callers `await useConfirm().confirm({...})`
|
|
365
|
+
([source](./app/composables/useConfirm.ts)) against one app-mounted `<ConfirmDialog />`.
|
|
366
|
+
|
|
291
367
|
## Task swimlanes
|
|
292
368
|
|
|
293
369
|
A service frame lays its tasks out in **status lanes**, not at coordinates. Three lanes a reader
|
|
@@ -1341,12 +1417,21 @@ wrong place is invisible until a user cannot find it:
|
|
|
1341
1417
|
|
|
1342
1418
|
## Develop & test
|
|
1343
1419
|
|
|
1420
|
+
This package has no `dev` or `lint` script of its own: it is a layer, consumed through `extends`,
|
|
1421
|
+
and linting is whole-tree from the repo root (CLAUDE.md). The `AGENTS.md` verify checklist carries
|
|
1422
|
+
the same list, plus the install-free frontend guards.
|
|
1423
|
+
|
|
1344
1424
|
```bash
|
|
1425
|
+
# From the repo root:
|
|
1345
1426
|
pnpm install
|
|
1346
|
-
pnpm dev
|
|
1347
|
-
pnpm
|
|
1348
|
-
pnpm
|
|
1349
|
-
|
|
1427
|
+
pnpm dev:frontend # Nuxt dev server via deploy/frontend; set NUXT_PUBLIC_API_BASE to a running Worker
|
|
1428
|
+
pnpm exec turbo run typecheck --filter=@cat-factory/app # typecheck goes through Turbo
|
|
1429
|
+
pnpm lint # oxlint + oxfmt over the whole tree
|
|
1430
|
+
|
|
1431
|
+
# From frontend/app:
|
|
1432
|
+
pnpm exec vitest run <file> # run the spec your change touched
|
|
1433
|
+
pnpm i18n:check # catalog is well-formed
|
|
1434
|
+
pnpm i18n:parity # locales are in parity
|
|
1350
1435
|
```
|
|
1351
1436
|
|
|
1352
1437
|
> Building/deploying the static site is covered in the deployment docs: see the
|
package/app/app.config.ts
CHANGED
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
export default defineAppConfig({
|
|
2
2
|
ui: {
|
|
3
|
+
// The default theme's alias map. It MUST equal `CAT_FACTORY_THEME.doc.colors`
|
|
4
|
+
// (`utils/theme/builtins.ts`): this is what the first paint renders from, before the theme
|
|
5
|
+
// plugin applies the active document over it (`theme.builtins.spec.ts` pins the equality).
|
|
3
6
|
colors: {
|
|
4
7
|
primary: 'indigo',
|
|
8
|
+
secondary: 'violet',
|
|
9
|
+
success: 'emerald',
|
|
10
|
+
info: 'sky',
|
|
11
|
+
warning: 'amber',
|
|
12
|
+
error: 'rose',
|
|
5
13
|
neutral: 'slate',
|
|
6
14
|
},
|
|
7
|
-
// Give every overlay the same layered
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
15
|
+
// Give every overlay the same layered surface the agent-run-details reader uses: the deep
|
|
16
|
+
// `app-950` surface (below `bg-default`) so the `bg-default` panels/cards inside pop, with
|
|
17
|
+
// `border-default` chrome. All tokens are theme role tokens (`app-950` is the hand-defined
|
|
18
|
+
// flipping token for the deep shade), so overlays track dark/light. Applies to all
|
|
19
|
+
// UModal/USlideover instances so they stay consistent without per-instance `:ui` overrides.
|
|
11
20
|
modal: {
|
|
12
21
|
slots: {
|
|
13
|
-
content: 'bg-
|
|
14
|
-
header: 'border-b border-
|
|
15
|
-
title: 'text-
|
|
22
|
+
content: 'bg-app-950 ring-default divide-default',
|
|
23
|
+
header: 'border-b border-default',
|
|
24
|
+
title: 'text-highlighted',
|
|
16
25
|
},
|
|
17
26
|
},
|
|
18
27
|
slideover: {
|
|
19
28
|
slots: {
|
|
20
|
-
content: 'bg-
|
|
21
|
-
header: 'border-b border-
|
|
22
|
-
title: 'text-
|
|
29
|
+
content: 'bg-app-950 ring-default divide-default',
|
|
30
|
+
header: 'border-b border-default',
|
|
31
|
+
title: 'text-highlighted',
|
|
23
32
|
},
|
|
24
33
|
},
|
|
25
34
|
// The toaster's scroll region is the ONE `[data-slot='viewport']` the app's own
|
package/app/assets/css/main.css
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
/* The shared rendered-markdown reader presentation (see prose.css). */
|
|
4
4
|
@import './prose.css';
|
|
5
5
|
|
|
6
|
+
/* The app's own mode-adaptive colour tokens (`app-*`), layered on Nuxt UI's. */
|
|
7
|
+
@import './tokens.css';
|
|
8
|
+
|
|
6
9
|
/* The two toaster rules below are scoped by the `app-toaster` marker class that
|
|
7
10
|
* `app.config.ts` puts on the toaster's viewport slot, NOT by `[data-slot='viewport']`.
|
|
8
11
|
* That attribute is Nuxt UI's name for the scroll region of ELEVEN components
|
|
@@ -53,10 +56,6 @@
|
|
|
53
56
|
|
|
54
57
|
/* ---- Agent Architecture Board: shared visual language ---------------------- */
|
|
55
58
|
|
|
56
|
-
:root {
|
|
57
|
-
--board-bg: #0b1020;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
59
|
html,
|
|
61
60
|
body,
|
|
62
61
|
#__nuxt {
|
|
@@ -68,9 +67,9 @@ body {
|
|
|
68
67
|
overflow: hidden;
|
|
69
68
|
}
|
|
70
69
|
|
|
71
|
-
/* Vue Flow surface
|
|
70
|
+
/* The Vue Flow surface is the board canvas: one step below the page background in both modes. */
|
|
72
71
|
.vue-flow__background {
|
|
73
|
-
background-color: var(--
|
|
72
|
+
background-color: var(--app-bg-canvas);
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
/* Touch: let the pane own one-finger pan + pinch-zoom rather than the browser
|
|
@@ -83,14 +82,15 @@ body {
|
|
|
83
82
|
touch-action: none;
|
|
84
83
|
}
|
|
85
84
|
|
|
86
|
-
/* Status-pulse used by blocked / decision-needed blocks
|
|
85
|
+
/* Status-pulse used by blocked / decision-needed blocks: the warning alias, so a theme that
|
|
86
|
+
* recolours `warning` recolours the halo. `color-mix` is how a custom property gets an alpha. */
|
|
87
87
|
@keyframes board-pulse {
|
|
88
88
|
0%,
|
|
89
89
|
100% {
|
|
90
|
-
box-shadow: 0 0 0 0
|
|
90
|
+
box-shadow: 0 0 0 0 color-mix(in srgb, var(--ui-warning) 55%, transparent);
|
|
91
91
|
}
|
|
92
92
|
50% {
|
|
93
|
-
box-shadow: 0 0 0 10px
|
|
93
|
+
box-shadow: 0 0 0 10px transparent;
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
@@ -98,14 +98,14 @@ body {
|
|
|
98
98
|
animation: board-pulse 1.4s ease-in-out infinite;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
/*
|
|
101
|
+
/* Success pulse used when a block reaches the "PR ready" state */
|
|
102
102
|
@keyframes board-pulse-green {
|
|
103
103
|
0%,
|
|
104
104
|
100% {
|
|
105
|
-
box-shadow: 0 0 0 0
|
|
105
|
+
box-shadow: 0 0 0 0 color-mix(in srgb, var(--ui-success) 60%, transparent);
|
|
106
106
|
}
|
|
107
107
|
50% {
|
|
108
|
-
box-shadow: 0 0 0 12px
|
|
108
|
+
box-shadow: 0 0 0 12px transparent;
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
|
|
@@ -121,7 +121,7 @@ body {
|
|
|
121
121
|
|
|
122
122
|
/* A selected edge: highlight it so the user knows what Delete/Backspace removes */
|
|
123
123
|
.vue-flow__edge.selected .vue-flow__edge-path {
|
|
124
|
-
stroke:
|
|
124
|
+
stroke: var(--ui-error) !important;
|
|
125
125
|
stroke-width: 2.5 !important;
|
|
126
126
|
}
|
|
127
127
|
|
package/app/assets/css/prose.css
CHANGED
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
transition: background 0.12s ease;
|
|
22
22
|
}
|
|
23
23
|
.reader-prose.review-mode [data-src-start]:hover {
|
|
24
|
-
background:
|
|
25
|
-
box-shadow: inset 2px 0 0
|
|
24
|
+
background: color-mix(in srgb, var(--ui-primary) 8%, transparent);
|
|
25
|
+
box-shadow: inset 2px 0 0 color-mix(in srgb, var(--ui-primary) 50%, transparent);
|
|
26
26
|
}
|
|
27
27
|
.reader-prose.review-mode [data-src-start]::before {
|
|
28
28
|
content: '+';
|
|
@@ -35,23 +35,23 @@
|
|
|
35
35
|
align-items: center;
|
|
36
36
|
justify-content: center;
|
|
37
37
|
border-radius: 0.25rem;
|
|
38
|
-
background:
|
|
39
|
-
color:
|
|
38
|
+
background: var(--ui-primary);
|
|
39
|
+
color: var(--ui-text-inverted);
|
|
40
40
|
font-size: 0.8rem;
|
|
41
41
|
line-height: 1;
|
|
42
42
|
}
|
|
43
43
|
.reader-prose.review-mode [data-src-start]:hover::before {
|
|
44
44
|
display: flex;
|
|
45
45
|
}
|
|
46
|
-
/* Persistent markers:
|
|
47
|
-
the block whose composer is currently open. */
|
|
46
|
+
/* Persistent markers: the warning alias for a block that already has a comment, the primary
|
|
47
|
+
alias for the block whose composer is currently open. */
|
|
48
48
|
.reader-prose .cf-commented {
|
|
49
|
-
background:
|
|
50
|
-
box-shadow: inset 2px 0 0
|
|
49
|
+
background: color-mix(in srgb, var(--ui-warning) 10%, transparent);
|
|
50
|
+
box-shadow: inset 2px 0 0 color-mix(in srgb, var(--ui-warning) 60%, transparent);
|
|
51
51
|
}
|
|
52
52
|
.reader-prose .cf-selected {
|
|
53
|
-
background:
|
|
54
|
-
box-shadow: inset 2px 0 0
|
|
53
|
+
background: color-mix(in srgb, var(--ui-primary) 12%, transparent);
|
|
54
|
+
box-shadow: inset 2px 0 0 color-mix(in srgb, var(--ui-primary) 80%, transparent);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/* Styling for the markdown HTML injected via v-html (out of scoped reach without
|
|
@@ -75,36 +75,36 @@
|
|
|
75
75
|
}
|
|
76
76
|
.reader-prose strong {
|
|
77
77
|
font-weight: 600;
|
|
78
|
-
color:
|
|
78
|
+
color: var(--ui-text-highlighted);
|
|
79
79
|
}
|
|
80
80
|
.reader-prose em {
|
|
81
81
|
font-style: italic;
|
|
82
82
|
}
|
|
83
83
|
.reader-prose code {
|
|
84
84
|
border-radius: 0.25rem;
|
|
85
|
-
background:
|
|
85
|
+
background: var(--ui-bg-elevated);
|
|
86
86
|
padding: 0.1rem 0.3rem;
|
|
87
|
-
font-family:
|
|
87
|
+
font-family: var(--font-mono);
|
|
88
88
|
font-size: 0.85em;
|
|
89
|
-
color:
|
|
89
|
+
color: var(--ui-primary);
|
|
90
90
|
}
|
|
91
91
|
.reader-prose pre {
|
|
92
92
|
margin: 0.6rem 0;
|
|
93
93
|
overflow: auto;
|
|
94
94
|
border-radius: 0.5rem;
|
|
95
|
-
background:
|
|
95
|
+
background: var(--app-bg-canvas);
|
|
96
96
|
padding: 0.75rem 0.9rem;
|
|
97
97
|
}
|
|
98
98
|
.reader-prose pre code {
|
|
99
99
|
background: transparent;
|
|
100
100
|
padding: 0;
|
|
101
|
-
color:
|
|
101
|
+
color: var(--ui-text-toned);
|
|
102
102
|
}
|
|
103
103
|
.reader-prose blockquote {
|
|
104
104
|
margin: 0.6rem 0;
|
|
105
|
-
border-left: 3px solid
|
|
105
|
+
border-left: 3px solid color-mix(in srgb, var(--ui-primary) 50%, transparent);
|
|
106
106
|
padding-left: 0.75rem;
|
|
107
|
-
color:
|
|
107
|
+
color: var(--ui-text-muted);
|
|
108
108
|
}
|
|
109
109
|
.reader-prose table {
|
|
110
110
|
margin: 0.6rem 0;
|
|
@@ -113,17 +113,17 @@
|
|
|
113
113
|
}
|
|
114
114
|
.reader-prose th,
|
|
115
115
|
.reader-prose td {
|
|
116
|
-
border: 1px solid
|
|
116
|
+
border: 1px solid var(--ui-border-muted);
|
|
117
117
|
padding: 0.3rem 0.6rem;
|
|
118
118
|
}
|
|
119
119
|
.reader-prose th {
|
|
120
|
-
background:
|
|
120
|
+
background: var(--ui-bg-elevated);
|
|
121
121
|
font-weight: 600;
|
|
122
122
|
}
|
|
123
123
|
.reader-prose hr {
|
|
124
124
|
margin: 1rem 0;
|
|
125
125
|
border: none;
|
|
126
|
-
border-top: 1px solid
|
|
126
|
+
border-top: 1px solid var(--ui-border-muted);
|
|
127
127
|
}
|
|
128
128
|
.reader-prose h1,
|
|
129
129
|
.reader-prose h2,
|
|
@@ -131,5 +131,5 @@
|
|
|
131
131
|
.reader-prose h4 {
|
|
132
132
|
margin: 0.6rem 0 0.3rem;
|
|
133
133
|
font-weight: 600;
|
|
134
|
-
color:
|
|
134
|
+
color: var(--ui-text-highlighted);
|
|
135
135
|
}
|