From 67e10138b5ac16cee908f4c94104082477a48f30 Mon Sep 17 00:00:00 2001 From: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com> Date: Thu, 23 Jul 2026 09:05:56 +0000 Subject: [PATCH] =?UTF-8?q?Follow-up:=20colour=20token=20migration=20(comp?= =?UTF-8?q?at=20=E2=86=92=20--c-*,=20hardcoded=20hex)=20(#7011)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to #7009, which built the theme token layer (`primitives` → `colors` → `compat`). This PR moves the whole app onto it, removes hardcoded colours, turns on enforcement so they can't come back, and adds a user-selectable accent. ## What this does - **Semantic tokens everywhere** — legacy colour aliases and raw hex are rewritten to `--c-*` tokens (`--c-surface*`, `--c-text*`, `--c-primary`, …). Straight rename, no visual change. Genuine literals (brand/OAuth, colour pickers, data-viz) are left as-is. - **Fixes missing colours** — some tokens the migration referenced were never defined, so a few surfaces (login button, auth banners, badges, procurement view) silently lost their colour. All defined now, and they adapt to light/dark and the accent automatically. - **Blocking colour lint** — CI now fails on hardcoded colours, undefined tokens, or unreadable low-contrast status colours. - **User-selectable accent** — light and dark each get their own accent from Settings → Appearance, contrast-clamped so text stays legible. "Default" keeps the standard blue. ## Still to come Remaining inline-style hex, the legacy token-definition files (`theme.css`, `tokens.css`), and folding `zIndex.ts` onto the dimension tokens. ## Testing `task frontend:check:all` green; light/dark and accent switching spot-checked. --- .taskfiles/frontend.yml | 6 +- frontend/.storybook/preview.tsx | 4 +- frontend/editor/scripts/lint/theme-lint.mjs | 737 +++++++++++++++--- .../slides/SaasOnboardingSlides.module.css | 10 +- .../shared/FreeLimitReachedModal.tsx | 2 +- .../shared/SpendCapReachedModal.tsx | 2 +- .../shared/config/configSections/Payg.css | 169 ++-- .../shared/config/configSections/Payg.tsx | 12 +- .../shared/config/configSections/PaygFree.css | 44 +- .../config/configSections/SpendCapControl.css | 40 +- .../config/configSections/TeamSection.tsx | 13 +- .../config/configSections/UpgradeModal.css | 37 +- .../editor/src/core/assets/Brand.stories.tsx | 4 +- .../src/core/components/FileManager.tsx | 2 +- .../annotation/shared/TextInputWithFont.tsx | 2 +- .../components/fileEditor/AddFileCard.tsx | 10 +- .../fileEditor/FileEditor.module.css | 90 +-- .../fileEditor/FileEditorThumbnail.module.css | 20 +- .../components/fileManager/DesktopLayout.tsx | 2 +- .../fileManager/EmptyFilesState.tsx | 8 +- .../components/fileManager/FileListItem.tsx | 2 +- .../components/fileManager/MobileLayout.tsx | 2 +- .../components/filesPage/FileDetailsPanel.tsx | 2 +- .../core/components/filesPage/FileGrid.tsx | 2 +- .../components/filesPage/FileManagerView.tsx | 16 +- .../components/filesPage/FileOriginBadge.tsx | 14 +- .../core/components/filesPage/FilesPage.css | 316 ++++---- .../filesPage/FolderAppearancePicker.tsx | 10 +- .../components/filesPage/FolderThumbnail.tsx | 4 +- .../components/filesPage/FolderTreePanel.css | 36 +- .../filesPage/MoveToFolderDialog.tsx | 6 +- .../src/core/components/layout/Workbench.tsx | 2 +- .../InitialOnboardingModal.module.css | 84 +- .../onboarding/OnboardingSlideShell.tsx | 4 +- .../components/onboarding/OnboardingTour.css | 6 +- .../slides/AnimatedSlideBackground.module.css | 2 +- .../onboarding/slides/DesktopInstallTitle.tsx | 4 +- .../onboarding/slides/FirstLoginSlide.tsx | 2 +- .../onboarding/slides/SecurityCheckSlide.tsx | 2 +- .../pageEditor/DragDropGrid.module.css | 10 +- .../components/pageEditor/FileThumbnail.tsx | 4 +- .../pageEditor/PageEditor.module.css | 12 +- .../pageEditor/PageEditorControls.tsx | 4 +- .../BulkSelectionPanel.module.css | 84 +- .../bulkSelectionPanel/OperatorsSection.tsx | 2 +- .../bulkSelectionPanel/PageSelectionInput.tsx | 4 +- .../bulkSelectionPanel/SelectPages.tsx | 2 +- .../core/components/shared/AppConfigModal.css | 18 +- .../core/components/shared/AppConfigModal.tsx | 12 +- .../src/core/components/shared/AppSwitch.css | 6 +- .../src/core/components/shared/Badge.tsx | 4 +- .../components/shared/EditableSecretField.tsx | 6 +- .../core/components/shared/ErrorBoundary.tsx | 2 +- .../src/core/components/shared/FileCard.tsx | 4 +- .../components/shared/FileDropdownMenu.tsx | 4 +- .../shared/FileSelectorPicker.module.css | 18 +- .../core/components/shared/FileSidebar.css | 88 +-- .../core/components/shared/FileSidebar.tsx | 6 +- .../components/shared/FileSidebarFileItem.css | 67 +- .../src/core/components/shared/Footer.tsx | 4 +- .../shared/HoverActionMenu.module.css | 4 +- .../components/shared/HoverActionMenu.tsx | 2 +- .../core/components/shared/LandingPage.css | 22 +- .../shared/LanguageSelector.module.css | 21 +- .../components/shared/LanguageSelector.tsx | 4 +- .../ObscuredOverlay.module.css | 2 +- .../shared/PageEditorFileDropdown.tsx | 6 +- .../core/components/shared/PolicyBadges.css | 2 +- .../src/core/components/shared/ToolIcon.tsx | 2 +- .../components/shared/ToolPanelHeader.css | 4 +- .../src/core/components/shared/Tooltip.tsx | 2 +- .../core/components/shared/UpdateModal.tsx | 16 +- .../core/components/shared/WorkbenchBar.css | 44 +- .../shared/filePreview/DocumentThumbnail.tsx | 2 +- .../shared/textInput/TextInput.module.css | 16 +- .../shared/tooltip/Tooltip.module.css | 64 +- .../shared/tooltip/TooltipContent.tsx | 12 +- .../core/components/toast/ToastRenderer.css | 26 +- .../core/components/tools/RightSidebar.tsx | 2 +- .../src/core/components/tools/ToolPanel.css | 140 ++-- .../components/tools/ToolPanelModePrompt.css | 82 +- .../src/core/components/tools/ToolPicker.tsx | 4 +- .../PageNumberPreview.module.css | 10 +- .../addPageNumbers/PageNumberPreview.tsx | 2 +- .../tools/addStamp/StampPreview.module.css | 10 +- .../tools/addStamp/StampPreviewUtils.ts | 2 +- .../tools/automate/AutomationEntry.tsx | 6 +- .../tools/automate/AutomationRun.tsx | 2 +- .../components/tools/automate/ToolList.tsx | 2 +- .../certSign/CertificateTypeSettings.tsx | 2 +- .../certSign/panels/SignRequestPanel.tsx | 6 +- .../components/tools/compare/compareView.css | 168 ++-- .../tools/convert/GroupedFormatDropdown.tsx | 2 +- .../editTableOfContents/BookmarkEditor.tsx | 7 +- .../EditTableOfContentsWorkbenchView.tsx | 10 +- .../getPdfInfo/sections/PerPageSection.tsx | 4 +- .../getPdfInfo/shared/ScrollableCodeBlock.tsx | 4 +- .../getPdfInfo/shared/accordionStyles.ts | 2 +- .../tools/ocr/LanguagePicker.module.css | 57 +- .../components/tools/ocr/LanguagePicker.tsx | 2 +- .../OverlayPdfsSettings.module.css | 6 +- .../tools/pageLayout/PageLayoutSettings.tsx | 2 +- .../tools/redact/RedactSingleStepSettings.tsx | 6 +- .../ReorganizePagesSettings.tsx | 2 +- .../core/components/tools/shared/ToolStep.tsx | 6 +- .../components/tools/showJS/ShowJSView.css | 24 +- .../tools/toolPicker/ToolPicker.css | 18 +- .../tools/toolPicker/ToolSearch.tsx | 6 +- .../validateSignature/reportView/styles.css | 24 +- .../components/viewer/AttachmentSidebar.css | 16 +- .../components/viewer/BookmarkSidebar.css | 18 +- .../components/viewer/BookmarkSidebar.tsx | 9 +- .../components/viewer/CommentsSidebar.tsx | 12 +- .../core/components/viewer/LayerSidebar.css | 28 +- .../core/components/viewer/LocalEmbedPDF.tsx | 2 +- .../components/viewer/PdfViewerToolbar.tsx | 2 +- .../core/components/viewer/SidebarBase.css | 17 +- .../components/viewer/ThumbnailSidebar.tsx | 12 +- .../core/data/useTranslatedToolRegistry.tsx | 8 +- frontend/editor/src/core/pages/HomePage.css | 32 +- .../src/core/pages/MobileScannerPage.tsx | 20 +- .../editor/src/core/styles/cookieconsent.css | 23 +- frontend/editor/src/core/styles/index.css | 6 +- frontend/editor/src/core/styles/theme.css | 109 +-- frontend/editor/src/core/theme/README.md | 11 +- frontend/editor/src/core/theme/colors.css | 90 +++ frontend/editor/src/core/theme/compat.css | 148 ---- frontend/editor/src/core/theme/index.css | 3 +- .../editor/src/core/theme/mantineTheme.ts | 109 +-- frontend/editor/src/core/theme/primitives.css | 124 +++ .../editor/src/core/tokens/Tokens.stories.tsx | 26 +- frontend/editor/src/core/tokens/base.css | 6 +- frontend/editor/src/core/tokens/tokens.css | 172 ++-- frontend/editor/src/core/tools/Compare.tsx | 4 +- .../core/tools/formFill/FormFieldSidebar.tsx | 6 +- .../core/tools/formFill/FormFill.module.css | 35 +- frontend/editor/src/core/ui/ActionIcon.tsx | 2 +- frontend/editor/src/core/ui/Avatar.css | 4 +- frontend/editor/src/core/ui/Banner.css | 22 +- frontend/editor/src/core/ui/Button.css | 4 +- .../editor/src/core/ui/Button.stories.tsx | 2 +- frontend/editor/src/core/ui/Button.tsx | 2 +- frontend/editor/src/core/ui/Card.css | 8 +- frontend/editor/src/core/ui/Card.stories.tsx | 10 +- frontend/editor/src/core/ui/CarouselDots.css | 6 +- frontend/editor/src/core/ui/ChatFABButton.css | 6 +- frontend/editor/src/core/ui/ChatFABWindow.css | 8 +- .../src/core/ui/ChatFABWindow.stories.tsx | 10 +- frontend/editor/src/core/ui/Checkbox.css | 22 +- frontend/editor/src/core/ui/ChipFlow.css | 2 +- frontend/editor/src/core/ui/Collapsible.css | 8 +- frontend/editor/src/core/ui/ColorInput.tsx | 93 ++- frontend/editor/src/core/ui/DataRow.css | 4 +- frontend/editor/src/core/ui/Drawer.css | 20 +- .../editor/src/core/ui/Drawer.stories.tsx | 6 +- frontend/editor/src/core/ui/Dropdown.css | 18 +- frontend/editor/src/core/ui/EmptyState.css | 8 +- frontend/editor/src/core/ui/FormField.css | 2 +- frontend/editor/src/core/ui/IconBadge.css | 6 +- .../editor/src/core/ui/Inline.stories.tsx | 2 +- frontend/editor/src/core/ui/Input.css | 12 +- frontend/editor/src/core/ui/ListRow.css | 22 +- frontend/editor/src/core/ui/MantineForms.css | 44 +- frontend/editor/src/core/ui/MethodBadge.css | 12 +- .../src/core/ui/MethodBadge.stories.tsx | 2 +- frontend/editor/src/core/ui/MetricCard.css | 20 +- frontend/editor/src/core/ui/Modal.css | 20 +- frontend/editor/src/core/ui/MultiSelect.tsx | 8 +- frontend/editor/src/core/ui/NavItem.css | 18 +- .../editor/src/core/ui/NavItem.stories.tsx | 10 +- frontend/editor/src/core/ui/NumberInput.tsx | 8 +- frontend/editor/src/core/ui/PanelHeader.css | 8 +- frontend/editor/src/core/ui/ProgressBar.css | 2 +- .../src/core/ui/ProgressBar.stories.tsx | 8 +- frontend/editor/src/core/ui/ProgressBar.tsx | 4 +- frontend/editor/src/core/ui/Radio.css | 16 +- .../editor/src/core/ui/SectionDivider.css | 2 +- .../src/core/ui/SectionDivider.stories.tsx | 10 +- frontend/editor/src/core/ui/SectionHeader.css | 6 +- frontend/editor/src/core/ui/Select.css | 16 +- frontend/editor/src/core/ui/Select.tsx | 8 +- frontend/editor/src/core/ui/SettingsRow.css | 4 +- .../src/core/ui/SettingsRow.stories.tsx | 2 +- frontend/editor/src/core/ui/SettingsShell.css | 26 +- .../src/core/ui/SettingsShell.stories.tsx | 4 +- frontend/editor/src/core/ui/Skeleton.css | 6 +- frontend/editor/src/core/ui/Slider.css | 16 +- .../editor/src/core/ui/Spinner.stories.tsx | 2 +- frontend/editor/src/core/ui/Stack.stories.tsx | 6 +- frontend/editor/src/core/ui/StatTile.css | 6 +- frontend/editor/src/core/ui/StatusBadge.css | 14 +- frontend/editor/src/core/ui/StepIndicator.css | 8 +- frontend/editor/src/core/ui/Table.css | 18 +- frontend/editor/src/core/ui/Tabs.css | 20 +- frontend/editor/src/core/ui/Toast.css | 10 +- frontend/editor/src/core/ui/ToggleSwitch.css | 8 +- frontend/editor/src/core/ui/accents.css | 86 +- .../components/DesktopOnboardingModal.tsx | 9 +- .../components/SetupWizard/desktopOAuth.css | 2 +- .../toolPicker/ToolPickerFooterExtensions.tsx | 4 +- .../src/desktop/routes/login/LoginHeader.tsx | 2 +- frontend/editor/src/output.css | 439 ++++++----- .../editor/src/portal/components/AppShell.css | 6 +- .../src/portal/components/AssistantButton.css | 8 +- .../src/portal/components/AssistantPanel.css | 36 +- .../components/AssistantPanel.stories.tsx | 2 +- .../editor/src/portal/components/AuthGate.tsx | 2 +- .../components/ChatFABWidget.stories.tsx | 16 +- .../portal/components/DownloadEditorModal.css | 26 +- .../portal/components/EditorStatusCard.css | 10 +- .../portal/components/EditorStatusCard.tsx | 2 +- .../components/NotificationsDropdown.css | 34 +- .../src/portal/components/ProcessorFlow.css | 56 +- .../src/portal/components/SearchModal.css | 16 +- .../portal/components/SearchModal.stories.tsx | 2 +- .../src/portal/components/SetupChecklist.css | 26 +- .../components/SetupChecklist.stories.tsx | 4 +- .../editor/src/portal/components/Sidebar.css | 29 +- .../src/portal/components/Sidebar.stories.tsx | 2 +- .../editor/src/portal/components/Sidebar.tsx | 12 +- .../src/portal/components/WelcomeBanner.css | 10 +- .../src/portal/components/billing/billing.css | 194 ++--- .../policies/ClassificationLabelsSection.css | 10 +- .../policies/PolicyCategoryIcon.css | 4 +- .../components/processor-flow/FlowSankey.tsx | 4 +- .../processor-flow/useFlowParticles.ts | 4 +- .../procurement/ProcurementModal.stories.tsx | 2 +- .../src/portal/contexts/TierContext.tsx | 4 +- .../src/portal/data/Endpoints.stories.tsx | 18 +- .../editor/src/portal/data/Ops.stories.tsx | 38 +- frontend/editor/src/portal/data/ops.ts | 4 +- frontend/editor/src/portal/theme/base.css | 4 +- .../editor/src/portal/theme/mantineTheme.ts | 16 +- .../editor/src/portal/views/AccountLink.css | 18 +- .../editor/src/portal/views/DeveloperDocs.css | 144 ++-- .../editor/src/portal/views/Documents.css | 30 +- .../editor/src/portal/views/EditorAdmin.css | 46 +- frontend/editor/src/portal/views/Home.css | 23 +- .../src/portal/views/Infrastructure.css | 54 +- .../src/portal/views/PipelineBuilder.css | 86 +- .../editor/src/portal/views/Pipelines.css | 20 +- frontend/editor/src/portal/views/Policies.css | 66 +- .../editor/src/portal/views/Procurement.css | 386 ++++----- .../editor/src/portal/views/SourceBuilder.css | 4 +- frontend/editor/src/portal/views/Sources.css | 112 +-- frontend/editor/src/portal/views/Usage.css | 54 +- frontend/editor/src/portal/views/Users.css | 84 +- .../auth/ui/AuthDefaultCredentials.tsx | 25 +- .../src/proprietary/auth/ui/auth-theme.css | 24 +- .../editor/src/proprietary/auth/ui/auth.css | 78 +- .../src/proprietary/billing/MeterBar.tsx | 13 +- .../components/LoginLandingRedirect.tsx | 2 +- .../proprietary/components/chat/ChatPanel.css | 60 +- .../components/chat/ChatQuickActions.tsx | 37 +- .../ClassificationCategoryManager.css | 6 +- .../shared/PolicyEnforcingOverlay.tsx | 2 +- .../shared/config/configSections/ApiKeys.tsx | 8 +- .../config/configSections/PeopleSection.tsx | 5 +- .../configSections/apiKeys/ApiKeySection.tsx | 8 +- .../dividerWithText/DividerWithText.css | 4 +- .../watchedFolders/CardExpansionModal.tsx | 12 +- .../components/watchedFolders/StatCard.tsx | 6 +- .../watchedFolders/WatchedFolderCard.tsx | 3 +- .../watchedFolders/WatchedFolderHomePage.tsx | 8 +- .../WatchedFolderManagementModal.tsx | 12 +- .../watchedFolders/WatchedFolderSection.tsx | 4 +- .../WatchedFolderWorkbenchView.tsx | 29 +- .../watchedFolders/WatchedFolders.css | 76 +- .../editor/src/proprietary/routes/Landing.tsx | 8 +- .../editor/src/proprietary/routes/Login.tsx | 16 +- .../routes/login/LoggedInState.tsx | 10 +- .../saas/components/auth/GuestUserBanner.css | 4 +- .../saas/components/shared/AppConfigModal.tsx | 12 +- .../shared/charts/StackedBarChart.css | 6 +- .../shared/charts/StackedBarChart.tsx | 4 +- .../shared/config/configSections/ApiKeys.tsx | 8 +- frontend/editor/src/saas/routes/Login.tsx | 6 +- frontend/editor/src/saas/routes/Signup.tsx | 4 +- .../src/saas/routes/authShared/saas-auth.css | 23 +- .../editor/src/saas/styles/saas-theme.css | 20 +- 280 files changed, 4030 insertions(+), 3474 deletions(-) delete mode 100644 frontend/editor/src/core/theme/compat.css diff --git a/.taskfiles/frontend.yml b/.taskfiles/frontend.yml index 9a3b1bdd47..7ac5300a15 100644 --- a/.taskfiles/frontend.yml +++ b/.taskfiles/frontend.yml @@ -207,10 +207,14 @@ tasks: - task: lint:colors lint:colors: - desc: "Enforce theme tokens — colours in core/theme route through the palette" + desc: "Enforce theme tokens — no hardcoded colours or raw primitives in components" + aliases: [lint:colours] deps: [install] cmds: - node editor/scripts/lint/theme-lint.mjs + - node editor/scripts/lint/theme-lint.mjs css-colors + - node editor/scripts/lint/theme-lint.mjs code-colors + - node editor/scripts/lint/theme-lint.mjs no-primitives contrast: desc: "Report low-contrast theme token pairs (warning only, never blocks)" diff --git a/frontend/.storybook/preview.tsx b/frontend/.storybook/preview.tsx index b2459cd926..339fe4f842 100644 --- a/frontend/.storybook/preview.tsx +++ b/frontend/.storybook/preview.tsx @@ -226,8 +226,8 @@ const preview: Preview = { backgrounds: { default: "app", values: [ - { name: "app", value: "var(--color-bg)" }, - { name: "surface", value: "var(--color-surface)" }, + { name: "app", value: "var(--c-bg)" }, + { name: "surface", value: "var(--c-surface)" }, ], }, a11y: { diff --git a/frontend/editor/scripts/lint/theme-lint.mjs b/frontend/editor/scripts/lint/theme-lint.mjs index b21b18f322..561fd5c1cc 100644 --- a/frontend/editor/scripts/lint/theme-lint.mjs +++ b/frontend/editor/scripts/lint/theme-lint.mjs @@ -1,19 +1,24 @@ #!/usr/bin/env node -// Theme colour lint — guards the theme SYSTEM (core/theme/). Two modes: +// Theme colour lint — guards the theme system + app-wide colour hygiene. Modes: // // node theme-lint.mjs enforce: literal colours live ONLY in -// primitives.css; colors/compat/dimensions must -// reference tokens; no duplicate primitives. -// (blocking) -// node theme-lint.mjs contrast warn-only WCAG contrast report (never blocks) -// -// Scope is deliberately just core/theme/ — the palette + token layer this PR -// owns, which is clean, so no baseline file is needed. Enforcing "no hardcoded -// colours" across the whole app (260+ existing sites) is a separate migration. +// primitives.css; core/theme references tokens; +// no duplicate primitives; every referenced +// --p-*/--c-* token resolves. (blocking) +// node theme-lint.mjs css-colors enforce: NO hardcoded colour in any source +// .css (primitives.css + generated output.css +// exempt). Scope: all editor/src. (blocking) +// node theme-lint.mjs code-colors enforce: no hardcoded colour in TS/TSX DOM +// code (default-deny with layered exemptions; +// `// theme-allow-color` opt-out). (blocking) +// node theme-lint.mjs contrast warn-only WCAG report — fixed --c-* pairs + +// status-tone text/fill pairs. (The tone gate +// below 1.6:1 is enforced in the default run.) // // Structural black / white / transparent (shadows, scrims) are always allowed. import { readFileSync, readdirSync } from "node:fs"; +import { execSync } from "node:child_process"; import { relative, resolve, join } from "node:path"; const THEME = resolve(process.cwd(), "editor/src/core/theme"); @@ -26,7 +31,6 @@ const PRIMITIVES = "editor/src/core/theme/primitives.css"; const THEME_FILES = [ "primitives.css", "colors.css", - "compat.css", "dimensions.css", "index.css", ]; @@ -34,8 +38,156 @@ const THEME_FILES = [ // ── colour helpers ───────────────────────────────────────────────────────── const HEX_RE = /#[0-9a-fA-F]{3,8}\b/g; const FUNC_RE = /\b(?:rgba?|hsla?)\(\s*[^)]*\)/g; -const NAMED_RE = - /\b(?:white|black|red|green|blue|orange|yellow|purple|gray|grey|silver|transparent)\b/g; +// CSS named colours (structural white/black/transparent handled separately). +// Kept broad so `color: teal`/`navy`/`crimson`/`cyan` can't slip past the gate. +const NAMED_COLORS = [ + "aliceblue", + "antiquewhite", + "aqua", + "aquamarine", + "azure", + "beige", + "bisque", + "blanchedalmond", + "blue", + "blueviolet", + "brown", + "burlywood", + "cadetblue", + "chartreuse", + "chocolate", + "coral", + "cornflowerblue", + "cornsilk", + "crimson", + "cyan", + "darkblue", + "darkcyan", + "darkgoldenrod", + "darkgray", + "darkgreen", + "darkgrey", + "darkkhaki", + "darkmagenta", + "darkolivegreen", + "darkorange", + "darkorchid", + "darkred", + "darksalmon", + "darkseagreen", + "darkslateblue", + "darkslategray", + "darkslategrey", + "darkturquoise", + "darkviolet", + "deeppink", + "deepskyblue", + "dimgray", + "dimgrey", + "dodgerblue", + "firebrick", + "floralwhite", + "forestgreen", + "fuchsia", + "gainsboro", + "ghostwhite", + "gold", + "goldenrod", + "gray", + "green", + "greenyellow", + "grey", + "honeydew", + "hotpink", + "indianred", + "indigo", + "ivory", + "khaki", + "lavender", + "lavenderblush", + "lawngreen", + "lemonchiffon", + "lightblue", + "lightcoral", + "lightcyan", + "lightgoldenrodyellow", + "lightgray", + "lightgreen", + "lightgrey", + "lightpink", + "lightsalmon", + "lightseagreen", + "lightskyblue", + "lightslategray", + "lightslategrey", + "lightsteelblue", + "lightyellow", + "lime", + "limegreen", + "linen", + "magenta", + "maroon", + "mediumaquamarine", + "mediumblue", + "mediumorchid", + "mediumpurple", + "mediumseagreen", + "mediumslateblue", + "mediumspringgreen", + "mediumturquoise", + "mediumvioletred", + "midnightblue", + "mintcream", + "mistyrose", + "moccasin", + "navajowhite", + "navy", + "oldlace", + "olive", + "olivedrab", + "orange", + "orangered", + "orchid", + "palegoldenrod", + "palegreen", + "paleturquoise", + "palevioletred", + "papayawhip", + "peachpuff", + "peru", + "pink", + "plum", + "powderblue", + "purple", + "rebeccapurple", + "red", + "rosybrown", + "royalblue", + "saddlebrown", + "salmon", + "sandybrown", + "seagreen", + "seashell", + "sienna", + "silver", + "skyblue", + "slateblue", + "slategray", + "slategrey", + "snow", + "springgreen", + "steelblue", + "tan", + "teal", + "thistle", + "tomato", + "turquoise", + "violet", + "wheat", + "yellow", + "yellowgreen", +]; +const NAMED_RE = new RegExp(`\\b(?:${NAMED_COLORS.join("|")})\\b`, "g"); function expandHex(hex) { let h = hex.slice(1).toLowerCase(); @@ -66,6 +218,98 @@ function stripComments(text) { return text.replace(/\/\*[\s\S]*?\*\//g, (m) => m.replace(/[^\n]/g, " ")); } +// ── shared colour math + token resolution (used by contrast report + tone guard) +function readPrimitives(css) { + const primitives = {}; + for (const m of css.matchAll( + /(--p-[a-z0-9-]+)\s*:\s*(#[0-9a-fA-F]{3,8})\s*;/g, + )) + primitives[m[1]] = m[2]; + return primitives; +} +function hexToRgb(hex) { + // expandHex normalises 3/4-digit shorthand to 6/8; parse alpha from 8-digit. + const h = expandHex(hex.startsWith("#") ? hex : "#" + hex).slice(1); + return { + r: parseInt(h.slice(0, 2), 16), + g: parseInt(h.slice(2, 4), 16), + b: parseInt(h.slice(4, 6), 16), + a: h.length >= 8 ? parseInt(h.slice(6, 8), 16) / 255 : 1, + }; +} +const over = (f, b) => ({ + r: f.r * f.a + b.r * (1 - f.a), + g: f.g * f.a + b.g * (1 - f.a), + b: f.b * f.a + b.b * (1 - f.a), + a: 1, +}); +const mix = (a, b, p) => ({ + r: (a.r * p + b.r * (100 - p)) / 100, + g: (a.g * p + b.g * (100 - p)) / 100, + b: (a.b * p + b.b * (100 - p)) / 100, + a: 1, +}); +// Resolve any token value: hex, rgb(a), var(--x[, fallback]) (--p-* → palette, +// else the theme map), or color-mix(in srgb, A n%, B|transparent). +function resolveColorValue(v, t, primitives, seen) { + if (v == null) return null; + // Collapse internal whitespace so multi-line values (e.g. a color-mix() split + // across lines in tokens.css) match the single-line grammars below. + v = v.replace(/\s+/g, " ").trim(); + let m; + if (v.startsWith("#")) return hexToRgb(v); + if ((m = v.match(/^rgba?\(([^)]+)\)$/))) { + const n = m[1] + .split(/[,/\s]+/) + .map(Number) + .filter((x) => !Number.isNaN(x)); + return { r: n[0], g: n[1], b: n[2], a: n[3] ?? 1 }; + } + if ((m = v.match(/^var\(\s*(--[a-z0-9-]+)\s*(?:,\s*([\s\S]+))?\)$/))) { + return resolveColorVar(m[1], m[2], t, primitives, seen); + } + if ( + (m = v.match( + /^color-mix\(\s*in srgb\s*,\s*(.+?)\s+(\d+)%\s*,\s*(.+?)\s*\)$/, + )) + ) { + const a = resolveColorValue(m[1], t, primitives, seen); + if (!a) return null; + if (m[3].trim() === "transparent") return { ...a, a: +m[2] / 100 }; + const b = resolveColorValue(m[3].trim(), t, primitives, seen); + return b ? mix(a, b, +m[2]) : null; + } + return null; +} +function resolveColorVar(name, fallback, t, primitives, seen) { + if (name.startsWith("--p-")) { + return primitives[name] + ? hexToRgb(primitives[name]) + : fallback + ? resolveColorValue(fallback, t, primitives, seen) + : null; + } + if (!seen.has(name) && t[name] !== undefined) { + const next = new Set(seen).add(name); + const r = resolveColorValue(t[name], t, primitives, next); + if (r) return r; + } + return fallback ? resolveColorValue(fallback, t, primitives, seen) : null; +} +const relativeLuminance = ({ r, g, b }) => { + const f = (v) => { + v /= 255; + return v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4; + }; + return 0.2126 * f(r) + 0.7152 * f(g) + 0.0722 * f(b); +}; +const contrastRatio = (a, b) => { + const [hi, lo] = [relativeLuminance(a), relativeLuminance(b)].sort( + (x, y) => y - x, + ); + return (hi + 0.05) / (lo + 0.05); +}; + // ── enforce: literals only in primitives.css, no duplicate primitives ──────── function check() { const violations = []; @@ -149,11 +393,7 @@ function check() { function reportContrast() { const primitivesCss = readFileSync(join(THEME, "primitives.css"), "utf8"); const colorsCss = readFileSync(join(THEME, "colors.css"), "utf8"); - const primitives = {}; - for (const m of primitivesCss.matchAll( - /(--p-[a-z0-9-]+)\s*:\s*(#[0-9a-fA-F]{3,8})\s*;/g, - )) - primitives[m[1]] = m[2]; + const primitives = readPrimitives(primitivesCss); const blocks = []; for (const m of colorsCss.matchAll(/([^{}]+)\{([^}]*)\}/g)) { const decls = {}; @@ -189,82 +429,8 @@ function reportContrast() { }; const flatten = (list) => Object.assign({ ...SEED }, ...list.map((b) => b.decls)); - const hexToRgb = (h) => { - h = h.replace("#", ""); - if (h.length === 3) - h = h - .split("") - .map((c) => c + c) - .join(""); - return { - r: parseInt(h.slice(0, 2), 16), - g: parseInt(h.slice(2, 4), 16), - b: parseInt(h.slice(4, 6), 16), - a: 1, - }; - }; - const over = (f, b) => ({ - r: f.r * f.a + b.r * (1 - f.a), - g: f.g * f.a + b.g * (1 - f.a), - b: f.b * f.a + b.b * (1 - f.a), - a: 1, - }); - const mix = (a, b, p) => ({ - r: (a.r * p + b.r * (100 - p)) / 100, - g: (a.g * p + b.g * (100 - p)) / 100, - b: (a.b * p + b.b * (100 - p)) / 100, - a: 1, - }); - // Resolve any token value: hex, rgb(a), var(--x[, fallback]) (--p-* → palette, - // else the theme map/seed), or color-mix(in srgb, A n%, B|transparent). - function resolveValue(v, t, seen) { - if (v == null) return null; - v = v.trim(); - let m; - if (v.startsWith("#")) return hexToRgb(v); - if ((m = v.match(/^rgba?\(([^)]+)\)$/))) { - const n = m[1] - .split(/[,/\s]+/) - .map(Number) - .filter((x) => !Number.isNaN(x)); - return { r: n[0], g: n[1], b: n[2], a: n[3] ?? 1 }; - } - if ((m = v.match(/^var\(\s*(--[a-z0-9-]+)\s*(?:,\s*([\s\S]+))?\)$/))) { - return resolveVar(m[1], m[2], t, seen); - } - if ((m = v.match(/^color-mix\(in srgb,\s*(.+?)\s+(\d+)%\s*,\s*(.+)\)$/))) { - const a = resolveValue(m[1], t, seen); - if (!a) return null; - if (m[3].trim() === "transparent") return { ...a, a: +m[2] / 100 }; - const b = resolveValue(m[3].trim(), t, seen); - return b ? mix(a, b, +m[2]) : null; - } - return null; - } - function resolveVar(name, fallback, t, seen) { - if (name.startsWith("--p-")) { - return primitives[name] - ? hexToRgb(primitives[name]) - : fallback - ? resolveValue(fallback, t, seen) - : null; - } - if (!seen.has(name) && t[name] !== undefined) { - const next = new Set(seen).add(name); - const r = resolveValue(t[name], t, next); - if (r) return r; - } - return fallback ? resolveValue(fallback, t, seen) : null; - } const resolve = (token, t) => - resolveValue(t[token] ?? null, t, new Set([token])); - const lum = ({ r, g, b }) => { - const f = (v) => { - v /= 255; - return v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4; - }; - return 0.2126 * f(r) + 0.7152 * f(g) + 0.0722 * f(b); - }; + resolveColorValue(t[token] ?? null, t, primitives, new Set([token])); const contrast = (t1, t2, t) => { const surface = resolve("--c-surface", t); let a = resolve(t1, t); @@ -272,8 +438,7 @@ function reportContrast() { if (!a || !b || !surface) return null; if (a.a < 1) a = over(a, surface); if (b.a < 1) b = over(b, surface); - const [hi, lo] = [lum(a), lum(b)].sort((x, y) => y - x); - return (hi + 0.05) / (lo + 0.05); + return contrastRatio(a, b); }; const PAIRS = [ ["--c-text", "--c-surface", 4.5], @@ -307,23 +472,397 @@ function reportContrast() { ); } +// ── status-tone text on its own fill ───────────────────────────────────────── +// Checks --color-{hue} text against its --color-{hue}-light fill, per theme. +// Below TONE_INVISIBLE blocks the build; TONE_FLOOR (WCAG AA) is advisory. +const TOKENS_CSS = resolve(process.cwd(), "editor/src/core/tokens/tokens.css"); +const TONE_FLOOR = 3.0; +const TONE_INVISIBLE = 1.6; +// Compute the contrast of every --color-{hue} text on its own --color-{hue}-light +// fill, per theme. Returns [{ theme, base, fill, ratio|null }] — no printing, so +// both the warn-only report and the blocking guard can share it. +function toneContrastResults() { + const primitives = readPrimitives( + readFileSync(join(THEME, "primitives.css"), "utf8"), + ); + // Strip comments first: a selector's captured prefix can otherwise include a + // preceding comment that mentions data-theme="dark", misclassifying the block. + const css = stripComments(readFileSync(TOKENS_CSS, "utf8")); + const isDark = (sel) => /data-theme="dark"|color-scheme="dark"/.test(sel); + const lightTones = {}; + const darkTones = {}; + for (const m of css.matchAll(/([^{}]+)\{([^}]*)\}/g)) { + const target = isDark(m[1]) ? darkTones : lightTones; + for (const d of m[2].matchAll(/(--color-[a-z0-9-]+)\s*:\s*([^;]+);/g)) + target[d[1]] = d[2].trim(); + } + // Dark only overrides the tones it redefines; unspecified ones inherit light. + const themes = { light: lightTones, dark: { ...lightTones, ...darkTones } }; + const white = { r: 255, g: 255, b: 255, a: 1 }; + const results = []; + for (const [theme, t] of Object.entries(themes)) { + const bases = Object.keys(t) + .map((k) => /^(--color-[a-z]+)-light$/.exec(k)?.[1]) + .filter((base) => base && t[base] !== undefined); + for (const base of bases) { + const fill = `${base}-light`; + const fg = resolveColorValue(t[base], t, primitives, new Set([base])); + const bg = resolveColorValue(t[fill], t, primitives, new Set([fill])); + const ratio = + fg && bg + ? contrastRatio( + fg.a < 1 ? over(fg, bg) : fg, + bg.a < 1 ? over(bg, white) : bg, + ) + : null; + results.push({ theme, base, fill, ratio }); + } + } + return results; +} + +function reportToneContrast() { + const results = toneContrastResults(); + let warnings = 0; + let invisible = 0; + console.log("tone-contrast report: text on its own -light fill\n"); + let theme = ""; + for (const { theme: th, base, fill, ratio } of results) { + if (th !== theme) { + theme = th; + console.log(` ${theme}`); + } + if (ratio == null) { + console.log(` ? ${base} on ${fill} (unresolved)`); + continue; + } + // ✖ = near-invisible (blocks CI), ⚠ = below the WCAG floor (warn only). + const mark = + ratio < TONE_INVISIBLE ? "✖ " : ratio < TONE_FLOOR ? "⚠ " : " "; + if (ratio < TONE_INVISIBLE) invisible++; + else if (ratio < TONE_FLOOR) warnings++; + console.log( + ` ${mark}${ratio.toFixed(2).padStart(5)} (floor ${TONE_FLOOR}, blocks <${TONE_INVISIBLE}) ${base} on ${fill}`, + ); + } + const parts = []; + if (invisible) + parts.push(`✖ ${invisible} near-invisible (<${TONE_INVISIBLE}:1)`); + if (warnings) parts.push(`⚠ ${warnings} below the ${TONE_FLOOR} floor`); + console.log( + parts.length + ? `\n${parts.join(", ")}. ✖ blocks the build; ⚠ is advisory.\n` + : "\n✓ all tones clear the floor.\n", + ); +} + +// ── css-colors (blocking): no hardcoded colour in ANY source .css ──────────── +// App-wide guard that source CSS routes every colour through the palette. File +// list from `git ls-files` (a VCS query, never a directory walk feeding a read). +// primitives.css (the literal home) and generated output.css are exempt. +function checkAppCss() { + const EXEMPT = /(?:^|\/)(?:primitives\.css|output\.css)$/; + const listed = execSync("git ls-files -- editor/src", { encoding: "utf8" }) + .split("\n") + .map((l) => l.trim()) + .filter((l) => l && l.endsWith(".css") && !EXEMPT.test(l)); + + const violations = []; + const lineOf = (text, index) => text.slice(0, index).split("\n").length; + for (const rel of listed) { + const text = stripComments(readFileSync(rel, "utf8")); + for (const re of [HEX_RE, FUNC_RE]) { + re.lastIndex = 0; + let m; + while ((m = re.exec(text)) !== null) { + if (/var\(/i.test(m[0])) continue; // rgb()/color-mix wrapping a token + const norm = normalizeColor(m[0]); + if (isStructuralColor(norm)) continue; + violations.push({ + file: rel, + line: lineOf(text, m.index), + msg: `raw colour ${m[0]} — define it in primitives.css and use var(--p-…)`, + }); + } + } + text.split("\n").forEach((line, i) => { + const colon = line.indexOf(":"); + if (colon < 0 || /[{}]/.test(line)) return; + if (!/^\s*(?:--)?[a-z][a-z0-9-]*\s*$/i.test(line.slice(0, colon))) return; + const value = line + .slice(colon + 1) + .replace(/--[a-z0-9-]+/gi, " ") + .replace(/url\([^)]*\)/g, " ") + .replace(/["'][^"']*["']/g, " "); + for (const nm of value.match(NAMED_RE) || []) { + if (isStructuralName(nm)) continue; + violations.push({ + file: rel, + line: i + 1, + msg: `named colour "${nm}" — define it in primitives.css and use var(--p-…)`, + }); + } + }); + } + return violations; +} + +// ── code-colors (blocking): no hardcoded colour in TS/TSX DOM code ─────────── +// Default-deny with layered exemptions: structural black/white/transparent; +// safe contexts on the line (var() fallback, canvas/pdf-lib rgb, an explicit +// `// theme-allow-color` opt-out); and exempt PATHS where colour literals are +// inherent (rendering/vendor/config/tests/stories). +const CODE_EXEMPT_PATH = [ + /Thumbnail|Overlay|DrawingCanvas|PageEditor|MobileScannerPage/, + // PDF rendering/drawing surfaces that legitimately carry colour literals — + // scoped to specific tool paths, not a blanket "pdf" substring (which used to + // exempt most of the app in a PDF product). + /pdfTextEditor|pixelCompare|\/compare\.ts$|customPrimary|accentColors/, + /validateSignature\/outputtedPDFSections|CenteredMessageSection|StatusBadgeSection/, + /\/viewer\/|Annotation|useViewerReadAloud|CommentsSidebar|\/constants\/search\.ts$|SignaturePreview/, + /ColorPicker|ColorControl|WatchedFolderManagementModal|watchedFolderPresets|fileColors|unifiedBackground|folder\.ts$|policyFolders/, + /OAuthButtons|oauthCallbackHtml/, + /mantineTheme|\/theme\.ts$|toolsTaxonomy|LayoutPreview|PageNumberPreview|CloudStorageIcons/, + /\/onboarding\//, + /addStamp|addWatermark|\/tooltips\//, + /UpgradeBanner|AdminPlanSection/, + /\.test\.[jt]sx?$|\.stories\.[jt]sx?$|\/types\//, +]; +const CODE_HEX = + /#(?:[0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{4}|[0-9a-fA-F]{3})(?![0-9a-fA-F])/g; +const CODE_RGB = /rgba?\(([^)]*)\)/gi; +const CODE_HSL = /hsla?\(([^)]*)\)/gi; +// NOTE: bare named colours (e.g. 'blue') are intentionally NOT flagged in +// TS/TSX — they are dominated by legitimate Mantine palette props (`c="red"`, +// `color="blue"`, which are theme-routed) and provider names ('azure'), so a +// string match produces mostly false positives. hsl()/hex/rgb() are unambiguous. +const codeStructuralHex = (h) => + /^#(?:000|fff|000f|ffff|000000|ffffff|00000000|ffffffff)$/i.test(h); +// Line-level skips for contexts where a colour literal is inherent (canvas / +// pdf-lib drawing, computed-style reads) or explicitly opted out. NOTE: a +// `var(--x, #hex)` literal fallback is deliberately NOT skipped — the hex in the +// fallback is still a hardcoded colour and must route through a token. +const CODE_SKIP_LINE = + /theme-allow-color|readColor\(|getPropertyValue|\.colors\.[a-z]+\?\.\[|fillStyle|strokeStyle|shadowColor|addColorStop|createLinearGradient|ctx\.|getContext/i; +function codeStripNonCode(text) { + return text + .replace(/\/\*[\s\S]*?\*\//g, (m) => m.replace(/[^\n]/g, " ")) + .replace( + /(^|[^:])\/\/[^\n]*/g, + (m, p) => p + m.slice(p.length).replace(/[^\n]/g, " "), + ) + .replace(/&#\d+;/g, " "); +} +function codeRgbIsColour(inner) { + if (/var\(/.test(inner)) return false; + const p = inner + .split(/[, /]+/) + .map((x) => x.trim()) + .filter(Boolean); + if (!/^\d/.test(p[0] || "")) return false; + const nums = p.slice(0, 3).map(Number); + if (nums.some((n) => Number.isNaN(n))) return false; + if (nums.every((n) => n <= 1)) return false; // pdf-lib rgb(0..1) + const k = `${nums[0]},${nums[1]},${nums[2]}`; + return k !== "0,0,0" && k !== "255,255,255"; +} +function checkCodeColors() { + const files = execSync("git ls-files -- editor/src", { encoding: "utf8" }) + .split("\n") + .map((l) => l.trim()) + .filter( + (l) => + /\.(ts|tsx)$/.test(l) && !CODE_EXEMPT_PATH.some((re) => re.test(l)), + ); + const violations = []; + for (const rel of files) { + const raw = readFileSync(rel, "utf8"); + const rawLines = raw.split("\n"); + const text = codeStripNonCode(raw); + text.split("\n").forEach((line, i) => { + if (/theme-allow-color/.test(rawLines[i] || "")) return; + if (CODE_SKIP_LINE.test(line)) return; + const hits = []; + for (const h of line.match(CODE_HEX) || []) + if (!codeStructuralHex(h)) hits.push(h); + for (const m of line.match(CODE_RGB) || []) + if (codeRgbIsColour(m.replace(/rgba?\(|\)/gi, ""))) hits.push(m); + for (const m of line.match(CODE_HSL) || []) + if (!/var\(/.test(m)) hits.push(m); + for (const h of hits) + violations.push({ + file: rel, + line: i + 1, + msg: `hardcoded colour ${h} — use a var(--c-*/--p-*) token, or add \`// theme-allow-color \` if it must be a literal`, + }); + }); + } + return violations; +} + +// ── token-resolution (blocking): every referenced --p-*/--c-* must resolve ──── +// A `var(--p-…)`/`var(--c-…)` with no fallback silently computes to the initial +// value (transparent/inherited) when the token is undefined, so the colour just +// disappears — invisible to the literal checks above. Assert every such +// reference has a definition somewhere (any source .css/.ts/.tsx) or a fallback. +// Runtime-injected families (--user-*, --mantine-*, --accent-*) are out of scope. +function checkTokenResolution() { + const files = execSync("git ls-files -- editor/src", { encoding: "utf8" }) + .split("\n") + .map((l) => l.trim()) + .filter((l) => /\.(css|ts|tsx)$/.test(l)); + const DEF_RE = /(--[a-z0-9-]+)\s*:/gi; + // Capture the token and the char that follows it (`,` ⇒ has a fallback). + const REF_RE = /var\(\s*(--[a-z0-9-]+)\s*(,|\))/gi; + const defined = new Set(); + const refs = []; + const lineOf = (text, index) => text.slice(0, index).split("\n").length; + for (const rel of files) { + const text = stripComments(readFileSync(rel, "utf8")); + for (const m of text.matchAll(DEF_RE)) defined.add(m[1]); + for (const m of text.matchAll(REF_RE)) { + const [token, next] = [m[1], m[2]]; + if (!/^--[pc]-/.test(token)) continue; // only our theme tokens + if (next === ",") continue; // has a fallback → degrades safely + refs.push({ file: rel, line: lineOf(text, m.index), token }); + } + } + return refs.filter((r) => !defined.has(r.token)); +} + +// ── no-primitives (blocking): components must reference --c-* SEMANTIC tokens, +// not raw --p-* palette primitives — otherwise a colour-scheme change to the +// semantic layer won't reach them. --p-* is allowed ONLY in the token-definition +// layer (primitives/colors/dimensions + legacy vocab files + accents). +const PRIMITIVE_LAYER = [ + /^editor\/src\/core\/theme\//, + /^editor\/src\/core\/styles\/theme\.css$/, + /^editor\/src\/core\/tokens\/tokens\.css$/, + /^editor\/src\/saas\/styles\/saas-theme\.css$/, + /^editor\/src\/proprietary\/auth\/ui\/auth-theme\.css$/, + /^editor\/src\/core\/ui\/accents\.css$/, +]; +function checkNoPrimitives() { + const files = execSync("git ls-files -- editor/src", { encoding: "utf8" }) + .split("\n") + .map((l) => l.trim()) + .filter( + (l) => + /\.(css|scss|ts|tsx)$/.test(l) && + !PRIMITIVE_LAYER.some((re) => re.test(l)), + ); + const REF = /var\(\s*(--p-[a-z0-9-]+)/g; + const violations = []; + const lineOf = (text, index) => text.slice(0, index).split("\n").length; + for (const rel of files) { + const text = stripComments(readFileSync(rel, "utf8")); + for (const m of text.matchAll(REF)) + violations.push({ file: rel, line: lineOf(text, m.index), token: m[1] }); + } + return violations; +} + // ── CLI ────────────────────────────────────────────────────────────────────── +if (process.argv.includes("no-primitives")) { + const v = checkNoPrimitives(); + if (v.length) { + console.error( + `\n✖ theme-lint no-primitives: ${v.length} raw --p-* primitive ref(s) in components — use a --c-* semantic token so colour-scheme changes propagate:\n`, + ); + for (const x of v) console.error(` ${x.file}:${x.line} var(${x.token})`); + console.error(""); + process.exit(1); + } + console.log( + "✓ theme-lint no-primitives: components reference --c-* semantic tokens (no raw --p-*)", + ); + process.exit(0); +} + if (process.argv.includes("contrast")) { reportContrast(); + reportToneContrast(); process.exit(0); // never blocks } +if (process.argv.includes("css-colors")) { + const v = checkAppCss(); + if (v.length) { + console.error( + `\n✖ theme-lint css-colors: ${v.length} hardcoded colour(s) in source CSS:\n`, + ); + for (const x of v) console.error(` ${x.file}:${x.line} ${x.msg}`); + console.error( + `\nDefine every colour once in core/theme/primitives.css and reference it with var(--p-…).\n`, + ); + process.exit(1); + } + console.log( + "✓ theme-lint css-colors: source CSS is free of hardcoded colour", + ); + process.exit(0); +} + +if (process.argv.includes("code-colors")) { + const v = checkCodeColors(); + if (v.length) { + console.error( + `\n✖ theme-lint code-colors: ${v.length} hardcoded colour(s) in TS/TSX:\n`, + ); + for (const x of v) console.error(` ${x.file}:${x.line} ${x.msg}`); + console.error(""); + process.exit(1); + } + console.log( + "✓ theme-lint code-colors: no hardcoded colour in TS/TSX DOM code (rendering/vendor/config areas exempt)", + ); + process.exit(0); +} + const violations = check(); -if (violations.length) { +// Block near-invisible status tones (< TONE_INVISIBLE) in either theme. +const toneViolations = toneContrastResults().filter( + (r) => r.ratio != null && r.ratio < TONE_INVISIBLE, +); +// Block references to --p-*/--c-* tokens that are defined nowhere (no fallback). +const unresolvedTokens = checkTokenResolution(); +if (unresolvedTokens.length) { console.error( - `\n✖ theme-lint: ${violations.length} raw/duplicate colour(s) in core/theme/:\n`, + `\n✖ theme-lint: ${unresolvedTokens.length} reference(s) to undefined --p-*/--c-* token(s) (colour silently drops to transparent/inherited):\n`, ); - for (const v of violations) console.error(` ${v.file}:${v.line} ${v.msg}`); + for (const r of unresolvedTokens) + console.error( + ` ${r.file}:${r.line} var(${r.token}) — not defined anywhere`, + ); console.error( - `\nDefine every colour once in core/theme/primitives.css and reference it with var(--p-…).\n`, + `\nDefine the token (primitive in primitives.css, semantic in colors.css) or give the var() a fallback.\n`, ); +} +if (violations.length || toneViolations.length || unresolvedTokens.length) { + if (violations.length) { + console.error( + `\n✖ theme-lint: ${violations.length} raw/duplicate colour(s) in core/theme/:\n`, + ); + for (const v of violations) + console.error(` ${v.file}:${v.line} ${v.msg}`); + console.error( + `\nDefine every colour once in core/theme/primitives.css and reference it with var(--p-…).\n`, + ); + } + if (toneViolations.length) { + console.error( + `\n✖ theme-lint: ${toneViolations.length} status tone(s) below the ${TONE_INVISIBLE}:1 legibility floor (text nearly invisible on its own fill):\n`, + ); + for (const v of toneViolations) + console.error( + ` ${v.base} on ${v.fill} — ${v.ratio.toFixed(2)}:1 in ${v.theme} theme`, + ); + console.error( + `\nGive --color-{hue}-light a paler/darker tint in core/tokens/tokens.css so the label is legible.\n`, + ); + } process.exit(1); } console.log( - "✓ theme-lint: core/theme colours all route through the primitive palette", + "✓ theme-lint: core/theme colours route through the primitive palette; status tones clear the legibility floor", ); diff --git a/frontend/editor/src/cloud/components/onboarding/slides/SaasOnboardingSlides.module.css b/frontend/editor/src/cloud/components/onboarding/slides/SaasOnboardingSlides.module.css index 3fcdb93831..a02d7c4ce9 100644 --- a/frontend/editor/src/cloud/components/onboarding/slides/SaasOnboardingSlides.module.css +++ b/frontend/editor/src/cloud/components/onboarding/slides/SaasOnboardingSlides.module.css @@ -8,7 +8,7 @@ } .freeHighlight { - background: linear-gradient(135deg, #6366f1, #ec4899); + background: linear-gradient(135deg, var(--c-hue-indigo), var(--c-hue-pink)); -webkit-background-clip: text; background-clip: text; color: transparent; @@ -36,7 +36,7 @@ flex-direction: column; max-height: 200px; overflow-y: auto; - border: 1px solid var(--border-default, #d1d5db); + border: 1px solid var(--c-border); border-radius: 12px; margin-bottom: 12px; } @@ -49,7 +49,7 @@ } .memberRow + .memberRow { - border-top: 1px solid var(--border-subtle, #e5e7eb); + border-top: 1px solid var(--c-border-subtle); } .memberIdentity { @@ -62,7 +62,7 @@ .memberName { font-size: 14px; font-weight: 600; - color: var(--onboarding-title, #111827); + color: var(--c-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -70,7 +70,7 @@ .memberEmail { font-size: 12px; - color: var(--onboarding-body, #6b7280); + color: var(--c-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; diff --git a/frontend/editor/src/cloud/components/shared/FreeLimitReachedModal.tsx b/frontend/editor/src/cloud/components/shared/FreeLimitReachedModal.tsx index 177a15b7af..118b0a2d91 100644 --- a/frontend/editor/src/cloud/components/shared/FreeLimitReachedModal.tsx +++ b/frontend/editor/src/cloud/components/shared/FreeLimitReachedModal.tsx @@ -87,7 +87,7 @@ export function FreeLimitReachedModal({ onClose }: FreeLimitReachedModalProps) { content: { overflow: "hidden", border: "none", - background: "var(--bg-surface)", + background: "var(--c-surface)", maxHeight: "90vh", display: "flex", flexDirection: "column", diff --git a/frontend/editor/src/cloud/components/shared/SpendCapReachedModal.tsx b/frontend/editor/src/cloud/components/shared/SpendCapReachedModal.tsx index 91f4ec6e95..405bbe2ef2 100644 --- a/frontend/editor/src/cloud/components/shared/SpendCapReachedModal.tsx +++ b/frontend/editor/src/cloud/components/shared/SpendCapReachedModal.tsx @@ -87,7 +87,7 @@ export function SpendCapReachedModal({ onClose }: SpendCapReachedModalProps) { content: { overflow: "hidden", border: "none", - background: "var(--bg-surface)", + background: "var(--c-surface)", maxHeight: "90vh", display: "flex", flexDirection: "column", diff --git a/frontend/editor/src/cloud/components/shared/config/configSections/Payg.css b/frontend/editor/src/cloud/components/shared/config/configSections/Payg.css index cf9378ac9e..581f3af671 100644 --- a/frontend/editor/src/cloud/components/shared/config/configSections/Payg.css +++ b/frontend/editor/src/cloud/components/shared/config/configSections/Payg.css @@ -2,25 +2,22 @@ Uses the app's semantic theme tokens (theme.css) so it tracks light/dark. */ .payg { - --payg-accent: #0a8bff; - --payg-accent-soft: rgba(10, 139, 255, 0.1); + --payg-accent: var(--c-primary); + --payg-accent-soft: color-mix(in srgb, var(--c-primary) 10%, transparent); --payg-radius: 14px; --payg-gap: 20px; /* Cards sit ON the modal content bg; in light that's white-on-white so we lean on border + shadow. Tokens are overridden per scheme below. */ - --payg-card-bg: var(--bg-surface); - --payg-card-border: var(--border-default); - --payg-inset-bg: var(--bg-raised); - --payg-divider: var(--border-subtle); + --payg-card-bg: var(--c-surface); + --payg-card-border: var(--c-border); + --payg-inset-bg: var(--c-surface-raised); + --payg-divider: var(--c-border-subtle); } -/* Dark mode: modal content bg is #131729 (--bg-surface), so lift cards above it */ +/* Dark mode: surfaces/borders track the neutral --c-* tokens (set on the base + rule); only the brand-azure accent tint is tuned brighter for dark. */ [data-mantine-color-scheme="dark"] .payg { - --payg-card-bg: #1c2340; - --payg-card-border: #2d3560; - --payg-inset-bg: #0d1020; - --payg-accent-soft: rgba(79, 142, 245, 0.16); - --payg-divider: #2d3560; + --payg-accent-soft: color-mix(in srgb, var(--c-primary) 16%, transparent); } /* ── Header ─────────────────────────────────────────────────────────── */ @@ -29,12 +26,12 @@ font-size: 1.35rem; font-weight: 700; letter-spacing: -0.01em; - color: var(--text-primary); + color: var(--c-text); } .payg-header__subtitle { margin-top: 4px; font-size: 0.875rem; - color: var(--text-muted); + color: var(--c-text-subtle); } .payg-role-pill { display: inline-flex; @@ -49,12 +46,12 @@ .payg-role-pill[data-leader="true"] { background: var(--payg-accent-soft); color: var(--payg-accent); - border: 1px solid rgba(10, 139, 255, 0.25); + border: 1px solid color-mix(in srgb, var(--c-primary) 25%, transparent); } .payg-role-pill[data-leader="false"] { - background: var(--bg-muted); - color: var(--text-muted); - border: 1px solid var(--border-default); + background: var(--c-surface-sunken); + color: var(--c-text-subtle); + border: 1px solid var(--c-border); } /* ── Plan header: free-vs-metered split (shared by free + subscribed) ──── */ @@ -73,7 +70,7 @@ } .payg-planhead__eyebrow { font-size: 0.78rem; - color: var(--text-muted); + color: var(--c-text-subtle); } .payg-planhead__split { display: grid; @@ -98,7 +95,7 @@ margin-bottom: 8px; } .payg-planhead__lbl--free { - color: #10b981; + color: var(--c-success); } .payg-planhead__lbl--meter { color: var(--payg-accent); @@ -110,14 +107,14 @@ margin: 0; font-size: 1.05rem; font-weight: 700; - color: var(--text-primary); + color: var(--c-text); letter-spacing: -0.01em; line-height: 1.25; } .payg-planhead__body { margin: 5px 0 0; font-size: 0.85rem; - color: var(--text-muted); + color: var(--c-text-subtle); line-height: 1.5; } @media (max-width: 640px) { @@ -147,11 +144,11 @@ .payg-card__title { font-size: 0.95rem; font-weight: 650; - color: var(--text-primary); + color: var(--c-text); } .payg-card__subtitle { font-size: 0.8125rem; - color: var(--text-muted); + color: var(--c-text-subtle); margin-top: 2px; } @@ -175,22 +172,22 @@ .payg-hero[data-state="FULL"]::before { background: linear-gradient( 135deg, - rgba(10, 139, 255, 0.12) 0%, - rgba(10, 139, 255, 0) 55% + color-mix(in srgb, var(--c-primary) 12%, transparent) 0%, + color-mix(in srgb, var(--c-primary) 0%, transparent) 55% ); } .payg-hero[data-state="WARNED"]::before { background: linear-gradient( 135deg, - rgba(234, 179, 8, 0.16) 0%, - rgba(234, 179, 8, 0) 55% + color-mix(in srgb, var(--c-warning) 16%, transparent) 0%, + color-mix(in srgb, var(--c-warning) 0%, transparent) 55% ); } .payg-hero[data-state="DEGRADED"]::before { background: linear-gradient( 135deg, - rgba(239, 68, 68, 0.16) 0%, - rgba(239, 68, 68, 0) 55% + color-mix(in srgb, var(--c-danger) 16%, transparent) 0%, + color-mix(in srgb, var(--c-danger) 0%, transparent) 55% ); } .payg-hero__inner { @@ -202,7 +199,7 @@ font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; - color: var(--text-muted); + color: var(--c-text-subtle); } .payg-hero__figure { display: flex; @@ -215,12 +212,12 @@ font-weight: 750; line-height: 1; letter-spacing: -0.03em; - color: var(--text-primary); + color: var(--c-text); font-variant-numeric: tabular-nums; } .payg-hero__cap { font-size: 1rem; - color: var(--text-muted); + color: var(--c-text-subtle); font-variant-numeric: tabular-nums; } .payg-hero__meta { @@ -229,10 +226,10 @@ flex-wrap: wrap; gap: 6px 18px; font-size: 0.8125rem; - color: var(--text-secondary); + color: var(--c-text-muted); } .payg-hero__meta-dot { - color: var(--border-strong); + color: var(--c-border-strong); } .payg-hero__credit { display: inline-flex; @@ -242,11 +239,11 @@ font-size: 0.75rem; font-weight: 600; color: var(--color-green-700); - background: rgba(34, 197, 94, 0.14); + background: color-mix(in srgb, var(--c-success) 14%, transparent); } [data-mantine-color-scheme="dark"] .payg-hero__credit { - color: #4ade80; - background: rgba(34, 197, 94, 0.18); + color: var(--c-success); + background: color-mix(in srgb, var(--c-success) 18%, transparent); } /* Make Mantine default-variant buttons read clearly on the lifted cards in @@ -257,16 +254,24 @@ /* Dark mode: the stock default button is a flat slab that disappears into the card. Lift it with a soft top-down gradient + brighter border, and warm the - hover so the buttons feel tactile against --payg-card-bg (#1c2340). Driven - through Mantine's --button-* vars. The same rule covers disabled buttons + hover so the buttons feel tactile against the card surface. Driven through + Mantine's --button-* vars. The same rule covers disabled buttons (Cancel/Update cap before the form is dirty) so they read identically to the always-enabled ones — Mantine only fades them via opacity. */ [data-mantine-color-scheme="dark"] .payg .mantine-Button-root[data-variant="default"] { - --button-bg: linear-gradient(180deg, #232a50 0%, #1c2340 100%); - --button-hover: linear-gradient(180deg, #2d3560 0%, #232a50 100%); - --button-bd: 1px solid #2d3560; + --button-bg: linear-gradient( + 180deg, + var(--c-surface-raised) 0%, + var(--c-surface) 100% + ); + --button-hover: linear-gradient( + 180deg, + var(--c-border) 0%, + var(--c-surface-raised) 100% + ); + --button-bd: 1px solid var(--c-border); --button-color: var(--mantine-color-white); box-shadow: 0 1px 0 rgba(255, 255, 255, 0.04) inset, @@ -307,7 +312,7 @@ } .payg-status[data-state="FULL"] .payg-status__dot { background: var(--color-green-500); - box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18); + box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-success) 18%, transparent); } .payg-status[data-state="WARNED"] { background: var(--color-yellow-100); @@ -315,7 +320,7 @@ } .payg-status[data-state="WARNED"] .payg-status__dot { background: var(--color-yellow-500); - box-shadow: 0 0 0 3px rgba(234, 179, 8, 0.2); + box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-warning) 20%, transparent); } .payg-status[data-state="DEGRADED"] { background: var(--color-red-100); @@ -323,7 +328,7 @@ } .payg-status[data-state="DEGRADED"] .payg-status__dot { background: var(--color-red-500); - box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.2); + box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-danger) 20%, transparent); } /* Segmented usage bar */ @@ -331,7 +336,7 @@ margin-top: 18px; height: 10px; border-radius: 999px; - background: var(--bg-muted); + background: var(--c-surface-sunken); overflow: hidden; position: relative; } @@ -341,13 +346,13 @@ transition: width 0.5s cubic-bezier(0.16, 1, 0.3, 1); } .payg-bar__fill[data-state="FULL"] { - background: linear-gradient(90deg, #0a8bff, #38bdf8); + background: var(--c-primary); } .payg-bar__fill[data-state="WARNED"] { - background: linear-gradient(90deg, #f59e0b, #fbbf24); + background: var(--c-warning); } .payg-bar__fill[data-state="DEGRADED"] { - background: linear-gradient(90deg, #dc2626, #f87171); + background: var(--c-danger); } /* ── "What counts as a document?" expandable help ───────────────────── */ @@ -365,10 +370,10 @@ font: inherit; font-size: 0.8125rem; font-weight: 600; - color: var(--text-secondary); + color: var(--c-text-muted); } .payg-help__toggle:hover { - color: var(--text-primary); + color: var(--c-text); } .payg-help__chevron { transition: transform 0.15s ease; @@ -381,10 +386,10 @@ padding: 12px 14px; border-radius: 10px; border: 1px solid var(--payg-card-border); - background: var(--bg-muted); + background: var(--c-surface-sunken); font-size: 0.8125rem; line-height: 1.45; - color: var(--text-secondary); + color: var(--c-text-muted); } .payg-help__panel ul { margin: 0; @@ -401,7 +406,7 @@ padding: 13px 16px; border-radius: 10px; background: var(--payg-accent-soft); - border: 1px solid rgba(10, 139, 255, 0.2); + border: 1px solid color-mix(in srgb, var(--c-primary) 20%, transparent); } .payg-preview__icon { color: var(--payg-accent); @@ -409,12 +414,12 @@ } .payg-preview__main { font-size: 0.875rem; - color: var(--text-primary); + color: var(--c-text); font-weight: 550; } .payg-preview__note { font-size: 0.75rem; - color: var(--text-muted); + color: var(--c-text-subtle); margin-top: 1px; } @@ -453,17 +458,17 @@ flex-shrink: 0; } .payg-gate[data-enabled="true"] .payg-gate__chip { - background: rgba(34, 197, 94, 0.16); - color: #22c55e; + background: color-mix(in srgb, var(--c-success) 16%, transparent); + color: var(--c-success); } .payg-gate[data-enabled="false"] .payg-gate__chip { - background: rgba(239, 68, 68, 0.16); - color: #f87171; + background: color-mix(in srgb, var(--c-danger) 16%, transparent); + color: var(--c-danger); } .payg-gate__label { font-size: 0.8125rem; line-height: 1.35; - color: var(--text-primary); + color: var(--c-text); flex: 1; } .payg-gate__tag { @@ -477,16 +482,16 @@ white-space: nowrap; } .payg-gate__tag[data-variant="on"] { - color: var(--text-muted); - background: var(--bg-muted); + color: var(--c-text-subtle); + background: var(--c-surface-sunken); } .payg-gate__tag[data-variant="pause"] { - color: #dc2626; - background: rgba(239, 68, 68, 0.12); + color: var(--c-danger); + background: color-mix(in srgb, var(--c-danger) 12%, transparent); } [data-mantine-color-scheme="dark"] .payg-gate__tag[data-variant="pause"] { - color: #f87171; - background: rgba(239, 68, 68, 0.18); + color: var(--c-danger); + background: color-mix(in srgb, var(--c-danger) 18%, transparent); } /* ── Member rows ────────────────────────────────────────────────────── */ @@ -509,17 +514,17 @@ justify-content: center; font-size: 0.8125rem; font-weight: 650; - color: #fff; + color: var(--c-text-on-primary); flex-shrink: 0; } .payg-member__name { font-size: 0.875rem; font-weight: 550; - color: var(--text-primary); + color: var(--c-text); } .payg-member__email { font-size: 0.75rem; - color: var(--text-muted); + color: var(--c-text-subtle); } .payg-member__usage { text-align: right; @@ -527,7 +532,7 @@ } .payg-member__usage-num { font-size: 0.8125rem; - color: var(--text-primary); + color: var(--c-text); font-variant-numeric: tabular-nums; } .payg-member__minibar { @@ -570,27 +575,27 @@ } .payg-activity__label { font-size: 0.8438rem; - color: var(--text-primary); + color: var(--c-text); flex: 1; } .payg-activity__ts { font-size: 0.75rem; - color: var(--text-muted); + color: var(--c-text-subtle); } .payg-activity__kind { font-size: 0.625rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; - color: var(--text-muted); - background: var(--bg-muted); + color: var(--c-text-subtle); + background: var(--c-surface-sunken); padding: 2px 8px; border-radius: 999px; } .payg-activity__units { font-size: 0.8125rem; font-weight: 650; - color: var(--text-primary); + color: var(--c-text); font-variant-numeric: tabular-nums; min-width: 58px; text-align: right; @@ -604,20 +609,20 @@ gap: 16px; padding: 20px 24px; border-radius: var(--payg-radius); - border: 1px solid rgba(99, 91, 255, 0.28); + border: 1px solid color-mix(in srgb, var(--c-accent-stripe) 28%, transparent); background: linear-gradient( 135deg, - rgba(99, 91, 255, 0.1) 0%, - rgba(99, 91, 255, 0.02) 100% + color-mix(in srgb, var(--c-accent-stripe) 10%, transparent) 0%, + color-mix(in srgb, var(--c-accent-stripe) 2%, transparent) 100% ); } .payg-stripe__title { font-size: 0.9375rem; font-weight: 650; - color: var(--text-primary); + color: var(--c-text); } .payg-stripe__subtitle { font-size: 0.8125rem; - color: var(--text-muted); + color: var(--c-text-subtle); margin-top: 2px; } diff --git a/frontend/editor/src/cloud/components/shared/config/configSections/Payg.tsx b/frontend/editor/src/cloud/components/shared/config/configSections/Payg.tsx index 8cf61f2385..53f4b98486 100644 --- a/frontend/editor/src/cloud/components/shared/config/configSections/Payg.tsx +++ b/frontend/editor/src/cloud/components/shared/config/configSections/Payg.tsx @@ -60,12 +60,12 @@ interface PaygProps { // Stable-ish avatar colour from a string. const AVATAR_COLORS = [ - "#0a8bff", - "#8b5cf6", - "#ec4899", - "#10b981", - "#f59e0b", - "#06b6d4", + "var(--c-avatar-1)", + "var(--c-avatar-2)", + "var(--c-avatar-3)", + "var(--c-avatar-4)", + "var(--c-avatar-5)", + "var(--c-avatar-6)", ]; function avatarColor(seed: string): string { let h = 0; diff --git a/frontend/editor/src/cloud/components/shared/config/configSections/PaygFree.css b/frontend/editor/src/cloud/components/shared/config/configSections/PaygFree.css index 6ade6c7b6d..9e89fa38eb 100644 --- a/frontend/editor/src/cloud/components/shared/config/configSections/PaygFree.css +++ b/frontend/editor/src/cloud/components/shared/config/configSections/PaygFree.css @@ -70,11 +70,11 @@ gap: 8px; font-size: 0.8rem; line-height: 1.45; - color: var(--text-muted); + color: var(--c-text-subtle); } .paygf-proc__membernote-icon { flex-shrink: 0; - color: var(--text-muted); + color: var(--c-text-subtle); font-size: 1.1rem !important; margin-top: 1px; } @@ -113,12 +113,12 @@ font-weight: 750; line-height: 1; letter-spacing: -0.02em; - color: var(--text-primary); + color: var(--c-text); font-variant-numeric: tabular-nums; } .paygf-meter__cap { font-size: 0.85rem; - color: var(--text-muted); + color: var(--c-text-subtle); font-variant-numeric: tabular-nums; } .paygf-meter .payg-bar { @@ -131,7 +131,7 @@ align-items: center; gap: 6px 10px; font-size: 0.78rem; - color: var(--text-secondary); + color: var(--c-text-muted); } /* ── Leader CTA card ──────────────────────────────────────────────────── */ @@ -145,8 +145,10 @@ border: 1.5px solid transparent; background: linear-gradient(var(--payg-card-bg), var(--payg-card-bg)) padding-box, - linear-gradient(135deg, var(--payg-accent) 0%, #6c5ce7 100%) border-box; - box-shadow: 0 10px 28px -18px rgba(10, 139, 255, 0.4); + linear-gradient(135deg, var(--payg-accent) 0%, var(--c-hue-purple) 100%) + border-box; + box-shadow: 0 10px 28px -18px + color-mix(in srgb, var(--c-primary) 40%, transparent); display: flex; flex-direction: column; gap: 16px; @@ -161,8 +163,12 @@ flex-shrink: 0; padding: 10px; border-radius: 12px; - background: linear-gradient(135deg, var(--payg-accent) 0%, #6c5ce7 100%); - color: white !important; + background: linear-gradient( + 135deg, + var(--payg-accent) 0%, + var(--c-hue-purple) 100% + ); + color: var(--c-text-on-primary) !important; font-size: 1.7rem !important; } .paygf-cta__heading-text { @@ -172,14 +178,14 @@ margin: 0; font-size: 1.2rem; font-weight: 700; - color: var(--text-primary); + color: var(--c-text); letter-spacing: -0.01em; line-height: 1.25; } .paygf-cta__subtitle { margin: 4px 0 0; font-size: 0.9rem; - color: var(--text-muted); + color: var(--c-text-subtle); line-height: 1.5; } @@ -196,7 +202,7 @@ align-items: flex-start; gap: 8px; font-size: 0.85rem; - color: var(--text-primary); + color: var(--c-text); line-height: 1.45; } .paygf-cta__check { @@ -220,7 +226,7 @@ .paygf-cta__reassurance { margin: 0; font-size: 0.78rem; - color: var(--text-muted); + color: var(--c-text-subtle); text-align: right; } @@ -237,7 +243,7 @@ } .paygf-member-note__icon { flex-shrink: 0; - color: var(--text-muted); + color: var(--c-text-subtle); padding: 8px; background: var(--payg-card-bg); border-radius: 10px; @@ -247,14 +253,14 @@ margin: 0; font-size: 1rem; font-weight: 700; - color: var(--text-primary); + color: var(--c-text); letter-spacing: -0.005em; line-height: 1.3; } .paygf-member-note__body { margin: 6px 0 0; font-size: 0.875rem; - color: var(--text-muted); + color: var(--c-text-subtle); line-height: 1.5; } @@ -285,14 +291,14 @@ font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; - color: var(--text-muted); + color: var(--c-text-subtle); margin-bottom: 10px; } .paygf-explainer__icon { font-size: 1rem !important; } .paygf-explainer__icon--free { - color: #10b981; + color: var(--c-success); } .paygf-explainer__icon--paid { color: var(--payg-accent); @@ -300,6 +306,6 @@ .paygf-explainer__text { margin: 0; font-size: 0.85rem; - color: var(--text-primary); + color: var(--c-text); line-height: 1.55; } diff --git a/frontend/editor/src/cloud/components/shared/config/configSections/SpendCapControl.css b/frontend/editor/src/cloud/components/shared/config/configSections/SpendCapControl.css index bc9ce0cef8..d0ed711434 100644 --- a/frontend/editor/src/cloud/components/shared/config/configSections/SpendCapControl.css +++ b/frontend/editor/src/cloud/components/shared/config/configSections/SpendCapControl.css @@ -9,12 +9,12 @@ Payg.css / UpgradeModal.css treatments the control sits beside. */ .scc { - --scc-accent: #0a8bff; - --scc-accent-text: #0a8bff; - --scc-accent-soft: rgba(10, 139, 255, 0.12); - --scc-accent-border: rgba(10, 139, 255, 0.25); - --scc-chip-bg: var(--bg-muted); - --scc-chip-border: var(--border-default); + --scc-accent: var(--c-primary); + --scc-accent-text: var(--c-primary); + --scc-accent-soft: color-mix(in srgb, var(--c-primary) 12%, transparent); + --scc-accent-border: color-mix(in srgb, var(--c-primary) 25%, transparent); + --scc-chip-bg: var(--c-surface-sunken); + --scc-chip-border: var(--c-border); /* Consistent vertical rhythm between the control row, the estimate, and any note — without it the blocks sit flush. */ display: flex; @@ -22,10 +22,10 @@ gap: 14px; } [data-mantine-color-scheme="dark"] .scc { - --scc-accent-text: #7ab4ff; - --scc-accent-soft: rgba(79, 142, 245, 0.16); - --scc-chip-bg: #1c2340; - --scc-chip-border: #2d3560; + /* Chip surface/border track the neutral --c-* tokens (base rule); only the + brand-azure accent is tuned brighter for dark. */ + --scc-accent-text: var(--c-primary); + --scc-accent-soft: color-mix(in srgb, var(--c-primary) 16%, transparent); } /* ── Inline row: presets · custom · no-cap · (save) ──────────────────── */ @@ -47,7 +47,7 @@ border-radius: 999px; border: 1px solid var(--scc-chip-border); background: var(--scc-chip-bg); - color: var(--text-secondary); + color: var(--c-text-muted); font: inherit; font-size: 0.85rem; font-weight: 600; @@ -59,8 +59,8 @@ background 0.12s ease; } .scc-chip:hover:not(:disabled) { - color: var(--text-primary); - border-color: var(--border-strong); + color: var(--c-text); + border-color: var(--c-border-strong); } .scc-chip[data-selected="true"] { background: var(--scc-accent-soft); @@ -90,7 +90,7 @@ background 0.12s ease; } .scc-custom:hover { - border-color: var(--border-strong); + border-color: var(--c-border-strong); } .scc-custom[data-active="true"] { border-style: solid; @@ -98,7 +98,7 @@ background: var(--scc-accent-soft); } .scc-custom__symbol { - color: var(--text-muted); + color: var(--c-text-subtle); font-size: 0.85rem; font-weight: 600; } @@ -111,14 +111,14 @@ border: none; outline: none; background: transparent; - color: var(--text-primary); + color: var(--c-text); font: inherit; font-size: 0.85rem; font-weight: 600; font-variant-numeric: tabular-nums; } .scc-custom__input::placeholder { - color: var(--text-muted); + color: var(--c-text-subtle); font-weight: 600; } .scc-custom:disabled, @@ -148,17 +148,17 @@ .scc-estimate__main { font-size: 0.875rem; font-weight: 550; - color: var(--text-primary); + color: var(--c-text); } .scc-estimate__sub { font-size: 0.75rem; - color: var(--text-muted); + color: var(--c-text-subtle); margin-top: 1px; } /* Quiet helper line (e.g. "Shown in USD — change later in your currency"). */ .scc-note { font-size: 0.8125rem; - color: var(--text-muted); + color: var(--c-text-subtle); line-height: 1.45; } diff --git a/frontend/editor/src/cloud/components/shared/config/configSections/TeamSection.tsx b/frontend/editor/src/cloud/components/shared/config/configSections/TeamSection.tsx index 44fc59c738..4eb064d8bf 100644 --- a/frontend/editor/src/cloud/components/shared/config/configSections/TeamSection.tsx +++ b/frontend/editor/src/cloud/components/shared/config/configSections/TeamSection.tsx @@ -11,6 +11,7 @@ import { } from "@mantine/core"; import { Button } from "@app/ui/Button"; import { ActionIcon } from "@app/ui/ActionIcon"; +import { StatusBadge } from "@app/ui/StatusBadge"; import { useTranslation } from "react-i18next"; import { useSaaSTeam } from "@app/contexts/SaaSTeamContext"; import LocalIcon from "@app/components/shared/LocalIcon"; @@ -265,12 +266,14 @@ const TeamSection: React.FC = () => { )} {isTeamLeader && ( - {t("team.leader", "LEADER")} + + {t("team.leader", "LEADER")} + )} {isPersonalTeam && ( - + {t("team.personal", "Personal")} - + )} )} @@ -430,8 +433,8 @@ const TeamSection: React.FC = () => { style={ member.role !== "LEADER" ? { - backgroundColor: "var(--tool-header-badge-bg)", - color: "var(--tool-header-badge-text)", + backgroundColor: "var(--c-surface-raised)", + color: "var(--c-accent-fg)", } : undefined } diff --git a/frontend/editor/src/cloud/components/shared/config/configSections/UpgradeModal.css b/frontend/editor/src/cloud/components/shared/config/configSections/UpgradeModal.css index c6da318f0f..46df9ddee4 100644 --- a/frontend/editor/src/cloud/components/shared/config/configSections/UpgradeModal.css +++ b/frontend/editor/src/cloud/components/shared/config/configSections/UpgradeModal.css @@ -5,22 +5,21 @@ user feels like they're filling out one form, not navigating pages. */ .upm { - --upm-accent: #0a8bff; - --upm-accent-2: #6c5ce7; - --upm-accent-soft: rgba(10, 139, 255, 0.08); - --upm-success: #10b981; + --upm-accent: var(--c-primary); + --upm-accent-2: var(--c-hue-purple); + --upm-accent-soft: color-mix(in srgb, var(--c-primary) 8%, transparent); + --upm-success: var(--c-success); --upm-radius: 18px; - --upm-card-bg: var(--bg-surface); - --upm-border: var(--border-default); - --upm-divider: var(--border-subtle); - --upm-text: var(--text-primary); - --upm-muted: var(--text-muted); + --upm-card-bg: var(--c-surface); + --upm-border: var(--c-border); + --upm-divider: var(--c-border-subtle); + --upm-text: var(--c-text); + --upm-muted: var(--c-text-subtle); } [data-mantine-color-scheme="dark"] .upm { - --upm-card-bg: #1c2340; - --upm-border: #2d3560; - --upm-divider: #2d3560; - --upm-accent-soft: rgba(79, 142, 245, 0.14); + /* Card/border/divider track the neutral --c-* tokens (base rule); only the + brand-azure accent tint is tuned for dark. */ + --upm-accent-soft: color-mix(in srgb, var(--c-primary) 14%, transparent); } /* Backdrop locks the page and centres the modal. z-index matches @@ -150,7 +149,7 @@ .upm-step[data-state="active"] .upm-step__dot { background: linear-gradient(135deg, var(--upm-accent), var(--upm-accent-2)); border-color: transparent; - color: white; + color: var(--c-text-on-primary); } .upm-step[data-state="done"] { color: var(--upm-success); @@ -158,7 +157,7 @@ .upm-step[data-state="done"] .upm-step__dot { background: var(--upm-success); border-color: transparent; - color: white; + color: var(--c-text-on-primary); } .upm-step__connector { flex: 1 1 auto; @@ -254,7 +253,7 @@ border-radius: 6px; } .upm-step__edit:hover { - background: rgba(10, 139, 255, 0.12); + background: color-mix(in srgb, var(--c-primary) 12%, transparent); } /* Placeholder card for the loading / error / mock states — a dashed, centered @@ -327,8 +326,10 @@ } .upm-confirm__icon { font-size: 64px !important; - color: #10b981; - filter: drop-shadow(0 6px 18px rgba(16, 185, 129, 0.35)); + color: var(--upm-success); + filter: drop-shadow( + 0 6px 18px color-mix(in srgb, var(--c-success) 35%, transparent) + ); } .upm-confirm__title { margin: 6px 0 0; diff --git a/frontend/editor/src/core/assets/Brand.stories.tsx b/frontend/editor/src/core/assets/Brand.stories.tsx index 886e7a023d..ac144c88b1 100644 --- a/frontend/editor/src/core/assets/Brand.stories.tsx +++ b/frontend/editor/src/core/assets/Brand.stories.tsx @@ -61,7 +61,9 @@ function Swatch({ label, src, onDark, h }: Asset & { h: number }) { > {label} -
+
{label}
diff --git a/frontend/editor/src/core/components/FileManager.tsx b/frontend/editor/src/core/components/FileManager.tsx index d05d05ea2b..6361d9d4a8 100644 --- a/frontend/editor/src/core/components/FileManager.tsx +++ b/frontend/editor/src/core/components/FileManager.tsx @@ -221,7 +221,7 @@ const FileManager: React.FC = ({ selectedTool }) => { width: "100%", border: "none", borderRadius: "var(--radius-md)", - backgroundColor: "var(--bg-file-manager)", + backgroundColor: "var(--c-bg)", }} styles={{ inner: { pointerEvents: "all" }, diff --git a/frontend/editor/src/core/components/annotation/shared/TextInputWithFont.tsx b/frontend/editor/src/core/components/annotation/shared/TextInputWithFont.tsx index 60905d3065..2760e9281c 100644 --- a/frontend/editor/src/core/components/annotation/shared/TextInputWithFont.tsx +++ b/frontend/editor/src/core/components/annotation/shared/TextInputWithFont.tsx @@ -227,7 +227,7 @@ export const TextInputWithFont: React.FC = ({ width: 24, height: 24, backgroundColor: textColor, - border: "1px solid #ccc", + border: "1px solid var(--c-border)", borderRadius: 4, cursor: disabled ? "default" : "pointer", }} diff --git a/frontend/editor/src/core/components/fileEditor/AddFileCard.tsx b/frontend/editor/src/core/components/fileEditor/AddFileCard.tsx index bf19c16967..5491138e6b 100644 --- a/frontend/editor/src/core/components/fileEditor/AddFileCard.tsx +++ b/frontend/editor/src/core/components/fileEditor/AddFileCard.tsx @@ -110,7 +110,7 @@ const AddFileCard = ({ variant="tertiary" style={{ backgroundColor: "var(--landing-button-bg)", - color: "var(--landing-button-color)", + color: "var(--c-accent-fg)", border: "1px solid var(--landing-button-border)", borderRadius: "2rem", height: "38px", @@ -129,7 +129,7 @@ const AddFileCard = ({ icon="add" width="1.5rem" height="1.5rem" - className="text-[var(--accent-interactive)]" + className="text-[var(--c-primary)]" /> {t("landing.addFiles", "Add Files")} @@ -140,7 +140,7 @@ const AddFileCard = ({ title={terminology.uploadFromComputer} style={{ backgroundColor: "var(--landing-button-bg)", - color: "var(--landing-button-color)", + color: "var(--c-accent-fg)", border: "1px solid var(--landing-button-border)", borderRadius: "1rem", height: "38px", @@ -161,7 +161,7 @@ const AddFileCard = ({ icon={icons.uploadIconName} width="1.25rem" height="1.25rem" - style={{ color: "var(--accent-interactive)", flexShrink: 0 }} + style={{ color: "var(--c-primary)", flexShrink: 0 }} /> {isUploadHover && ( { flex: 1, display: "flex", flexDirection: "column", - backgroundColor: "var(--bg-file-list)", + backgroundColor: "var(--c-surface)", border: "1px solid var(--mantine-color-gray-2)", boxShadow: "0 2px 8px rgba(0, 0, 0, 0.1)", overflow: "hidden", diff --git a/frontend/editor/src/core/components/fileManager/EmptyFilesState.tsx b/frontend/editor/src/core/components/fileManager/EmptyFilesState.tsx index 95cbff8b9b..59b42ef954 100644 --- a/frontend/editor/src/core/components/fileManager/EmptyFilesState.tsx +++ b/frontend/editor/src/core/components/fileManager/EmptyFilesState.tsx @@ -81,8 +81,8 @@ const EmptyFilesState: React.FC = () => { variant="tertiary" aria-label={t("emptyFilesState.upload", "Upload")} style={{ - backgroundColor: "var(--bg-file-manager)", - color: "var(--landing-button-color)", + backgroundColor: "var(--c-bg)", + color: "var(--c-accent-fg)", border: "1px solid var(--landing-button-border)", borderRadius: isUploadHover ? "2rem" : "1rem", height: "38px", @@ -103,7 +103,7 @@ const EmptyFilesState: React.FC = () => { icon={icons.uploadIconName} width="1.25rem" height="1.25rem" - style={{ color: "var(--accent-interactive)" }} + style={{ color: "var(--c-primary)" }} /> {isUploadHover && ( @@ -115,7 +115,7 @@ const EmptyFilesState: React.FC = () => { {/* Instruction Text */} {terminology.dropFilesHere} diff --git a/frontend/editor/src/core/components/fileManager/FileListItem.tsx b/frontend/editor/src/core/components/fileManager/FileListItem.tsx index ba1fe52bc9..5a8e721c1b 100644 --- a/frontend/editor/src/core/components/fileManager/FileListItem.tsx +++ b/frontend/editor/src/core/components/fileManager/FileListItem.tsx @@ -189,7 +189,7 @@ const FileListItem: React.FC = ({ backgroundColor: isSelected || shouldShowHovered ? "var(--mantine-color-gray-1)" - : "var(--bg-file-list)", + : "var(--c-surface)", opacity: 1, transition: "background-color 0.15s ease", userSelect: "none", diff --git a/frontend/editor/src/core/components/fileManager/MobileLayout.tsx b/frontend/editor/src/core/components/fileManager/MobileLayout.tsx index 2545a9d604..9cc8c6ed99 100644 --- a/frontend/editor/src/core/components/fileManager/MobileLayout.tsx +++ b/frontend/editor/src/core/components/fileManager/MobileLayout.tsx @@ -47,7 +47,7 @@ const MobileLayout: React.FC = () => { flex: 1, display: "flex", flexDirection: "column", - backgroundColor: "var(--bg-file-list)", + backgroundColor: "var(--c-surface)", borderRadius: "0.5rem", border: "1px solid var(--mantine-color-gray-2)", overflow: "hidden", diff --git a/frontend/editor/src/core/components/filesPage/FileDetailsPanel.tsx b/frontend/editor/src/core/components/filesPage/FileDetailsPanel.tsx index 07c2e771dc..693d8efae7 100644 --- a/frontend/editor/src/core/components/filesPage/FileDetailsPanel.tsx +++ b/frontend/editor/src/core/components/filesPage/FileDetailsPanel.tsx @@ -201,7 +201,7 @@ export function FileDetailsPanel({ ) : ( )} diff --git a/frontend/editor/src/core/components/filesPage/FileGrid.tsx b/frontend/editor/src/core/components/filesPage/FileGrid.tsx index 69c30f98a3..ce9be12ad2 100644 --- a/frontend/editor/src/core/components/filesPage/FileGrid.tsx +++ b/frontend/editor/src/core/components/filesPage/FileGrid.tsx @@ -499,7 +499,7 @@ function FolderCard({
{currentTab === "local" @@ -991,9 +991,9 @@ export default function FileManagerView() { style={{ padding: "0.6rem 1.25rem", background: - "color-mix(in srgb, var(--mantine-color-red-6, #e03131) 12%, transparent)", - color: "var(--text-primary)", - borderBottom: "1px solid var(--border-subtle)", + "color-mix(in srgb, var(--mantine-color-red-6) 12%, transparent)", + color: "var(--c-text)", + borderBottom: "1px solid var(--c-border-subtle)", fontSize: "0.85rem", display: "flex", justifyContent: "space-between", @@ -1083,15 +1083,15 @@ export default function FileManagerView() { style={{ background: currentTab === tab.id - ? "var(--hover-bg)" + ? "var(--c-hover)" : "transparent", border: "none", borderRadius: "0.3rem", padding: "0.2rem 0.6rem", color: currentTab === tab.id - ? "var(--text-primary)" - : "var(--text-muted)", + ? "var(--c-text)" + : "var(--c-text-subtle)", fontWeight: currentTab === tab.id ? 500 : 400, fontSize: "0.75rem", cursor: "pointer", @@ -1662,7 +1662,7 @@ const SearchField = React.forwardRef< const { t } = useTranslation(); return (
- + @@ -163,13 +163,13 @@ function IconButton({ justifyContent: "center", fontSize: "1.1rem", borderRadius: "0.4rem", - background: selected ? "var(--hover-bg)" : "transparent", + background: selected ? "var(--c-hover)" : "transparent", border: selected - ? "1px solid var(--accent-interactive, #6366f1)" + ? "1px solid var(--c-primary)" : "1px solid transparent", cursor: disabled ? "not-allowed" : "pointer", padding: 0, - color: "var(--text-primary)", + color: "var(--c-text)", }} > {icon.glyph || "-"} diff --git a/frontend/editor/src/core/components/filesPage/FolderThumbnail.tsx b/frontend/editor/src/core/components/filesPage/FolderThumbnail.tsx index b8e68f9f7f..39554a21ee 100644 --- a/frontend/editor/src/core/components/filesPage/FolderThumbnail.tsx +++ b/frontend/editor/src/core/components/filesPage/FolderThumbnail.tsx @@ -30,7 +30,7 @@ export function FolderThumbnail({ size = "thumb", iconGlyph, }: FolderThumbnailProps) { - const accent = color ?? "var(--accent-interactive, #6366f1)"; + const accent = color ?? "var(--c-primary, #6366f1)"; const px = SIZE_PX[size]; const showBadge = size === "thumb" && (fileCount ?? 0) > 0; // Per-instance unique ids - `${color}` previously embedded `#` and CSS @@ -149,7 +149,7 @@ export function FolderThumbnail({ minWidth: "1.4rem", height: "1.4rem", borderRadius: "999px", - background: "var(--bg-surface, #fff)", + background: "var(--c-surface, #fff)", border: `1px solid ${accent}`, color: accent, fontSize: "0.7rem", diff --git a/frontend/editor/src/core/components/filesPage/FolderTreePanel.css b/frontend/editor/src/core/components/filesPage/FolderTreePanel.css index 2b75efe685..4a98babcbc 100644 --- a/frontend/editor/src/core/components/filesPage/FolderTreePanel.css +++ b/frontend/editor/src/core/components/filesPage/FolderTreePanel.css @@ -15,8 +15,8 @@ .folder-tree-panel { width: 0; flex-shrink: 0; - background: var(--bg-toolbar); - border-right: 0 solid var(--border-subtle); + background: var(--c-bg-raised); + border-right: 0 solid var(--c-border-subtle); overflow: hidden; height: 100%; pointer-events: none; @@ -65,11 +65,7 @@ .folder-tree-panel-resizer:hover, .folder-tree-panel-resizer:focus-visible { - background: color-mix( - in srgb, - var(--accent-interactive, #6366f1) 35%, - transparent - ); + background: color-mix(in srgb, var(--c-primary) 35%, transparent); outline: none; } @@ -87,7 +83,7 @@ font-size: 13px; font-weight: 600; letter-spacing: 0.02em; - color: var(--text-muted); + color: var(--c-text-subtle); text-transform: uppercase; } @@ -112,7 +108,7 @@ margin: 0 8px; cursor: pointer; user-select: none; - color: var(--text-secondary); + color: var(--c-text-muted); font-size: 14px; position: relative; transition: background-color 0.15s ease; @@ -120,23 +116,19 @@ } .files-page-tree-node:hover { - background: var(--hover-bg); + background: var(--c-hover); } .files-page-tree-node.is-active { - background: var(--hover-bg); - color: var(--text-primary); + background: var(--c-hover); + color: var(--c-text); font-weight: 500; } .files-page-tree-node.is-drop-target { - background: color-mix( - in srgb, - var(--accent-interactive, #6366f1) 12%, - transparent - ); - box-shadow: inset 0 0 0 1px var(--accent-interactive, #6366f1); - color: var(--text-primary); + background: color-mix(in srgb, var(--c-primary) 12%, transparent); + box-shadow: inset 0 0 0 1px var(--c-primary); + color: var(--c-text); } .files-page-tree-toggle { @@ -145,7 +137,7 @@ justify-content: center; width: 16px; height: 16px; - color: var(--text-muted); + color: var(--c-text-subtle); flex-shrink: 0; } @@ -165,7 +157,7 @@ align-items: center; justify-content: center; flex-shrink: 0; - color: var(--text-muted); + color: var(--c-text-subtle); margin-left: 8px; font-size: 18px; } @@ -183,7 +175,7 @@ } .files-page-tree-count { - color: var(--text-muted); + color: var(--c-text-subtle); font-size: 12px; flex-shrink: 0; margin-left: 8px; diff --git a/frontend/editor/src/core/components/filesPage/MoveToFolderDialog.tsx b/frontend/editor/src/core/components/filesPage/MoveToFolderDialog.tsx index b6e098ea4d..0d978621d9 100644 --- a/frontend/editor/src/core/components/filesPage/MoveToFolderDialog.tsx +++ b/frontend/editor/src/core/components/filesPage/MoveToFolderDialog.tsx @@ -127,7 +127,7 @@ export function MoveToFolderDialog({
{/* Workbench Bar - animates in/out based on file presence */} {currentView !== "myFiles" && diff --git a/frontend/editor/src/core/components/onboarding/InitialOnboardingModal/InitialOnboardingModal.module.css b/frontend/editor/src/core/components/onboarding/InitialOnboardingModal/InitialOnboardingModal.module.css index e1f46bc6e8..f9439dcdd2 100644 --- a/frontend/editor/src/core/components/onboarding/InitialOnboardingModal/InitialOnboardingModal.module.css +++ b/frontend/editor/src/core/components/onboarding/InitialOnboardingModal/InitialOnboardingModal.module.css @@ -22,7 +22,7 @@ display: flex; align-items: center; justify-content: center; - box-shadow: 0 16px 32px rgba(15, 23, 42, 0.18); + box-shadow: 0 16px 32px rgba(0, 0, 0, 0.18); animation: heroLogoScale 0.25s ease forwards; } @@ -49,10 +49,10 @@ .securityCard { width: 100%; max-width: 480px; - background: var(--bg-surface, #ffffff); + background: var(--c-surface); border-radius: 16px; padding: 20px; - box-shadow: 0 12px 32px rgba(15, 23, 42, 0.12); + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12); display: flex; flex-direction: column; gap: 16px; @@ -65,7 +65,7 @@ font-weight: 500; font-size: 15px; line-height: 1.5; - color: var(--onboarding-body, #1f2937); + color: var(--c-text-muted); } .mfaSlideContent { @@ -77,10 +77,10 @@ .mfaCard { width: 100%; max-width: 560px; - background: var(--bg-surface, #ffffff); + background: var(--c-surface); border-radius: 16px; padding: 20px; - box-shadow: 0 12px 32px rgba(15, 23, 42, 0.12); + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12); } .mfaSetupGrid { @@ -94,7 +94,7 @@ padding: 12px; background: #ffffff; border-radius: 12px; - box-shadow: 0 8px 16px rgba(15, 23, 42, 0.12); + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.12); display: flex; justify-content: center; } @@ -102,7 +102,7 @@ .mfaSteps { margin: 0; padding-left: 18px; - color: var(--onboarding-body, #1f2937); + color: var(--c-text-muted); font-size: 14px; line-height: 1.5; } @@ -149,11 +149,7 @@ padding: 4px; outline: none; } - -.iconButton:focus { - outline: none; -} - +.iconButton:focus, .iconButton:focus-visible { outline: none; } @@ -194,14 +190,7 @@ text-align: center; animation: heroLogoEnter 0.25s ease forwards; } - -.title { - text-align: center; - opacity: 0; - transform: translateX(24px); - animation: bodySlideIn 0.25s ease forwards; -} - +.title, .bodyCopy { text-align: center; opacity: 0; @@ -273,13 +262,13 @@ opacity: 1; border: 1px solid rgba(255, 255, 255, 0.9); background: rgba(255, 255, 255, 0.9); - color: #1f2933; + color: var(--c-text); box-shadow: 0 0 8px rgba(255, 255, 255, 0.7); } /* Modal content styles */ .modalContent { - background: var(--bg-surface); + background: var(--c-surface); position: relative; } @@ -299,7 +288,7 @@ sans-serif; font-weight: 600; font-size: 22px; - color: var(--onboarding-title); + color: var(--c-text); } /* Body text styles */ @@ -313,7 +302,7 @@ Arial, sans-serif; font-size: 16px; - color: var(--onboarding-body); + color: var(--c-text-muted); line-height: 1.5; } @@ -335,8 +324,8 @@ } .v2Badge { - background: #dbefff; - color: #2a4bff; + background: var(--c-primary-tint); + color: var(--c-accent-fg); padding: 3px 9px; border-radius: 6px; font-size: 12px; @@ -345,7 +334,7 @@ /* Icon styles */ .heroIcon { - color: var(--onboarding-title, #0f172a); + color: var(--c-text); } /* ===================================================================== */ @@ -353,7 +342,7 @@ /* ===================================================================== */ .card { - background: var(--bg-surface); + background: var(--c-surface); display: flex; flex-direction: column; } @@ -383,7 +372,7 @@ font-size: 17px; font-weight: 700; letter-spacing: -0.01em; - color: var(--onboarding-title, #0f172a); + color: var(--c-text); } .headerRight { @@ -395,8 +384,8 @@ .stepPill { font-size: 12px; font-weight: 600; - color: var(--onboarding-body, #64748b); - background: var(--bg-muted, #f1f5f9); + color: var(--c-text-muted); + background: var(--c-surface-sunken); padding: 5px 11px; border-radius: 9999px; white-space: nowrap; @@ -413,17 +402,17 @@ flex: 1; height: 5px; border-radius: 9999px; - background: var(--onboarding-step-inactive, #e2e8f0); + background: var(--onboarding-step-inactive, var(--c-border)); transition: background 0.2s ease; } .progressSegDone { - background: var(--color-blue, #3b82f6); + background: var(--c-primary); } .divider { height: 1px; - background: var(--border-subtle, rgba(15, 23, 42, 0.08)); + background: var(--c-border-subtle); } /* ---- content ---- */ @@ -445,7 +434,7 @@ min-height: 128px; border-radius: 14px; overflow: hidden; - background: linear-gradient(155deg, #eef1fb 0%, #f6f4fc 55%, #fbf4f7 100%); + background: var(--c-onboarding-hero); } .heroArt { @@ -459,18 +448,18 @@ height: 62px; border-radius: 15px; object-fit: contain; - filter: drop-shadow(0 10px 20px rgba(15, 23, 42, 0.16)); + filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.16)); } .heroTile { width: 62px; height: 62px; border-radius: 15px; - background: #ffffff; + background: var(--c-onboarding-hero-tile); display: flex; align-items: center; justify-content: center; - box-shadow: 0 10px 22px rgba(15, 23, 42, 0.14); + box-shadow: 0 10px 22px rgba(0, 0, 0, 0.14); } /* ---- title + body (left-aligned, clean) ---- */ @@ -479,14 +468,14 @@ font-weight: 600; letter-spacing: -0.01em; line-height: 1.3; - color: var(--onboarding-title, #0f172a); + color: var(--c-text); text-align: left; } .bodyNew { font-size: 14px; line-height: 1.5; - color: var(--onboarding-body, #475569); + color: var(--c-text-muted); text-align: left; } @@ -513,16 +502,9 @@ gap: 12px; } -/* ---- dark theme surface tuning ---- */ -:global([data-mantine-color-scheme="dark"]) .heroPanel { - background: linear-gradient(155deg, #1a2236 0%, #171e30 55%, #201a28 100%); -} - +/* ---- dark theme surface tuning ---- + Hero panel + tile colours flip via the themed --c-onboarding-hero* tokens; + only the tile's heavier dark shadow needs a per-scheme override. */ :global([data-mantine-color-scheme="dark"]) .heroTile { - background: #0f1626; box-shadow: 0 12px 28px rgba(0, 0, 0, 0.4); } - -:global([data-mantine-color-scheme="dark"]) .divider { - background: rgba(255, 255, 255, 0.08); -} diff --git a/frontend/editor/src/core/components/onboarding/OnboardingSlideShell.tsx b/frontend/editor/src/core/components/onboarding/OnboardingSlideShell.tsx index 3a8a2a57e4..49d94662eb 100644 --- a/frontend/editor/src/core/components/onboarding/OnboardingSlideShell.tsx +++ b/frontend/editor/src/core/components/onboarding/OnboardingSlideShell.tsx @@ -116,7 +116,7 @@ export default function OnboardingSlideShell({ content: { overflow: "hidden", border: "none", - background: "var(--bg-surface)", + background: "var(--c-surface)", maxHeight: "90vh", }, }} @@ -193,7 +193,7 @@ export default function OnboardingSlideShell({
{body} - +
diff --git a/frontend/editor/src/core/components/onboarding/OnboardingTour.css b/frontend/editor/src/core/components/onboarding/OnboardingTour.css index a1cbd4f3d8..a689b9f3f4 100644 --- a/frontend/editor/src/core/components/onboarding/OnboardingTour.css +++ b/frontend/editor/src/core/components/onboarding/OnboardingTour.css @@ -13,7 +13,7 @@ box-shadow: 0 0 0 2px var(--mantine-primary-color-filled), 0 0 15px var(--mantine-primary-color-filled), - inset 0 0 15px rgba(59, 130, 246, 0.1); + inset 0 0 15px color-mix(in srgb, var(--c-primary) 10%, transparent); border-radius: 8px; } @@ -23,13 +23,13 @@ box-shadow: 0 0 0 3px var(--mantine-primary-color-filled), 0 0 20px var(--mantine-primary-color-filled), - inset 0 0 20px rgba(59, 130, 246, 0.1); + inset 0 0 20px color-mix(in srgb, var(--c-primary) 10%, transparent); } 50% { box-shadow: 0 0 0 3px var(--mantine-primary-color-filled), 0 0 30px var(--mantine-primary-color-filled), - inset 0 0 30px rgba(59, 130, 246, 0.2); + inset 0 0 30px color-mix(in srgb, var(--c-primary) 20%, transparent); } } diff --git a/frontend/editor/src/core/components/onboarding/slides/AnimatedSlideBackground.module.css b/frontend/editor/src/core/components/onboarding/slides/AnimatedSlideBackground.module.css index e278703955..7ca0b4fd93 100644 --- a/frontend/editor/src/core/components/onboarding/slides/AnimatedSlideBackground.module.css +++ b/frontend/editor/src/core/components/onboarding/slides/AnimatedSlideBackground.module.css @@ -40,7 +40,7 @@ position: absolute; border-radius: 50%; pointer-events: none; - box-shadow: 0 18px 36px rgba(15, 23, 42, 0.12); + box-shadow: 0 18px 36px rgba(0, 0, 0, 0.12); animation-name: circleSway; animation-timing-function: ease-in-out; animation-iteration-count: infinite; diff --git a/frontend/editor/src/core/components/onboarding/slides/DesktopInstallTitle.tsx b/frontend/editor/src/core/components/onboarding/slides/DesktopInstallTitle.tsx index efb95b95bb..b76eff2c30 100644 --- a/frontend/editor/src/core/components/onboarding/slides/DesktopInstallTitle.tsx +++ b/frontend/editor/src/core/components/onboarding/slides/DesktopInstallTitle.tsx @@ -129,9 +129,9 @@ export const DesktopInstallTitle: React.FC = ({ leftSection={iconKey ? : undefined} style={{ backgroundColor: isSelected - ? "var(--bg-muted, #f1f5f9)" + ? "var(--c-surface-sunken, #f1f5f9)" : "transparent", - color: "var(--onboarding-title, #0f172a)", + color: "var(--c-text, #0f172a)", fontWeight: isSelected ? 600 : 500, }} > diff --git a/frontend/editor/src/core/components/onboarding/slides/FirstLoginSlide.tsx b/frontend/editor/src/core/components/onboarding/slides/FirstLoginSlide.tsx index 89de08e6e7..d684592a4a 100644 --- a/frontend/editor/src/core/components/onboarding/slides/FirstLoginSlide.tsx +++ b/frontend/editor/src/core/components/onboarding/slides/FirstLoginSlide.tsx @@ -125,7 +125,7 @@ function FirstLoginForm({ icon="info-rounded" width={20} height={20} - style={{ color: "#3B82F6", flexShrink: 0 }} + style={{ color: "var(--c-primary)", flexShrink: 0 }} /> {t( diff --git a/frontend/editor/src/core/components/onboarding/slides/SecurityCheckSlide.tsx b/frontend/editor/src/core/components/onboarding/slides/SecurityCheckSlide.tsx index 02b3e8502c..6101605772 100644 --- a/frontend/editor/src/core/components/onboarding/slides/SecurityCheckSlide.tsx +++ b/frontend/editor/src/core/components/onboarding/slides/SecurityCheckSlide.tsx @@ -26,7 +26,7 @@ export default function SecurityCheckSlide({ icon="error" width={20} height={20} - style={{ color: "#F04438", flexShrink: 0 }} + style={{ color: "var(--c-danger)", flexShrink: 0 }} /> {i18n.t( diff --git a/frontend/editor/src/core/components/pageEditor/DragDropGrid.module.css b/frontend/editor/src/core/components/pageEditor/DragDropGrid.module.css index afad117774..519ec608e0 100644 --- a/frontend/editor/src/core/components/pageEditor/DragDropGrid.module.css +++ b/frontend/editor/src/core/components/pageEditor/DragDropGrid.module.css @@ -28,15 +28,15 @@ .selectionBox { position: absolute; - border: 2px dashed #3b82f6; - background-color: rgba(59, 130, 246, 0.1); + border: 2px dashed var(--c-primary); + background-color: color-mix(in srgb, var(--c-primary) 10%, transparent); pointer-events: none; } .dropIndicator { position: absolute; width: 4px; - background-color: rgba(96, 165, 250, 0.8); + background-color: color-mix(in srgb, var(--c-primary) 80%, transparent); border-radius: 2px; pointer-events: none; } @@ -50,8 +50,8 @@ position: absolute; top: -8px; right: -8px; - background-color: #3b82f6; - color: #ffffff; + background-color: var(--c-primary); + color: var(--c-text-on-primary); border-radius: 50%; width: 32px; height: 32px; diff --git a/frontend/editor/src/core/components/pageEditor/FileThumbnail.tsx b/frontend/editor/src/core/components/pageEditor/FileThumbnail.tsx index 472fc141d7..f3730a9399 100644 --- a/frontend/editor/src/core/components/pageEditor/FileThumbnail.tsx +++ b/frontend/editor/src/core/components/pageEditor/FileThumbnail.tsx @@ -241,7 +241,7 @@ const FileThumbnail = ({ onToggleFile(file.id)} - color="var(--checkbox-checked-bg)" + color="var(--c-primary)" /> ) : (
@@ -372,7 +372,7 @@ const FileThumbnail = ({ objectFit: "contain", borderRadius: 0, background: "#ffffff", - border: "1px solid var(--border-default)", + border: "1px solid var(--c-border)", display: "block", marginLeft: "auto", marginRight: "auto", diff --git a/frontend/editor/src/core/components/pageEditor/PageEditor.module.css b/frontend/editor/src/core/components/pageEditor/PageEditor.module.css index 3be018ffa2..fe8660a04a 100644 --- a/frontend/editor/src/core/components/pageEditor/PageEditor.module.css +++ b/frontend/editor/src/core/components/pageEditor/PageEditor.module.css @@ -21,13 +21,13 @@ @keyframes pageMovedHighlight { 0% { - background-color: rgba(59, 130, 246, 0.32); + background-color: color-mix(in srgb, var(--c-primary) 32%, transparent); } 60% { - background-color: rgba(59, 130, 246, 0.12); + background-color: color-mix(in srgb, var(--c-primary) 12%, transparent); } 100% { - background-color: rgba(59, 130, 246, 0); + background-color: color-mix(in srgb, var(--c-primary) 0%, transparent); } } @@ -63,7 +63,7 @@ /* Action styles */ .actionRow:hover { - background: var(--hover-bg); + background: var(--c-hover); } .actionDanger { @@ -72,7 +72,7 @@ .actionsDivider { height: 1px; - background: var(--border-default); + background: var(--c-border); margin: 4px 0; } @@ -86,7 +86,7 @@ .unsupportedPill { margin-left: 1.75rem; - background: #6b7280; + background: var(--c-text-subtle); color: white; padding: 4px 8px; border-radius: 12px; diff --git a/frontend/editor/src/core/components/pageEditor/PageEditorControls.tsx b/frontend/editor/src/core/components/pageEditor/PageEditorControls.tsx index 96762a9203..fe73984fef 100644 --- a/frontend/editor/src/core/components/pageEditor/PageEditorControls.tsx +++ b/frontend/editor/src/core/components/pageEditor/PageEditorControls.tsx @@ -121,8 +121,8 @@ const PageEditorControls = ({ borderBottomLeftRadius: 0, borderBottomRightRadius: 0, boxShadow: "0 -2px 8px rgba(0,0,0,0.04)", - backgroundColor: "var(--bg-toolbar)", - border: "1px solid var(--border-default)", + backgroundColor: "var(--c-bg-raised)", + border: "1px solid var(--c-border)", borderRadius: "16px 16px 0 0", pointerEvents: "auto", minWidth: 360, diff --git a/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/BulkSelectionPanel.module.css b/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/BulkSelectionPanel.module.css index f80bebaa26..1ecd05808b 100644 --- a/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/BulkSelectionPanel.module.css +++ b/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/BulkSelectionPanel.module.css @@ -31,7 +31,7 @@ .rightCol { width: 8rem; - border-left: 0.0625rem solid var(--border-default); + border-left: 0.0625rem solid var(--c-border); padding-left: 0.75rem; display: flex; flex-direction: column; @@ -47,15 +47,15 @@ width: 100%; border-radius: 1.25rem; border: 0.0625rem solid var(--bulk-card-border); - background-color: var(--bulk-card-bg); - color: var(--text-primary); + background-color: var(--c-surface); + color: var(--c-text); transition: all 0.2s ease; min-height: 2rem; } .operatorChip:hover:not(:disabled) { border-color: var(--bulk-card-hover-border); - background-color: var(--hover-bg); + background-color: var(--c-hover); transform: translateY(-0.0625rem); box-shadow: var(--shadow-sm); } @@ -70,24 +70,12 @@ cursor: not-allowed; } -:global([data-mantine-color-scheme="dark"]) .operatorChip { - background-color: var(--bulk-card-bg); - border-color: var(--bulk-card-border); - color: var(--text-primary); -} - -:global([data-mantine-color-scheme="dark"]) .operatorChip:hover:not(:disabled) { - background-color: var(--hover-bg); - border-color: var(--bulk-card-hover-border); - color: var(--text-primary); -} - .dropdownHeader { display: flex; justify-content: space-between; align-items: center; padding: 0.75rem; - border-bottom: 0.0625rem solid var(--border-default); + border-bottom: 0.0625rem solid var(--c-border); margin-bottom: 0.5rem; } @@ -111,7 +99,7 @@ } .chevron { - color: var(--text-muted); + color: var(--c-text-subtle); } /* Icon-based chevrons */ @@ -151,13 +139,13 @@ .selectedList { max-height: 8rem; overflow: auto; - background-color: var(--bg-raised); - border: 0.0625rem solid var(--border-default); + background-color: var(--c-surface-raised); + border: 0.0625rem solid var(--c-border); border-radius: 0.75rem; padding: 0.5rem 0.75rem; margin-top: 0.5rem; min-width: 24rem; - color: var(--text-primary); + color: var(--c-text); } .selectedText { @@ -175,7 +163,7 @@ justify-content: space-between; align-items: center; padding: 0.75rem; - border-bottom: 0.0625rem solid var(--border-default); + border-bottom: 0.0625rem solid var(--c-border); margin-bottom: 0.5rem; } @@ -193,26 +181,18 @@ } .advancedItem:hover { - background-color: var(--hover-bg); -} - -:global([data-mantine-color-scheme="dark"]) .advancedItem:hover { - background-color: var(--hover-bg); + background-color: var(--c-hover); } .advancedCard { - background-color: var(--bulk-card-bg); + background-color: var(--c-surface); border: none; border-radius: 0.75rem; padding: 0.25rem; margin-bottom: 0.5rem; width: 100%; box-sizing: border-box; - color: var(--text-primary); -} - -:global([data-mantine-color-scheme="dark"]) .advancedCard { - background-color: var(--bulk-card-bg); + color: var(--c-text); } .inputGroup { @@ -226,24 +206,17 @@ .applyButton { min-width: 4rem; flex-shrink: 0; -} - -/* Style inputs and buttons within advanced cards to match bg-raised */ -.advancedCard :global(.mantine-NumberInput-input) { - background-color: var(--bg-raised) !important; - border-color: var(--border-default) !important; - color: var(--text-primary) !important; -} - +} /* Style inputs and buttons within advanced cards to match bg-raised */ +.advancedCard :global(.mantine-NumberInput-input), .advancedCard :global(.mantine-Button-root) { - background-color: var(--bg-raised) !important; - border-color: var(--border-default) !important; - color: var(--text-primary) !important; + background-color: var(--c-surface-raised) !important; + border-color: var(--c-border) !important; + color: var(--c-text) !important; } .advancedCard :global(.mantine-Button-root:hover) { - background-color: var(--hover-bg) !important; - border-color: var(--border-strong) !important; + background-color: var(--c-hover) !important; + border-color: var(--c-border-strong) !important; } /* Error helper text above the input */ @@ -254,8 +227,8 @@ /* Compact error container for inline tool settings */ .errorCompact { - background-color: var(--bg-raised); - border: 0.0625rem solid var(--border-default); + background-color: var(--c-surface-raised); + border: 0.0625rem solid var(--c-border); border-radius: 0.75rem; padding: 0.5rem 0.75rem; margin-top: 0.5rem; @@ -271,11 +244,6 @@ overflow: hidden; } -/* Dark-mode adjustments */ -:global([data-mantine-color-scheme="dark"]) .selectedList { - background-color: var(--bg-raised); -} - /* Small screens: allow the section to shrink instead of enforcing a large min width */ @media (max-width: 480px) { .panelGroup, @@ -290,16 +258,16 @@ .panelContainer { max-height: 95vh; overflow: auto; - background-color: var(--bulk-panel-bg); - color: var(--text-primary); + background-color: var(--c-surface); + color: var(--c-text); border-radius: 0.5rem; } /* Override Mantine Popover dropdown background */ :global(.mantine-Popover-dropdown) { - background-color: var(--bulk-panel-bg) !important; + background-color: var(--c-surface) !important; border-color: var(--bulk-card-border) !important; - color: var(--text-primary) !important; + color: var(--c-text) !important; } /* Override Mantine Switch outline */ diff --git a/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/OperatorsSection.tsx b/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/OperatorsSection.tsx index d2ff79ad97..682a134268 100644 --- a/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/OperatorsSection.tsx +++ b/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/OperatorsSection.tsx @@ -17,7 +17,7 @@ const OperatorsSection = ({ return (
- + {t("bulkSelection.keywords.title", "Keywords")}: diff --git a/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/PageSelectionInput.tsx b/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/PageSelectionInput.tsx index 2e5513a7c8..f0add9d978 100644 --- a/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/PageSelectionInput.tsx +++ b/frontend/editor/src/core/components/pageEditor/bulkSelectionPanel/PageSelectionInput.tsx @@ -44,7 +44,7 @@ const PageSelectionInput = ({ icon="gpp-maybe-outline-rounded" width="1rem" height="1rem" - style={{ color: "var(--text-instruction)" }} + style={{ color: "var(--c-accent-fg)" }} /> {t("bulkSelection.pageSelection.title", "Page Selection")} @@ -53,7 +53,7 @@ const PageSelectionInput = ({ {typeof advancedOpened === "boolean" && ( - + {t("bulkSelection.advanced.title", "Advanced")} - + {title} {error && ( diff --git a/frontend/editor/src/core/components/shared/AppConfigModal.css b/frontend/editor/src/core/components/shared/AppConfigModal.css index 3f979258fb..46033eaf97 100644 --- a/frontend/editor/src/core/components/shared/AppConfigModal.css +++ b/frontend/editor/src/core/components/shared/AppConfigModal.css @@ -63,7 +63,8 @@ } .modal-nav-scroll:hover { - scrollbar-color: rgba(128, 128, 128, 0.5) transparent; + scrollbar-color: color-mix(in srgb, var(--c-border-strong) 50%, transparent) + transparent; } .modal-nav-scroll::-webkit-scrollbar { @@ -81,11 +82,11 @@ } .modal-nav-scroll:hover::-webkit-scrollbar-thumb { - background-color: rgba(128, 128, 128, 0.5); + background-color: color-mix(in srgb, var(--c-border-strong) 50%, transparent); } .modal-nav-scroll::-webkit-scrollbar-thumb:hover { - background-color: rgba(128, 128, 128, 0.7); + background-color: color-mix(in srgb, var(--c-border-strong) 70%, transparent); } .modal-nav-section { @@ -131,7 +132,8 @@ } .modal-content-scroll:hover { - scrollbar-color: rgba(128, 128, 128, 0.5) transparent; + scrollbar-color: color-mix(in srgb, var(--c-border-strong) 50%, transparent) + transparent; } .modal-content-scroll::-webkit-scrollbar { @@ -149,11 +151,11 @@ } .modal-content-scroll:hover::-webkit-scrollbar-thumb { - background-color: rgba(128, 128, 128, 0.5); + background-color: color-mix(in srgb, var(--c-border-strong) 50%, transparent); } .modal-content-scroll::-webkit-scrollbar-thumb:hover { - background-color: rgba(128, 128, 128, 0.7); + background-color: color-mix(in srgb, var(--c-border-strong) 70%, transparent); } .modal-header { @@ -212,8 +214,8 @@ bottom: 0; left: 0; right: 0; - background: var(--modal-content-bg); - border-top: 1px solid var(--modal-header-border); + background: var(--c-surface); + border-top: 1px solid var(--c-border-subtle); padding: 1rem 2rem; margin: 0 -2rem; margin-bottom: -1rem; diff --git a/frontend/editor/src/core/components/shared/AppConfigModal.tsx b/frontend/editor/src/core/components/shared/AppConfigModal.tsx index 1a9485cce8..9ad7963b6f 100644 --- a/frontend/editor/src/core/components/shared/AppConfigModal.tsx +++ b/frontend/editor/src/core/components/shared/AppConfigModal.tsx @@ -165,13 +165,13 @@ const AppConfigModalInner: React.FC = ({ const colors = useMemo( () => ({ - navBg: "var(--modal-nav-bg)", - sectionTitle: "var(--modal-nav-section-title)", + navBg: "var(--c-bg-raised)", + sectionTitle: "var(--c-text-subtle)", navItem: "var(--modal-nav-item)", - navItemActive: "var(--modal-nav-item-active)", - navItemActiveBg: "var(--modal-nav-item-active-bg)", - contentBg: "var(--modal-content-bg)", - headerBorder: "var(--modal-header-border)", + navItemActive: "var(--c-accent-fg)", + navItemActiveBg: "var(--c-primary-subtle)", + contentBg: "var(--c-surface)", + headerBorder: "var(--c-border-subtle)", }), [], ); diff --git a/frontend/editor/src/core/components/shared/AppSwitch.css b/frontend/editor/src/core/components/shared/AppSwitch.css index c40080b1e9..bccf8fbceb 100644 --- a/frontend/editor/src/core/components/shared/AppSwitch.css +++ b/frontend/editor/src/core/components/shared/AppSwitch.css @@ -9,15 +9,15 @@ background: none; cursor: pointer; border-radius: var(--radius-sm); - color: var(--color-text-4); + color: var(--c-text-subtle); transition: background var(--motion-fast), color var(--motion-fast); } .app-switch-btn:hover { - background: var(--color-bg-hover); - color: var(--color-text-2); + background: var(--c-hover); + color: var(--c-text-muted); } .app-switch-icon { diff --git a/frontend/editor/src/core/components/shared/Badge.tsx b/frontend/editor/src/core/components/shared/Badge.tsx index dd15bec465..04ca973a8e 100644 --- a/frontend/editor/src/core/components/shared/Badge.tsx +++ b/frontend/editor/src/core/components/shared/Badge.tsx @@ -79,8 +79,8 @@ const Badge: React.FC = ({ // Default styling return { - background: "var(--tool-header-badge-bg)", - color: "var(--tool-header-badge-text)", + background: "var(--c-surface-raised)", + color: "var(--c-accent-fg)", }; }; diff --git a/frontend/editor/src/core/components/shared/EditableSecretField.tsx b/frontend/editor/src/core/components/shared/EditableSecretField.tsx index 24e6d881c3..4168996959 100644 --- a/frontend/editor/src/core/components/shared/EditableSecretField.tsx +++ b/frontend/editor/src/core/components/shared/EditableSecretField.tsx @@ -78,7 +78,11 @@ export default function EditableSecretField({ )} {description && (

{description}

diff --git a/frontend/editor/src/core/components/shared/ErrorBoundary.tsx b/frontend/editor/src/core/components/shared/ErrorBoundary.tsx index a2003a7d61..b5330058c4 100644 --- a/frontend/editor/src/core/components/shared/ErrorBoundary.tsx +++ b/frontend/editor/src/core/components/shared/ErrorBoundary.tsx @@ -117,7 +117,7 @@ export default class ErrorBoundary extends React.Component< style={{ fontSize: "0.75rem", overflow: "auto", - backgroundColor: "#f5f5f5", + backgroundColor: "var(--c-surface-sunken)", padding: "1rem", borderRadius: "4px", maxHeight: "300px", diff --git a/frontend/editor/src/core/components/shared/FileCard.tsx b/frontend/editor/src/core/components/shared/FileCard.tsx index c731092459..e43dbeeb1c 100644 --- a/frontend/editor/src/core/components/shared/FileCard.tsx +++ b/frontend/editor/src/core/components/shared/FileCard.tsx @@ -74,7 +74,7 @@ const FileCard = ({ diff --git a/frontend/editor/src/core/components/shared/FileDropdownMenu.tsx b/frontend/editor/src/core/components/shared/FileDropdownMenu.tsx index 735d633fee..00eb8b7c56 100644 --- a/frontend/editor/src/core/components/shared/FileDropdownMenu.tsx +++ b/frontend/editor/src/core/components/shared/FileDropdownMenu.tsx @@ -54,8 +54,8 @@ export const FileDropdownMenu: React.FC = ({ (
{isGoogleDriveEnabled && ( ( aria-label={t("watchedFolders.sidebarTitle", "Watched Folders")} style={ isWatchedFoldersActive - ? { backgroundColor: "var(--active-bg)" } + ? { backgroundColor: "var(--c-active)" } : undefined } > @@ -1197,7 +1197,7 @@ const FileSidebar = forwardRef( {!stubsLoaded ? (
- +
) : filteredFileStubs.length > 0 ? (
diff --git a/frontend/editor/src/core/components/shared/FileSidebarFileItem.css b/frontend/editor/src/core/components/shared/FileSidebarFileItem.css index 09c0c5e8eb..4d742f7be6 100644 --- a/frontend/editor/src/core/components/shared/FileSidebarFileItem.css +++ b/frontend/editor/src/core/components/shared/FileSidebarFileItem.css @@ -17,7 +17,7 @@ background: transparent; } .file-sidebar-file-list::-webkit-scrollbar-thumb { - background: rgb(var(--border)); + background: var(--c-border); border-radius: 2px; } @@ -63,15 +63,15 @@ } .file-sidebar-file-item:hover:not(.selected) { - background-color: rgba(59, 130, 246, 0.06); + background-color: color-mix(in srgb, var(--c-primary) 6%, transparent); } .file-sidebar-file-item.selected { - background-color: rgba(59, 130, 246, 0.12); + background-color: color-mix(in srgb, var(--c-primary) 12%, transparent); } .file-sidebar-file-item.active:not(.selected) { - background-color: rgba(59, 130, 246, 0.06); + background-color: color-mix(in srgb, var(--c-primary) 6%, transparent); } /* Icon wrapper */ @@ -95,7 +95,7 @@ width: 20px; height: 20px; border-radius: 5px; - border: 1.5px solid var(--border-hover, var(--border-strong)); + border: 1.5px solid var(--c-border-strong); } .file-sidebar-file-item:hover .file-sidebar-file-checkbox-hover { @@ -116,7 +116,7 @@ width: 20px; height: 20px; border-radius: 5px; - background-color: #3b82f6; + background-color: var(--c-primary); display: flex; align-items: center; justify-content: center; @@ -124,7 +124,7 @@ } .file-sidebar-check-svg { - color: white; + color: var(--c-text-on-primary); flex-shrink: 0; } @@ -179,14 +179,14 @@ display: block; font-size: 13px; font-weight: 500; - color: var(--text-primary); + color: var(--c-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .file-sidebar-file-item.selected .file-sidebar-file-name { - color: #3b82f6; + color: var(--c-accent-fg); } .file-sidebar-file-meta-row { @@ -199,7 +199,7 @@ .file-sidebar-file-meta { font-size: 11px; - color: var(--text-muted); + color: var(--c-text-subtle); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -211,7 +211,7 @@ align-items: center; justify-content: center; flex-shrink: 0; - color: var(--accent-interactive, #6366f1); + color: var(--c-primary); } /* ---- Folder membership tags ---- */ @@ -250,7 +250,7 @@ font-size: 10px; font-weight: 600; line-height: 1.2; - color: var(--text-secondary); + color: var(--c-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -260,7 +260,7 @@ font-size: 10px; font-weight: 600; line-height: 1; - color: var(--text-muted); + color: var(--c-text-subtle); cursor: default; flex-shrink: 0; } @@ -277,7 +277,7 @@ background: transparent; border-radius: 4px; cursor: pointer; - color: var(--text-muted); + color: var(--c-text-subtle); padding: 0; opacity: 0; transition: @@ -297,48 +297,45 @@ bottom: 0; z-index: 2; /* solid base + green tint overlay so content behind doesn't bleed through */ - background-color: var(--bg-toolbar); + background-color: var(--c-bg-raised); background-image: linear-gradient( - rgba(34, 197, 94, 0.1), - rgba(34, 197, 94, 0.1) + color-mix(in srgb, var(--c-success) 10%, transparent), + color-mix(in srgb, var(--c-success) 10%, transparent) ); } .file-sidebar-file-item.viewed .file-sidebar-file-name { - color: #22c55e; + color: var(--c-success); } .file-sidebar-file-item.viewed .file-sidebar-file-check { - background-color: #22c55e; + background-color: var(--c-success); } /* viewed takes precedence over selected */ .file-sidebar-file-item.viewed.selected { - background-color: var(--bg-toolbar); + background-color: var(--c-bg-raised); background-image: linear-gradient( - rgba(34, 197, 94, 0.1), - rgba(34, 197, 94, 0.1) + color-mix(in srgb, var(--c-success) 10%, transparent), + color-mix(in srgb, var(--c-success) 10%, transparent) ); } /* Always show eye for the currently viewed file */ .file-sidebar-file-item.viewed .file-sidebar-eye-btn { opacity: 1; - color: #22c55e; + color: var(--c-success); } .file-sidebar-eye-btn:hover { - color: var(--text-primary); + color: var(--c-text); } /* Eye open: shown by default */ .file-sidebar-eye-open { display: block !important; } -.file-sidebar-eye-closed { - display: none !important; -} - +.file-sidebar-eye-closed, /* On hover over a viewed item: swap to eye-closed */ .file-sidebar-file-item.viewed:hover .file-sidebar-eye-open { display: none !important; @@ -359,7 +356,7 @@ background: transparent; border-radius: 4px; cursor: pointer; - color: var(--text-muted); + color: var(--c-text-subtle); padding: 0; opacity: 0; transition: @@ -376,14 +373,14 @@ } .file-sidebar-kebab-btn:hover { - color: var(--text-primary); + color: var(--c-text); } /* ---- Date group headers ---- */ .file-sidebar-date-group-header { font-size: 11px; font-weight: 500; - color: var(--text-muted); + color: var(--c-text-subtle); padding: 0 10px 2px 10px; margin-top: 8px; user-select: none; @@ -410,13 +407,13 @@ .file-sidebar-empty-text { font-size: 12px; - color: var(--text-muted); + color: var(--c-text-subtle); margin: 0 0 2px 0; } .file-sidebar-empty-hint { font-size: 11px; - color: var(--text-muted); + color: var(--c-text-subtle); opacity: 0.7; margin: 0; } @@ -426,8 +423,8 @@ position: fixed; z-index: 9999; transform: translateY(-50%); - background: var(--bg-surface, #fff); - border: 1px solid var(--border-subtle); + background: var(--c-surface); + border: 1px solid var(--c-border-subtle); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18); padding: 4px; diff --git a/frontend/editor/src/core/components/shared/Footer.tsx b/frontend/editor/src/core/components/shared/Footer.tsx index 2fb7312fba..8ae0d3d4c1 100644 --- a/frontend/editor/src/core/components/shared/Footer.tsx +++ b/frontend/editor/src/core/components/shared/Footer.tsx @@ -54,8 +54,8 @@ export default function Footer({
= ({ disabled={action.disabled} onClick={action.onClick} aria-label={action.label} - style={{ color: action.color || "var(--text-secondary)" }} + style={{ color: action.color || "var(--c-text-muted)" }} data-tour={action.dataTour} > {action.icon} diff --git a/frontend/editor/src/core/components/shared/LandingPage.css b/frontend/editor/src/core/components/shared/LandingPage.css index 8762c1368d..57729a806a 100644 --- a/frontend/editor/src/core/components/shared/LandingPage.css +++ b/frontend/editor/src/core/components/shared/LandingPage.css @@ -10,7 +10,7 @@ font-size: 2rem; font-weight: 700; line-height: 1.25; - color: var(--text-primary); + color: var(--c-text); } .landing-subtitle { @@ -20,7 +20,7 @@ font-size: 0.9375rem; line-height: 1.5; max-width: 28rem; - color: var(--text-secondary); + color: var(--c-text-muted); } /* ── Document stack ──────────────────────────────────────── */ @@ -49,7 +49,7 @@ width: 128px; height: 160px; transform-origin: bottom center; - border: 1px solid #e5e7eb; + border: 1px solid var(--c-illustration-line); box-shadow: var(--landing-doc-shadow-back-idle); } @@ -103,10 +103,10 @@ /* Bars — static light colours, never change with theme */ .landing-bar { border-radius: 9999px; - background-color: #e5e7eb; + background-color: var(--c-illustration-line); } .landing-bar--strong { - background-color: #d1d5db; + background-color: var(--c-illustration-line-strong); } /* ── Action buttons ──────────────────────────────────────── */ @@ -121,27 +121,27 @@ .landing-btn-secondary { border-radius: 0.75rem !important; font-weight: 600 !important; - border-color: var(--landing-button-border, var(--border-default)) !important; - background-color: var(--landing-button-bg, var(--bg-surface)) !important; - color: var(--landing-button-color, var(--text-primary)) !important; + border-color: var(--landing-button-border, var(--c-border)) !important; + background-color: var(--landing-button-bg, var(--c-surface)) !important; + color: var(--c-accent-fg, var(--c-text)) !important; } .landing-btn-secondary:hover { background-color: var( --landing-button-hover-bg, - var(--landing-button-bg, var(--bg-surface)) + var(--landing-button-bg, var(--c-surface)) ) !important; } /* Icon-only variant: accent colour instead of button text colour */ .landing-btn-icon { - color: var(--accent-interactive) !important; + color: var(--c-primary) !important; } /* Dropzone accept/reject outlines. Mantine 8 no longer supports nested * `&[data-accept]` selectors inside the `styles` prop object, so these are * plain CSS attribute selectors on a class applied to the Dropzone root. */ .landing-dropzone[data-accept] { - outline: 2px dashed var(--accent-interactive); + outline: 2px dashed var(--c-primary); outline-offset: 4px; } .landing-dropzone[data-reject] { diff --git a/frontend/editor/src/core/components/shared/LanguageSelector.module.css b/frontend/editor/src/core/components/shared/LanguageSelector.module.css index 8f2248687b..68c1d672bf 100644 --- a/frontend/editor/src/core/components/shared/LanguageSelector.module.css +++ b/frontend/editor/src/core/components/shared/LanguageSelector.module.css @@ -6,7 +6,7 @@ } .languageItem { - border-right: 2px solid var(--mantine-color-gray-3); + border-right: 2px solid var(--c-border); } .languageItem:nth-child(4n) { @@ -20,7 +20,7 @@ } .languageItem:nth-child(4n) { - border-right: 2px solid var(--mantine-color-gray-3); + border-right: 2px solid var(--c-border); } .languageItem:nth-child(2n) { @@ -34,7 +34,7 @@ } .languageItem:nth-child(4n) { - border-right: 2px solid var(--mantine-color-gray-3); + border-right: 2px solid var(--c-border); } .languageItem:nth-child(3n) { @@ -42,23 +42,12 @@ } } -/* Dark theme support */ -[data-mantine-color-scheme="dark"] .languageItem { - border-right-color: var(--mantine-color-dark-3); -} - +/* Dark theme: divider colour comes from the adaptive --c-border token on the + base rules; only the layout quirk (no right border on 4n) differs. */ [data-mantine-color-scheme="dark"] .languageItem:nth-child(4n) { border-right: none; } -[data-mantine-color-scheme="dark"] .languageItem:nth-child(2n) { - border-right-color: var(--mantine-color-dark-3); -} - -[data-mantine-color-scheme="dark"] .languageItem:nth-child(3n) { - border-right-color: var(--mantine-color-dark-3); -} - /* Responsive text visibility */ .languageText { display: none; diff --git a/frontend/editor/src/core/components/shared/LanguageSelector.tsx b/frontend/editor/src/core/components/shared/LanguageSelector.tsx index aad6c714d7..257f7cd0f5 100644 --- a/frontend/editor/src/core/components/shared/LanguageSelector.tsx +++ b/frontend/editor/src/core/components/shared/LanguageSelector.tsx @@ -91,10 +91,10 @@ const LanguageItem: React.FC = ({ ? "light-dark(var(--mantine-color-blue-1), var(--mantine-color-blue-8))" : undefined, color: disabled - ? "var(--text-muted)" + ? "var(--c-text-subtle)" : isSelected ? "light-dark(var(--mantine-color-blue-9), var(--mantine-color-blue-3))" - : "var(--text-primary)", + : "var(--c-text)", }} > {label} diff --git a/frontend/editor/src/core/components/shared/ObscuredOverlay/ObscuredOverlay.module.css b/frontend/editor/src/core/components/shared/ObscuredOverlay/ObscuredOverlay.module.css index 5651993c4c..4f390cf066 100644 --- a/frontend/editor/src/core/components/shared/ObscuredOverlay/ObscuredOverlay.module.css +++ b/frontend/editor/src/core/components/shared/ObscuredOverlay/ObscuredOverlay.module.css @@ -12,7 +12,7 @@ padding: 16px; color: #ffffff; font-weight: 600; - background: rgba(16, 18, 27, 0.55); + background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); border: 1px solid rgba(255, 255, 255, 0.06); diff --git a/frontend/editor/src/core/components/shared/PageEditorFileDropdown.tsx b/frontend/editor/src/core/components/shared/PageEditorFileDropdown.tsx index fbe44c35c6..b15374d101 100644 --- a/frontend/editor/src/core/components/shared/PageEditorFileDropdown.tsx +++ b/frontend/editor/src/core/components/shared/PageEditorFileDropdown.tsx @@ -197,8 +197,8 @@ export const PageEditorFileDropdown: React.FC = ({ = ({ marginTop: "0.5rem", cursor: "pointer", backgroundColor: "transparent", - borderTop: "1px solid var(--border-subtle)", + borderTop: "1px solid var(--c-border-subtle)", transition: "background-color 0.15s ease", }} onMouseEnter={(e) => { diff --git a/frontend/editor/src/core/components/shared/PolicyBadges.css b/frontend/editor/src/core/components/shared/PolicyBadges.css index d193cc752e..3a919e24c9 100644 --- a/frontend/editor/src/core/components/shared/PolicyBadges.css +++ b/frontend/editor/src/core/components/shared/PolicyBadges.css @@ -17,7 +17,7 @@ width: 15px; height: 15px; border-radius: 4px; - color: var(--text-secondary); + color: var(--c-text-muted); background: color-mix(in srgb, currentColor 16%, transparent); pointer-events: auto; } diff --git a/frontend/editor/src/core/components/shared/ToolIcon.tsx b/frontend/editor/src/core/components/shared/ToolIcon.tsx index d0a1c82b9b..b1aa129304 100644 --- a/frontend/editor/src/core/components/shared/ToolIcon.tsx +++ b/frontend/editor/src/core/components/shared/ToolIcon.tsx @@ -14,7 +14,7 @@ interface ToolIconProps { export const ToolIcon: React.FC = ({ icon, opacity = 1, - color = "var(--tools-text-and-icon-color)", + color = "var(--c-text)", marginRight = "0.5rem", }) => { return ( diff --git a/frontend/editor/src/core/components/shared/ToolPanelHeader.css b/frontend/editor/src/core/components/shared/ToolPanelHeader.css index f1d99d1913..6080586d07 100644 --- a/frontend/editor/src/core/components/shared/ToolPanelHeader.css +++ b/frontend/editor/src/core/components/shared/ToolPanelHeader.css @@ -18,7 +18,7 @@ flex: 1; min-width: 0; padding: 0.4rem 0.75rem 0.4rem 0.4rem; - border: 1px solid var(--border-subtle, var(--mantine-color-default-border)); + border: 1px solid var(--c-border-subtle, var(--mantine-color-default-border)); border-radius: 9999px; background: var(--mantine-color-body); text-align: left; @@ -70,7 +70,7 @@ so it doesn't read as a clashing lighter card on the dark toolbar. */ [data-mantine-color-scheme="dark"] .sui-panelhdr__bar { background: transparent; - border-color: var(--border-subtle, var(--mantine-color-default-border)); + border-color: var(--c-border-subtle, var(--mantine-color-default-border)); } [data-mantine-color-scheme="dark"] .sui-panelhdr__icon { diff --git a/frontend/editor/src/core/components/shared/Tooltip.tsx b/frontend/editor/src/core/components/shared/Tooltip.tsx index 9c94bc4726..5403940751 100644 --- a/frontend/editor/src/core/components/shared/Tooltip.tsx +++ b/frontend/editor/src/core/components/shared/Tooltip.tsx @@ -383,7 +383,7 @@ export const Tooltip: React.FC = ({ zIndex: Z_INDEX_OVER_FULLSCREEN_SURFACE, visibility: positionReady ? "visible" : "hidden", opacity: positionReady ? 1 : 0, - color: "var(--text-primary)", + color: "var(--c-text)", ...containerStyle, }} className={`${styles["tooltip-container"]} ${isPinned ? styles.pinned : ""}`} diff --git a/frontend/editor/src/core/components/shared/UpdateModal.tsx b/frontend/editor/src/core/components/shared/UpdateModal.tsx index 4a5e5b2404..f2c14f16fb 100644 --- a/frontend/editor/src/core/components/shared/UpdateModal.tsx +++ b/frontend/editor/src/core/components/shared/UpdateModal.tsx @@ -291,7 +291,7 @@ const UpdateModal: React.FC = ({ = ({ style={{ borderTop: idx === 0 - ? "1px solid var(--border-subtle, var(--mantine-color-default-border))" + ? "1px solid var(--c-border-subtle, var(--mantine-color-default-border))" : undefined, borderBottom: - "1px solid var(--border-subtle, var(--mantine-color-default-border))", + "1px solid var(--c-border-subtle, var(--mantine-color-default-border))", padding: "10px 12px", }} > @@ -576,10 +576,10 @@ const UpdateModal: React.FC = ({ style={{ borderTop: index === 0 - ? "1px solid var(--border-subtle, var(--mantine-color-default-border))" + ? "1px solid var(--c-border-subtle, var(--mantine-color-default-border))" : undefined, borderBottom: - "1px solid var(--border-subtle, var(--mantine-color-default-border))", + "1px solid var(--c-border-subtle, var(--mantine-color-default-border))", }} > = ({ pb="sm" style={{ borderTop: - "1px solid var(--border-subtle, var(--mantine-color-default-border))", + "1px solid var(--c-border-subtle, var(--mantine-color-default-border))", }} > @@ -749,7 +749,7 @@ const UpdateModal: React.FC = ({ = ({ = ({ fontWeight: 700, letterSpacing: "0.1em", textTransform: "uppercase", - color: "var(--text-secondary)", + color: "var(--c-text-muted)", background: "rgb(var(--border))", padding: "3px 10px", borderRadius: "6px", diff --git a/frontend/editor/src/core/components/shared/textInput/TextInput.module.css b/frontend/editor/src/core/components/shared/textInput/TextInput.module.css index 72fa8abb7b..b5131b014f 100644 --- a/frontend/editor/src/core/components/shared/textInput/TextInput.module.css +++ b/frontend/editor/src/core/components/shared/textInput/TextInput.module.css @@ -15,7 +15,7 @@ display: flex; align-items: center; justify-content: center; - color: var(--search-text-and-icon-color); + color: var(--c-text-subtle); } .input { @@ -27,12 +27,12 @@ outline: none; box-shadow: none; transition: box-shadow 0.2s ease; - background-color: var(--input-bg); - color: var(--search-text-and-icon-color); + background-color: var(--c-input-bg); + color: var(--c-text-subtle); } .input::placeholder { - color: var(--search-text-and-icon-color); + color: var(--c-text-subtle); opacity: 1; } @@ -65,13 +65,9 @@ justify-content: center; font-size: 16px; transition: background-color 0.2s ease; - color: var(--search-text-and-icon-color); + color: var(--c-text-subtle); } .clearButton:hover { - background-color: rgba(0, 0, 0, 0.1); -} - -[data-mantine-color-scheme="dark"] .clearButton:hover { - background-color: rgba(255, 255, 255, 0.1); + background-color: var(--c-hover); } diff --git a/frontend/editor/src/core/components/shared/tooltip/Tooltip.module.css b/frontend/editor/src/core/components/shared/tooltip/Tooltip.module.css index e2b5ecca10..fa4023dc56 100644 --- a/frontend/editor/src/core/components/shared/tooltip/Tooltip.module.css +++ b/frontend/editor/src/core/components/shared/tooltip/Tooltip.module.css @@ -1,9 +1,9 @@ /* Tooltip Container */ .tooltip-container { position: fixed; - border: 0.0625rem solid var(--border-default); + border: 0.0625rem solid var(--c-border); border-radius: 0.75rem; - background-color: var(--bg-raised); + background-color: var(--c-surface-raised); box-shadow: 0 0.625rem 0.9375rem -0.1875rem rgba(0, 0, 0, 0.1), 0 0.25rem 0.375rem -0.125rem rgba(0, 0, 0, 0.05); @@ -15,25 +15,25 @@ transform 100ms ease-out; max-width: 50vh; max-height: 80vh; - color: var(--text-primary); + color: var(--c-text); display: flex; flex-direction: column; } /* Pinned tooltip indicator */ .tooltip-container.pinned { - border-color: var(--primary-color, #3b82f6); + border-color: var(--primary-color, var(--c-primary)); box-shadow: 0 0.625rem 0.9375rem -0.1875rem rgba(0, 0, 0, 0.1), 0 0.25rem 0.375rem -0.125rem rgba(0, 0, 0, 0.05), - 0 0 0 0.125rem rgba(59, 130, 246, 0.1); + 0 0 0 0.125rem color-mix(in srgb, var(--c-primary) 10%, transparent); } /* Pinned tooltip header */ .tooltip-container.pinned .tooltip-header { - background-color: var(--primary-color, #3b82f6); + background-color: var(--primary-color, var(--c-primary)); color: white; - border-color: var(--primary-color, #3b82f6); + border-color: var(--primary-color, var(--c-primary)); } /* Close button */ @@ -42,10 +42,10 @@ top: 0.5rem; right: 0.5rem; font-size: 0.875rem; - background: var(--bg-raised); + background: var(--c-surface-raised); padding: 0.25rem; border-radius: 0.25rem; - border: 0.0625rem solid var(--border-default); + border: 0.0625rem solid var(--c-border); cursor: pointer; transition: background-color 0.2s ease, @@ -64,15 +64,15 @@ } .tooltip-pin-button:hover { - background-color: #ef4444 !important; - border-color: #ef4444 !important; + background-color: var(--c-danger) !important; + border-color: var(--c-danger) !important; } .tooltip-pin-button:focus, .tooltip-pin-button:focus-visible { outline: none; - border-color: var(--border-default) !important; - background-color: var(--bg-raised) !important; + border-color: var(--c-border) !important; + background-color: var(--c-surface-raised) !important; } /* Tooltip Header */ @@ -107,7 +107,7 @@ /* Tooltip Body */ .tooltip-body { padding: 1rem; - color: var(--text-primary) !important; + color: var(--c-text) !important; font-size: 0.875rem !important; line-height: 1.6 !important; overflow-y: auto; @@ -116,47 +116,49 @@ } .tooltip-body * { - color: var(--text-primary) !important; + color: var(--c-text) !important; } /* Link styling within tooltips */ .tooltip-body a { - color: var(--link-color, #3b82f6) !important; + color: var(--link-color, var(--c-primary)) !important; text-decoration: underline; - text-decoration-color: var(--link-underline-color, rgba(59, 130, 246, 0.3)); + text-decoration-color: var( + --link-underline-color, + color-mix(in srgb, var(--c-primary) 30%, transparent) + ); transition: color 0.2s ease, text-decoration-color 0.2s ease; } .tooltip-body a:hover { - color: var(--link-hover-color, #2563eb) !important; + color: var(--link-hover-color, var(--c-primary-hover)) !important; text-decoration-color: var( --link-hover-underline-color, - rgba(37, 99, 235, 0.5) + color-mix(in srgb, var(--c-primary-hover) 50%, transparent) ); } - -.tooltip-container .tooltip-body { - color: var(--text-primary) !important; -} - +.tooltip-container .tooltip-body, .tooltip-container .tooltip-body * { - color: var(--text-primary) !important; + color: var(--c-text) !important; } /* Ensure links maintain their styling */ .tooltip-container .tooltip-body a { - color: var(--link-color, #3b82f6) !important; + color: var(--link-color, var(--c-primary)) !important; text-decoration: underline; - text-decoration-color: var(--link-underline-color, rgba(59, 130, 246, 0.3)); + text-decoration-color: var( + --link-underline-color, + color-mix(in srgb, var(--c-primary) 30%, transparent) + ); } .tooltip-container .tooltip-body a:hover { - color: var(--link-hover-color, #2563eb) !important; + color: var(--link-hover-color, var(--c-primary-hover)) !important; text-decoration-color: var( --link-hover-underline-color, - rgba(37, 99, 235, 0.5) + color-mix(in srgb, var(--c-primary-hover) 50%, transparent) ); } @@ -165,8 +167,8 @@ position: absolute; width: 0.5rem; height: 0.5rem; - background: var(--bg-raised); - border: 0.0625rem solid var(--border-default); + background: var(--c-surface-raised); + border: 0.0625rem solid var(--c-border); transform: rotate(45deg); } diff --git a/frontend/editor/src/core/components/shared/tooltip/TooltipContent.tsx b/frontend/editor/src/core/components/shared/tooltip/TooltipContent.tsx index 08436799f9..28d18c4e4c 100644 --- a/frontend/editor/src/core/components/shared/tooltip/TooltipContent.tsx +++ b/frontend/editor/src/core/components/shared/tooltip/TooltipContent.tsx @@ -17,13 +17,13 @@ export const TooltipContent: React.FC = ({
-
+
{tips ? ( <> {tips.map((tip, index) => ( @@ -35,8 +35,8 @@ export const TooltipContent: React.FC = ({
= ({

= ({ style={{ margin: "0", paddingLeft: "16px", - color: "var(--text-secondary)", + color: "var(--c-text-muted)", fontSize: "13px", }} > diff --git a/frontend/editor/src/core/components/toast/ToastRenderer.css b/frontend/editor/src/core/components/toast/ToastRenderer.css index 6ecd9e3dfd..9a9bbbe609 100644 --- a/frontend/editor/src/core/components/toast/ToastRenderer.css +++ b/frontend/editor/src/core/components/toast/ToastRenderer.css @@ -75,26 +75,26 @@ /* Toast Alert Type Colors */ .toast-item--success { background: var(--color-green-100); - color: var(--text-primary); + color: var(--c-text); border: 1px solid var(--color-green-400); } .toast-item--error { background: var(--color-red-100); - color: var(--text-primary); + color: var(--c-text); border: 1px solid var(--color-red-400); } .toast-item--warning { background: var(--color-yellow-100); - color: var(--text-primary); + color: var(--c-text); border: 1px solid var(--color-yellow-400); } .toast-item--neutral { - background: var(--bg-surface); - color: var(--text-primary); - border: 1px solid var(--border-default); + background: var(--c-surface); + color: var(--c-text); + border: 1px solid var(--c-border); } /* Toast Header Row */ @@ -146,7 +146,7 @@ border-radius: 999px; border: none; background: transparent; - color: var(--text-secondary); + color: var(--c-text-muted); cursor: pointer; display: flex; align-items: center; @@ -166,7 +166,7 @@ .toast-progress-container { margin-top: 8px; height: 6px; - background: var(--bg-muted); + background: var(--c-surface-sunken); border-radius: 999px; overflow: hidden; } @@ -217,21 +217,21 @@ } .toast-action-button--success { - color: var(--text-primary); + color: var(--c-text); border-color: var(--color-green-400); } .toast-action-button--error { - color: var(--text-primary); + color: var(--c-text); border-color: var(--color-red-400); } .toast-action-button--warning { - color: var(--text-primary); + color: var(--c-text); border-color: var(--color-yellow-400); } .toast-action-button--neutral { - color: var(--text-primary); - border-color: var(--border-default); + color: var(--c-text); + border-color: var(--c-border); } diff --git a/frontend/editor/src/core/components/tools/RightSidebar.tsx b/frontend/editor/src/core/components/tools/RightSidebar.tsx index 41110ac034..73ec5db69f 100644 --- a/frontend/editor/src/core/components/tools/RightSidebar.tsx +++ b/frontend/editor/src/core/components/tools/RightSidebar.tsx @@ -168,7 +168,7 @@ export default function RightSidebar() { ref={toolPanelRef} data-sidebar="tool-panel" data-tour={fullscreenExpanded ? undefined : "tool-panel"} - className={`tool-panel flex flex-col ${fullscreenExpanded ? "tool-panel--fullscreen-active" : "overflow-hidden"} bg-[var(--bg-toolbar)] border-l border-[var(--border-subtle)] transition-all duration-300 ease-out ${isMobile ? "h-full border-r-0" : "h-screen"} ${fullscreenExpanded ? "tool-panel--fullscreen" : ""}`} + className={`tool-panel flex flex-col ${fullscreenExpanded ? "tool-panel--fullscreen-active" : "overflow-hidden"} bg-[var(--c-bg-raised)] border-l border-[var(--c-border-subtle)] transition-all duration-300 ease-out ${isMobile ? "h-full border-r-0" : "h-screen"} ${fullscreenExpanded ? "tool-panel--fullscreen" : ""}`} style={{ width: computedWidth(), padding: "0", diff --git a/frontend/editor/src/core/components/tools/ToolPanel.css b/frontend/editor/src/core/components/tools/ToolPanel.css index e9cbb9b1b2..8a2d17f3fa 100644 --- a/frontend/editor/src/core/components/tools/ToolPanel.css +++ b/frontend/editor/src/core/components/tools/ToolPanel.css @@ -4,8 +4,8 @@ align-items: center; gap: 2px; padding: 4px 8px; - border-bottom: 1px solid var(--border-subtle); - background-color: var(--bg-toolbar); + border-bottom: 1px solid var(--c-border-subtle); + background-color: var(--c-bg-raised); flex-shrink: 0; } @@ -13,115 +13,107 @@ .tool-panel__fullscreen-surface-inner { --fullscreen-bg-surface-1: color-mix( in srgb, - var(--bg-toolbar) 96%, + var(--c-bg-raised) 96%, transparent ); - --fullscreen-bg-surface-2: color-mix( - in srgb, - var(--bg-background) 90%, - transparent - ); - --fullscreen-bg-header: var(--bg-toolbar); - --fullscreen-bg-controls-1: var(--bg-toolbar); + --fullscreen-bg-surface-2: color-mix(in srgb, var(--c-bg) 90%, transparent); + --fullscreen-bg-header: var(--c-bg-raised); + --fullscreen-bg-controls-1: var(--c-bg-raised); --fullscreen-bg-controls-2: color-mix( in srgb, - var(--bg-toolbar) 95%, - var(--bg-background) - ); - --fullscreen-bg-body-1: color-mix( - in srgb, - var(--bg-background) 86%, - transparent + var(--c-bg-raised) 95%, + var(--c-bg) ); + --fullscreen-bg-body-1: color-mix(in srgb, var(--c-bg) 86%, transparent); --fullscreen-bg-body-2: color-mix( in srgb, - var(--bg-toolbar) 78%, + var(--c-bg-raised) 78%, transparent ); - --fullscreen-bg-group: color-mix(in srgb, var(--bg-toolbar) 82%, transparent); - --fullscreen-bg-item: color-mix(in srgb, var(--bg-toolbar) 88%, transparent); + --fullscreen-bg-group: color-mix( + in srgb, + var(--c-bg-raised) 82%, + transparent + ); + --fullscreen-bg-item: color-mix(in srgb, var(--c-bg-raised) 88%, transparent); --fullscreen-bg-list-item: color-mix( in srgb, - var(--bg-toolbar) 86%, + var(--c-bg-raised) 86%, transparent ); --fullscreen-bg-icon-detailed: color-mix( in srgb, - var(--bg-muted) 75%, + var(--c-surface-sunken) 75%, transparent ); --fullscreen-bg-icon-compact: color-mix( in srgb, - var(--bg-muted) 70%, + var(--c-surface-sunken) 70%, transparent ); --fullscreen-border-subtle-75: color-mix( in srgb, - var(--border-subtle) 75%, + var(--c-border-subtle) 75%, transparent ); --fullscreen-border-subtle-70: color-mix( in srgb, - var(--border-subtle) 70%, + var(--c-border-subtle) 70%, transparent ); --fullscreen-border-subtle-65: color-mix( in srgb, - var(--border-subtle) 65%, + var(--c-border-subtle) 65%, transparent ); --fullscreen-border-favorites: color-mix( in srgb, var(--special-color-favorites) 25%, - var(--border-subtle) + var(--c-border-subtle) ); --fullscreen-border-recommended: color-mix( in srgb, var(--special-color-recommended) 25%, - var(--border-subtle) + var(--c-border-subtle) ); --fullscreen-shadow-primary: color-mix( in srgb, - var(--shadow-color, rgba(15, 23, 42, 0.55)) 25%, + var(--shadow-color, color-mix(in srgb, black 55%, transparent)) 25%, transparent ); --fullscreen-shadow-secondary: color-mix( in srgb, - var(--shadow-color, rgba(15, 23, 42, 0.35)) 30%, + var(--shadow-color, color-mix(in srgb, black 35%, transparent)) 30%, transparent ); --fullscreen-shadow-group: color-mix( in srgb, - var(--shadow-color, rgba(15, 23, 42, 0.45)) 18%, + var(--shadow-color, color-mix(in srgb, black 45%, transparent)) 18%, transparent ); --fullscreen-accent-hover: color-mix( in srgb, - var(--text-primary) 20%, - var(--border-subtle) + var(--c-text) 20%, + var(--c-border-subtle) ); --fullscreen-accent-selected: color-mix( in srgb, - var(--text-primary) 30%, - var(--border-subtle) - ); - --fullscreen-accent-ring: color-mix( - in srgb, - var(--text-primary) 15%, - transparent + var(--c-text) 30%, + var(--c-border-subtle) ); + --fullscreen-accent-ring: color-mix(in srgb, var(--c-text) 15%, transparent); --fullscreen-accent-list-bg: color-mix( in srgb, - var(--text-primary) 8%, - var(--bg-toolbar) + var(--c-text) 8%, + var(--c-bg-raised) ); --fullscreen-accent-list-border: color-mix( in srgb, - var(--text-primary) 20%, - var(--border-subtle) + var(--c-text) 20%, + var(--c-border-subtle) ); - --fullscreen-text-icon: var(--text-primary); - --fullscreen-text-icon-compact: var(--text-primary); + --fullscreen-text-icon: var(--c-text); + --fullscreen-text-icon-compact: var(--c-text); } .tool-panel { @@ -153,7 +145,7 @@ .tool-panel__collapsed-divider { height: 1px; - background: var(--border-subtle); + background: var(--c-border-subtle); margin: 0 0.5rem 8px; } @@ -178,7 +170,7 @@ border: 1px solid transparent; border-radius: 0.5rem; background: transparent; - color: var(--tools-text-and-icon-color); + color: var(--c-text); cursor: pointer; transition: background 120ms ease-out, @@ -198,8 +190,8 @@ .tool-panel__expand-btn { flex-shrink: 0; - color: var(--text-secondary) !important; - border-color: var(--border-subtle) !important; + color: var(--c-text-muted) !important; + border-color: var(--c-border-subtle) !important; } /* The collapse/expand toggle keeps a stable identity across the collapsed strip @@ -210,25 +202,25 @@ } .tool-panel__expand-btn svg { - color: var(--text-secondary) !important; + color: var(--c-text-muted) !important; } .tool-panel__expand-btn:hover { - color: var(--text-primary) !important; + color: var(--c-text) !important; border-color: var(--border) !important; } .tool-panel__collapsed-search-btn { flex-shrink: 0; - color: var(--text-secondary) !important; + color: var(--c-text-muted) !important; } .tool-panel__collapsed-search-btn svg { - color: var(--text-secondary) !important; + color: var(--c-text-muted) !important; } .tool-panel__collapsed-search-btn:hover { - color: var(--text-primary) !important; + color: var(--c-text) !important; } .tool-panel__back-btn { @@ -237,7 +229,7 @@ .tool-panel__back-bar { flex-shrink: 0; - border-bottom: 1px solid var(--border-subtle) !important; + border-bottom: 1px solid var(--c-border-subtle) !important; } .tool-panel--fullscreen-active { @@ -282,7 +274,7 @@ /* Search that separates the Policies section from the Tools list below it. */ .tool-panel__between-search { padding: 0.5rem 0.75rem 0.25rem; - border-top: 1px solid var(--border-subtle, var(--color-border)); + border-top: 1px solid var(--c-border-subtle, var(--c-border)); } .tool-panel__between-search .search-input-container { @@ -292,7 +284,7 @@ /* Slightly recessed search field so it reads as distinct from the panel. */ .tool-panel__between-search input { - background-color: var(--bg-muted); + background-color: var(--c-surface-sunken); } ::view-transition-old(tool-rail) { @@ -334,7 +326,7 @@ } .tool-panel--fullscreen { - background: var(--bg-toolbar); + background: var(--c-bg-raised); } .tool-panel__placeholder { @@ -342,7 +334,7 @@ display: flex; align-items: center; justify-content: center; - color: var(--text-muted); + color: var(--c-text-subtle); font-size: 0.9rem; padding: 1.5rem; text-align: center; @@ -403,8 +395,8 @@ align-items: center; gap: 1rem; padding: 0.75rem 1.75rem; - border-bottom: 1px solid var(--border-subtle); - background: var(--bg-toolbar); + border-bottom: 1px solid var(--c-border-subtle); + background: var(--c-bg-raised); } .tool-panel__fullscreen-brand { @@ -428,8 +420,8 @@ align-items: center; gap: 1rem; padding: 0.75rem 1.75rem; - border-bottom: 1px solid var(--tool-panel-search-border-bottom); - background: var(--tool-panel-search-bg); + border-bottom: 1px solid var(--c-border); + background: var(--c-surface-sunken); } .tool-panel__fullscreen-controls .search-input-container { @@ -546,7 +538,10 @@ .tool-panel__fullscreen-item:hover:not([aria-disabled="true"]):not(:disabled) { transform: translateY(-2px); border-color: var(--fullscreen-accent-hover); - box-shadow: var(--shadow-xl, 0 18px 34px rgba(15, 23, 42, 0.14)); + box-shadow: var( + --shadow-xl, + 0 18px 34px color-mix(in srgb, black 14%, transparent) + ); } .tool-panel__fullscreen-item--selected { @@ -619,8 +614,8 @@ inset: 0; background: linear-gradient( 135deg, - color-mix(in srgb, var(--text-primary) 12%, transparent), - color-mix(in srgb, var(--text-primary) 4%, transparent) + color-mix(in srgb, var(--c-text) 12%, transparent), + color-mix(in srgb, var(--c-text) 4%, transparent) ); opacity: 0; transition: opacity 0.2s ease; @@ -630,8 +625,7 @@ .tool-panel__fullscreen-item:hover:not([aria-disabled="true"]) .tool-panel__fullscreen-icon { transform: scale(1.08); - box-shadow: 0 4px 12px - color-mix(in srgb, var(--text-primary) 15%, transparent); + box-shadow: 0 4px 12px color-mix(in srgb, var(--c-text) 15%, transparent); } .tool-panel__fullscreen-item:hover:not([aria-disabled="true"]) @@ -656,7 +650,7 @@ } .tool-panel__fullscreen-name { - color: var(--text-primary); + color: var(--c-text); font-size: 13px !important; font-weight: 500 !important; } @@ -753,8 +747,8 @@ inset: 0; background: linear-gradient( 135deg, - color-mix(in srgb, var(--text-primary) 10%, transparent), - color-mix(in srgb, var(--text-primary) 3%, transparent) + color-mix(in srgb, var(--c-text) 10%, transparent), + color-mix(in srgb, var(--c-text) 3%, transparent) ); opacity: 0; transition: opacity 0.2s ease; @@ -764,7 +758,7 @@ .tool-panel__fullscreen-list-item:hover:not([aria-disabled="true"]) .tool-panel__fullscreen-list-icon { transform: scale(1.06); - box-shadow: 0 2px 8px color-mix(in srgb, var(--text-primary) 12%, transparent); + box-shadow: 0 2px 8px color-mix(in srgb, var(--c-text) 12%, transparent); } .tool-panel__fullscreen-list-item:hover:not([aria-disabled="true"]) diff --git a/frontend/editor/src/core/components/tools/ToolPanelModePrompt.css b/frontend/editor/src/core/components/tools/ToolPanelModePrompt.css index 2749abe537..58421faa4c 100644 --- a/frontend/editor/src/core/components/tools/ToolPanelModePrompt.css +++ b/frontend/editor/src/core/components/tools/ToolPanelModePrompt.css @@ -1,10 +1,10 @@ .tool-panel-mode-prompt__modal { - background: color-mix(in srgb, var(--bg-toolbar) 94%, transparent); - border: 1px solid color-mix(in srgb, var(--border-subtle) 70%, transparent); + background: color-mix(in srgb, var(--c-bg-raised) 94%, transparent); + border: 1px solid color-mix(in srgb, var(--c-border-subtle) 70%, transparent); box-shadow: 0 32px 64px color-mix( in srgb, - var(--shadow-color, rgba(15, 23, 42, 0.55)) 20%, + var(--shadow-color, color-mix(in srgb, black 55%, transparent)) 20%, transparent ); max-width: min(46rem, 100%); @@ -22,8 +22,8 @@ gap: 1rem; background: linear-gradient( 145deg, - color-mix(in srgb, var(--bg-surface) 96%, transparent), - color-mix(in srgb, var(--bg-muted) 70%, transparent) + color-mix(in srgb, var(--c-surface) 96%, transparent), + color-mix(in srgb, var(--c-surface-sunken) 70%, transparent) ); width: 100%; max-width: 19rem; @@ -31,28 +31,20 @@ .tool-panel-mode-prompt__card--sidebar { border: 1px solid - color-mix( - in srgb, - var(--accent-primary, var(--mantine-color-blue-6, #228be6)) 18%, - var(--border-subtle) - ); + color-mix(in srgb, var(--c-primary) 18%, var(--c-border-subtle)); background: linear-gradient( 165deg, - color-mix(in srgb, var(--bg-surface) 96%, transparent), - color-mix( - in srgb, - var(--accent-primary, var(--mantine-color-blue-6, #228be6)) 8%, - transparent - ) + color-mix(in srgb, var(--c-surface) 96%, transparent), + color-mix(in srgb, var(--c-primary) 8%, transparent) ); } .tool-panel-mode-prompt__preview { border-radius: 0.9rem; - border: 1px solid color-mix(in srgb, var(--border-subtle) 70%, transparent); + border: 1px solid color-mix(in srgb, var(--c-border-subtle) 70%, transparent); background: linear-gradient( 135deg, - color-mix(in srgb, var(--bg-muted) 82%, transparent), + color-mix(in srgb, var(--c-surface-sunken) 82%, transparent), transparent 75% ); padding: 0.75rem; @@ -76,54 +68,49 @@ gap: 0.45rem; background: linear-gradient( 180deg, - color-mix(in srgb, var(--bg-muted) 88%, transparent), - color-mix(in srgb, var(--bg-muted) 72%, transparent) + color-mix(in srgb, var(--c-surface-sunken) 88%, transparent), + color-mix(in srgb, var(--c-surface-sunken) 72%, transparent) ); - border: 1px solid color-mix(in srgb, var(--border-subtle) 65%, transparent); + border: 1px solid color-mix(in srgb, var(--c-border-subtle) 65%, transparent); } .tool-panel-mode-prompt__sidebar-search { height: 0.5rem; border-radius: 0.4rem; - background: color-mix(in srgb, var(--bg-background) 90%, transparent); - border: 1px solid color-mix(in srgb, var(--border-subtle) 60%, transparent); + background: color-mix(in srgb, var(--c-bg) 90%, transparent); + border: 1px solid color-mix(in srgb, var(--c-border-subtle) 60%, transparent); } .tool-panel-mode-prompt__sidebar-item { height: 0.55rem; border-radius: 0.35rem; - background: color-mix( - in srgb, - var(--accent-primary, var(--mantine-color-blue-6, #228be6)) 32%, - var(--bg-muted) - ); + background: color-mix(in srgb, var(--c-primary) 32%, var(--c-surface-sunken)); } .tool-panel-mode-prompt__sidebar-item--muted { - background: color-mix(in srgb, var(--bg-background) 88%, transparent); + background: color-mix(in srgb, var(--c-bg) 88%, transparent); } .tool-panel-mode-prompt__workspace { flex: 1; border-radius: 0.65rem; - border: 1px solid color-mix(in srgb, var(--border-subtle) 65%, transparent); + border: 1px solid color-mix(in srgb, var(--c-border-subtle) 65%, transparent); padding: 0.5rem; display: grid; gap: 0.35rem; grid-template-rows: 1.4fr 0.6fr; background: linear-gradient( 160deg, - color-mix(in srgb, var(--bg-background) 94%, transparent), - color-mix(in srgb, var(--bg-muted) 68%, transparent) + color-mix(in srgb, var(--c-bg) 94%, transparent), + color-mix(in srgb, var(--c-surface-sunken) 68%, transparent) ); } .tool-panel-mode-prompt__workspace-page { border-radius: 0.45rem; - background: color-mix(in srgb, var(--bg-surface) 96%, transparent); - border: 1px solid color-mix(in srgb, var(--border-subtle) 55%, transparent); - box-shadow: inset 0 0 0 1px - color-mix(in srgb, var(--bg-background) 60%, transparent); + background: color-mix(in srgb, var(--c-surface) 96%, transparent); + border: 1px solid color-mix(in srgb, var(--c-border-subtle) 55%, transparent); + box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-bg) 60%, transparent); } .tool-panel-mode-prompt__workspace-page--secondary { @@ -151,11 +138,11 @@ .tool-panel-mode-prompt__legacy-card { border-radius: 0.45rem; - border: 1px solid color-mix(in srgb, var(--border-subtle) 55%, transparent); + border: 1px solid color-mix(in srgb, var(--c-border-subtle) 55%, transparent); background: linear-gradient( 150deg, - color-mix(in srgb, var(--bg-muted) 88%, transparent), - color-mix(in srgb, var(--bg-background) 76%, transparent) + color-mix(in srgb, var(--c-surface-sunken) 88%, transparent), + color-mix(in srgb, var(--c-bg) 76%, transparent) ); height: 1.2rem; } @@ -185,11 +172,11 @@ .tool-panel-mode-prompt__fullscreen-card { border-radius: 0.45rem; - border: 1px solid color-mix(in srgb, var(--border-subtle) 55%, transparent); + border: 1px solid color-mix(in srgb, var(--c-border-subtle) 55%, transparent); background: linear-gradient( 150deg, - color-mix(in srgb, var(--bg-muted) 88%, transparent), - color-mix(in srgb, var(--bg-background) 76%, transparent) + color-mix(in srgb, var(--c-surface-sunken) 88%, transparent), + color-mix(in srgb, var(--c-bg) 76%, transparent) ); height: 1.2rem; } @@ -210,20 +197,15 @@ } .tool-panel-mode-prompt__action:hover { - box-shadow: 0 10px 18px - color-mix( - in srgb, - var(--accent-primary, var(--mantine-color-blue-6, #228be6)) 25%, - transparent - ); + box-shadow: 0 10px 18px color-mix(in srgb, var(--c-primary) 25%, transparent); } .tool-panel-mode-prompt__maybe-later { - color: color-mix(in srgb, var(--text-secondary) 90%, var(--text-muted)); + color: color-mix(in srgb, var(--c-text-muted) 90%, var(--c-text-subtle)); } .tool-panel-mode-prompt__maybe-later:hover { - background: color-mix(in srgb, var(--bg-muted) 78%, transparent); + background: color-mix(in srgb, var(--c-surface-sunken) 78%, transparent); } @media (max-width: 600px) { diff --git a/frontend/editor/src/core/components/tools/ToolPicker.tsx b/frontend/editor/src/core/components/tools/ToolPicker.tsx index 779e945b8c..6cda34aff2 100644 --- a/frontend/editor/src/core/components/tools/ToolPicker.tsx +++ b/frontend/editor/src/core/components/tools/ToolPicker.tsx @@ -37,7 +37,7 @@ const HEADER_TEXT_STYLE: React.CSSProperties = { padding: "0.25rem 0 0.35rem 0.5rem", textTransform: "uppercase", letterSpacing: "0.06em", - color: "var(--text-muted)", + color: "var(--c-text-subtle)", }; const SCROLLABLE_STYLE: React.CSSProperties = { flex: 1, @@ -50,7 +50,7 @@ const SCROLLABLE_STYLE: React.CSSProperties = { const CONTAINER_STYLE: React.CSSProperties = { display: "flex", flexDirection: "column", - background: "var(--bg-toolbar)", + background: "var(--c-bg-raised)", }; const toTitleCase = (s: string) => s.replace( diff --git a/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.module.css b/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.module.css index 8a20a78340..d2ae85a88b 100644 --- a/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.module.css +++ b/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.module.css @@ -16,7 +16,7 @@ } .containerBorder { - border: 1px solid var(--border-default, #333); + border: 1px solid var(--c-border); } /* Page thumbnail styles */ @@ -105,8 +105,8 @@ .gridTileSelected, .gridTileHovered { - border: 2px solid var(--mantine-primary-color-filled, #3b82f6); - background-color: rgba(59, 130, 246, 0.2); + border: 2px solid var(--c-primary); + background-color: color-mix(in srgb, var(--c-primary) 20%, transparent); } /* Preview header */ @@ -116,14 +116,14 @@ .divider { height: 1px; - background-color: var(--border-default, #333); + background-color: var(--c-border); margin-bottom: 8px; } .previewLabel { font-size: 14px; font-weight: 500; - color: var(--text-primary); + color: var(--c-text); text-align: center; } diff --git a/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.tsx b/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.tsx index fe92d1ff42..6e35b286a9 100644 --- a/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.tsx +++ b/frontend/editor/src/core/components/tools/addPageNumbers/PageNumberPreview.tsx @@ -220,7 +220,7 @@ export default function PageNumberPreview({ width: "100%", aspectRatio: `${(pageSize?.widthPts ?? 595.28) / (pageSize?.heightPts ?? 841.89)} / 1`, backgroundColor: pageThumbnail ? "white" : "rgba(255,255,255,0.03)", - border: "1px solid var(--border-default, #333)", + border: "1px solid var(--c-border, #333)", overflow: "hidden" as const, }), [pageSize, pageThumbnail], diff --git a/frontend/editor/src/core/components/tools/addStamp/StampPreview.module.css b/frontend/editor/src/core/components/tools/addStamp/StampPreview.module.css index 7e740f6f51..dccf897eaa 100644 --- a/frontend/editor/src/core/components/tools/addStamp/StampPreview.module.css +++ b/frontend/editor/src/core/components/tools/addStamp/StampPreview.module.css @@ -16,7 +16,7 @@ } .containerBorder { - border: 1px solid var(--border-default, #333); + border: 1px solid var(--c-border); } /* Page thumbnail styles */ @@ -95,7 +95,7 @@ .gridTileSelected, .gridTileHovered { - border: 2px solid var(--mantine-primary-color-filled, #3b82f6); + border: 2px solid var(--c-primary); } /* Preview header */ @@ -105,14 +105,14 @@ .divider { height: 1px; - background-color: var(--border-default, #333); + background-color: var(--c-border); margin-bottom: 8px; } .previewLabel { font-size: 14px; font-weight: 500; - color: var(--text-primary); + color: var(--c-text); text-align: center; } @@ -127,7 +127,7 @@ /* Information text container */ .informationContainer { - background-color: var(--information-text-bg); + background-color: var(--c-surface); padding: 2px; padding-left: 8px; padding-right: 8px; diff --git a/frontend/editor/src/core/components/tools/addStamp/StampPreviewUtils.ts b/frontend/editor/src/core/components/tools/addStamp/StampPreviewUtils.ts index 97120c0fcf..8ac3c73551 100644 --- a/frontend/editor/src/core/components/tools/addStamp/StampPreviewUtils.ts +++ b/frontend/editor/src/core/components/tools/addStamp/StampPreviewUtils.ts @@ -280,7 +280,7 @@ export function computeStampPreviewStyle( width: "100%", aspectRatio: `${(pageSize?.widthPts ?? 595.28) / (pageSize?.heightPts ?? 841.89)} / 1`, backgroundColor: hasPageThumbnail ? "white" : "rgba(255,255,255,0.03)", - border: "1px solid var(--border-default, #333)", + border: "1px solid var(--c-border, #333)", overflow: "hidden", }, item: { diff --git a/frontend/editor/src/core/components/tools/automate/AutomationEntry.tsx b/frontend/editor/src/core/components/tools/automate/AutomationEntry.tsx index 322d2d87fc..8ffbfeda81 100644 --- a/frontend/editor/src/core/components/tools/automate/AutomationEntry.tsx +++ b/frontend/editor/src/core/components/tools/automate/AutomationEntry.tsx @@ -191,11 +191,9 @@ export default function AutomationEntry({ className="tool-button" style={{ borderRadius: 0, - color: "var(--tools-text-and-icon-color)", + color: "var(--c-text)", overflow: "visible", - backgroundColor: shouldShowMenu - ? "var(--automation-entry-hover-bg)" - : undefined, + backgroundColor: shouldShowMenu ? "var(--c-hover)" : undefined, }} > {buttonContent} diff --git a/frontend/editor/src/core/components/tools/automate/AutomationRun.tsx b/frontend/editor/src/core/components/tools/automate/AutomationRun.tsx index e59996ab8f..4f63a80d3c 100644 --- a/frontend/editor/src/core/components/tools/automate/AutomationRun.tsx +++ b/frontend/editor/src/core/components/tools/automate/AutomationRun.tsx @@ -153,7 +153,7 @@ export default function AutomationRun({ style={{ width: 16, height: 16, - border: "2px solid #ccc", + border: "2px solid var(--c-border)", borderRadius: "50%", }} /> diff --git a/frontend/editor/src/core/components/tools/automate/ToolList.tsx b/frontend/editor/src/core/components/tools/automate/ToolList.tsx index ad67ed4aa9..e2fe54deb0 100644 --- a/frontend/editor/src/core/components/tools/automate/ToolList.tsx +++ b/frontend/editor/src/core/components/tools/automate/ToolList.tsx @@ -148,7 +148,7 @@ export default function ToolList({ borderTop: "none", borderRadius: "0 0 var(--mantine-radius-lg) var(--mantine-radius-lg)", - backgroundColor: "var(--active-bg)", + backgroundColor: "var(--c-active)", padding: "var(--mantine-spacing-xs)", }} > diff --git a/frontend/editor/src/core/components/tools/certSign/CertificateTypeSettings.tsx b/frontend/editor/src/core/components/tools/certSign/CertificateTypeSettings.tsx index 4311c5f6ca..aaab1cb93e 100644 --- a/frontend/editor/src/core/components/tools/certSign/CertificateTypeSettings.tsx +++ b/frontend/editor/src/core/components/tools/certSign/CertificateTypeSettings.tsx @@ -75,7 +75,7 @@ const CertificateTypeSettings = ({ if (!hasAlternativeSources) { return ( -

+
{t( "certSign.source.noOtherSources", "No other certificate sources are available.", diff --git a/frontend/editor/src/core/components/tools/certSign/panels/SignRequestPanel.tsx b/frontend/editor/src/core/components/tools/certSign/panels/SignRequestPanel.tsx index 2b128ebd11..0f21335833 100644 --- a/frontend/editor/src/core/components/tools/certSign/panels/SignRequestPanel.tsx +++ b/frontend/editor/src/core/components/tools/certSign/panels/SignRequestPanel.tsx @@ -317,9 +317,9 @@ const SignRequestPanel = ({ data }: SignRequestPanelProps) => { onClick={handleAddToActiveFiles} fullWidth style={{ - backgroundColor: "var(--landing-inner-paper-bg)", - color: "var(--btn-open-file)", - border: "1px solid var(--landing-inner-paper-border)", + backgroundColor: "var(--c-surface-raised)", + color: "var(--c-primary)", + border: "1px solid var(--c-border)", }} > {t("certSign.collab.signRequest.addToFiles", "Add to Active Files")} diff --git a/frontend/editor/src/core/components/tools/compare/compareView.css b/frontend/editor/src/core/components/tools/compare/compareView.css index 7a86c69d4a..aaa703fcc1 100644 --- a/frontend/editor/src/core/components/tools/compare/compareView.css +++ b/frontend/editor/src/core/components/tools/compare/compareView.css @@ -5,19 +5,14 @@ .compare-dropdown-sticky { position: sticky; z-index: 2; - background: var(--compare-page-label-bg); + background: var(--c-surface-sunken); color: var(--compare-page-label-fg); font-size: 0.75rem; padding: 0.25rem 0.5rem; - border-bottom: 1px solid var(--border-subtle); + border-bottom: 1px solid var(--c-border-subtle); pointer-events: none; } -[data-mantine-color-scheme="dark"] .compare-dropdown-sticky { - background: var(--compare-page-label-bg); - color: var(--compare-page-label-fg); - border-bottom: 1px solid var(--border-default); -} .compare-workbench { display: flex; flex-direction: column; @@ -91,9 +86,9 @@ position: sticky; top: 0; z-index: 10; - background: var(--bg-toolbar); + background: var(--c-bg-raised); backdrop-filter: blur(8px); - border-bottom: 1px solid var(--border-default); + border-bottom: 1px solid var(--c-border); padding: 0.5rem; margin: -0.5rem -0.5rem 0.5rem -0.5rem; } @@ -164,21 +159,13 @@ margin: 0 !important; border-top-left-radius: 8px !important; border-top-right-radius: 8px !important; -} - -/* Style the dropdown container */ -.compare-changes-select .mantine-Combobox-dropdown { - border: 1px solid var(--border-subtle) !important; - border-radius: 8px !important; - box-shadow: var(--shadow-md) !important; - background-color: var(--bg-surface) !important; -} - +} /* Style the dropdown container */ +.compare-changes-select .mantine-Combobox-dropdown, .compare-changes-select--comparison .mantine-Combobox-dropdown { - border: 1px solid var(--border-subtle) !important; + border: 1px solid var(--c-border-subtle) !important; border-radius: 8px !important; box-shadow: var(--shadow-md) !important; - background-color: var(--bg-surface) !important; + background-color: var(--c-surface) !important; } /* Custom scrollbar for ScrollArea */ @@ -187,18 +174,18 @@ } .compare-changes-select .mantine-ScrollArea-viewport::-webkit-scrollbar-track { - background: var(--bg-muted) !important; + background: var(--c-surface-sunken) !important; border-radius: 3px !important; } .compare-changes-select .mantine-ScrollArea-viewport::-webkit-scrollbar-thumb { - background: var(--border-strong) !important; + background: var(--c-border-strong) !important; border-radius: 3px !important; } .compare-changes-select .mantine-ScrollArea-viewport::-webkit-scrollbar-thumb:hover { - background: var(--text-muted) !important; + background: var(--c-text-subtle) !important; } .compare-changes-select--comparison @@ -208,27 +195,21 @@ .compare-changes-select--comparison .mantine-ScrollArea-viewport::-webkit-scrollbar-track { - background: var(--bg-muted) !important; + background: var(--c-surface-sunken) !important; border-radius: 3px !important; } .compare-changes-select--comparison .mantine-ScrollArea-viewport::-webkit-scrollbar-thumb { - background: var(--border-strong) !important; + background: var(--c-border-strong) !important; border-radius: 3px !important; } .compare-changes-select--comparison .mantine-ScrollArea-viewport::-webkit-scrollbar-thumb:hover { - background: var(--text-muted) !important; -} - -/* Style the dropdown options */ -.compare-changes-select .mantine-Combobox-option { - font-size: 0.875rem !important; - padding: 8px 12px !important; -} - + background: var(--c-text-subtle) !important; +} /* Style the dropdown options */ +.compare-changes-select .mantine-Combobox-option, .compare-changes-select--comparison .mantine-Combobox-option { font-size: 0.875rem !important; padding: 8px 12px !important; @@ -240,27 +221,16 @@ .compare-changes-select--comparison .mantine-Combobox-option:hover { background-color: var(--spdf-compare-added-badge-bg) !important; -} - -/* Style the search input */ -.compare-changes-select .mantine-Combobox-search { - font-size: 0.875rem !important; - padding: 8px 12px !important; - border-bottom: 1px solid var(--border-subtle) !important; -} - +} /* Style the search input */ +.compare-changes-select .mantine-Combobox-search, .compare-changes-select--comparison .mantine-Combobox-search { font-size: 0.875rem !important; padding: 8px 12px !important; - border-bottom: 1px solid var(--border-subtle) !important; + border-bottom: 1px solid var(--c-border-subtle) !important; } - -.compare-changes-select .mantine-Combobox-search::placeholder { - color: var(--text-muted) !important; -} - +.compare-changes-select .mantine-Combobox-search::placeholder, .compare-changes-select--comparison .mantine-Combobox-search::placeholder { - color: var(--text-muted) !important; + color: var(--c-text-subtle) !important; } /* Style the chevron - ensure proper coloring */ @@ -273,29 +243,49 @@ /* Flash/pulse highlight for navigated change */ @keyframes compare-flash { 0% { - outline: 4px solid rgba(255, 235, 59, 0); - box-shadow: 0 0 0 rgba(255, 235, 59, 0); - background-color: rgba(255, 235, 59, 0.2) !important; + outline: 4px solid color-mix(in srgb, var(--c-highlight) 0%, transparent); + box-shadow: 0 0 0 color-mix(in srgb, var(--c-highlight) 0%, transparent); + background-color: color-mix( + in srgb, + var(--c-highlight) 20%, + transparent + ) !important; } 25% { - outline: 4px solid rgba(255, 235, 59, 1); - box-shadow: 0 0 20px rgba(255, 235, 59, 0.8); - background-color: rgba(255, 235, 59, 0.4) !important; + outline: 4px solid color-mix(in srgb, var(--c-highlight) 100%, transparent); + box-shadow: 0 0 20px color-mix(in srgb, var(--c-highlight) 80%, transparent); + background-color: color-mix( + in srgb, + var(--c-highlight) 40%, + transparent + ) !important; } 50% { - outline: 4px solid rgba(255, 235, 59, 1); - box-shadow: 0 0 30px rgba(255, 235, 59, 0.9); - background-color: rgba(255, 235, 59, 0.5) !important; + outline: 4px solid color-mix(in srgb, var(--c-highlight) 100%, transparent); + box-shadow: 0 0 30px color-mix(in srgb, var(--c-highlight) 90%, transparent); + background-color: color-mix( + in srgb, + var(--c-highlight) 50%, + transparent + ) !important; } 75% { - outline: 4px solid rgba(255, 235, 59, 0.8); - box-shadow: 0 0 15px rgba(255, 235, 59, 0.6); - background-color: rgba(255, 235, 59, 0.3) !important; + outline: 4px solid color-mix(in srgb, var(--c-highlight) 80%, transparent); + box-shadow: 0 0 15px color-mix(in srgb, var(--c-highlight) 60%, transparent); + background-color: color-mix( + in srgb, + var(--c-highlight) 30%, + transparent + ) !important; } 100% { - outline: 4px solid rgba(255, 235, 59, 0); - box-shadow: 0 0 0 rgba(255, 235, 59, 0); - background-color: rgba(255, 235, 59, 0) !important; + outline: 4px solid color-mix(in srgb, var(--c-highlight) 0%, transparent); + box-shadow: 0 0 0 color-mix(in srgb, var(--c-highlight) 0%, transparent); + background-color: color-mix( + in srgb, + var(--c-highlight) 0%, + transparent + ) !important; } } @@ -304,14 +294,18 @@ z-index: 1000; position: relative; /* Bonus: temporarily override red/green to yellow during flash for clarity */ - background-color: rgba(255, 235, 59, 0.5) !important; + background-color: color-mix( + in srgb, + var(--c-highlight) 50%, + transparent + ) !important; } /* Union overlay for group flash */ .compare-diff-flash-overlay { animation: compare-flash 1.5s ease-in-out 1; z-index: 999; - background-color: rgba(255, 235, 59, 0.4); + background-color: color-mix(in srgb, var(--c-highlight) 40%, transparent); pointer-events: none; border-radius: 2px; } @@ -328,7 +322,7 @@ width: 0.75rem; height: 0.75rem; border-radius: 999px; - border: 1px solid rgba(15, 23, 42, 0.15); + border: 1px solid var(--c-border); } .compare-summary__stats { @@ -343,10 +337,10 @@ } .compare-summary__segment { - border: 1px solid var(--mantine-color-gray-3); + border: 1px solid var(--c-border); border-radius: 0.5rem; padding: 0.75rem; - background-color: var(--mantine-color-gray-0); + background-color: var(--c-surface); } .compare-diff-page { @@ -357,10 +351,10 @@ .compare-diff-page__canvas { position: relative; - border: 1px solid var(--border-strong); + border: 1px solid var(--c-border-strong); border-radius: 0.75rem; overflow: hidden; - background-color: var(--bg-surface); + background-color: var(--c-surface); width: 100%; } @@ -381,7 +375,7 @@ margin-right: auto; max-width: 100%; background-color: #fff; /* ensure stable white backing during load */ - border: 1px solid var(--border-subtle); + border: 1px solid var(--c-border-subtle); will-change: transform; } @@ -403,7 +397,7 @@ display: inline-block; padding: 2px 8px; border-radius: 8px; - background-color: var(--compare-page-label-bg); + background-color: var(--c-surface-sunken); color: var(--compare-page-label-fg); } @@ -432,7 +426,7 @@ } .compare-dropdown-option__page { font-size: 0.7rem; - color: var(--text-muted); + color: var(--c-text-subtle); } .compare-dropdown-option__text { display: -webkit-box; @@ -446,11 +440,11 @@ /* Non-sticky in-flow group headers; sticky handled by floating header */ .compare-dropdown-group { position: static; - background: var(--compare-page-label-bg); + background: var(--c-surface-sunken); color: var(--compare-page-label-fg); font-size: 0.75rem; padding: 0.25rem 0.5rem; - border-bottom: 1px solid var(--border-subtle); + border-bottom: 1px solid var(--c-border-subtle); } .compare-dropdown-group.compare-dropdown-group--hidden { @@ -461,15 +455,9 @@ overflow: hidden; } -[data-mantine-color-scheme="dark"] .compare-dropdown-group { - background: var(--compare-page-label-bg); - color: var(--compare-page-label-fg); - border-bottom: 1px solid var(--border-default); -} - /* Light grey rendering flag next to page labels in the dropdown */ .compare-dropdown-rendering-flag { - color: var(--text-muted); + color: var(--c-text-subtle); margin-left: 0.25rem; } @@ -489,7 +477,7 @@ position: sticky; top: 0; z-index: 2; - background: var(--bg-background); + background: var(--c-bg); padding: 0.25rem 0; } @@ -550,7 +538,7 @@ padding-bottom: 32px; } .compare-pixel-page { - border: 1px solid var(--mantine-color-default-border, #dee2e6); + border: 1px solid var(--mantine-color-default-border, var(--c-border)); border-radius: 8px; padding: 12px; background: var(--mantine-color-body, #fff); @@ -568,13 +556,13 @@ } .compare-pixel-triptych figure img { display: block; - border: 1px solid var(--mantine-color-default-border, #dee2e6); + border: 1px solid var(--mantine-color-default-border, var(--c-border)); background: #fff; } .compare-pixel-triptych figcaption { font-size: 11px; text-align: center; - color: var(--mantine-color-dimmed, #868e96); + color: var(--mantine-color-dimmed, var(--c-text-muted)); } .compare-pixel-overlay { position: relative; @@ -583,7 +571,7 @@ .compare-pixel-overlay-img { display: block; width: 100%; - border: 1px solid var(--mantine-color-default-border, #dee2e6); + border: 1px solid var(--mantine-color-default-border, var(--c-border)); } .compare-pixel-overlay-top { position: absolute; diff --git a/frontend/editor/src/core/components/tools/convert/GroupedFormatDropdown.tsx b/frontend/editor/src/core/components/tools/convert/GroupedFormatDropdown.tsx index 7ffd30fa85..8ab2f10662 100644 --- a/frontend/editor/src/core/components/tools/convert/GroupedFormatDropdown.tsx +++ b/frontend/editor/src/core/components/tools/convert/GroupedFormatDropdown.tsx @@ -104,7 +104,7 @@ const GroupedFormatDropdown = ({ cursor: disabled ? "not-allowed" : "pointer", width: "100%", color: disabled - ? "var(--dropdown-trigger-text-disabled)" + ? "var(--c-text-subtle)" : "var(--dropdown-trigger-text)", }} > diff --git a/frontend/editor/src/core/components/tools/editTableOfContents/BookmarkEditor.tsx b/frontend/editor/src/core/components/tools/editTableOfContents/BookmarkEditor.tsx index 9b6152cf55..c1711a635c 100644 --- a/frontend/editor/src/core/components/tools/editTableOfContents/BookmarkEditor.tsx +++ b/frontend/editor/src/core/components/tools/editTableOfContents/BookmarkEditor.tsx @@ -219,8 +219,9 @@ export default function BookmarkEditor({ withBorder p="md" style={{ - borderColor: "var(--border-default)", - background: level === 0 ? "var(--bg-surface)" : "var(--bg-muted)", + borderColor: "var(--c-border)", + background: + level === 0 ? "var(--c-surface)" : "var(--c-surface-sunken)", }} > @@ -380,7 +381,7 @@ export default function BookmarkEditor({ {bookmark.children.map((child) => ( diff --git a/frontend/editor/src/core/components/tools/editTableOfContents/EditTableOfContentsWorkbenchView.tsx b/frontend/editor/src/core/components/tools/editTableOfContents/EditTableOfContentsWorkbenchView.tsx index 148917dba6..d5f8901673 100644 --- a/frontend/editor/src/core/components/tools/editTableOfContents/EditTableOfContentsWorkbenchView.tsx +++ b/frontend/editor/src/core/components/tools/editTableOfContents/EditTableOfContentsWorkbenchView.tsx @@ -100,7 +100,7 @@ const EditTableOfContentsWorkbenchView = ({ width: "100%", height: "100%", overflowY: "auto", - background: "var(--bg-raised)", + background: "var(--c-surface-raised)", }} > @@ -121,8 +121,8 @@ const EditTableOfContentsWorkbenchView = ({ radius="md" p="xl" style={{ - backgroundColor: "var(--bg-surface)", - borderColor: "var(--border-default)", + backgroundColor: "var(--c-surface)", + borderColor: "var(--c-border)", boxShadow: "var(--shadow-md)", }} > @@ -167,8 +167,8 @@ const EditTableOfContentsWorkbenchView = ({ radius="md" p="xl" style={{ - backgroundColor: "var(--bg-surface)", - borderColor: "var(--border-default)", + backgroundColor: "var(--c-surface)", + borderColor: "var(--c-border)", boxShadow: "var(--shadow-md)", }} > diff --git a/frontend/editor/src/core/components/tools/getPdfInfo/sections/PerPageSection.tsx b/frontend/editor/src/core/components/tools/getPdfInfo/sections/PerPageSection.tsx index 0c11cf592a..80eb184a42 100644 --- a/frontend/editor/src/core/components/tools/getPdfInfo/sections/PerPageSection.tsx +++ b/frontend/editor/src/core/components/tools/getPdfInfo/sections/PerPageSection.tsx @@ -125,8 +125,8 @@ const PerPageSection: React.FC = ({
= ({ block style={{ whiteSpace: "pre-wrap", - backgroundColor: "var(--bg-raised)", - color: "var(--text-primary)", + backgroundColor: "var(--c-surface-raised)", + color: "var(--c-text)", maxHeight, overflowY: "auto", }} diff --git a/frontend/editor/src/core/components/tools/getPdfInfo/shared/accordionStyles.ts b/frontend/editor/src/core/components/tools/getPdfInfo/shared/accordionStyles.ts index 73e45eee63..b10d60174f 100644 --- a/frontend/editor/src/core/components/tools/getPdfInfo/shared/accordionStyles.ts +++ b/frontend/editor/src/core/components/tools/getPdfInfo/shared/accordionStyles.ts @@ -5,7 +5,7 @@ type AccordionStyles = Partial>; export const pdfInfoAccordionStyles: AccordionStyles = { item: { - backgroundColor: "var(--accordion-item-bg)", + backgroundColor: "var(--c-surface-raised)", }, control: { backgroundColor: "transparent", diff --git a/frontend/editor/src/core/components/tools/ocr/LanguagePicker.module.css b/frontend/editor/src/core/components/tools/ocr/LanguagePicker.module.css index 6f7ae437b1..02e91270fa 100644 --- a/frontend/editor/src/core/components/tools/ocr/LanguagePicker.module.css +++ b/frontend/editor/src/core/components/tools/ocr/LanguagePicker.module.css @@ -5,9 +5,9 @@ flex-direction: row; align-items: center; /* Center align items vertically */ height: 32px; - border: 1px solid var(--border-default); - background-color: var(--mantine-color-white); /* Use Mantine color variable */ - color: var(--text-secondary); + border: 1px solid var(--c-border); + background-color: var(--c-input-bg); + color: var(--c-text-muted); border-radius: var(--radius-sm); padding: 4px 8px; font-size: 13px; @@ -15,25 +15,9 @@ transition: all 0.2s ease; } -/* Dark mode background */ -[data-mantine-color-scheme="dark"] .languagePicker { - background-color: var( - --mantine-color-dark-6 - ); /* Use Mantine dark color instead of hardcoded */ -} - .languagePicker:hover { - border-color: var(--border-strong); - background-color: var( - --mantine-color-gray-0 - ); /* Light gray on hover for light mode */ -} - -/* Dark mode hover */ -[data-mantine-color-scheme="dark"] .languagePicker:hover { - background-color: var( - --mantine-color-dark-5 - ); /* Use Mantine color variable */ + border-color: var(--c-border-strong); + background-color: var(--c-hover); } .languagePicker:disabled { @@ -43,30 +27,25 @@ .languagePickerIcon { font-size: 16px; - color: var(--text-muted); + color: var(--c-text-subtle); margin-left: auto; display: flex; align-items: center; /* Center the icon vertically */ } .languagePickerDropdown { - background-color: var(--mantine-color-white); /* Use Mantine color variable */ - border: 1px solid var(--border-default); + background-color: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-sm); padding: 4px; } -/* Dark mode dropdown background */ -[data-mantine-color-scheme="dark"] .languagePickerDropdown { - background-color: var(--mantine-color-dark-6); -} - .languagePickerOption { padding: 6px 10px; cursor: pointer; border-radius: var(--radius-xs); font-size: 13px; - color: var(--text-primary); + color: var(--c-text); transition: background-color 0.2s ease; } @@ -81,14 +60,7 @@ } .languagePickerOption:hover { - background-color: var( - --mantine-color-gray-0 - ); /* Light gray on hover for light mode */ -} - -/* Dark mode option hover */ -[data-mantine-color-scheme="dark"] .languagePickerOption:hover { - background-color: var(--mantine-color-dark-5); + background-color: var(--c-hover); } /* Additional helper classes for the component */ @@ -110,7 +82,7 @@ .languagePickerScrollArea { max-height: 180px; - border-bottom: 1px solid var(--border-default); + border-bottom: 1px solid var(--c-border); padding-bottom: 8px; } @@ -121,12 +93,7 @@ } .languagePickerLink { - color: var(--mantine-color-blue-6); + color: var(--c-accent-fg); text-decoration: underline; cursor: pointer; } - -/* Dark mode link */ -[data-mantine-color-scheme="dark"] .languagePickerLink { - color: var(--mantine-color-blue-4); -} diff --git a/frontend/editor/src/core/components/tools/ocr/LanguagePicker.tsx b/frontend/editor/src/core/components/tools/ocr/LanguagePicker.tsx index 4649df64b4..78d51bcc3b 100644 --- a/frontend/editor/src/core/components/tools/ocr/LanguagePicker.tsx +++ b/frontend/editor/src/core/components/tools/ocr/LanguagePicker.tsx @@ -158,7 +158,7 @@ const LanguagePicker: React.FC = ({
Manual redaction interface will be available here when implemented. diff --git a/frontend/editor/src/core/components/tools/reorganizePages/ReorganizePagesSettings.tsx b/frontend/editor/src/core/components/tools/reorganizePages/ReorganizePagesSettings.tsx index b01b717bb0..a5bbe2fa66 100644 --- a/frontend/editor/src/core/components/tools/reorganizePages/ReorganizePagesSettings.tsx +++ b/frontend/editor/src/core/components/tools/reorganizePages/ReorganizePagesSettings.tsx @@ -40,7 +40,7 @@ export default function ReorganizePagesSettings({ {selectedMode && (
); diff --git a/frontend/editor/src/core/components/tools/showJS/ShowJSView.css b/frontend/editor/src/core/components/tools/showJS/ShowJSView.css index 301589a930..7237fe7a3b 100644 --- a/frontend/editor/src/core/components/tools/showJS/ShowJSView.css +++ b/frontend/editor/src/core/components/tools/showJS/ShowJSView.css @@ -7,7 +7,7 @@ white-space: pre; tab-size: 2; margin: 0; - color: var(--text-primary); + color: var(--c-text); } .tok-kw { @@ -35,7 +35,7 @@ align-items: center; gap: 6px; min-width: 64px; - color: var(--text-muted); + color: var(--c-text-subtle); user-select: none; } .line-number { @@ -45,7 +45,7 @@ .fold-toggle { border: none; background: transparent; - color: var(--text-muted); + color: var(--c-text-subtle); cursor: pointer; padding: 0 2px; } @@ -62,21 +62,29 @@ flex: 1 1 auto; } .collapsed-indicator { - color: var(--text-muted); + color: var(--c-text-subtle); font-style: italic; cursor: pointer; padding-left: 8px; } .collapsed-inline { - color: var(--text-muted); + color: var(--c-text-subtle); margin-left: 6px; } .search-hit { - background: rgba(255, 235, 59, 0.4); /* yellow highlight */ + background: color-mix( + in srgb, + var(--c-highlight) 40%, + transparent + ); /* yellow highlight */ border-radius: 2px; } .search-hit-active { - background: rgba(33, 150, 243, 0.4); /* active blue */ + background: color-mix( + in srgb, + var(--c-primary) 40%, + transparent + ); /* active blue */ } .showjs-root { @@ -92,7 +100,7 @@ border: 1px solid var(--mantine-color-gray-4); border-radius: 8px; overflow: hidden; - background: var(--bg-file-manager); + background: var(--c-bg); } .showjs-toolbar { diff --git a/frontend/editor/src/core/components/tools/toolPicker/ToolPicker.css b/frontend/editor/src/core/components/tools/toolPicker/ToolPicker.css index b48932d6aa..b3b8fe3a2b 100644 --- a/frontend/editor/src/core/components/tools/toolPicker/ToolPicker.css +++ b/frontend/editor/src/core/components/tools/toolPicker/ToolPicker.css @@ -12,12 +12,12 @@ } .tool-picker-scrollable::-webkit-scrollbar-thumb { - background-color: var(--mantine-color-gray-4); + background-color: var(--c-border); border-radius: 0.1875rem; } .tool-picker-scrollable::-webkit-scrollbar-thumb:hover { - background-color: var(--mantine-color-gray-5); + background-color: var(--c-border-strong); } .search-input { @@ -28,7 +28,7 @@ text-transform: uppercase; padding-bottom: 0.5rem; font-size: 0.75rem; - color: var(--tool-subcategory-text-color); + color: var(--c-text-subtle); /* Align the text with tool labels to account for icon gutter */ padding-left: 1rem; } @@ -44,24 +44,20 @@ text-transform: uppercase; font-weight: 600; font-size: 0.75rem; - color: var(--tool-subcategory-text-color); + color: var(--c-text-subtle); white-space: nowrap; overflow: visible; } .tool-subcategory-row-rule { height: 1px; - background-color: var(--tool-subcategory-rule-color); + background-color: var(--c-border-subtle); flex: 1 1 auto; } -/* Selected tool highlight — theme-aware via CSS variable */ +/* Selected tool highlight — theme-aware via the adaptive --c-active token */ :root { - --tool-button-selected-bg: var(--mantine-color-gray-2); -} - -[data-mantine-color-scheme="dark"] { - --tool-button-selected-bg: var(--mantine-color-dark-4); + --tool-button-selected-bg: var(--c-active); } /* Compact tool buttons (padding via the Button `p`/`py` props). diff --git a/frontend/editor/src/core/components/tools/toolPicker/ToolSearch.tsx b/frontend/editor/src/core/components/tools/toolPicker/ToolSearch.tsx index 66463b9005..39eaf2a57b 100644 --- a/frontend/editor/src/core/components/tools/toolPicker/ToolSearch.tsx +++ b/frontend/editor/src/core/components/tools/toolPicker/ToolSearch.tsx @@ -148,15 +148,13 @@ const ToolSearch = ({ setDropdownOpen(false); }} leftSection={ -
- {tool.icon} -
+
{tool.icon}
} fullWidth justify="start" style={{ borderRadius: "6px", - color: "var(--tools-text-and-icon-color)", + color: "var(--c-text)", padding: "8px 12px", }} > diff --git a/frontend/editor/src/core/components/tools/validateSignature/reportView/styles.css b/frontend/editor/src/core/components/tools/validateSignature/reportView/styles.css index 096470305e..b4c9e1c815 100644 --- a/frontend/editor/src/core/components/tools/validateSignature/reportView/styles.css +++ b/frontend/editor/src/core/components/tools/validateSignature/reportView/styles.css @@ -44,7 +44,7 @@ .simulated-page { width: min(820px, 100%); min-height: 1040px; - background-color: var(--bg-raised) !important; + background-color: var(--c-surface-raised) !important; box-shadow: 0 12px 32px var(--shadow-color) !important; border-radius: 12px !important; padding: 48px 56px !important; @@ -52,7 +52,7 @@ overflow: hidden; display: flex; flex-direction: column; - color: var(--text-primary) !important; + color: var(--c-text) !important; } /* Container for the interactive report view */ @@ -60,19 +60,19 @@ width: 100%; height: 100%; /* Match Active Files/Page Editor background */ - background: var(--bg-background) !important; + background: var(--c-bg) !important; padding: 32px 24px 48px; overflow-y: auto; } /* Keep field blocks stable colors across themes */ .field-value { - border: 1px solid var(--border-default) !important; - background-color: var(--bg-raised) !important; + border: 1px solid var(--c-border) !important; + background-color: var(--c-surface-raised) !important; } .field-container { - color: var(--text-primary) !important; + color: var(--c-text) !important; } /* Thumbnail preview styles */ @@ -111,19 +111,19 @@ /* Flash highlight animation for section navigation */ @keyframes section-flash { 0% { - background-color: rgba(255, 235, 59, 0); + background-color: color-mix(in srgb, var(--c-highlight) 0%, transparent); box-shadow: none; } 20% { - background-color: rgba(255, 235, 59, 0.35); - box-shadow: 0 0 20px rgba(255, 235, 59, 0.5); + background-color: color-mix(in srgb, var(--c-highlight) 35%, transparent); + box-shadow: 0 0 20px color-mix(in srgb, var(--c-highlight) 50%, transparent); } 50% { - background-color: rgba(255, 235, 59, 0.25); - box-shadow: 0 0 15px rgba(255, 235, 59, 0.4); + background-color: color-mix(in srgb, var(--c-highlight) 25%, transparent); + box-shadow: 0 0 15px color-mix(in srgb, var(--c-highlight) 40%, transparent); } 100% { - background-color: rgba(255, 235, 59, 0); + background-color: color-mix(in srgb, var(--c-highlight) 0%, transparent); box-shadow: none; } } diff --git a/frontend/editor/src/core/components/viewer/AttachmentSidebar.css b/frontend/editor/src/core/components/viewer/AttachmentSidebar.css index 6c20964ab3..addaca8979 100644 --- a/frontend/editor/src/core/components/viewer/AttachmentSidebar.css +++ b/frontend/editor/src/core/components/viewer/AttachmentSidebar.css @@ -21,7 +21,7 @@ border-radius: 0.65rem; cursor: pointer; transition: all 0.2s ease; - background: color-mix(in srgb, var(--bg-toolbar) 86%, transparent); + background: color-mix(in srgb, var(--c-bg-raised) 86%, transparent); border: 1px solid transparent; width: 100%; box-sizing: border-box; @@ -31,12 +31,8 @@ } .attachment-item:hover { - background: color-mix(in srgb, var(--text-primary) 8%, var(--bg-toolbar)); - border-color: color-mix( - in srgb, - var(--text-primary) 20%, - var(--border-subtle) - ); + background: color-mix(in srgb, var(--c-text) 8%, var(--c-bg-raised)); + border-color: color-mix(in srgb, var(--c-text) 20%, var(--c-border-subtle)); transform: translateX(2px); } @@ -46,7 +42,7 @@ .attachment-item:focus-visible { outline: 2px solid - color-mix(in srgb, var(--text-primary) 30%, var(--border-subtle)); + color-mix(in srgb, var(--c-text) 30%, var(--c-border-subtle)); outline-offset: 2px; } @@ -54,7 +50,7 @@ .attachment-item__download-icon { flex-shrink: 0; transition: transform 0.2s ease; - color: var(--text-muted); + color: var(--c-text-subtle); } .attachment-item:hover .attachment-item__download-icon { @@ -75,7 +71,7 @@ line-height: 1.35; overflow-wrap: anywhere; word-break: break-word; - color: var(--text-primary); + color: var(--c-text); } .attachment-item__meta { diff --git a/frontend/editor/src/core/components/viewer/BookmarkSidebar.css b/frontend/editor/src/core/components/viewer/BookmarkSidebar.css index 74214fe8b9..5d8beab4e0 100644 --- a/frontend/editor/src/core/components/viewer/BookmarkSidebar.css +++ b/frontend/editor/src/core/components/viewer/BookmarkSidebar.css @@ -32,16 +32,12 @@ .bookmark-item--clickable { cursor: pointer; - background: color-mix(in srgb, var(--bg-toolbar) 86%, transparent); + background: color-mix(in srgb, var(--c-bg-raised) 86%, transparent); } .bookmark-item--clickable:hover { - background: color-mix(in srgb, var(--text-primary) 8%, var(--bg-toolbar)); - border-color: color-mix( - in srgb, - var(--text-primary) 20%, - var(--border-subtle) - ); + background: color-mix(in srgb, var(--c-text) 8%, var(--c-bg-raised)); + border-color: color-mix(in srgb, var(--c-text) 20%, var(--c-border-subtle)); transform: translateX(2px); } @@ -51,7 +47,7 @@ .bookmark-item--clickable:focus-visible { outline: 2px solid - color-mix(in srgb, var(--text-primary) 30%, var(--border-subtle)); + color-mix(in srgb, var(--c-text) 30%, var(--c-border-subtle)); outline-offset: 2px; } @@ -75,7 +71,7 @@ width: 2rem; height: 2rem; flex-shrink: 0; - color: var(--text-muted); + color: var(--c-text-subtle); font-size: 1.25rem; opacity: 0.5; font-weight: 300; @@ -94,11 +90,11 @@ line-height: 1.35; overflow-wrap: anywhere; word-break: break-word; - color: var(--text-primary); + color: var(--c-text); } .bookmark-item--clickable:hover .bookmark-item__title { - color: var(--text-primary); + color: var(--c-text); } .bookmark-item__page { diff --git a/frontend/editor/src/core/components/viewer/BookmarkSidebar.tsx b/frontend/editor/src/core/components/viewer/BookmarkSidebar.tsx index a9125215bc..2acd3e309d 100644 --- a/frontend/editor/src/core/components/viewer/BookmarkSidebar.tsx +++ b/frontend/editor/src/core/components/viewer/BookmarkSidebar.tsx @@ -845,9 +845,10 @@ export const BookmarkSidebar = ({ p="sm" data-testid="bookmark-add-form" style={{ - border: "1px solid var(--border-subtle)", + border: "1px solid var(--c-border-subtle)", borderRadius: 6, - background: "var(--bg-raised, var(--mantine-color-gray-0))", + background: + "var(--c-surface-raised, var(--mantine-color-gray-0))", }} > @@ -945,8 +946,8 @@ export const BookmarkSidebar = ({ px="sm" py="xs" style={{ - borderTop: "1px solid var(--border-subtle)", - backgroundColor: "var(--bg-toolbar)", + borderTop: "1px solid var(--c-border-subtle)", + backgroundColor: "var(--c-bg-raised)", flexShrink: 0, }} > diff --git a/frontend/editor/src/core/components/viewer/CommentsSidebar.tsx b/frontend/editor/src/core/components/viewer/CommentsSidebar.tsx index e25f9671d9..3bbc5c8f53 100644 --- a/frontend/editor/src/core/components/viewer/CommentsSidebar.tsx +++ b/frontend/editor/src/core/components/viewer/CommentsSidebar.tsx @@ -679,8 +679,8 @@ export function CommentsSidebar({ top: 0, bottom: 0, width: SIDEBAR_WIDTH, - backgroundColor: "var(--bg-file-manager)", - borderLeft: "1px solid var(--border-subtle)", + backgroundColor: "var(--c-bg)", + borderLeft: "1px solid var(--c-border-subtle)", zIndex: 998, display: "flex", flexDirection: "column", @@ -690,7 +690,7 @@ export function CommentsSidebar({
@@ -902,9 +902,9 @@ export function CommentsSidebar({ style={{ border: selectedAnnotationIds.has(id) ? "1px solid var(--mantine-color-blue-3)" - : "1px solid var(--border-subtle)", + : "1px solid var(--c-border-subtle)", borderRadius: 8, - backgroundColor: "var(--bg-raised)", + backgroundColor: "var(--c-surface-raised)", }} > {displayZoomPercent}% diff --git a/frontend/editor/src/core/components/viewer/SidebarBase.css b/frontend/editor/src/core/components/viewer/SidebarBase.css index 058796038d..8e7771dead 100644 --- a/frontend/editor/src/core/components/viewer/SidebarBase.css +++ b/frontend/editor/src/core/components/viewer/SidebarBase.css @@ -6,15 +6,15 @@ flex-direction: column; background: linear-gradient( 135deg, - color-mix(in srgb, var(--bg-toolbar) 96%, transparent), - color-mix(in srgb, var(--bg-background) 90%, transparent) + color-mix(in srgb, var(--c-bg-raised) 96%, transparent), + color-mix(in srgb, var(--c-bg) 90%, transparent) ); border-left: 1px solid - color-mix(in srgb, var(--border-subtle) 75%, transparent); + color-mix(in srgb, var(--c-border-subtle) 75%, transparent); box-shadow: -2px 0 16px color-mix( in srgb, - var(--shadow-color, rgba(15, 23, 42, 0.35)) 20%, + var(--shadow-color, color-mix(in srgb, black 35%, transparent)) 20%, transparent ); backdrop-filter: blur(12px); @@ -26,8 +26,8 @@ align-items: center; justify-content: space-between; padding: 0.75rem 0.875rem; - background: var(--bg-toolbar); - border-bottom: 1px solid var(--border-subtle); + background: var(--c-bg-raised); + border-bottom: 1px solid var(--c-border-subtle); } .sidebar-base__header-title { @@ -46,9 +46,8 @@ /* Search Section (used by bookmark & attachment sidebars) */ .sidebar-base__search { - background: var(--tool-panel-search-bg, var(--bg-toolbar)); - border-bottom: 1px solid - var(--tool-panel-search-border-bottom, var(--border-subtle)); + background: var(--c-surface-sunken, var(--c-bg-raised)); + border-bottom: 1px solid var(--c-border, var(--c-border-subtle)); padding-top: 0.75rem !important; } diff --git a/frontend/editor/src/core/components/viewer/ThumbnailSidebar.tsx b/frontend/editor/src/core/components/viewer/ThumbnailSidebar.tsx index 6b195c4485..c44271258a 100644 --- a/frontend/editor/src/core/components/viewer/ThumbnailSidebar.tsx +++ b/frontend/editor/src/core/components/viewer/ThumbnailSidebar.tsx @@ -238,7 +238,7 @@ export function ThumbnailSidebar({ onMouseEnter={(e) => { if (scrollState.currentPage !== pageIndex + 1) { e.currentTarget.style.backgroundColor = - "var(--hover-bg)"; + "var(--c-hover)"; } }} onMouseLeave={(e) => { @@ -259,7 +259,7 @@ export function ThumbnailSidebar({ height: "auto", borderRadius: "4px", boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)", - border: "1px solid var(--border-subtle)", + border: "1px solid var(--c-border-subtle)", }} /> @@ -285,13 +285,13 @@ export function ThumbnailSidebar({ style={{ width: "11.5rem", height: "15rem", - backgroundColor: "var(--bg-muted)", - border: "1px solid var(--border-subtle)", + backgroundColor: "var(--c-surface-sunken)", + border: "1px solid var(--c-border-subtle)", borderRadius: "4px", display: "flex", alignItems: "center", justifyContent: "center", - color: "var(--text-muted)", + color: "var(--c-text-subtle)", fontSize: "12px", }} > @@ -307,7 +307,7 @@ export function ThumbnailSidebar({ color: scrollState.currentPage === pageIndex + 1 ? "var(--color-primary-500)" - : "var(--text-muted)", + : "var(--c-text-subtle)", }} > Page {pageIndex + 1} diff --git a/frontend/editor/src/core/data/useTranslatedToolRegistry.tsx b/frontend/editor/src/core/data/useTranslatedToolRegistry.tsx index 58b61c71be..120f955b42 100644 --- a/frontend/editor/src/core/data/useTranslatedToolRegistry.tsx +++ b/frontend/editor/src/core/data/useTranslatedToolRegistry.tsx @@ -1199,7 +1199,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog { icon="open-in-new-rounded" width="1.5rem" height="1.5rem" - style={{ color: "#2F7BF6" }} + style={{ color: "var(--c-accent-fg, var(--c-primary))" }} /> ), name: t("home.devApi.title", "API"), @@ -1219,7 +1219,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog { icon="open-in-new-rounded" width="1.5rem" height="1.5rem" - style={{ color: "#2F7BF6" }} + style={{ color: "var(--c-accent-fg, var(--c-primary))" }} /> ), name: t("home.devFolderScanning.title", "Automated Folder Scanning"), @@ -1242,7 +1242,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog { icon="open-in-new-rounded" width="1.5rem" height="1.5rem" - style={{ color: "#2F7BF6" }} + style={{ color: "var(--c-accent-fg, var(--c-primary))" }} /> ), name: t("home.devSsoGuide.title", "SSO Guide"), @@ -1262,7 +1262,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog { icon="open-in-new-rounded" width="1.5rem" height="1.5rem" - style={{ color: "#2F7BF6" }} + style={{ color: "var(--c-accent-fg, var(--c-primary))" }} /> ), name: t("home.devAirgapped.title", "Air-gapped Setup"), diff --git a/frontend/editor/src/core/pages/HomePage.css b/frontend/editor/src/core/pages/HomePage.css index cfd3bded5c..7af1e89404 100644 --- a/frontend/editor/src/core/pages/HomePage.css +++ b/frontend/editor/src/core/pages/HomePage.css @@ -3,13 +3,13 @@ flex-direction: column; height: 100%; width: 100%; - background-color: var(--bg-background); + background-color: var(--c-bg); } .mobile-toggle { padding: 0.5rem 0.75rem; - border-bottom: 1px solid var(--border-subtle); - background: var(--bg-toolbar); + border-bottom: 1px solid var(--c-border-subtle); + background: var(--c-bg-raised); display: flex; flex-direction: column; gap: 0.35rem; @@ -47,8 +47,8 @@ gap: 0.25rem; padding: 0.2rem; border-radius: 9999px; - background: var(--bg-background); - border: 1px solid var(--border-subtle); + background: var(--c-bg); + border: 1px solid var(--c-border-subtle); } .mobile-toggle-button { @@ -57,7 +57,7 @@ padding: 0.4rem 0.9rem; font-size: 0.8125rem; font-weight: 600; - color: var(--text-muted); + color: var(--c-text-subtle); background: transparent; transition: background 0.2s ease, @@ -65,18 +65,18 @@ } .mobile-toggle-button:focus-visible { - outline: 2px solid var(--primary-color, #228be6); + outline: 2px solid var(--c-primary); outline-offset: 2px; } .mobile-toggle-button.active { - background: var(--primary-surface, rgba(34, 139, 230, 0.12)); - color: var(--text-primary); + background: var(--c-primary-subtle); + color: var(--c-text); } .mobile-toggle-hint { font-size: 0.7rem; - color: var(--text-muted); + color: var(--c-text-subtle); text-align: center; } @@ -134,8 +134,8 @@ align-items: center; justify-content: space-around; padding: 0.5rem; - border-top: 1px solid var(--border-subtle); - background: var(--bg-toolbar); + border-top: 1px solid var(--c-border-subtle); + background: var(--c-bg-raised); gap: 0.5rem; position: relative; z-index: 10; @@ -152,7 +152,7 @@ padding: 0.5rem; border: none; background: transparent; - color: var(--text-primary); + color: var(--c-text); cursor: pointer; border-radius: 0.5rem; transition: background 0.2s ease; @@ -165,16 +165,16 @@ @media (hover: hover) and (pointer: fine) { .mobile-bottom-button:hover { - background: var(--bg-hover, rgba(0, 0, 0, 0.05)); + background: var(--c-hover); } } .mobile-bottom-button:active { - background: var(--bg-active, rgba(0, 0, 0, 0.1)); + background: var(--c-active); } .mobile-bottom-button-label { font-size: 0.75rem; font-weight: 500; - color: var(--text-muted); + color: var(--c-text-subtle); } diff --git a/frontend/editor/src/core/pages/MobileScannerPage.tsx b/frontend/editor/src/core/pages/MobileScannerPage.tsx index cf4e3e3564..bce84cf371 100644 --- a/frontend/editor/src/core/pages/MobileScannerPage.tsx +++ b/frontend/editor/src/core/pages/MobileScannerPage.tsx @@ -995,7 +995,7 @@ export default function MobileScannerPage() { @@ -1025,7 +1025,7 @@ export default function MobileScannerPage() { background: loadingStatus.includes("✗") ? "var(--mantine-color-red-1)" : "var(--mantine-color-blue-1)", - borderBottom: "1px solid var(--border-subtle)", + borderBottom: "1px solid var(--c-border-subtle)", fontSize: "0.85rem", fontFamily: "monospace", textAlign: "center", @@ -1231,8 +1231,8 @@ export default function MobileScannerPage() { {/* Controls bar - fixed at bottom */} @@ -1372,8 +1372,8 @@ export default function MobileScannerPage() { {/* Controls bar - fixed at bottom */} @@ -1401,7 +1401,7 @@ export default function MobileScannerPage() { )} {capturedImages.length > 0 && ( - + {t("mobileScanner.batchImages", "Batch")} ({capturedImages.length} @@ -1442,7 +1442,7 @@ export default function MobileScannerPage() { height: "80px", borderRadius: "var(--radius-sm)", overflow: "hidden", - border: "2px solid var(--border-subtle)", + border: "2px solid var(--c-border-subtle)", }} > ({ root: { - backgroundColor: "var(--bg-surface)", - border: "1px solid var(--border-default)", - color: "var(--text-primary)", + backgroundColor: "var(--c-surface)", + border: "1px solid var(--c-border)", + color: "var(--c-text)", "&:hover": { - backgroundColor: "var(--hover-bg)", + backgroundColor: "var(--c-hover)", borderColor: "var(--color-primary-500)", }, }, @@ -150,8 +150,8 @@ export const mantineTheme = createTheme({ Paper: { styles: { root: { - backgroundColor: "var(--bg-surface)", - border: "1px solid var(--border-subtle)", + backgroundColor: "var(--c-surface)", + border: "1px solid var(--c-border-subtle)", }, }, }, @@ -159,8 +159,8 @@ export const mantineTheme = createTheme({ Card: { styles: { root: { - backgroundColor: "var(--bg-surface)", - border: "1px solid var(--border-subtle)", + backgroundColor: "var(--c-surface)", + border: "1px solid var(--c-border-subtle)", boxShadow: "var(--shadow-sm)", }, }, @@ -170,7 +170,7 @@ export const mantineTheme = createTheme({ styles: { root: { backgroundColor: "var(--color-gray-100)", - color: "var(--text-primary)", + color: "var(--c-text)", }, }, }, @@ -178,16 +178,16 @@ export const mantineTheme = createTheme({ Textarea: { styles: (_theme: MantineTheme) => ({ input: { - backgroundColor: "var(--bg-surface)", - borderColor: "var(--border-default)", - color: "var(--text-primary)", + backgroundColor: "var(--c-surface)", + borderColor: "var(--c-border)", + color: "var(--c-text)", "&:focus": { borderColor: "var(--color-primary-500)", boxShadow: "0 0 0 1px var(--color-primary-500)", }, }, label: { - color: "var(--text-secondary)", + color: "var(--c-text-muted)", fontWeight: "var(--font-weight-medium)", }, }), @@ -196,16 +196,16 @@ export const mantineTheme = createTheme({ TextInput: { styles: (_theme: MantineTheme) => ({ input: { - backgroundColor: "var(--bg-surface)", - borderColor: "var(--border-default)", - color: "var(--text-primary)", + backgroundColor: "var(--c-surface)", + borderColor: "var(--c-border)", + color: "var(--c-text)", "&:focus": { borderColor: "var(--color-primary-500)", boxShadow: "0 0 0 1px var(--color-primary-500)", }, }, label: { - color: "var(--text-secondary)", + color: "var(--c-text-muted)", fontWeight: "var(--font-weight-medium)", }, }), @@ -214,16 +214,16 @@ export const mantineTheme = createTheme({ PasswordInput: { styles: (_theme: MantineTheme) => ({ input: { - backgroundColor: "var(--bg-surface)", - borderColor: "var(--border-default)", - color: "var(--text-primary)", + backgroundColor: "var(--c-surface)", + borderColor: "var(--c-border)", + color: "var(--c-text)", "&:focus": { borderColor: "var(--color-primary-500)", boxShadow: "0 0 0 1px var(--color-primary-500)", }, }, label: { - color: "var(--text-secondary)", + color: "var(--c-text-muted)", fontWeight: "var(--font-weight-medium)", }, }), @@ -232,26 +232,26 @@ export const mantineTheme = createTheme({ Select: { styles: { input: { - backgroundColor: "var(--bg-surface)", - borderColor: "var(--border-default)", - color: "var(--text-primary)", + backgroundColor: "var(--c-surface)", + borderColor: "var(--c-border)", + color: "var(--c-text)", "&:focus": { borderColor: "var(--color-primary-500)", boxShadow: "0 0 0 1px var(--color-primary-500)", }, }, label: { - color: "var(--text-secondary)", + color: "var(--c-text-muted)", fontWeight: "var(--font-weight-medium)", }, dropdown: { - backgroundColor: "var(--bg-surface)", - borderColor: "var(--border-subtle)", + backgroundColor: "var(--c-surface)", + borderColor: "var(--c-border-subtle)", boxShadow: "var(--shadow-lg)", }, option: { - color: "var(--text-primary)", - "--combobox-option-hover": "var(--hover-bg)", + color: "var(--c-text)", + "--combobox-option-hover": "var(--c-hover)", "--combobox-option-selected": "var(--color-primary-100)", }, }, @@ -260,26 +260,26 @@ export const mantineTheme = createTheme({ MultiSelect: { styles: { input: { - backgroundColor: "var(--bg-surface)", - borderColor: "var(--border-default)", - color: "var(--text-primary)", + backgroundColor: "var(--c-surface)", + borderColor: "var(--c-border)", + color: "var(--c-text)", "&:focus": { borderColor: "var(--color-primary-500)", boxShadow: "0 0 0 1px var(--color-primary-500)", }, }, label: { - color: "var(--text-secondary)", + color: "var(--c-text-muted)", fontWeight: "var(--font-weight-medium)", }, dropdown: { - backgroundColor: "var(--bg-surface)", - borderColor: "var(--border-subtle)", + backgroundColor: "var(--c-surface)", + borderColor: "var(--c-border-subtle)", boxShadow: "var(--shadow-lg)", }, option: { - color: "var(--text-primary)", - "--combobox-option-hover": "var(--hover-bg)", + color: "var(--c-text)", + "--combobox-option-hover": "var(--c-hover)", "--combobox-option-selected": "var(--color-primary-100)", }, }, @@ -287,8 +287,9 @@ export const mantineTheme = createTheme({ Tooltip: { styles: { tooltip: { - backgroundColor: "var( --tooltip-title-bg)", - color: "var( --tooltip-title-color)", + backgroundColor: + "color-mix( in srgb, var(--c-primary) 12%, var(--c-surface) )", + color: "var(--c-text)", border: "1px solid var(--tooltip-border)", fontSize: "0.75rem", fontWeight: "500", @@ -301,14 +302,14 @@ export const mantineTheme = createTheme({ Checkbox: { styles: { input: { - borderColor: "var(--border-default)", + borderColor: "var(--c-border)", "&:checked": { backgroundColor: "var(--color-primary-500)", borderColor: "var(--color-primary-500)", }, }, label: { - color: "var(--text-primary)", + color: "var(--c-text)", }, }, }, @@ -316,7 +317,7 @@ export const mantineTheme = createTheme({ Slider: { styles: { track: { - backgroundColor: "var(--bg-muted)", + backgroundColor: "var(--c-surface-sunken)", }, bar: { backgroundColor: "var(--color-primary-500)", @@ -326,10 +327,10 @@ export const mantineTheme = createTheme({ borderColor: "var(--color-primary-500)", }, mark: { - borderColor: "var(--border-default)", + borderColor: "var(--c-border)", }, markLabel: { - color: "var(--text-muted)", + color: "var(--c-text-subtle)", }, }, }, @@ -337,16 +338,16 @@ export const mantineTheme = createTheme({ Modal: { styles: { content: { - backgroundColor: "var(--bg-surface)", - border: "1px solid var(--border-subtle)", + backgroundColor: "var(--c-surface)", + border: "1px solid var(--c-border-subtle)", boxShadow: "var(--shadow-xl)", }, header: { - backgroundColor: "var(--bg-surface)", - borderBottom: "1px solid var(--border-subtle)", + backgroundColor: "var(--c-surface)", + borderBottom: "1px solid var(--c-border-subtle)", }, title: { - color: "var(--text-primary)", + color: "var(--c-text)", fontWeight: "var(--font-weight-semibold)", }, }, @@ -355,15 +356,15 @@ export const mantineTheme = createTheme({ Notification: { styles: { root: { - backgroundColor: "var(--bg-surface)", - border: "1px solid var(--border-subtle)", + backgroundColor: "var(--c-surface)", + border: "1px solid var(--c-border-subtle)", boxShadow: "var(--shadow-lg)", }, title: { - color: "var(--text-primary)", + color: "var(--c-text)", }, description: { - color: "var(--text-secondary)", + color: "var(--c-text-muted)", }, }, }, diff --git a/frontend/editor/src/core/theme/primitives.css b/frontend/editor/src/core/theme/primitives.css index 901a3dd646..22716816a2 100644 --- a/frontend/editor/src/core/theme/primitives.css +++ b/frontend/editor/src/core/theme/primitives.css @@ -42,4 +42,128 @@ --p-red-400: #f87171; --p-red-500: #ef4444; --p-red-600: #dc2626; + + /* Brand-red + ai-accent scales, consumed by core/ui/accents.css. */ + --p-brand-red-200: #d9a8a8; + --p-brand-red-300: #d98a8a; + --p-brand-red-650: #8e3131; + --p-brand-red-700: #7a2929; + --p-brand-red-900: #5a2424; + --p-cyan-400: #22d3ee; + --p-indigo-200: #c7d2fe; + --p-indigo-300: #a5b4fc; + --p-indigo-400: #818cf8; + --p-indigo-500: #6366f1; + --p-indigo-800: #3730a3; + + /* Extended accent/status/neutral weights referenced by app CSS. */ + --p-azure-300: #7ab4ff; + --p-azure-400: #38bdf8; + --p-cyan-500: #06b6d4; + --p-green-400: #4ade80; + --p-pink-500: #ec4899; + --p-purple-500: #6c5ce7; + --p-periwinkle-500: #635bff; + --p-teal-700: #0f7b6c; + --p-gray-450: #868e96; + --p-gray-b0: #b0b0b0; + --p-gray-mid: #808080; + + /* Brand red (login/auth CTAs) — base + hover, complementing the -200..-900 scale above. */ + --p-brand-red: #af3434; + --p-brand-red-600: #9a2e2e; + + /* Highlight flash (compare / show-JS / signature-report animations). */ + --p-flash-yellow: #ffeb3b; + + /* Onboarding hero gradient stops (dark decorative navies + light tints). */ + --p-navy-850: #1a2236; + --p-navy-880: #171e30; + --p-navy-900: #0f1626; + --p-plum-900: #201a28; + --p-tint-blue: #eef1fb; + --p-tint-violet: #f6f4fc; + --p-tint-pink: #fbf4f7; + + /* Notion-style procurement view palette. */ + --p-notion-blue: #2383e2; + --p-notion-blue-strong: #1b6ec2; + --p-notion-blue-border: #b8d5f2; + --p-notion-ink: #37352f; + --p-notion-gray: #9b9a97; + --p-notion-gray-strong: #787774; + --p-notion-paper: #f5f4f1; + --p-notion-paper-2: #f0eee9; + --p-notion-border: #e3e1dc; + --p-notion-border-2: #eae8e3; + --p-notion-border-cool: #d3d1cb; + + /* Vendor status chips (procurement / auth callback). */ + --p-vendor-red: #ef5350; + --p-vendor-red-text: #c62828; + --p-vendor-red-soft: #ef9a9a; + --p-vendor-red-bg: #ffebee; + --p-vendor-red-border: #ffcdd2; + --p-vendor-red-bg-dark: #3d2020; + --p-vendor-red-border-dark: #5d3030; + --p-vendor-green: #66bb6a; + + /* Palette entries migrated from literals in consuming files. */ + --p-c-0550ae: #0550ae; + --p-emerald-600: #059669; + --p-code-string: #0a3069; + --p-azure-500: #0a8bff; + --p-navy-950: #0d1020; + --p-c-0f172a: #0f172a; + --p-emerald-500: #10b981; + --p-navy-700: #16213e; + --p-c-1a2332: #1a2332; + --p-c-1c2340: #1c2340; + --p-c-1e293b: #1e293b; + --p-c-1f2328: #1f2328; + --p-royal-700: #2040a0; + --p-c-2d3560: #2d3560; + --p-emerald-400: #34d399; + --p-azure-650: #3a7be8; + --p-navy-500: #3b4b6e; + --p-c-475569: #475569; + --p-c-334155: #334155; + --p-c-cbd5e1: #cbd5e1; + --p-azure-550: #4c8bf5; + --p-c-545454: #545454; + --p-azure-450: #5b9bf7; + --p-c-64748b: #64748b; + --p-c-656d76: #656d76; + --p-c-6e7781: #6e7781; + --p-violet-600: #7c3aed; + --p-c-7e7e7e: #7e7e7e; + --p-c-8250df: #8250df; + --p-violet-500: #8b5cf6; + --p-c-8c959f: #8c959f; + --p-blue-200: #93c5fd; + --p-c-94a3b8: #94a3b8; + --p-code-type: #953800; + --p-violet-400: #a78bfa; + --p-c-acacac: #acacac; + --p-c-c084fc: #c084fc; + --p-art-red-muted: #c56565; + --p-c-cf222e: #cf222e; + --p-c-d0d6dc: #d0d6dc; + --p-c-d0d7de: #d0d7de; + --p-c-d0dbdc: #d0dbdc; + --p-c-d3d3d3: #d3d3d3; + --p-c-d62626: #d62626; + --p-c-e6e6e6: #e6e6e6; + --p-c-eaeef2: #eaeef2; + --p-c-eef1f4: #eef1f4; + --p-c-f1f5f9: #f1f5f9; + --p-c-f472b6: #f472b6; + --p-c-f6f8fa: #f6f8fa; + --p-c-f8fafc: #f8fafc; + --p-art-red-soft: #fc9999; + --p-art-red-light: #fca5a5; + --p-art-red: #ff4b4b; + --p-c-ffc107: #ffc107; + --p-c-c2c8e0: #c2c8e0; + --p-c-4f8ef5: #4f8ef5; } diff --git a/frontend/editor/src/core/tokens/Tokens.stories.tsx b/frontend/editor/src/core/tokens/Tokens.stories.tsx index 7543d7d4d6..0003c06b17 100644 --- a/frontend/editor/src/core/tokens/Tokens.stories.tsx +++ b/frontend/editor/src/core/tokens/Tokens.stories.tsx @@ -42,8 +42,8 @@ function Group({ heading, swatches }: { heading: string; swatches: Swatch[] }) { alignItems: "center", gap: 10, padding: 10, - background: "var(--color-surface)", - border: "1px solid var(--color-border)", + background: "var(--c-surface)", + border: "1px solid var(--c-border)", borderRadius: "var(--radius-md)", }} > @@ -53,7 +53,7 @@ function Group({ heading, swatches }: { heading: string; swatches: Swatch[] }) { height: 36, borderRadius: 6, background: `var(${s.varName})`, - border: "1px solid var(--color-border)", + border: "1px solid var(--c-border)", flexShrink: 0, }} /> @@ -62,7 +62,7 @@ function Group({ heading, swatches }: { heading: string; swatches: Swatch[] }) { style={{ fontSize: 12, fontWeight: 500, - color: "var(--color-text-2)", + color: "var(--c-text-muted)", }} > {s.label} @@ -71,7 +71,7 @@ function Group({ heading, swatches }: { heading: string; swatches: Swatch[] }) { style={{ fontSize: 11, fontFamily: "var(--font-mono)", - color: "var(--color-text-4)", + color: "var(--c-text-subtle)", overflow: "hidden", textOverflow: "ellipsis", }} @@ -154,14 +154,14 @@ export const Typography: Story = { display: "flex", flexDirection: "column", gap: 18, - color: "var(--color-text-1)", + color: "var(--c-text)", }} >
@@ -181,7 +181,7 @@ export const Typography: Story = {
@@ -193,7 +193,7 @@ export const Typography: Story = {
@@ -207,7 +207,7 @@ export const Typography: Story = {
@@ -221,7 +221,7 @@ export const Typography: Story = {
@@ -240,8 +240,8 @@ export const Motion: Story = {
{ data-slot-state="filled" data-slot-filename={stub?.name} style={{ - border: "1px solid var(--border-default)", + border: "1px solid var(--c-border)", borderRadius: "var(--radius-md)", padding: "0.75rem 1rem", - background: "var(--bg-surface)", + background: "var(--c-surface)", width: "100%", minHeight: "9rem", position: "relative", diff --git a/frontend/editor/src/core/tools/formFill/FormFieldSidebar.tsx b/frontend/editor/src/core/tools/formFill/FormFieldSidebar.tsx index 2e49991ceb..d348c5c241 100644 --- a/frontend/editor/src/core/tools/formFill/FormFieldSidebar.tsx +++ b/frontend/editor/src/core/tools/formFill/FormFieldSidebar.tsx @@ -82,9 +82,9 @@ export function FormFieldSidebar({ visible, onToggle }: FormFieldSidebarProps) { zIndex: 999, display: "flex", flexDirection: "column", - background: "var(--bg-toolbar, var(--mantine-color-body))", + background: "var(--c-bg-raised, var(--mantine-color-body))", borderLeft: - "1px solid var(--border-subtle, var(--mantine-color-default-border))", + "1px solid var(--c-border-subtle, var(--mantine-color-default-border))", boxShadow: "-4px 0 16px rgba(0,0,0,0.08)", }} > @@ -96,7 +96,7 @@ export function FormFieldSidebar({ visible, onToggle }: FormFieldSidebarProps) { justifyContent: "space-between", padding: "0.625rem 0.75rem", borderBottom: - "1px solid var(--border-subtle, var(--mantine-color-default-border))", + "1px solid var(--c-border-subtle, var(--mantine-color-default-border))", flexShrink: 0, }} > diff --git a/frontend/editor/src/core/tools/formFill/FormFill.module.css b/frontend/editor/src/core/tools/formFill/FormFill.module.css index 4cffc284f5..800e610c03 100644 --- a/frontend/editor/src/core/tools/formFill/FormFill.module.css +++ b/frontend/editor/src/core/tools/formFill/FormFill.module.css @@ -8,8 +8,7 @@ .modeTabs { flex-shrink: 0; - border-bottom: 1px solid - var(--border-default, var(--mantine-color-default-border)); + border-bottom: 1px solid var(--c-border, var(--mantine-color-default-border)); background: transparent; padding: 0.25rem; } @@ -44,7 +43,7 @@ font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; - color: var(--text-muted); + color: var(--c-text-subtle); transition: color 0.15s ease; line-height: 1; } @@ -59,8 +58,7 @@ flex-shrink: 0; padding: 0.75rem 1rem; background: transparent; - border-bottom: 1px solid - var(--border-default, var(--mantine-color-default-border)); + border-bottom: 1px solid var(--c-border, var(--mantine-color-default-border)); display: flex; flex-direction: column; gap: 0.625rem; @@ -76,7 +74,7 @@ .progressLabel { font-size: 0.6875rem; font-weight: 600; - color: var(--text-muted); + color: var(--c-text-subtle); white-space: nowrap; } @@ -133,7 +131,7 @@ content: ""; flex: 1; height: 1px; - background: var(--border-default, var(--mantine-color-default-border)); + background: var(--c-border, var(--mantine-color-default-border)); opacity: 0.2; } @@ -142,22 +140,22 @@ font-weight: 800; text-transform: uppercase; letter-spacing: 0.1em; - color: var(--text-muted); + color: var(--c-text-subtle); opacity: 0.6; } .fieldCard { padding: 0.625rem 0.75rem; border-radius: var(--radius-md); - border: 1px solid var(--border-default, var(--mantine-color-default-border)); - background: var(--bg-surface, var(--mantine-color-body)); + border: 1px solid var(--c-border, var(--mantine-color-default-border)); + background: var(--c-surface, var(--mantine-color-body)); cursor: pointer; transition: all 0.15s ease; } .fieldCard:hover { border-color: var(--mantine-color-blue-5); - background: var(--bg-surface); + background: var(--c-surface); } .fieldCardActive { @@ -193,7 +191,7 @@ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; - color: var(--text-primary); + color: var(--c-text); } .fieldRequired { @@ -214,7 +212,7 @@ .fieldHint { margin-top: 0.375rem; font-size: 0.6875rem; - color: var(--text-muted); + color: var(--c-text-subtle); line-height: 1.4; font-style: italic; opacity: 0.8; @@ -235,7 +233,7 @@ gap: 0.75rem; padding: 5rem 1.5rem; text-align: center; - color: var(--text-muted); + color: var(--c-text-subtle); background: transparent; } @@ -263,14 +261,13 @@ .statusBar { flex-shrink: 0; padding: 0.5rem 1rem; - border-top: 1px solid - var(--border-default, var(--mantine-color-default-border)); + border-top: 1px solid var(--c-border, var(--mantine-color-default-border)); display: flex; align-items: center; justify-content: space-between; font-size: 0.6875rem; font-weight: 600; - color: var(--text-muted); + color: var(--c-text-subtle); background: transparent; } @@ -294,7 +291,7 @@ .comingSoonTitle { font-size: 1rem; font-weight: 800; - color: var(--text-primary); + color: var(--c-text); text-transform: uppercase; letter-spacing: 0.05em; } @@ -302,6 +299,6 @@ .comingSoonDesc { font-size: 0.75rem; line-height: 1.6; - color: var(--text-muted); + color: var(--c-text-subtle); max-width: 200px; } diff --git a/frontend/editor/src/core/ui/ActionIcon.tsx b/frontend/editor/src/core/ui/ActionIcon.tsx index 44584be569..682e4b41e5 100644 --- a/frontend/editor/src/core/ui/ActionIcon.tsx +++ b/frontend/editor/src/core/ui/ActionIcon.tsx @@ -100,7 +100,7 @@ export const ActionIcon = forwardRef( "--ai-bg": "transparent", "--ai-hover": "transparent", "--ai-color": "var(--_text)", - "--ai-hover-color": "var(--color-text-1)", + "--ai-hover-color": "var(--c-text)", "--ai-bd": "1px solid transparent", } : { diff --git a/frontend/editor/src/core/ui/Avatar.css b/frontend/editor/src/core/ui/Avatar.css index 21089db8f0..e2e8dc63bd 100644 --- a/frontend/editor/src/core/ui/Avatar.css +++ b/frontend/editor/src/core/ui/Avatar.css @@ -70,6 +70,6 @@ background: var(--grad-red-btn); } .sui-avatar--neutral { - background: var(--color-bg-muted); - color: var(--color-text-2); + background: var(--c-surface-sunken); + color: var(--c-text-muted); } diff --git a/frontend/editor/src/core/ui/Banner.css b/frontend/editor/src/core/ui/Banner.css index 937905a915..6f3a53e930 100644 --- a/frontend/editor/src/core/ui/Banner.css +++ b/frontend/editor/src/core/ui/Banner.css @@ -10,29 +10,29 @@ } .sui-banner--info { - background: var(--color-blue-light); - color: var(--color-text-2); - border-color: var(--color-blue-border); + background: var(--c-primary-tint); + color: var(--c-text-muted); + border-color: var(--c-primary-border); } .sui-banner--success { background: var(--color-green-light); - color: var(--color-text-2); + color: var(--c-text-muted); border-color: var(--color-green-border); } .sui-banner--warning { background: var(--color-amber-light); - color: var(--color-text-2); + color: var(--c-text-muted); border-color: var(--color-amber-border); } .sui-banner--danger { background: var(--color-red-light); - color: var(--color-text-2); + color: var(--c-text-muted); border-color: var(--color-red-border); } .sui-banner--neutral { background: var(--color-bg-subtle); - color: var(--color-text-2); - border-color: var(--color-border); + color: var(--c-text-muted); + border-color: var(--c-border); } .sui-banner__icon { @@ -45,7 +45,7 @@ } .sui-banner--info .sui-banner__icon { - color: var(--color-blue); + color: var(--c-primary); } .sui-banner--success .sui-banner__icon { color: var(--color-green); @@ -63,10 +63,10 @@ } .sui-banner__title { font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .sui-banner__desc { - color: var(--color-text-3); + color: var(--c-text-subtle); margin-top: 0.125rem; } diff --git a/frontend/editor/src/core/ui/Button.css b/frontend/editor/src/core/ui/Button.css index 6ec23ca9ea..529d97fe16 100644 --- a/frontend/editor/src/core/ui/Button.css +++ b/frontend/editor/src/core/ui/Button.css @@ -67,8 +67,8 @@ [data-theme="dark"] .sui-btn.mantine-Button-root:disabled:not([data-loading]), [data-theme="dark"] .sui-btn.mantine-Button-root[data-disabled]:not([data-loading]) { - background: var(--color-bg-muted); - color: var(--color-text-5); + background: var(--c-surface-sunken); + color: var(--c-text-subtle); border-color: transparent; opacity: 1; } diff --git a/frontend/editor/src/core/ui/Button.stories.tsx b/frontend/editor/src/core/ui/Button.stories.tsx index d35a24aed7..374d31c46e 100644 --- a/frontend/editor/src/core/ui/Button.stories.tsx +++ b/frontend/editor/src/core/ui/Button.stories.tsx @@ -172,7 +172,7 @@ export const Loading: Story = { /** Disabled primary — dark mode keeps a muted accent instead of grey. */ export const DisabledDark: Story = { render: () => ( -
+
setOpen(false)}> -

+

The drawer body scrolls when its content overflows. The header and footer (when present) are sticky.

@@ -79,7 +79,7 @@ export const WithFooter: Story = { } > -

+

Sticky footer demo — scroll the body, footer stays anchored.

diff --git a/frontend/editor/src/core/ui/Dropdown.css b/frontend/editor/src/core/ui/Dropdown.css index 736371e6ae..38b20ee1d8 100644 --- a/frontend/editor/src/core/ui/Dropdown.css +++ b/frontend/editor/src/core/ui/Dropdown.css @@ -8,8 +8,8 @@ top: calc(100% + var(--space-1)); min-width: 12rem; padding: var(--space-1); - background: var(--color-dropdown-bg); - border: 1px solid var(--color-dropdown-border); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); z-index: var(--z-dropdown); @@ -34,7 +34,7 @@ width: 100%; text-align: left; font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); border-radius: var(--radius-sm); /* Explicit button reset: hosts without a global button reset (e.g. the editor) would otherwise show the UA's buttonface background and border. */ @@ -48,13 +48,13 @@ } .sui-dd__item:hover:not(.is-disabled) { - background: var(--color-dropdown-hover); - color: var(--color-text-1); + background: var(--c-hover); + color: var(--c-text); } .sui-dd__item.is-active { - background: var(--color-nav-active); - color: var(--color-nav-active-text); + background: var(--c-primary-subtle); + color: var(--c-accent-fg); font-weight: 500; } @@ -73,11 +73,11 @@ margin-left: auto; font-family: var(--font-mono); font-size: 0.6875rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } .sui-dd__divider { height: 1px; - background: var(--color-divider); + background: var(--c-border-subtle); margin: var(--space-1) 0; } diff --git a/frontend/editor/src/core/ui/EmptyState.css b/frontend/editor/src/core/ui/EmptyState.css index e78db8b664..bf8250bc82 100644 --- a/frontend/editor/src/core/ui/EmptyState.css +++ b/frontend/editor/src/core/ui/EmptyState.css @@ -14,7 +14,7 @@ .sui-empty__icon { display: inline-flex; margin-bottom: var(--space-2); - color: var(--color-text-4); + color: var(--c-text-subtle); } .sui-empty__eyebrow { @@ -22,14 +22,14 @@ font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; - color: var(--color-blue); + color: var(--c-primary); } .sui-empty__title { margin: 0; font-size: 1.125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .sui-empty--compact .sui-empty__title { @@ -41,7 +41,7 @@ max-width: 32rem; font-size: 0.875rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); } .sui-empty--compact .sui-empty__copy { diff --git a/frontend/editor/src/core/ui/FormField.css b/frontend/editor/src/core/ui/FormField.css index 0ae531bc65..f5cbe2d5fc 100644 --- a/frontend/editor/src/core/ui/FormField.css +++ b/frontend/editor/src/core/ui/FormField.css @@ -24,7 +24,7 @@ .sui-field__help { font-size: 0.6875rem; - color: var(--color-text-4); + color: var(--c-text-subtle); line-height: 1.45; } diff --git a/frontend/editor/src/core/ui/IconBadge.css b/frontend/editor/src/core/ui/IconBadge.css index aaca06f217..9aa3f8f46f 100644 --- a/frontend/editor/src/core/ui/IconBadge.css +++ b/frontend/editor/src/core/ui/IconBadge.css @@ -7,7 +7,7 @@ /* Resolved tint. Each accent class sets --ib-base; --ib-accent defaults to it but a consumer can override --ib-accent alone (e.g. to neutralise the badge until hover) without losing the per-accent base. */ - --ib-accent: var(--ib-base, var(--color-blue)); + --ib-accent: var(--ib-base, var(--c-primary)); color: var(--ib-accent); background: color-mix(in srgb, var(--ib-accent) 14%, transparent); } @@ -20,7 +20,7 @@ height: 2rem; } .sui-iconbadge--blue { - --ib-base: var(--color-blue); + --ib-base: var(--c-primary); } .sui-iconbadge--purple { --ib-base: var(--color-purple); @@ -38,6 +38,6 @@ --ib-base: var(--color-orange); } .sui-iconbadge--neutral { - --ib-base: var(--color-text-1); + --ib-base: var(--c-text); background: none; } diff --git a/frontend/editor/src/core/ui/Inline.stories.tsx b/frontend/editor/src/core/ui/Inline.stories.tsx index 10233e1371..5149f36018 100644 --- a/frontend/editor/src/core/ui/Inline.stories.tsx +++ b/frontend/editor/src/core/ui/Inline.stories.tsx @@ -29,7 +29,7 @@ export const SpaceBetween: Story = { style={{ width: "30rem", padding: 12, - border: "1px solid var(--color-border)", + border: "1px solid var(--c-border)", borderRadius: 8, }} > diff --git a/frontend/editor/src/core/ui/Input.css b/frontend/editor/src/core/ui/Input.css index 09a7ca0cda..3c68bdd8c5 100644 --- a/frontend/editor/src/core/ui/Input.css +++ b/frontend/editor/src/core/ui/Input.css @@ -3,18 +3,18 @@ align-items: center; gap: var(--space-2); padding: 0 var(--space-2); - background: var(--color-surface); - border: 1px solid var(--color-border-input); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-md); - color: var(--color-text-1); + color: var(--c-text); transition: border-color var(--motion-fast), box-shadow var(--motion-fast); } .sui-input:focus-within { - border-color: var(--color-blue); - box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-blue) 16%, transparent); + border-color: var(--c-primary); + box-shadow: 0 0 0 2px color-mix(in srgb, var(--c-primary) 16%, transparent); } .sui-input--sm { @@ -61,6 +61,6 @@ .sui-input__icon { display: inline-flex; align-items: center; - color: var(--color-text-4); + color: var(--c-text-subtle); flex-shrink: 0; } diff --git a/frontend/editor/src/core/ui/ListRow.css b/frontend/editor/src/core/ui/ListRow.css index 8317b76fc5..836dba4d8f 100644 --- a/frontend/editor/src/core/ui/ListRow.css +++ b/frontend/editor/src/core/ui/ListRow.css @@ -6,20 +6,20 @@ padding: 0.7rem 0.875rem; text-align: left; background: transparent; - color: var(--color-text-1); + color: var(--c-text); } .sui-listrow--divider { - border-top: 1px solid var(--color-border); + border-top: 1px solid var(--c-border); } .sui-listrow--interactive { cursor: pointer; transition: background var(--motion-fast); } .sui-listrow--interactive:hover { - background: var(--color-bg-hover); + background: var(--c-hover); } .sui-listrow--interactive:focus-visible { - outline: 0.125rem solid var(--color-blue); + outline: 0.125rem solid var(--c-primary); outline-offset: -0.125rem; } @@ -32,8 +32,8 @@ border-radius: var(--radius-md); flex-shrink: 0; margin-top: 0.05rem; - color: var(--color-text-4); - background: var(--color-bg-muted); + color: var(--c-text-subtle); + background: var(--c-surface-sunken); } .sui-listrow__leading[data-tone="success"] { color: var(--color-green); @@ -48,8 +48,8 @@ background: color-mix(in srgb, var(--color-red) 14%, transparent); } .sui-listrow__leading[data-tone="info"] { - color: var(--color-blue); - background: color-mix(in srgb, var(--color-blue) 14%, transparent); + color: var(--c-primary); + background: color-mix(in srgb, var(--c-primary) 14%, transparent); } .sui-listrow__leading[data-tone="purple"] { color: var(--color-purple); @@ -65,19 +65,19 @@ .sui-listrow__title { font-size: 0.8125rem; font-weight: 500; - color: var(--color-text-1); + color: var(--c-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .sui-listrow__desc { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); margin-top: 0.125rem; } .sui-listrow__meta { font-size: 0.6875rem; - color: var(--color-text-4); + color: var(--c-text-subtle); margin-top: 0.125rem; } .sui-listrow__trailing { diff --git a/frontend/editor/src/core/ui/MantineForms.css b/frontend/editor/src/core/ui/MantineForms.css index fb95e15c07..ebedf547f7 100644 --- a/frontend/editor/src/core/ui/MantineForms.css +++ b/frontend/editor/src/core/ui/MantineForms.css @@ -13,11 +13,11 @@ * here act as a typed reference and as a fallback for any slot Mantine reads * before the inline vars are applied. */ .sui-mantine-wrapper { - --input-bg: var(--color-surface); - --input-bd: var(--color-border-input); - --input-bd-focus: var(--color-blue); + --input-bg: var(--c-surface); + --input-bd: var(--c-border); + --input-bd-focus: var(--c-primary); --input-radius: var(--radius-md); - --input-color: var(--color-text-1); + --input-color: var(--c-text); --input-placeholder-color: var(--color-text-placeholder); --input-height-sm: 1.75rem; --input-height-md: 2.25rem; @@ -31,7 +31,7 @@ /* SUI focus ring — matches .sui-input:focus-within */ .sui-mantine-wrapper[data-focused], .sui-mantine-wrapper:focus-within { - box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-blue) 16%, transparent); + box-shadow: 0 0 0 2px color-mix(in srgb, var(--c-primary) 16%, transparent); } /* Error state */ @@ -54,9 +54,9 @@ /* ---- MultiSelect pills ---- */ /* Pills match SUI's Chip component: small rounded tags. */ .sui-mantine-pill { - background: var(--color-blue-light) !important; - color: var(--color-blue-dark) !important; - border: 1px solid var(--color-blue-border) !important; + background: var(--c-primary-tint) !important; + color: var(--c-primary-hover) !important; + border: 1px solid var(--c-primary-border) !important; border-radius: var(--radius-sm) !important; font-size: 0.75rem !important; font-weight: 500 !important; @@ -69,26 +69,26 @@ /* ---- NumberInput controls (increment/decrement buttons) ---- */ .sui-mantine-control { - border-color: var(--color-border-input) !important; - color: var(--color-text-3) !important; + border-color: var(--c-border) !important; + color: var(--c-text-subtle) !important; } .sui-mantine-control:hover { - background: var(--color-bg-hover) !important; - color: var(--color-text-1) !important; + background: var(--c-hover) !important; + color: var(--c-text) !important; } /* ---- Select: hide Mantine's right-section clear button border ---- */ .sui-mantine-wrapper .mantine-Select-section { - color: var(--color-text-3); + color: var(--c-text-subtle); } /* ---- Slider ---- */ .sui-mantine-slider { - --slider-color: var(--color-blue); - --slider-track-bg: var(--color-border); - --slider-thumb-color: var(--color-surface); - --slider-thumb-bd: var(--color-blue); + --slider-color: var(--c-primary); + --slider-track-bg: var(--c-border); + --slider-thumb-color: var(--c-surface); + --slider-thumb-bd: var(--c-primary); } .sui-mantine-slider:focus-within { @@ -97,13 +97,13 @@ /* Thumb focus ring matches SUI */ .sui-mantine-slider .mantine-Slider-thumb:focus-visible { - box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-blue) 16%, transparent); + box-shadow: 0 0 0 2px color-mix(in srgb, var(--c-primary) 16%, transparent); outline: none; } /* Mark labels use SUI text tokens */ .sui-mantine-slider .mantine-Slider-markLabel { - color: var(--color-text-3); + color: var(--c-text-subtle); font-size: 0.75rem; } @@ -112,7 +112,7 @@ * SuiProvider syncs forceColorScheme to SUI theme, so * [data-mantine-color-scheme="dark"] === [data-theme="dark"] in practice. ---- */ [data-mantine-color-scheme="dark"] .sui-mantine-wrapper { - --input-bg: var(--color-surface); - --input-bd: var(--color-border-input); - --input-color: var(--color-text-1); + --input-bg: var(--c-surface); + --input-bd: var(--c-border); + --input-color: var(--c-text); } diff --git a/frontend/editor/src/core/ui/MethodBadge.css b/frontend/editor/src/core/ui/MethodBadge.css index 75703b92d8..9b138ed389 100644 --- a/frontend/editor/src/core/ui/MethodBadge.css +++ b/frontend/editor/src/core/ui/MethodBadge.css @@ -10,14 +10,14 @@ line-height: 1.4; } .sui-method--get { - color: var(--color-green); + color: var(--color-green-dark); background: var(--color-green-light); border-color: var(--color-green-border); } .sui-method--post { - color: var(--color-blue); - background: var(--color-blue-light); - border-color: var(--color-blue-border); + color: var(--c-primary); + background: var(--c-primary-tint); + border-color: var(--c-primary-border); } .sui-method--put { color: var(--color-amber-dark); @@ -25,12 +25,12 @@ border-color: var(--color-amber-border); } .sui-method--patch { - color: var(--color-purple); + color: var(--color-purple-dark); background: var(--color-purple-light); border-color: var(--color-purple-border); } .sui-method--delete { - color: var(--color-red); + color: var(--color-red-dark); background: var(--color-red-light); border-color: var(--color-red-border); } diff --git a/frontend/editor/src/core/ui/MethodBadge.stories.tsx b/frontend/editor/src/core/ui/MethodBadge.stories.tsx index 9110ef9f06..6dd557ab82 100644 --- a/frontend/editor/src/core/ui/MethodBadge.stories.tsx +++ b/frontend/editor/src/core/ui/MethodBadge.stories.tsx @@ -23,7 +23,7 @@ export const InRow: Story = {
/v1/coi diff --git a/frontend/editor/src/core/ui/MetricCard.css b/frontend/editor/src/core/ui/MetricCard.css index 59c2b45000..8c7adfeb00 100644 --- a/frontend/editor/src/core/ui/MetricCard.css +++ b/frontend/editor/src/core/ui/MetricCard.css @@ -3,8 +3,8 @@ flex-direction: column; gap: 0.5rem; padding: 1.125rem 1.25rem; - background: var(--color-surface); - border: 1px solid var(--color-border); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); transition: @@ -36,12 +36,12 @@ cursor: pointer; } .sui-metric--interactive:hover { - border-color: var(--color-border-hover); + border-color: var(--c-border-strong); box-shadow: var(--shadow-lg); transform: translateY(-0.0625rem); } .sui-metric--interactive:focus-visible { - outline: 2px solid var(--color-blue); + outline: 2px solid var(--c-primary); outline-offset: 2px; } @@ -53,18 +53,18 @@ } .sui-metric__label { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); font-weight: 500; letter-spacing: 0.01em; } .sui-metric__icon { - color: var(--color-text-5); + color: var(--c-text-subtle); display: inline-flex; } .sui-metric__value { font-size: 1.625rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); line-height: 1.1; } .sui-metric__footer { @@ -88,9 +88,7 @@ .sui-metric__delta--down { color: var(--color-red); } -.sui-metric__delta--flat { - color: var(--color-text-5); -} +.sui-metric__delta--flat, .sui-metric__desc { - color: var(--color-text-4); + color: var(--c-text-subtle); } diff --git a/frontend/editor/src/core/ui/Modal.css b/frontend/editor/src/core/ui/Modal.css index a3d081b42d..2773585415 100644 --- a/frontend/editor/src/core/ui/Modal.css +++ b/frontend/editor/src/core/ui/Modal.css @@ -1,7 +1,7 @@ .sui-modal__backdrop { position: fixed; inset: 0; - background: rgba(15, 23, 42, 0.55); + background: rgba(0, 0, 0, 0.55); display: flex; align-items: flex-start; justify-content: center; @@ -15,12 +15,12 @@ /* Set our own font: the modal portals to , so it can't inherit the app's font through the DOM (the portal's .portal-scope isn't an ancestor). */ font-family: var(--font-sans); - background: var(--color-surface); - border: 1px solid var(--color-border); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-xl); box-shadow: - 0 1.25rem 3rem rgba(15, 23, 42, 0.35), - 0 0 0 1px var(--color-border-light); + 0 1.25rem 3rem rgba(0, 0, 0, 0.35), + 0 0 0 1px var(--c-border-subtle); display: flex; flex-direction: column; width: 100%; @@ -59,7 +59,7 @@ align-items: flex-start; gap: 0.75rem; padding: 1rem 1.125rem 0.75rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .sui-modal__header-text { @@ -70,13 +70,13 @@ .sui-modal__title { font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .sui-modal__sub { margin-top: 0.125rem; font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Sizing/background/hover are owned by the Button; this just keeps it from @@ -89,12 +89,12 @@ flex: 1 1 auto; overflow-y: auto; padding: 1rem 1.125rem 1.125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .sui-modal__footer { padding: 0.875rem 1.125rem; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); display: flex; justify-content: flex-end; gap: 0.5rem; diff --git a/frontend/editor/src/core/ui/MultiSelect.tsx b/frontend/editor/src/core/ui/MultiSelect.tsx index 31ac9544f8..0d2ab92ad8 100644 --- a/frontend/editor/src/core/ui/MultiSelect.tsx +++ b/frontend/editor/src/core/ui/MultiSelect.tsx @@ -8,11 +8,11 @@ import { useInputAria } from "@app/ui/ariaForwarding"; import "@app/ui/MantineForms.css"; const SUI_INPUT_VARS = { - "--input-bg": "var(--color-surface)", - "--input-bd": "var(--color-border-input)", - "--input-bd-focus": "var(--color-blue)", + "--input-bg": "var(--c-surface)", + "--input-bd": "var(--c-border)", + "--input-bd-focus": "var(--c-primary)", "--input-radius": "var(--radius-md)", - "--input-color": "var(--color-text-1)", + "--input-color": "var(--c-text)", "--input-placeholder-color": "var(--color-text-placeholder)", "--input-height-sm": "1.75rem", "--input-height-md": "2.25rem", diff --git a/frontend/editor/src/core/ui/NavItem.css b/frontend/editor/src/core/ui/NavItem.css index 982abbc26b..8b9949eab5 100644 --- a/frontend/editor/src/core/ui/NavItem.css +++ b/frontend/editor/src/core/ui/NavItem.css @@ -6,7 +6,7 @@ padding: 0.4375rem 0.75rem; margin: 0.0625rem 0.5rem; border-radius: var(--radius-lg); - color: var(--color-nav-text); + color: var(--c-text-subtle); font-size: 0.8125rem; font-weight: 400; transition: @@ -15,16 +15,16 @@ text-align: left; } .sui-navitem:hover { - background: var(--color-nav-hover); - color: var(--color-nav-hover-text); + background: var(--c-hover); + color: var(--c-text-muted); } .sui-navitem.is-active { - background: var(--color-nav-active); - color: var(--color-nav-active-text); + background: var(--c-primary-subtle); + color: var(--c-accent-fg); font-weight: 500; } .sui-navitem.is-active:hover { - background: var(--color-nav-active); + background: var(--c-primary-subtle); } .sui-navitem__icon { width: 1rem; @@ -43,7 +43,7 @@ margin-left: auto; } .sui-navitem:focus-visible { - outline: 0.125rem solid var(--color-blue); + outline: 0.125rem solid var(--c-primary); outline-offset: 0.125rem; } @@ -61,7 +61,7 @@ border-radius: 3px; } .sui-navitem[data-accent="blue"]::before { - background: var(--color-blue); + background: var(--c-primary); } .sui-navitem[data-accent="purple"]::before { background: var(--color-purple); @@ -76,7 +76,7 @@ background: var(--color-red); } .sui-navitem[data-accent="blue"] .sui-navitem__icon { - color: var(--color-blue); + color: var(--c-primary); } .sui-navitem[data-accent="purple"] .sui-navitem__icon { color: var(--color-purple); diff --git a/frontend/editor/src/core/ui/NavItem.stories.tsx b/frontend/editor/src/core/ui/NavItem.stories.tsx index 7ceb981d79..52d74138bc 100644 --- a/frontend/editor/src/core/ui/NavItem.stories.tsx +++ b/frontend/editor/src/core/ui/NavItem.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { NavItem } from "@app/ui/NavItem"; import { SectionDivider } from "@app/ui/SectionDivider"; -function Dot({ color = "var(--color-blue)" }: { color?: string }) { +function Dot({ color = "var(--c-primary)" }: { color?: string }) { return ( = {
@@ -55,8 +55,8 @@ export const WithTrailingBadge: Story = { @@ -75,8 +75,8 @@ export const InContext_UsageMeter: Story = { marginBottom: 6, }} > - Docs processed - + Docs processed + 412 / 500
diff --git a/frontend/editor/src/core/ui/ProgressBar.tsx b/frontend/editor/src/core/ui/ProgressBar.tsx index 570fc43099..e6ca30c0e1 100644 --- a/frontend/editor/src/core/ui/ProgressBar.tsx +++ b/frontend/editor/src/core/ui/ProgressBar.tsx @@ -45,10 +45,10 @@ export function ProgressBar({ ? "linear-gradient(90deg, var(--color-red), color-mix(in srgb, var(--color-red) 70%, white))" : v >= 0.8 ? "linear-gradient(90deg, var(--color-amber), color-mix(in srgb, var(--color-amber) 70%, white))" - : "linear-gradient(90deg, var(--color-blue), color-mix(in srgb, var(--color-blue) 70%, white))"; + : "linear-gradient(90deg, var(--c-primary), color-mix(in srgb, var(--c-primary) 70%, white))"; } else { fill = - "linear-gradient(90deg, var(--color-blue), color-mix(in srgb, var(--color-blue) 70%, white))"; + "linear-gradient(90deg, var(--c-primary), color-mix(in srgb, var(--c-primary) 70%, white))"; } } return ( diff --git a/frontend/editor/src/core/ui/Radio.css b/frontend/editor/src/core/ui/Radio.css index 162d0a9d5e..7000c12219 100644 --- a/frontend/editor/src/core/ui/Radio.css +++ b/frontend/editor/src/core/ui/Radio.css @@ -17,7 +17,7 @@ gap: var(--space-2); cursor: pointer; font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .sui-radio--disabled { opacity: 0.5; @@ -37,8 +37,8 @@ height: 1rem; margin-top: 0.0625rem; border-radius: 50%; - border: 1.5px solid var(--color-border-hover); - background: var(--color-surface); + border: 1.5px solid var(--c-border-strong); + background: var(--c-surface); display: inline-flex; align-items: center; justify-content: center; @@ -47,12 +47,12 @@ } .sui-radio__input:focus-visible + .sui-radio__dot { - outline: 2px solid var(--color-blue); + outline: 2px solid var(--c-primary); outline-offset: 2px; } .sui-radio__input:checked + .sui-radio__dot { - border-color: var(--color-blue); + border-color: var(--c-primary); } .sui-radio__input:checked + .sui-radio__dot::after { @@ -60,7 +60,7 @@ width: 0.5rem; height: 0.5rem; border-radius: 50%; - background: var(--color-blue); + background: var(--c-primary); } .sui-radio__text { @@ -68,10 +68,10 @@ flex-direction: column; } .sui-radio__label { - color: var(--color-text-1); + color: var(--c-text); font-weight: 500; } .sui-radio__desc { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } diff --git a/frontend/editor/src/core/ui/SectionDivider.css b/frontend/editor/src/core/ui/SectionDivider.css index 8999f6f0a3..ddfa8f0363 100644 --- a/frontend/editor/src/core/ui/SectionDivider.css +++ b/frontend/editor/src/core/ui/SectionDivider.css @@ -1,5 +1,5 @@ .sui-divider { height: 0.0625rem; - background: var(--color-sidebar-divider); + background: var(--c-border-subtle); width: 100%; } diff --git a/frontend/editor/src/core/ui/SectionDivider.stories.tsx b/frontend/editor/src/core/ui/SectionDivider.stories.tsx index 8cd433e83a..dd758dfd39 100644 --- a/frontend/editor/src/core/ui/SectionDivider.stories.tsx +++ b/frontend/editor/src/core/ui/SectionDivider.stories.tsx @@ -13,9 +13,9 @@ type Story = StoryObj; export const Default: Story = { render: () => (
-

Section above

+

Section above

-

Section below

+

Section below

), }; @@ -25,11 +25,11 @@ export const InContext_SidebarGroups: Story = {
diff --git a/frontend/editor/src/core/ui/SectionHeader.css b/frontend/editor/src/core/ui/SectionHeader.css index 63a354cc23..8a534d09a1 100644 --- a/frontend/editor/src/core/ui/SectionHeader.css +++ b/frontend/editor/src/core/ui/SectionHeader.css @@ -17,14 +17,14 @@ button.sui-sectionhdr { font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; - color: var(--color-text-4); + color: var(--c-text-subtle); } .sui-sectionhdr__count { font-size: 0.6875rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .sui-sectionhdr__chevron { - color: var(--color-text-4); + color: var(--c-text-subtle); flex-shrink: 0; transition: transform var(--motion-fast); } diff --git a/frontend/editor/src/core/ui/Select.css b/frontend/editor/src/core/ui/Select.css index b01cf2ecd1..7ced297651 100644 --- a/frontend/editor/src/core/ui/Select.css +++ b/frontend/editor/src/core/ui/Select.css @@ -2,18 +2,18 @@ position: relative; display: inline-flex; align-items: center; - background: var(--color-surface); - border: 1px solid var(--color-border-input); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-md); - color: var(--color-text-1); + color: var(--c-text); transition: border-color var(--motion-fast), box-shadow var(--motion-fast); } .sui-select:focus-within { - border-color: var(--color-blue); - box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-blue) 16%, transparent); + border-color: var(--c-primary); + box-shadow: 0 0 0 2px color-mix(in srgb, var(--c-primary) 16%, transparent); } .sui-select--sm { @@ -53,8 +53,8 @@ * select's color-scheme to the active SUI theme so the popup is always legible. */ .sui-select__el option { - background-color: var(--color-surface); - color: var(--color-text-1); + background-color: var(--c-surface); + color: var(--c-text); } [data-theme="dark"] .sui-select__el { color-scheme: dark; @@ -75,5 +75,5 @@ display: inline-flex; align-items: center; pointer-events: none; - color: var(--color-text-4); + color: var(--c-text-subtle); } diff --git a/frontend/editor/src/core/ui/Select.tsx b/frontend/editor/src/core/ui/Select.tsx index fa2d5346b7..242ddf9740 100644 --- a/frontend/editor/src/core/ui/Select.tsx +++ b/frontend/editor/src/core/ui/Select.tsx @@ -7,11 +7,11 @@ import { useInputAria } from "@app/ui/ariaForwarding"; import "@app/ui/MantineForms.css"; const SUI_INPUT_VARS = { - "--input-bg": "var(--color-surface)", - "--input-bd": "var(--color-border-input)", - "--input-bd-focus": "var(--color-blue)", + "--input-bg": "var(--c-surface)", + "--input-bd": "var(--c-border)", + "--input-bd-focus": "var(--c-primary)", "--input-radius": "var(--radius-md)", - "--input-color": "var(--color-text-1)", + "--input-color": "var(--c-text)", "--input-placeholder-color": "var(--color-text-placeholder)", "--input-height-sm": "1.75rem", "--input-height-md": "2.25rem", diff --git a/frontend/editor/src/core/ui/SettingsRow.css b/frontend/editor/src/core/ui/SettingsRow.css index f374a5fdab..18d707c489 100644 --- a/frontend/editor/src/core/ui/SettingsRow.css +++ b/frontend/editor/src/core/ui/SettingsRow.css @@ -13,11 +13,11 @@ .sui-settingsrow__label { font-size: 0.8125rem; font-weight: 500; - color: var(--color-text-1); + color: var(--c-text); } .sui-settingsrow__desc { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); margin-top: 0.125rem; } .sui-settingsrow__control { diff --git a/frontend/editor/src/core/ui/SettingsRow.stories.tsx b/frontend/editor/src/core/ui/SettingsRow.stories.tsx index 4527ef2689..792171942b 100644 --- a/frontend/editor/src/core/ui/SettingsRow.stories.tsx +++ b/frontend/editor/src/core/ui/SettingsRow.stories.tsx @@ -48,7 +48,7 @@ export const List: Story = { key={r.label} style={{ padding: "0.7rem 0.875rem", - borderTop: i > 0 ? "1px solid var(--color-border)" : undefined, + borderTop: i > 0 ? "1px solid var(--c-border)" : undefined, }} > { const [active, setActive] = useState("profile"); return ( -
+
} > -

+

Content for the “{LABELS[active]}” section renders here.

diff --git a/frontend/editor/src/core/ui/Skeleton.css b/frontend/editor/src/core/ui/Skeleton.css index 98da3c7dbe..42dccfb5be 100644 --- a/frontend/editor/src/core/ui/Skeleton.css +++ b/frontend/editor/src/core/ui/Skeleton.css @@ -2,9 +2,9 @@ display: inline-block; background: linear-gradient( 90deg, - var(--color-bg-muted) 0%, - var(--color-bg-hover) 50%, - var(--color-bg-muted) 100% + var(--c-surface-sunken) 0%, + var(--c-hover) 50%, + var(--c-surface-sunken) 100% ); background-size: 200% 100%; animation: shimmer 1.4s linear infinite; diff --git a/frontend/editor/src/core/ui/Slider.css b/frontend/editor/src/core/ui/Slider.css index 005ca0cbba..7be91a36c6 100644 --- a/frontend/editor/src/core/ui/Slider.css +++ b/frontend/editor/src/core/ui/Slider.css @@ -17,10 +17,10 @@ border-radius: var(--radius-pill); background: linear-gradient( 90deg, - var(--color-blue) 0%, - var(--color-blue) var(--slider-pct), - var(--color-bg-muted) var(--slider-pct), - var(--color-bg-muted) 100% + var(--c-primary) 0%, + var(--c-primary) var(--slider-pct), + var(--c-surface-sunken) var(--slider-pct), + var(--c-surface-sunken) 100% ); outline: none; } @@ -32,7 +32,7 @@ height: 1rem; border-radius: 50%; background: #fff; - border: 2px solid var(--color-blue); + border: 2px solid var(--c-primary); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); cursor: pointer; transition: transform var(--motion-fast); @@ -43,13 +43,13 @@ height: 1rem; border-radius: 50%; background: #fff; - border: 2px solid var(--color-blue); + border: 2px solid var(--c-primary); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); cursor: pointer; } .sui-slider__input:focus-visible::-webkit-slider-thumb { - outline: 2px solid var(--color-blue); + outline: 2px solid var(--c-primary); outline-offset: 2px; } @@ -64,5 +64,5 @@ font-family: var(--font-mono); font-size: 0.75rem; font-weight: 500; - color: var(--color-text-2); + color: var(--c-text-muted); } diff --git a/frontend/editor/src/core/ui/Spinner.stories.tsx b/frontend/editor/src/core/ui/Spinner.stories.tsx index 9435ffec3a..f2bc56a9ac 100644 --- a/frontend/editor/src/core/ui/Spinner.stories.tsx +++ b/frontend/editor/src/core/ui/Spinner.stories.tsx @@ -31,7 +31,7 @@ export const SizeRow: Story = { export const InheritsColor: Story = { render: () => (
- + diff --git a/frontend/editor/src/core/ui/Stack.stories.tsx b/frontend/editor/src/core/ui/Stack.stories.tsx index d35a40928c..20f6948632 100644 --- a/frontend/editor/src/core/ui/Stack.stories.tsx +++ b/frontend/editor/src/core/ui/Stack.stories.tsx @@ -17,7 +17,7 @@ function Box({ children }: { children: React.ReactNode }) {
{(["1", "2", "4", "6"] as const).map((gap) => ( -
+
gap {gap}
A @@ -59,7 +59,7 @@ export const InCard: Story = {
Card title
-
+
Stack is the default vertical container — it's how you compose every card body, list, and form section.
diff --git a/frontend/editor/src/core/ui/StatTile.css b/frontend/editor/src/core/ui/StatTile.css index c29455fc72..0fdc22c8ca 100644 --- a/frontend/editor/src/core/ui/StatTile.css +++ b/frontend/editor/src/core/ui/StatTile.css @@ -9,14 +9,14 @@ font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--color-text-5); + color: var(--c-text-subtle); font-weight: 600; } .sui-stat__value { font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); font-variant-numeric: tabular-nums; } @@ -34,6 +34,6 @@ .sui-stat__value code { font-family: var(--font-mono); font-size: 0.75rem; - color: var(--color-text-2); + color: var(--c-text-muted); word-break: break-all; } diff --git a/frontend/editor/src/core/ui/StatusBadge.css b/frontend/editor/src/core/ui/StatusBadge.css index 62f6fb0f3a..230c99b40d 100644 --- a/frontend/editor/src/core/ui/StatusBadge.css +++ b/frontend/editor/src/core/ui/StatusBadge.css @@ -8,15 +8,15 @@ letter-spacing: 0.01em; border: 1px solid transparent; line-height: 1; - color: var(--sui-status-c, var(--color-text-3)); + color: var(--sui-status-c, var(--c-text-subtle)); background: color-mix( in srgb, - var(--sui-status-c, var(--color-text-3)) 12%, + var(--sui-status-c, var(--c-text-subtle)) 12%, transparent ); border-color: color-mix( in srgb, - var(--sui-status-c, var(--color-text-3)) 28%, + var(--sui-status-c, var(--c-text-subtle)) 28%, transparent ); } @@ -51,9 +51,9 @@ /* Neutral keeps the plain muted surface rather than an accent tint. */ .sui-status--neutral { - color: var(--color-text-3); - background: var(--color-bg-muted); - border-color: var(--color-border-light); + color: var(--c-text-subtle); + background: var(--c-surface-sunken); + border-color: var(--c-border-subtle); } /* Tones only pick the accent; the base rule builds the fill + border. `-dark` is theme-adaptive, so text stays legible on the pale fill in both themes. */ @@ -67,7 +67,7 @@ --sui-status-c: var(--color-red-dark); } .sui-status--info { - --sui-status-c: var(--color-blue-dark); + --sui-status-c: var(--c-primary-hover); } .sui-status--purple { --sui-status-c: var(--color-purple-dark); diff --git a/frontend/editor/src/core/ui/StepIndicator.css b/frontend/editor/src/core/ui/StepIndicator.css index d5d46e7bd5..8c364d9c56 100644 --- a/frontend/editor/src/core/ui/StepIndicator.css +++ b/frontend/editor/src/core/ui/StepIndicator.css @@ -6,7 +6,7 @@ .sui-steps__bar { flex: 1; border-radius: 999px; - background: var(--color-border); + background: var(--c-border); transition: background var(--motion-fast); } .sui-steps--md .sui-steps__bar { @@ -17,11 +17,11 @@ } /* Completed steps: solid accent. */ .sui-steps__bar[data-state="done"] { - background: var(--color-blue); + background: var(--c-primary); } /* Current step: solid accent + a soft ring so it reads as "you are here". */ .sui-steps__bar[data-state="current"] { - background: var(--color-blue); + background: var(--c-primary); box-shadow: 0 0 0 0.1875rem - color-mix(in srgb, var(--color-blue) 22%, transparent); + color-mix(in srgb, var(--c-primary) 22%, transparent); } diff --git a/frontend/editor/src/core/ui/Table.css b/frontend/editor/src/core/ui/Table.css index 3b17a6c44d..696bbc8afb 100644 --- a/frontend/editor/src/core/ui/Table.css +++ b/frontend/editor/src/core/ui/Table.css @@ -1,9 +1,9 @@ .sui-table-wrap { width: 100%; overflow-x: auto; - border: 1px solid var(--color-border); + border: 1px solid var(--c-border); border-radius: var(--radius-md); - background: var(--color-surface); + background: var(--c-surface); } .sui-table { @@ -15,12 +15,12 @@ .sui-table__th { text-align: left; font-weight: 600; - color: var(--color-text-4); + color: var(--c-text-subtle); font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em; padding: 0.625rem 0.875rem; - border-bottom: 1px solid var(--color-border); + border-bottom: 1px solid var(--c-border); white-space: nowrap; } .sui-table__th--right, @@ -34,8 +34,8 @@ .sui-table__td { padding: 0.625rem 0.875rem; - color: var(--color-text-2); - border-bottom: 1px solid var(--color-border-light); + color: var(--c-text-muted); + border-bottom: 1px solid var(--c-border-subtle); vertical-align: middle; } .sui-table tbody tr:last-child .sui-table__td { @@ -47,15 +47,15 @@ transition: background var(--motion-fast); } .sui-table__row--interactive:hover { - background: var(--color-bg-hover); + background: var(--c-hover); } .sui-table__row--interactive:focus-visible { - outline: 0.125rem solid var(--color-blue); + outline: 0.125rem solid var(--c-primary); outline-offset: -0.125rem; } .sui-table__empty { padding: 2rem; text-align: center; - color: var(--color-text-4); + color: var(--c-text-subtle); } diff --git a/frontend/editor/src/core/ui/Tabs.css b/frontend/editor/src/core/ui/Tabs.css index b9dd365fc7..9fa18ce5b4 100644 --- a/frontend/editor/src/core/ui/Tabs.css +++ b/frontend/editor/src/core/ui/Tabs.css @@ -7,7 +7,7 @@ .sui-tabs--pill { } .sui-tabs--underline { - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); padding-bottom: var(--space-1); gap: var(--space-3); } @@ -18,7 +18,7 @@ gap: var(--space-1_5); padding: var(--space-1_5) var(--space-3); font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); background: transparent; border: 1px solid transparent; transition: @@ -28,8 +28,8 @@ } .sui-tabs__tab:hover:not(.is-disabled) { - color: var(--color-text-1); - background: var(--color-bg-hover); + color: var(--c-text); + background: var(--c-hover); } .sui-tabs__tab.is-disabled { @@ -42,9 +42,9 @@ border-radius: var(--radius-pill); } .sui-tabs--pill .sui-tabs__tab.is-active { - color: var(--sui-tab-accent, var(--color-blue)); - background: var(--color-blue-light); - border-color: var(--sui-tab-accent, var(--color-blue-border)); + color: var(--sui-tab-accent, var(--c-primary)); + background: var(--c-primary-tint); + border-color: var(--sui-tab-accent, var(--c-primary-border)); font-weight: 500; } @@ -56,8 +56,8 @@ margin-bottom: -1px; } .sui-tabs--underline .sui-tabs__tab.is-active { - color: var(--sui-tab-accent, var(--color-blue)); - border-bottom-color: var(--sui-tab-accent, var(--color-blue)); + color: var(--sui-tab-accent, var(--c-primary)); + border-bottom-color: var(--sui-tab-accent, var(--c-primary)); font-weight: 500; } @@ -69,7 +69,7 @@ .sui-tabs__count { font-size: 0.6875rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } .sui-tabs__tab.is-active .sui-tabs__count { diff --git a/frontend/editor/src/core/ui/Toast.css b/frontend/editor/src/core/ui/Toast.css index a1ca3a67bf..eff290522d 100644 --- a/frontend/editor/src/core/ui/Toast.css +++ b/frontend/editor/src/core/ui/Toast.css @@ -16,8 +16,8 @@ align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4); - background: var(--color-surface); - border: 1px solid var(--color-border); + background: var(--c-surface); + border: 1px solid var(--c-border); border-left-width: 3px; border-radius: var(--radius-md); box-shadow: var(--shadow-lg); @@ -25,7 +25,7 @@ } .sui-toast--info { - border-left-color: var(--color-blue); + border-left-color: var(--c-primary); } .sui-toast--success { border-left-color: var(--color-green); @@ -44,10 +44,10 @@ } .sui-toast__title { font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .sui-toast__desc { - color: var(--color-text-3); + color: var(--c-text-subtle); margin-top: 0.125rem; line-height: 1.45; } diff --git a/frontend/editor/src/core/ui/ToggleSwitch.css b/frontend/editor/src/core/ui/ToggleSwitch.css index f5025ebfbe..1b6aa90528 100644 --- a/frontend/editor/src/core/ui/ToggleSwitch.css +++ b/frontend/editor/src/core/ui/ToggleSwitch.css @@ -34,7 +34,7 @@ transition: transform var(--motion-base); } .sui-toggle input:checked + .sui-toggle__track { - background: var(--color-blue); + background: var(--c-primary); } .sui-toggle input:checked + .sui-toggle__track .sui-toggle__thumb { transform: translateX(1rem); @@ -65,14 +65,14 @@ .sui-toggle__label { font-size: 0.8125rem; font-weight: 500; - color: var(--color-text-2); + color: var(--c-text-muted); } .sui-toggle__desc { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .sui-toggle input:focus-visible + .sui-toggle__track { - outline: 2px solid var(--color-blue); + outline: 2px solid var(--c-primary); outline-offset: 2px; } diff --git a/frontend/editor/src/core/ui/accents.css b/frontend/editor/src/core/ui/accents.css index 1d47b4ec89..404f98cc52 100644 --- a/frontend/editor/src/core/ui/accents.css +++ b/frontend/editor/src/core/ui/accents.css @@ -2,24 +2,26 @@ * accents derive from --color-* tokens (auto dark), neutral/brand/ai are explicit. */ .sui-acc-default { - --_solid: var(--color-blue); - --_solid-hover: var(--color-blue-dark); + --_solid: var(--c-primary); + --_solid-hover: var(--c-primary-hover); --_on: #ffffff; - --_text: var(--color-blue-dark); - --_bd: var(--color-blue-border); - --_tint: color-mix(in srgb, var(--color-blue) 12%, transparent); + --_text: var(--c-primary-hover); + --_bd: color-mix(in srgb, var(--c-primary) 38%, var(--c-surface)); + --_tint: color-mix(in srgb, var(--c-primary) 12%, transparent); } html[data-app-theme="custom"] .sui-acc-default { --_on: var(--c-text-on-primary); } +/* Danger is pinned to a fixed deep red (not the theme-lightened coral), so the + fill and the outline/text are the SAME red in both light and dark. */ .sui-acc-danger { - --_solid: var(--color-red); - --_solid-hover: var(--color-red-dark); + --_solid: var(--p-red-500); + --_solid-hover: var(--p-red-600); --_on: #ffffff; - --_text: var(--color-red-dark); - --_bd: var(--color-red-border); - --_tint: color-mix(in srgb, var(--color-red) 12%, transparent); + --_text: var(--p-red-500); + --_bd: color-mix(in srgb, var(--p-red-500) 45%, transparent); + --_tint: color-mix(in srgb, var(--p-red-500) 12%, transparent); } .sui-acc-success { --_solid: var(--color-green); @@ -49,57 +51,57 @@ html[data-app-theme="custom"] .sui-acc-default { /* neutral: low-emphasis grey — no palette token, so explicit. */ .sui-acc-neutral { - --_solid: #475569; - --_solid-hover: #334155; + --_solid: var(--p-c-475569); + --_solid-hover: var(--p-c-334155); --_on: #ffffff; - --_text: #475569; - --_bd: #cbd5e1; - --_tint: rgba(71, 85, 105, 0.1); + --_text: var(--p-c-475569); + --_bd: var(--p-c-cbd5e1); + --_tint: color-mix(in srgb, var(--p-c-475569) 10%, transparent); } [data-theme="dark"] .sui-acc-neutral { - --_solid: #64748b; - --_solid-hover: #475569; - --_text: #cbd5e1; - --_bd: #334155; - --_tint: rgba(148, 163, 184, 0.16); + --_solid: var(--p-c-64748b); + --_solid-hover: var(--p-c-475569); + --_text: var(--p-c-cbd5e1); + --_bd: var(--p-c-334155); + --_tint: color-mix(in srgb, var(--p-c-94a3b8) 16%, transparent); } /* brand: Stirling red — a bespoke brand colour, not part of the token palette. */ .sui-acc-brand { - --_solid: #8e3131; - --_solid-hover: #7a2929; + --_solid: var(--p-brand-red-650); + --_solid-hover: var(--p-brand-red-700); --_on: #ffffff; - --_text: #8e3131; - --_bd: #d9a8a8; - --_tint: rgba(142, 49, 49, 0.09); + --_text: var(--p-brand-red-650); + --_bd: var(--p-brand-red-200); + --_tint: color-mix(in srgb, var(--p-brand-red-650) 9%, transparent); } [data-theme="dark"] .sui-acc-brand { - --_text: #d98a8a; - --_bd: #5a2424; - --_tint: rgba(217, 138, 138, 0.16); + --_text: var(--p-brand-red-300); + --_bd: var(--p-brand-red-900); + --_tint: color-mix(in srgb, var(--p-brand-red-300) 16%, transparent); } /* ai: multi-hue gradient for AI features — no single-colour token. */ .sui-acc-ai { --_solid: linear-gradient( 135deg, - #8b5cf6 0%, - #6366f1 38%, - #3b82f6 72%, - #22d3ee 100% + var(--p-violet-500) 0%, + var(--p-indigo-500) 38%, + var(--p-blue-500) 72%, + var(--p-cyan-400) 100% ); --_solid-hover: linear-gradient( 135deg, - #8b5cf6 0%, - #6366f1 38%, - #3b82f6 72%, - #22d3ee 100% + var(--p-violet-500) 0%, + var(--p-indigo-500) 38%, + var(--p-blue-500) 72%, + var(--p-cyan-400) 100% ); --_on: #ffffff; - --_text: #6366f1; - --_bd: #c7d2fe; - --_tint: rgba(99, 102, 241, 0.1); + --_text: var(--p-indigo-500); + --_bd: var(--p-indigo-200); + --_tint: color-mix(in srgb, var(--p-indigo-500) 10%, transparent); } [data-theme="dark"] .sui-acc-ai { - --_text: #a5b4fc; - --_bd: #3730a3; - --_tint: rgba(129, 140, 248, 0.18); + --_text: var(--p-indigo-300); + --_bd: var(--p-indigo-800); + --_tint: color-mix(in srgb, var(--p-indigo-400) 18%, transparent); } diff --git a/frontend/editor/src/desktop/components/DesktopOnboardingModal.tsx b/frontend/editor/src/desktop/components/DesktopOnboardingModal.tsx index 96bddff2af..4f9222c2b0 100644 --- a/frontend/editor/src/desktop/components/DesktopOnboardingModal.tsx +++ b/frontend/editor/src/desktop/components/DesktopOnboardingModal.tsx @@ -15,7 +15,10 @@ import { connectionModeService } from "@app/services/connectionModeService"; const ONBOARDING_KEY = "stirling-desktop-onboarding-seen"; -const SIGN_IN_GRADIENT: [string, string] = ["#3B82F6", "#7C3AED"]; +const SIGN_IN_GRADIENT: [string, string] = [ + "var(--c-hue-blue)", + "var(--c-hue-violet)", +]; /** * Desktop-specific onboarding modal. @@ -76,7 +79,7 @@ export function DesktopOnboardingModal() { content: { overflow: "hidden", border: "none", - background: "var(--bg-surface)", + background: "var(--c-surface)", maxHeight: "90vh", display: "flex", flexDirection: "column", @@ -158,7 +161,7 @@ export function DesktopOnboardingModal() {
{welcomeSlide.body}
- +
diff --git a/frontend/editor/src/desktop/components/SetupWizard/desktopOAuth.css b/frontend/editor/src/desktop/components/SetupWizard/desktopOAuth.css index 55ab193a4c..3483c3563a 100644 --- a/frontend/editor/src/desktop/components/SetupWizard/desktopOAuth.css +++ b/frontend/editor/src/desktop/components/SetupWizard/desktopOAuth.css @@ -30,7 +30,7 @@ } .oauth-button-vertical-desktop:hover:not(:disabled) { - background-color: var(--bg-raised); + background-color: var(--c-surface-raised); } .oauth-button-vertical-desktop:disabled { diff --git a/frontend/editor/src/desktop/components/tools/toolPicker/ToolPickerFooterExtensions.tsx b/frontend/editor/src/desktop/components/tools/toolPicker/ToolPickerFooterExtensions.tsx index 1dc41e9497..d573f189af 100644 --- a/frontend/editor/src/desktop/components/tools/toolPicker/ToolPickerFooterExtensions.tsx +++ b/frontend/editor/src/desktop/components/tools/toolPicker/ToolPickerFooterExtensions.tsx @@ -40,8 +40,8 @@ export function ToolPickerFooterExtensions() { px="sm" py={10} style={{ - borderTop: "1px solid var(--border-default)", - background: "var(--bg-toolbar)", + borderTop: "1px solid var(--c-border)", + background: "var(--c-bg-raised)", flexShrink: 0, }} > diff --git a/frontend/editor/src/desktop/routes/login/LoginHeader.tsx b/frontend/editor/src/desktop/routes/login/LoginHeader.tsx index fc715e6696..1b7900956e 100644 --- a/frontend/editor/src/desktop/routes/login/LoginHeader.tsx +++ b/frontend/editor/src/desktop/routes/login/LoginHeader.tsx @@ -63,7 +63,7 @@ export default function LoginHeader({ aria-label={t("common.close", "Close")} style={{ flexShrink: 0, - color: "var(--text-secondary)", + color: "var(--c-text-muted)", outline: "none", }} > diff --git a/frontend/editor/src/output.css b/frontend/editor/src/output.css index c77b20bc87..09e3931f55 100644 --- a/frontend/editor/src/output.css +++ b/frontend/editor/src/output.css @@ -1,362 +1,375 @@ -*, ::before, ::after { - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; - --tw-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: +*, +::before, +::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: +; } ::backdrop { - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; - --tw-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: +; } .mb-3 { - margin-bottom: 0.75rem + margin-bottom: 0.75rem; } .mb-4 { - margin-bottom: 1rem + margin-bottom: 1rem; } .mr-2 { - margin-right: 0.5rem + margin-right: 0.5rem; } .mt-2 { - margin-top: 0.5rem + margin-top: 0.5rem; } .mt-4 { - margin-top: 1rem + margin-top: 1rem; } .block { - display: block + display: block; } .flex { - display: flex + display: flex; } .hidden { - display: none + display: none; } .h-6 { - height: 1.5rem + height: 1.5rem; } .h-full { - height: 100% + height: 100%; } .h-screen { - height: 100vh + height: 100vh; } .w-6 { - width: 1.5rem + width: 1.5rem; } .w-64 { - width: 16rem + width: 16rem; } .w-72 { - width: 18rem + width: 18rem; } .w-full { - width: 100% + width: 100%; } .max-w-3xl { - max-width: 48rem + max-width: 48rem; } .flex-1 { - flex: 1 1 0% + flex: 1 1 0%; } .cursor-pointer { - cursor: pointer + cursor: pointer; } .list-disc { - list-style-type: disc + list-style-type: disc; } .flex-col { - flex-direction: column + flex-direction: column; } .items-center { - align-items: center + align-items: center; } .justify-center { - justify-content: center + justify-content: center; } .justify-between { - justify-content: space-between + justify-content: space-between; } .space-x-2 > :not([hidden]) ~ :not([hidden]) { - --tw-space-x-reverse: 0; - margin-right: calc(0.5rem * var(--tw-space-x-reverse)); - margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))) + --tw-space-x-reverse: 0; + margin-right: calc(0.5rem * var(--tw-space-x-reverse)); + margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); } .space-x-3 > :not([hidden]) ~ :not([hidden]) { - --tw-space-x-reverse: 0; - margin-right: calc(0.75rem * var(--tw-space-x-reverse)); - margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))) + --tw-space-x-reverse: 0; + margin-right: calc(0.75rem * var(--tw-space-x-reverse)); + margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); } .space-y-2 > :not([hidden]) ~ :not([hidden]) { - --tw-space-y-reverse: 0; - margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)) + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); } .space-y-3 > :not([hidden]) ~ :not([hidden]) { - --tw-space-y-reverse: 0; - margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)) + --tw-space-y-reverse: 0; + margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); } .space-y-4 > :not([hidden]) ~ :not([hidden]) { - --tw-space-y-reverse: 0; - margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(1rem * var(--tw-space-y-reverse)) + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)); } .overflow-hidden { - overflow: hidden + overflow: hidden; } .overflow-y-auto { - overflow-y: auto + overflow-y: auto; } .rounded { - border-radius: 0.25rem + border-radius: 0.25rem; } .rounded-md { - border-radius: 0.375rem + border-radius: 0.375rem; } .border { - border-width: 1px + border-width: 1px; } .border-b { - border-bottom-width: 1px + border-bottom-width: 1px; } .border-l { - border-left-width: 1px + border-left-width: 1px; } .border-r { - border-right-width: 1px + border-right-width: 1px; } .border-none { - border-style: none + border-style: none; } .bg-blue-600 { - --tw-bg-opacity: 1; - background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)) + --tw-bg-opacity: 1; + background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)); } .bg-gray-100 { - --tw-bg-opacity: 1; - background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1)) + --tw-bg-opacity: 1; + background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1)); } .bg-gray-50 { - --tw-bg-opacity: 1; - background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1)) + --tw-bg-opacity: 1; + background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1)); } .bg-green-600 { - --tw-bg-opacity: 1; - background-color: rgb(22 163 74 / var(--tw-bg-opacity, 1)) + --tw-bg-opacity: 1; + background-color: rgb(22 163 74 / var(--tw-bg-opacity, 1)); } .bg-white { - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)) + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); } .p-2 { - padding: 0.5rem + padding: 0.5rem; } .p-4 { - padding: 1rem + padding: 1rem; } .px-2 { - padding-left: 0.5rem; - padding-right: 0.5rem + padding-left: 0.5rem; + padding-right: 0.5rem; } .px-4 { - padding-left: 1rem; - padding-right: 1rem + padding-left: 1rem; + padding-right: 1rem; } .py-1 { - padding-top: 0.25rem; - padding-bottom: 0.25rem + padding-top: 0.25rem; + padding-bottom: 0.25rem; } .py-2 { - padding-top: 0.5rem; - padding-bottom: 0.5rem + padding-top: 0.5rem; + padding-bottom: 0.5rem; } .pl-5 { - padding-left: 1.25rem + padding-left: 1.25rem; } .text-left { - text-align: left + text-align: left; } .text-center { - text-align: center + text-align: center; } .text-lg { - font-size: 1.125rem; - line-height: 1.75rem + font-size: 1.125rem; + line-height: 1.75rem; } .text-sm { - font-size: 0.875rem; - line-height: 1.25rem + font-size: 0.875rem; + line-height: 1.25rem; } .text-xl { - font-size: 1.25rem; - line-height: 1.75rem + font-size: 1.25rem; + line-height: 1.75rem; } .text-xs { - font-size: 0.75rem; - line-height: 1rem + font-size: 0.75rem; + line-height: 1rem; } .font-medium { - font-weight: 500 + font-weight: 500; } .font-semibold { - font-weight: 600 + font-weight: 600; } .leading-none { - line-height: 1 + line-height: 1; } .text-blue-600 { - --tw-text-opacity: 1; - color: rgb(37 99 235 / var(--tw-text-opacity, 1)) + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity, 1)); } .text-gray-500 { - --tw-text-opacity: 1; - color: rgb(107 114 128 / var(--tw-text-opacity, 1)) + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity, 1)); } .text-gray-600 { - --tw-text-opacity: 1; - color: rgb(75 85 99 / var(--tw-text-opacity, 1)) + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity, 1)); } .text-red-500 { - --tw-text-opacity: 1; - color: rgb(239 68 68 / var(--tw-text-opacity, 1)) + --tw-text-opacity: 1; + color: rgb(239 68 68 / var(--tw-text-opacity, 1)); } .text-red-600 { - --tw-text-opacity: 1; - color: rgb(220 38 38 / var(--tw-text-opacity, 1)) + --tw-text-opacity: 1; + color: rgb(220 38 38 / var(--tw-text-opacity, 1)); } .text-white { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity, 1)) + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)); } .underline { - text-decoration-line: underline + text-decoration-line: underline; } .shadow { - --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) + --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); + --tw-shadow-colored: + 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + box-shadow: + var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); } .shadow-sm { - --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); - --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: + var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); } .grayscale { - --tw-grayscale: grayscale(100%); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) + --tw-grayscale: grayscale(100%); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) + var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) + var(--tw-sepia) var(--tw-drop-shadow); } .filter { - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) + var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) + var(--tw-sepia) var(--tw-drop-shadow); } .hover\:bg-blue-700:hover { - --tw-bg-opacity: 1; - background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1)) + --tw-bg-opacity: 1; + background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1)); } .hover\:bg-gray-200:hover { - --tw-bg-opacity: 1; - background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1)) + --tw-bg-opacity: 1; + background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1)); } .hover\:bg-green-700:hover { - --tw-bg-opacity: 1; - background-color: rgb(21 128 61 / var(--tw-bg-opacity, 1)) + --tw-bg-opacity: 1; + background-color: rgb(21 128 61 / var(--tw-bg-opacity, 1)); } .hover\:underline:hover { - text-decoration-line: underline + text-decoration-line: underline; } diff --git a/frontend/editor/src/portal/components/AppShell.css b/frontend/editor/src/portal/components/AppShell.css index a01026480a..6535832399 100644 --- a/frontend/editor/src/portal/components/AppShell.css +++ b/frontend/editor/src/portal/components/AppShell.css @@ -10,8 +10,8 @@ height: 100vh; height: 100dvh; /* mobile browser chrome shrinks the viewport; dvh tracks it */ overflow: hidden; - background: var(--color-bg); - color: var(--color-text-2); + background: var(--c-bg); + color: var(--c-text-muted); } .portal-shell__main { @@ -55,7 +55,7 @@ position: fixed; inset: 0; z-index: 75; - background: rgba(15, 23, 42, 0.55); + background: var(--c-overlay); } @media (max-width: 48rem) { diff --git a/frontend/editor/src/portal/components/AssistantButton.css b/frontend/editor/src/portal/components/AssistantButton.css index 107ff7c1ac..6ae6e34e46 100644 --- a/frontend/editor/src/portal/components/AssistantButton.css +++ b/frontend/editor/src/portal/components/AssistantButton.css @@ -8,14 +8,14 @@ display: inline-flex; align-items: center; justify-content: center; - color: #fff; + color: var(--c-text-on-primary); background: linear-gradient( 135deg, - var(--color-blue) 0%, + var(--c-primary) 0%, var(--color-purple) 100% ); box-shadow: - 0 0.5rem 1.25rem rgba(59, 130, 246, 0.35), + 0 0.5rem 1.25rem color-mix(in srgb, var(--c-primary) 35%, transparent), inset 0 0.0625rem 0 rgba(255, 255, 255, 0.2); transition: transform var(--motion-base), @@ -26,7 +26,7 @@ .portal-assistant-btn:hover { transform: scale(1.08); box-shadow: - 0 0.75rem 1.75rem rgba(59, 130, 246, 0.45), + 0 0.75rem 1.75rem color-mix(in srgb, var(--c-primary) 45%, transparent), inset 0 0.0625rem 0 rgba(255, 255, 255, 0.25); } diff --git a/frontend/editor/src/portal/components/AssistantPanel.css b/frontend/editor/src/portal/components/AssistantPanel.css index 90a66f169d..2e5edc907f 100644 --- a/frontend/editor/src/portal/components/AssistantPanel.css +++ b/frontend/editor/src/portal/components/AssistantPanel.css @@ -6,8 +6,8 @@ width: min(23.75rem, calc(100vw - 2rem)); height: 32.5rem; max-height: calc(100dvh - 7rem); - background: var(--color-surface); - border: 1px solid var(--color-border); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-xl); box-shadow: var(--shadow-lg); display: flex; @@ -26,7 +26,7 @@ color: var(--color-text-on-accent); background: linear-gradient( 135deg, - var(--color-blue) 0%, + var(--c-primary) 0%, var(--color-purple) 100% ); } @@ -91,17 +91,17 @@ padding: 0.4375rem 0.625rem; font-size: 0.8125rem; text-align: left; - color: var(--color-text-2); - background: var(--color-surface); - border: 1px solid var(--color-border); + color: var(--c-text-muted); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-md); transition: border-color var(--motion-fast), background var(--motion-fast); } .portal-assistant__suggestion:hover { - background: var(--color-bg-hover); - border-color: var(--color-blue-border); + background: var(--c-hover); + border-color: var(--c-primary-border); } .portal-assistant__bubble { @@ -116,16 +116,16 @@ .portal-assistant__bubble--user { align-self: flex-end; - background: var(--color-blue); + background: var(--c-primary); color: var(--color-text-on-accent); border-bottom-right-radius: 0.25rem; } .portal-assistant__bubble--assistant { align-self: flex-start; - background: var(--color-surface); - color: var(--color-text-2); - border: 1px solid var(--color-border); + background: var(--c-surface); + color: var(--c-text-muted); + border: 1px solid var(--c-border); border-bottom-left-radius: 0.25rem; } @@ -138,7 +138,7 @@ width: 0.375rem; height: 0.375rem; border-radius: 50%; - background: var(--color-text-5); + background: var(--c-text-subtle); animation: pulse 1.2s ease-in-out infinite; } .portal-assistant__typing span:nth-child(2) { @@ -153,8 +153,8 @@ align-items: center; gap: 0.5rem; padding: 0.625rem 0.75rem; - border-top: 1px solid var(--color-border); - background: var(--color-surface); + border-top: 1px solid var(--c-border); + background: var(--c-surface); } .portal-assistant__input { @@ -162,15 +162,15 @@ font: inherit; font-size: 0.8125rem; background: transparent; - border: 1px solid var(--color-border-input); + border: 1px solid var(--c-border); border-radius: var(--radius-md); padding: 0.4375rem 0.625rem; - color: var(--color-text-1); + color: var(--c-text); outline: none; transition: border-color var(--motion-fast); } .portal-assistant__input:focus { - border-color: var(--color-blue); + border-color: var(--c-primary); } .portal-assistant__send { diff --git a/frontend/editor/src/portal/components/AssistantPanel.stories.tsx b/frontend/editor/src/portal/components/AssistantPanel.stories.tsx index 92fe3e0bdf..911f389566 100644 --- a/frontend/editor/src/portal/components/AssistantPanel.stories.tsx +++ b/frontend/editor/src/portal/components/AssistantPanel.stories.tsx @@ -18,7 +18,7 @@ const meta: Meta = { parameters: { layout: "fullscreen" }, decorators: [ (S) => ( -
+
diff --git a/frontend/editor/src/portal/components/AuthGate.tsx b/frontend/editor/src/portal/components/AuthGate.tsx index a7f4e58ef5..0af62ee53b 100644 --- a/frontend/editor/src/portal/components/AuthGate.tsx +++ b/frontend/editor/src/portal/components/AuthGate.tsx @@ -19,7 +19,7 @@ function FullScreenMessage({ children }: { children: ReactNode }) { alignItems: "center", justifyContent: "center", gap: "0.75rem", - color: "var(--color-text-3)", + color: "var(--c-text-subtle)", }} > {children} diff --git a/frontend/editor/src/portal/components/ChatFABWidget.stories.tsx b/frontend/editor/src/portal/components/ChatFABWidget.stories.tsx index b6124bbd25..af7d67eea7 100644 --- a/frontend/editor/src/portal/components/ChatFABWidget.stories.tsx +++ b/frontend/editor/src/portal/components/ChatFABWidget.stories.tsx @@ -55,7 +55,7 @@ function MockChatContent({ alignItems: "center", justifyContent: "space-between", padding: "14px 16px 10px", - borderBottom: "1px solid var(--color-border, #e3e8ee)", + borderBottom: "1px solid var(--c-border, #e3e8ee)", flexShrink: 0, }} > @@ -65,7 +65,7 @@ function MockChatContent({ shape="circle" onClick={onClose} aria-label="Close chat" - style={{ color: "var(--color-text-4, #64748b)" }} + style={{ color: "var(--c-text-subtle, #64748b)" }} > ✕ @@ -91,7 +91,7 @@ function MockChatContent({ background: m.role === "user" ? "#3b82f6" - : "var(--color-bg-muted, #f3f4f6)", + : "var(--c-surface-sunken, #f3f4f6)", color: m.role === "user" ? "#fff" : "inherit", borderRadius: 10, padding: "8px 12px", @@ -108,17 +108,17 @@ function MockChatContent({
What do you want to do? @@ -149,7 +149,7 @@ function ChatFABWidgetDemo({ width: "100%", height: "100%", overflow: "hidden", - background: "var(--color-bg, #f8f9fb)", + background: "var(--c-bg, #f8f9fb)", }} > {/* FAB button */} @@ -249,7 +249,7 @@ function ChatFABFullFlowDemo() { padding: "4px 10px", borderRadius: 6, background: - step === s ? "#3b82f6" : "var(--color-bg-muted, #f3f4f6)", + step === s ? "#3b82f6" : "var(--c-surface-sunken, #f3f4f6)", color: step === s ? "#fff" : "inherit", fontWeight: step === s ? 600 : 400, }} diff --git a/frontend/editor/src/portal/components/DownloadEditorModal.css b/frontend/editor/src/portal/components/DownloadEditorModal.css index fba739501f..4742833be8 100644 --- a/frontend/editor/src/portal/components/DownloadEditorModal.css +++ b/frontend/editor/src/portal/components/DownloadEditorModal.css @@ -14,7 +14,7 @@ font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-install__section:first-child { margin-top: 0; @@ -27,9 +27,9 @@ gap: 0.875rem; width: 100%; padding: 0.75rem 0.875rem; - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-md); - background: var(--color-surface); + background: var(--c-surface); text-align: left; cursor: pointer; transition: @@ -37,8 +37,8 @@ background var(--motion-fast); } .portal-install__option:hover { - border-color: var(--color-border-input); - background: var(--color-bg-hover); + border-color: var(--c-border); + background: var(--c-hover); } .portal-install__option-icon { @@ -48,8 +48,8 @@ height: 2.25rem; flex-shrink: 0; border-radius: 0.625rem; - color: var(--color-blue); - background: var(--color-blue-light); + color: var(--c-primary); + background: var(--c-primary-tint); } .portal-install__option-text { @@ -60,14 +60,14 @@ .portal-install__option-text strong { font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-install__option-text span { font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-install__option-chevron { - color: var(--color-text-5); + color: var(--c-text-subtle); flex-shrink: 0; } @@ -88,13 +88,13 @@ font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-install__note { margin: 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-install__guide { align-self: flex-start; @@ -106,7 +106,7 @@ background: none; font-size: 0.8125rem; font-weight: 600; - color: var(--color-blue); + color: var(--c-primary); cursor: pointer; } .portal-install__guide:hover { diff --git a/frontend/editor/src/portal/components/EditorStatusCard.css b/frontend/editor/src/portal/components/EditorStatusCard.css index 10d8a020b4..e71a50bac3 100644 --- a/frontend/editor/src/portal/components/EditorStatusCard.css +++ b/frontend/editor/src/portal/components/EditorStatusCard.css @@ -4,8 +4,8 @@ .portal-editor-hero { border-radius: var(--radius-xl); - border: 1px solid var(--color-border-input); - background: var(--color-surface); + border: 1px solid var(--c-border); + background: var(--c-surface); box-shadow: var(--shadow-sm); overflow: hidden; } @@ -15,7 +15,7 @@ align-items: center; gap: 1.25rem; padding: 1rem 1.25rem; - background: color-mix(in srgb, var(--c-primary) 22%, var(--p-zinc-950)); + background: color-mix(in srgb, var(--c-primary) 22%, var(--c-hero-dark)); } .portal-editor-hero__logo { @@ -123,7 +123,7 @@ .portal-editor-hero__action .portal-editor-hero__cta.sui-btn { background: #ffffff; border-color: #ffffff; - color: var(--color-hero-navy); + color: var(--c-hero-dark-cta-text); } .portal-editor-hero__action .portal-editor-hero__cta.sui-btn:hover { background: rgba(255, 255, 255, 0.88); @@ -141,5 +141,5 @@ /* Attached footer strip (setup checklist). */ .portal-editor-hero__footer { - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } diff --git a/frontend/editor/src/portal/components/EditorStatusCard.tsx b/frontend/editor/src/portal/components/EditorStatusCard.tsx index 8d3b7dcbcf..1734d677c3 100644 --- a/frontend/editor/src/portal/components/EditorStatusCard.tsx +++ b/frontend/editor/src/portal/components/EditorStatusCard.tsx @@ -28,7 +28,7 @@ function StirlingMark() { fill="none" aria-hidden > - + = { parameters: { layout: "fullscreen" }, decorators: [ (S) => ( -
+
diff --git a/frontend/editor/src/portal/components/SetupChecklist.css b/frontend/editor/src/portal/components/SetupChecklist.css index a19919e640..0fcb71e678 100644 --- a/frontend/editor/src/portal/components/SetupChecklist.css +++ b/frontend/editor/src/portal/components/SetupChecklist.css @@ -21,7 +21,7 @@ width: 100%; padding: 0.6875rem 1.25rem; border: none; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); background: transparent; text-align: left; cursor: pointer; @@ -31,7 +31,7 @@ border-top: none; } .portal-setup__row:hover { - background: var(--color-bg-hover); + background: var(--c-hover); } /* Numbered step marker */ @@ -42,10 +42,10 @@ height: 1.5rem; flex-shrink: 0; border-radius: 50%; - border: 1px solid var(--color-border-input); + border: 1px solid var(--c-border); font-size: 0.75rem; font-weight: 600; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Completed step: filled green check. */ .portal-setup__num.is-done { @@ -54,7 +54,7 @@ color: #fff; } .portal-setup__row.is-done .portal-setup__text strong { - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-setup__text { @@ -65,12 +65,12 @@ .portal-setup__text strong { font-size: 0.875rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-setup__text span { font-size: 0.75rem; line-height: 1.4; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* ── Enterprise upsell rung ── */ @@ -81,10 +81,10 @@ gap: 1rem; flex-wrap: wrap; padding: 0.75rem 1.25rem; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); background: linear-gradient( 90deg, - color-mix(in srgb, var(--color-blue) 5%, transparent) 0%, + color-mix(in srgb, var(--c-primary) 5%, transparent) 0%, transparent 55% ); } @@ -105,18 +105,18 @@ font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; - color: var(--color-blue-dark); - background: var(--color-blue-light); + color: var(--c-primary-hover); + background: var(--c-primary-tint); } .portal-setup__enterprise-text { margin: 0; font-size: 0.8125rem; line-height: 1.45; - color: var(--color-text-3); + color: var(--c-text-subtle); min-width: 0; } .portal-setup__enterprise-text strong { - color: var(--color-text-1); + color: var(--c-text); font-weight: 700; } diff --git a/frontend/editor/src/portal/components/SetupChecklist.stories.tsx b/frontend/editor/src/portal/components/SetupChecklist.stories.tsx index 78af75d188..432be155d7 100644 --- a/frontend/editor/src/portal/components/SetupChecklist.stories.tsx +++ b/frontend/editor/src/portal/components/SetupChecklist.stories.tsx @@ -23,10 +23,10 @@ const meta: Meta = {
diff --git a/frontend/editor/src/portal/components/Sidebar.css b/frontend/editor/src/portal/components/Sidebar.css index 1e0096fc4e..c9dfa871ee 100644 --- a/frontend/editor/src/portal/components/Sidebar.css +++ b/frontend/editor/src/portal/components/Sidebar.css @@ -2,8 +2,8 @@ width: 15rem; height: 100vh; height: 100dvh; /* track mobile browser chrome */ - background: var(--color-sidebar-bg); - border-right: 1px solid var(--color-sidebar-border); + background: var(--c-bg-raised); + border-right: 1px solid var(--c-border); display: flex; flex-direction: column; flex-shrink: 0; @@ -41,7 +41,7 @@ .portal-sidebar--open { transform: translateX(0); visibility: visible; - box-shadow: 0 0.5rem 2rem rgba(15, 23, 42, 0.35); + box-shadow: 0 0.5rem 2rem rgba(0, 0, 0, 0.35); } .portal-sidebar__close { display: inline-flex; @@ -55,7 +55,7 @@ display: flex; align-items: center; gap: 0.5rem; - border-bottom: 1px solid var(--color-sidebar-divider); + border-bottom: 1px solid var(--c-border-subtle); } /* Stirling Processor wordmark (theme-switched in Sidebar.tsx); matches the @@ -67,6 +67,19 @@ flex-shrink: 0; } +/* Show the wordmark that matches the rendered scheme (black text on light, + white text on dark). Keyed on data-mantine-color-scheme so it follows the + actual theme, not the portal's separate (and sometimes stale) theme state. */ +.portal-sidebar__wordmark--dark { + display: none; +} +[data-mantine-color-scheme="dark"] .portal-sidebar__wordmark--light { + display: none; +} +[data-mantine-color-scheme="dark"] .portal-sidebar__wordmark--dark { + display: block; +} + /* App switcher (down-arrow → Portal / Editor); button and menu styling live with the shared AppSwitch element. */ .portal-sidebar__app-switch { @@ -86,8 +99,8 @@ /* Each section is a labelled card: a small header above its nav items. */ .portal-sidebar__section { - background: var(--color-surface); - border: 1px solid var(--color-sidebar-divider); + background: var(--c-surface); + border: 1px solid var(--c-border-subtle); border-radius: 0.625rem; padding: 0.5rem 0.375rem 0.375rem; display: flex; @@ -101,7 +114,7 @@ font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.02em; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-sidebar__group { @@ -112,7 +125,7 @@ /* Footer */ .portal-sidebar__footer { - border-top: 1px solid var(--color-sidebar-divider); + border-top: 1px solid var(--c-border-subtle); padding: 0.5rem 0.625rem 0.75rem; display: flex; flex-direction: column; diff --git a/frontend/editor/src/portal/components/Sidebar.stories.tsx b/frontend/editor/src/portal/components/Sidebar.stories.tsx index df4d6c1cdb..d40d710adb 100644 --- a/frontend/editor/src/portal/components/Sidebar.stories.tsx +++ b/frontend/editor/src/portal/components/Sidebar.stories.tsx @@ -11,7 +11,7 @@ const meta: Meta = { style={{ display: "flex", height: "100vh", - background: "var(--color-bg)", + background: "var(--c-bg)", }} > diff --git a/frontend/editor/src/portal/components/Sidebar.tsx b/frontend/editor/src/portal/components/Sidebar.tsx index 4eec4dcc06..b4f5300d16 100644 --- a/frontend/editor/src/portal/components/Sidebar.tsx +++ b/frontend/editor/src/portal/components/Sidebar.tsx @@ -80,9 +80,17 @@ export function Sidebar() { inert={isMobile && !mobileNavOpen} >
+ {/* Both wordmarks render; CSS shows the right one per the actual color + scheme (data-mantine-color-scheme), so it tracks the rendered theme + rather than the portal's separate theme state. */} {t("portal.shell.sidebar.brandSuffix")} + {t("portal.shell.sidebar.brandSuffix")} diff --git a/frontend/editor/src/portal/components/WelcomeBanner.css b/frontend/editor/src/portal/components/WelcomeBanner.css index 457291eadb..157ee24ac0 100644 --- a/frontend/editor/src/portal/components/WelcomeBanner.css +++ b/frontend/editor/src/portal/components/WelcomeBanner.css @@ -4,10 +4,10 @@ .portal-welcome { border-radius: var(--radius-xl); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); overflow: hidden; isolation: isolate; - background: var(--color-surface); + background: var(--c-surface); } /* ── Dark product header strip ── */ @@ -18,7 +18,7 @@ gap: 1rem; flex-wrap: wrap; padding: 0.875rem 1.25rem; - background: color-mix(in srgb, var(--c-primary) 22%, var(--p-zinc-950)); + background: color-mix(in srgb, var(--c-primary) 22%, var(--c-hero-dark)); } .portal-welcome__brand { @@ -90,7 +90,7 @@ .portal-welcome__header .portal-welcome__cta.sui-btn { background: #ffffff; border-color: #ffffff; - color: var(--color-hero-navy); + color: var(--c-hero-dark-cta-text); } .portal-welcome__header .portal-welcome__cta.sui-btn:hover { background: rgba(255, 255, 255, 0.88); @@ -99,5 +99,5 @@ /* ── Steps + enterprise (setup checklist) sit directly under the header ── */ .portal-welcome__footer { - background: var(--color-surface); + background: var(--c-surface); } diff --git a/frontend/editor/src/portal/components/billing/billing.css b/frontend/editor/src/portal/components/billing/billing.css index 423e917c94..3ab25438db 100644 --- a/frontend/editor/src/portal/components/billing/billing.css +++ b/frontend/editor/src/portal/components/billing/billing.css @@ -28,7 +28,7 @@ .portal-billing__spend-foot { margin-top: auto; padding-top: 1rem; - border-top: 1px solid var(--color-border); + border-top: 1px solid var(--c-border); } .portal-billing__spend-foot:not(:first-child) { margin-top: 1.25rem; @@ -42,25 +42,25 @@ padding: 0.3rem 0.7rem; font-size: 0.8125rem; font-weight: 500; - color: var(--color-blue); + color: var(--c-primary); background: var(--color-bg-subtle); - border: 1px solid var(--color-border); + border: 1px solid var(--c-border); border-radius: 999px; cursor: pointer; } .portal-billing__suggested:hover { - border-color: var(--color-blue); + border-color: var(--c-primary); } .portal-billing__guardrail { margin-top: 0.85rem; padding: 0.7rem 0.85rem; font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); background: var(--color-bg-subtle); border-radius: 0.6rem; } .portal-billing__guardrail strong { - color: var(--color-text-1); + color: var(--c-text); } .portal-billing__edit-actions { display: flex; @@ -99,20 +99,20 @@ font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; - color: var(--color-text-3); + color: var(--c-text-subtle); margin-bottom: 0.25rem; } .portal-billing__section-title { font-size: 1.05rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); margin: 0 0 0.25rem; } .portal-billing__section-sub { font-size: 0.875rem; - color: var(--color-text-3); + color: var(--c-text-subtle); margin: 0 0 1rem; } @@ -153,20 +153,20 @@ .portal-billing__checkout-status-title { font-size: 1.125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); margin: 0.25rem 0 0; } .portal-billing__checkout-status-body { font-size: 0.9375rem; - color: var(--color-text-2); + color: var(--c-text-muted); margin: 0; max-width: 32rem; } .portal-billing__checkout-status-hint { font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); margin: 0; } @@ -188,7 +188,7 @@ font-size: 1.25rem; font-weight: 600; margin: 0; - color: var(--color-text-1); + color: var(--c-text); } .portal-billing__meter-figures { @@ -206,21 +206,21 @@ .portal-billing__meter-num { font-size: 1.75rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-billing__meter-num--muted { - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-billing__meter-label { font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-billing__meter-track { height: 0.5rem; - background: var(--color-bg-subtle, #e5e7eb); + background: var(--color-bg-subtle, var(--c-surface-sunken)); border-radius: 999px; overflow: hidden; margin-bottom: 0.75rem; @@ -228,14 +228,14 @@ .portal-billing__meter-fill { height: 100%; - background: linear-gradient(90deg, var(--color-blue), var(--color-purple)); + background: linear-gradient(90deg, var(--c-primary), var(--color-purple)); border-radius: 999px; transition: width 200ms ease; } .portal-billing__meter-foot { font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); margin: 0.75rem 0 0; } @@ -265,12 +265,12 @@ font-weight: 750; line-height: 1; letter-spacing: -0.02em; - color: var(--color-text-1, #0f172a); + color: var(--c-text); font-variant-numeric: tabular-nums; } .paygf-meter__cap { font-size: 0.85rem; - color: var(--color-text-3, #64748b); + color: var(--c-text-subtle); font-variant-numeric: tabular-nums; } .paygf-meter .payg-bar { @@ -283,7 +283,7 @@ align-items: center; gap: 6px 10px; font-size: 0.78rem; - color: var(--color-text-2, #475569); + color: var(--c-text-muted); } /* Status chip (Healthy / Approaching / Cap reached). Solid hex colours @@ -333,7 +333,7 @@ margin-top: 18px; height: 10px; border-radius: 999px; - background: var(--color-bg-subtle, #e5e7eb); + background: var(--color-bg-subtle, var(--c-surface-sunken)); overflow: hidden; position: relative; } @@ -343,7 +343,7 @@ transition: width 0.5s cubic-bezier(0.16, 1, 0.3, 1); } .payg-bar__fill[data-state="FULL"] { - background: var(--color-blue); + background: var(--c-primary); } .payg-bar__fill[data-state="WARNED"] { background: var(--color-amber); @@ -363,12 +363,12 @@ font-size: 1.25rem; font-weight: 600; margin: 0; - color: var(--color-text-1); + color: var(--c-text); } .portal-billing__plan-sub { font-size: 0.9375rem; - color: var(--color-text-2); + color: var(--c-text-muted); margin: 0 0 0.5rem; } @@ -383,7 +383,7 @@ .portal-billing__plan-features li { font-size: 0.875rem; - color: var(--color-text-2); + color: var(--c-text-muted); padding-left: 1.25rem; position: relative; } @@ -405,12 +405,12 @@ .portal-billing__plan-reassure { font-size: 0.75rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-billing__plan-readonly { font-size: 0.875rem; - color: var(--color-text-3); + color: var(--c-text-subtle); font-style: italic; margin: 0; } @@ -432,16 +432,16 @@ display: flex; justify-content: space-between; font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-billing__breakdown-value { - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-billing__breakdown-track { height: 0.5rem; - background: var(--color-bg-subtle, #e5e7eb); + background: var(--color-bg-subtle, var(--c-surface-sunken)); border-radius: 999px; overflow: hidden; } @@ -453,7 +453,7 @@ } .portal-billing__breakdown-fill--blue { - background: var(--color-blue); + background: var(--c-primary); } .portal-billing__breakdown-fill--purple { @@ -478,13 +478,13 @@ flex-direction: column; gap: 0.25rem; font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-billing__cap-input { width: 8rem; padding: 0.5rem 0.75rem; - border: 1px solid var(--color-border, #d1d5db); + border: 1px solid var(--c-border); border-radius: 0.375rem; font-size: 0.9375rem; font-family: inherit; @@ -495,7 +495,7 @@ align-items: center; gap: 0.375rem; font-size: 0.875rem; - color: var(--color-text-2); + color: var(--c-text-muted); cursor: pointer; } @@ -512,12 +512,12 @@ .portal-billing__member-name { font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-billing__member-email { font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-billing__invoice-num { @@ -526,7 +526,7 @@ } .portal-billing__invoice-desc { - color: var(--color-text-1, #0f172a); + color: var(--c-text); font-size: 0.9375rem; } @@ -566,26 +566,26 @@ Same class names + structure so the visual is identical to the SaaS Plan page; when the shared-component move lands, these dedupe to one stylesheet. */ .scc { - --scc-accent: var(--color-blue); - --scc-accent-text: var(--color-blue); - --scc-accent-soft: color-mix(in srgb, var(--color-blue) 12%, transparent); - --scc-accent-border: color-mix(in srgb, var(--color-blue) 25%, transparent); - --scc-chip-bg: var(--color-bg-muted, #f8fafc); - --scc-chip-border: var(--color-border, #e2e8f0); - --scc-text-primary: var(--color-text-1, #0f172a); - --scc-text-secondary: var(--color-text-2, #475569); - --scc-text-muted: var(--color-text-3, #64748b); - --scc-border-strong: var(--color-text-4, #94a3b8); + --scc-accent: var(--c-primary); + --scc-accent-text: var(--c-primary); + --scc-accent-soft: color-mix(in srgb, var(--c-primary) 12%, transparent); + --scc-accent-border: color-mix(in srgb, var(--c-primary) 25%, transparent); + --scc-chip-bg: var(--c-surface-sunken); + --scc-chip-border: var(--c-border); + --scc-text-primary: var(--c-text); + --scc-text-secondary: var(--c-text-muted); + --scc-text-muted: var(--c-text-subtle); + --scc-border-strong: var(--c-text-subtle); display: flex; flex-direction: column; gap: 14px; margin-top: 0.75rem; } [data-theme="dark"] .scc { - --scc-accent-text: var(--color-blue); - --scc-accent-soft: color-mix(in srgb, var(--color-blue) 16%, transparent); - --scc-chip-bg: var(--color-bg-muted); - --scc-chip-border: var(--color-border); + --scc-accent-text: var(--c-primary); + --scc-accent-soft: color-mix(in srgb, var(--c-primary) 16%, transparent); + --scc-chip-bg: var(--c-surface-sunken); + --scc-chip-border: var(--c-border); } .scc-row { @@ -719,7 +719,7 @@ } .portal-billing__planhead-eyebrow { font-size: 0.78rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-billing__role-pill { display: inline-flex; @@ -732,14 +732,14 @@ white-space: nowrap; } .portal-billing__role-pill[data-leader="true"] { - background: color-mix(in srgb, var(--color-blue) 12%, transparent); - color: var(--color-blue); - border: 1px solid color-mix(in srgb, var(--color-blue) 25%, transparent); + background: color-mix(in srgb, var(--c-primary) 12%, transparent); + color: var(--c-primary); + border: 1px solid color-mix(in srgb, var(--c-primary) 25%, transparent); } .portal-billing__role-pill[data-leader="false"] { - background: var(--color-bg-muted); - color: var(--color-text-3); - border: 1px solid var(--color-border); + background: var(--c-surface-sunken); + color: var(--c-text-subtle); + border: 1px solid var(--c-border); } .portal-billing__planhead-split { display: grid; @@ -751,7 +751,7 @@ .portal-billing__planhead-col--meter { padding-right: 0; padding-left: 22px; - border-left: 1px solid var(--color-border); + border-left: 1px solid var(--c-border); } .portal-billing__planhead-lbl { display: inline-flex; @@ -767,27 +767,27 @@ color: var(--color-green); } .portal-billing__planhead-lbl--meter { - color: var(--color-blue); + color: var(--c-primary); } .portal-billing__planhead-title { margin: 0; font-size: 1.05rem; font-weight: 700; - color: var(--color-text-1); + color: var(--c-text); letter-spacing: -0.01em; line-height: 1.25; } .portal-billing__planhead-body { margin: 5px 0 0; font-size: 0.85rem; - color: var(--color-text-3); + color: var(--c-text-subtle); line-height: 1.5; } /* The period meter merged into the plan-head card, divided from the split. */ .portal-billing__planhead-meter { margin-top: 18px; padding-top: 18px; - border-top: 1px solid var(--color-border); + border-top: 1px solid var(--c-border); } @media (max-width: 640px) { .portal-billing__planhead-split { @@ -801,7 +801,7 @@ padding-left: 0; padding-top: 16px; border-left: none; - border-top: 1px solid var(--color-border); + border-top: 1px solid var(--c-border); } } @@ -820,7 +820,7 @@ border-radius: 0.375rem; font-size: 0.8125rem; font-weight: 500; - color: var(--color-text-1, #0f172a); + color: var(--c-text); text-decoration: none; border: 1px solid transparent; transition: @@ -829,14 +829,14 @@ } .portal-billing__invoice-link:hover { - background: var(--color-bg-muted, #f1f5f9); - border-color: var(--color-border, #e2e8f0); + background: var(--c-surface-sunken); + border-color: var(--c-border); } .portal-billing__invoice-link:focus-visible { outline: none; - border-color: var(--color-blue); - background: var(--color-bg-muted, #f1f5f9); + border-color: var(--c-primary); + background: var(--c-surface-sunken); } .portal-billing__invoice-footer { @@ -861,7 +861,7 @@ margin: 0; font-size: 1.5rem; font-weight: 700; - color: var(--color-text-1); + color: var(--c-text); } /* ── Free PDF Editors (fleet) card ───────────────────────────────────── */ @@ -880,8 +880,8 @@ line-height: 0; border-radius: 0.65rem; background: var(--color-bg-subtle); - border: 1px solid var(--color-border); - color: var(--color-blue); + border: 1px solid var(--c-border); + color: var(--c-primary); } /* Identity, stats, and the "Invite teammates" action all sit on one line; the metric cells render flat (no per-stat box) and are divided by hairlines, so @@ -902,7 +902,7 @@ background: transparent; border: 0; box-shadow: none; - border-left: 1px solid var(--color-border); + border-left: 1px solid var(--c-border); padding: 0 0 0 1.5rem; min-width: 0; gap: 0.3rem; @@ -931,7 +931,7 @@ border-radius: 0; font-size: 0.85rem; font-weight: 400; - color: var(--color-text-3, #64748b); + color: var(--c-text-subtle); } .portal-billing__trial-meter .payg-status__dot, .portal-billing__spend-meter .payg-status__dot { @@ -972,25 +972,25 @@ font-weight: 750; line-height: 1; letter-spacing: -0.02em; - color: var(--color-text-1); + color: var(--c-text); font-variant-numeric: tabular-nums; } .portal-billing__bignum-unit { font-size: 0.85rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-billing__segbar { display: flex; height: 0.55rem; border-radius: 999px; overflow: hidden; - background: var(--color-bg-muted, #f1f5f9); + background: var(--c-surface-sunken); } .portal-billing__segbar-seg { height: 100%; } .portal-billing__segbar-seg--blue { - background: var(--color-blue); + background: var(--c-primary); } .portal-billing__segbar-seg--purple { background: var(--color-purple); @@ -1018,7 +1018,7 @@ flex-shrink: 0; } .portal-billing__dot--blue { - background: var(--color-blue); + background: var(--c-primary); } .portal-billing__dot--purple { background: var(--color-purple); @@ -1028,24 +1028,24 @@ } .portal-billing__seglegend-label { font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-billing__seglegend-val { - color: var(--color-text-2); + color: var(--c-text-muted); font-variant-numeric: tabular-nums; } .portal-billing__seglegend-desc { - color: var(--color-text-4); + color: var(--c-text-subtle); } /* ── Spend-limit projection line ─────────────────────────────────────── */ .portal-billing__projection { margin: 0.85rem 0 0; font-size: 0.85rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-billing__projection strong { - color: var(--color-amber, #d97706); + color: var(--color-amber, var(--c-warning)); } /* ── Checkout modal: 2-step (spend limit → payment) ──────────────────── */ @@ -1070,15 +1070,15 @@ height: 4px; flex: 1; border-radius: var(--radius-pill); - background: var(--color-border); + background: var(--c-border); } .portal-billing__checkout-steps span.is-done { - background: var(--color-blue); + background: var(--c-primary); } .portal-billing__checkout-stepcount { font-size: 0.75rem; font-weight: 600; - color: var(--color-text-5); + color: var(--c-text-subtle); white-space: nowrap; } @@ -1086,7 +1086,7 @@ margin: 0; font-size: 0.75rem; line-height: 1.55; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-billing__checkout-cap-actions { display: flex; @@ -1101,9 +1101,9 @@ flex-direction: column; gap: 0.5rem; padding: 1rem; - border: 1px solid var(--color-border-input); + border: 1px solid var(--c-border); border-radius: var(--radius-md); - background: var(--color-surface); + background: var(--c-surface); } .portal-billing__card-placeholder-head { display: flex; @@ -1111,14 +1111,14 @@ justify-content: space-between; font-size: 0.75rem; font-weight: 600; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-billing__card-placeholder-badge { font-size: 0.625rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; - color: var(--color-text-5); + color: var(--c-text-subtle); background: var(--color-bg-code); padding: 0.125rem 0.375rem; border-radius: var(--radius-sm); @@ -1129,15 +1129,15 @@ gap: 0.625rem; padding: 0.75rem 0.875rem; background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-sm); font-family: var(--font-mono); font-size: 0.8125rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-billing__card-placeholder-note { margin: 0; font-size: 0.6875rem; line-height: 1.5; - color: var(--color-text-5); + color: var(--c-text-subtle); } diff --git a/frontend/editor/src/portal/components/policies/ClassificationLabelsSection.css b/frontend/editor/src/portal/components/policies/ClassificationLabelsSection.css index 02f7bfdbf5..13c1f4812f 100644 --- a/frontend/editor/src/portal/components/policies/ClassificationLabelsSection.css +++ b/frontend/editor/src/portal/components/policies/ClassificationLabelsSection.css @@ -8,11 +8,11 @@ display: flex; gap: var(--space-3); font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .classification-summary-note { font-size: 0.75rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } /* Expandable category → labels list. */ @@ -24,10 +24,10 @@ flex-direction: column; } .classification-category { - border-top: 1px solid var(--border-default); + border-top: 1px solid var(--c-border); } .classification-category:last-child { - border-bottom: 1px solid var(--border-default); + border-bottom: 1px solid var(--c-border); } .classification-category-header { min-height: 2.5rem; @@ -43,7 +43,7 @@ } .classification-category-count { font-size: 0.75rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .classification-category-labels { display: flex; diff --git a/frontend/editor/src/portal/components/policies/PolicyCategoryIcon.css b/frontend/editor/src/portal/components/policies/PolicyCategoryIcon.css index 96113b7aa1..ee0b6dde44 100644 --- a/frontend/editor/src/portal/components/policies/PolicyCategoryIcon.css +++ b/frontend/editor/src/portal/components/policies/PolicyCategoryIcon.css @@ -8,8 +8,8 @@ height: 2rem; flex-shrink: 0; border-radius: var(--radius-lg); - background: var(--color-bg-muted); - color: var(--color-text-3); + background: var(--c-surface-sunken); + color: var(--c-text-subtle); /* The shared MUI outline glyph inherits its size from here. */ font-size: 1.15rem; } diff --git a/frontend/editor/src/portal/components/processor-flow/FlowSankey.tsx b/frontend/editor/src/portal/components/processor-flow/FlowSankey.tsx index 43170a21a4..962cef995a 100644 --- a/frontend/editor/src/portal/components/processor-flow/FlowSankey.tsx +++ b/frontend/editor/src/portal/components/processor-flow/FlowSankey.tsx @@ -67,8 +67,8 @@ export function FlowSankey({ sources, outcomes, policies }: FlowSankeyProps) { const y0R = padY + (H - (midH + (outcomes.length - 1) * gap)) / 2; const outFill = (key: FlowOutcomeKey) => OUTCOME_FILL[key]; - const srcFill = "var(--color-blue)"; - const waistFill = "var(--color-text-4)"; + const srcFill = "var(--c-primary)"; + const waistFill = "var(--c-text-subtle)"; const ribbon = ( x0: number, diff --git a/frontend/editor/src/portal/components/processor-flow/useFlowParticles.ts b/frontend/editor/src/portal/components/processor-flow/useFlowParticles.ts index 7efbee40e2..65fc6cc9ad 100644 --- a/frontend/editor/src/portal/components/processor-flow/useFlowParticles.ts +++ b/frontend/editor/src/portal/components/processor-flow/useFlowParticles.ts @@ -140,7 +140,7 @@ export function useFlowParticles({ ) as SVGCircleElement; c.setAttribute("r", "2.5"); c.setAttribute("opacity", "0.75"); - c.style.fill = "var(--color-blue)"; + c.style.fill = "var(--c-primary)"; pg.appendChild(c); particles.push({ el: c, @@ -219,7 +219,7 @@ export function useFlowParticles({ p.phase = 2; p.t = 0; p.el.style.fill = - OUTCOME_FILL[outcomeKeys[p.out]] ?? "var(--color-blue)"; + OUTCOME_FILL[outcomeKeys[p.out]] ?? "var(--c-primary)"; p.el.setAttribute("r", "2.5"); p.el.setAttribute("opacity", "0.75"); } diff --git a/frontend/editor/src/portal/components/procurement/ProcurementModal.stories.tsx b/frontend/editor/src/portal/components/procurement/ProcurementModal.stories.tsx index 6c57c501c7..7fb8b865f2 100644 --- a/frontend/editor/src/portal/components/procurement/ProcurementModal.stories.tsx +++ b/frontend/editor/src/portal/components/procurement/ProcurementModal.stories.tsx @@ -26,7 +26,7 @@ export const Open: Story = { children: (

Ready for payment

-

+

Your quote is accepted. Continue to checkout to pay your committed contract and go live.

diff --git a/frontend/editor/src/portal/contexts/TierContext.tsx b/frontend/editor/src/portal/contexts/TierContext.tsx index 152e1f7a0b..411a3f75ba 100644 --- a/frontend/editor/src/portal/contexts/TierContext.tsx +++ b/frontend/editor/src/portal/contexts/TierContext.tsx @@ -18,8 +18,8 @@ export interface TierInfo { export const TIER_INFO: Record = { // Matches SaaS branding (editor/cloud Payg + PaygFree): the always-free // manual-tools tier is "Editor plan"; the metered tier is "Processor plan". - free: { labelKey: "portal.tier.free", dotColor: "var(--color-text-4)" }, - pro: { labelKey: "portal.tier.pro", dotColor: "var(--color-blue)" }, + free: { labelKey: "portal.tier.free", dotColor: "var(--c-text-subtle)" }, + pro: { labelKey: "portal.tier.pro", dotColor: "var(--c-primary)" }, enterprise: { labelKey: "portal.tier.enterprise", dotColor: "var(--color-purple)", diff --git a/frontend/editor/src/portal/data/Endpoints.stories.tsx b/frontend/editor/src/portal/data/Endpoints.stories.tsx index f702b5dea4..5f3a561766 100644 --- a/frontend/editor/src/portal/data/Endpoints.stories.tsx +++ b/frontend/editor/src/portal/data/Endpoints.stories.tsx @@ -21,7 +21,7 @@ type Story = StoryObj; export const ByVertical: Story = { render: () => (
-
+
{ALL_ENDPOINTS.length} endpoints across {VERTICALS.length} verticals
{VERTICALS.map((v) => ( @@ -42,12 +42,10 @@ export const ByVertical: Story = { background: v.color, }} /> -

+

{v.label}

- + {v.endpoints.length} endpoints
@@ -61,8 +59,8 @@ export const ByVertical: Story = { gap: 12, alignItems: "center", padding: "0.625rem 0.875rem", - background: "var(--color-surface)", - border: "1px solid var(--color-border)", + background: "var(--c-surface)", + border: "1px solid var(--c-border)", borderRadius: "var(--radius-md)", }} > @@ -71,7 +69,7 @@ export const ByVertical: Story = { style={{ fontFamily: "var(--font-mono)", fontSize: 12, - color: "var(--color-text-2)", + color: "var(--c-text-muted)", }} > {e.endpoint} @@ -81,7 +79,7 @@ export const ByVertical: Story = { style={{ fontSize: 13, fontWeight: 500, - color: "var(--color-text-1)", + color: "var(--c-text)", }} > {e.name} @@ -89,7 +87,7 @@ export const ByVertical: Story = {
= { ingest: "var(--color-green)", - validate: "var(--color-blue)", + validate: "var(--c-primary)", modify: "#F97316", secure: "var(--color-red)", store: "var(--color-purple)", @@ -60,12 +60,12 @@ export const PipelineOps: Story = { fontSize: 13, textTransform: "uppercase", letterSpacing: 0.6, - color: "var(--color-text-3)", + color: "var(--c-text-subtle)", }} > {stage} - + {PIPELINE_OPS[stage].length} ops
@@ -109,7 +109,7 @@ export const PipelineOps: Story = { export const LibraryByCategory: Story = { render: () => (
-
+
{LIBRARY_OPS.length} library ops across {OP_CATEGORIES.length}{" "} categories
@@ -137,18 +137,18 @@ export const LibraryByCategory: Story = { style={{ margin: 0, fontSize: 13, - color: "var(--color-text-1)", + color: "var(--c-text)", }} > {cat.name} - + {cat.blurb} @@ -207,8 +207,8 @@ export const Agents: Story = { key={a.id} style={{ padding: 14, - background: "var(--color-surface)", - border: "1px solid var(--color-border)", + background: "var(--c-surface)", + border: "1px solid var(--c-border)", borderRadius: 8, }} > @@ -220,14 +220,14 @@ export const Agents: Story = { marginBottom: 4, }} > - + {a.label}
@@ -241,8 +241,8 @@ export const Agents: Story = { fontSize: 11, padding: "0.125rem 0.375rem", borderRadius: 4, - background: "var(--color-bg-muted)", - color: "var(--color-text-3)", + background: "var(--c-surface-sunken)", + color: "var(--c-text-subtle)", fontFamily: "var(--font-mono)", }} > @@ -267,13 +267,13 @@ export const SourcesAndDestinations: Story = { key={s.id} style={{ padding: "0.625rem 0.75rem", - border: "1px solid var(--color-border)", + border: "1px solid var(--c-border)", borderRadius: 6, - background: "var(--color-surface)", + background: "var(--c-surface)", }} >
{s.label}
-
+
{s.desc}
@@ -288,13 +288,13 @@ export const SourcesAndDestinations: Story = { key={d.id} style={{ padding: "0.625rem 0.75rem", - border: "1px solid var(--color-border)", + border: "1px solid var(--c-border)", borderRadius: 6, - background: "var(--color-surface)", + background: "var(--c-surface)", }} >
{d.label}
-
+
{d.desc}
diff --git a/frontend/editor/src/portal/data/ops.ts b/frontend/editor/src/portal/data/ops.ts index e5803971ad..f650a13fad 100644 --- a/frontend/editor/src/portal/data/ops.ts +++ b/frontend/editor/src/portal/data/ops.ts @@ -425,7 +425,7 @@ export const OP_CATEGORIES: readonly OpCategoryMeta[] = [ }, { name: "Validation", - color: "var(--color-blue)", + color: "var(--c-primary)", blurb: "Schema checks, trust gates, filters", }, { @@ -470,7 +470,7 @@ export const OP_CATEGORIES: readonly OpCategoryMeta[] = [ }, { name: "Developer Tools", - color: "var(--color-text-5)", + color: "var(--c-text-subtle)", blurb: "Repair, compress, metadata", }, ]; diff --git a/frontend/editor/src/portal/theme/base.css b/frontend/editor/src/portal/theme/base.css index b9fa93d9e6..5326abaffc 100644 --- a/frontend/editor/src/portal/theme/base.css +++ b/frontend/editor/src/portal/theme/base.css @@ -9,7 +9,7 @@ :where, `.portal-scope button` would outweigh `.sui-btn` and strip its fill. */ .portal-scope { - color: var(--color-text-2); + color: var(--c-text-muted); font-family: var(--font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; @@ -31,7 +31,7 @@ } :where(.portal-scope) a { - color: var(--color-blue); + color: var(--c-primary); text-decoration: none; } diff --git a/frontend/editor/src/portal/theme/mantineTheme.ts b/frontend/editor/src/portal/theme/mantineTheme.ts index 01953245f9..d78f31ed69 100644 --- a/frontend/editor/src/portal/theme/mantineTheme.ts +++ b/frontend/editor/src/portal/theme/mantineTheme.ts @@ -84,25 +84,25 @@ const purple = tuple( */ export const suiCssVariablesResolver: CSSVariablesResolver = () => ({ variables: { - "--mantine-color-text": "var(--color-text-1)", + "--mantine-color-text": "var(--c-text)", "--mantine-color-placeholder": "var(--color-text-placeholder)", - "--mantine-color-body": "var(--color-bg)", + "--mantine-color-body": "var(--c-bg)", }, light: { // Popover/dropdown background + combobox search input - "--mantine-color-white": "var(--color-surface)", + "--mantine-color-white": "var(--c-surface)", // Option hover background - "--mantine-color-gray-0": "var(--color-bg-hover)", + "--mantine-color-gray-0": "var(--c-hover)", // Dropdown border - "--mantine-color-gray-2": "var(--color-border)", + "--mantine-color-gray-2": "var(--c-border)", }, dark: { // Popover/dropdown background (dark-6 is the floating surface in dark mode) - "--mantine-color-dark-6": "var(--color-surface)", + "--mantine-color-dark-6": "var(--c-surface)", // Deeper background used for option hover + combobox search input - "--mantine-color-dark-7": "var(--color-bg)", + "--mantine-color-dark-7": "var(--c-bg)", // Border in dark mode - "--mantine-color-dark-4": "var(--color-border)", + "--mantine-color-dark-4": "var(--c-border)", }, }); diff --git a/frontend/editor/src/portal/views/AccountLink.css b/frontend/editor/src/portal/views/AccountLink.css index 07b49a03f1..34afe4d7af 100644 --- a/frontend/editor/src/portal/views/AccountLink.css +++ b/frontend/editor/src/portal/views/AccountLink.css @@ -19,13 +19,13 @@ margin: 0; font-size: 1.375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-link__page-sub { margin: 0.25rem 0 0; font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); max-width: 44rem; } @@ -49,14 +49,14 @@ font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-link__title { margin: 0.125rem 0 0; font-size: 1.125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-link__form, @@ -85,13 +85,13 @@ margin: 0; font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-link__section-sub { margin: 0.25rem 0 0; font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); max-width: 44rem; } @@ -110,16 +110,16 @@ .portal-link__cell-strong { font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-link__device-id { font-size: 0.6875rem; - color: var(--color-text-5); + color: var(--c-text-subtle); font-variant-numeric: tabular-nums; } .portal-link__muted { - color: var(--color-text-4); + color: var(--c-text-subtle); font-size: 0.8125rem; } diff --git a/frontend/editor/src/portal/views/DeveloperDocs.css b/frontend/editor/src/portal/views/DeveloperDocs.css index 1786940dd5..d986c1448a 100644 --- a/frontend/editor/src/portal/views/DeveloperDocs.css +++ b/frontend/editor/src/portal/views/DeveloperDocs.css @@ -35,7 +35,7 @@ min-height: 0; height: 100%; overflow-y: auto; - border-right: 1px solid var(--color-border-light); + border-right: 1px solid var(--c-border-subtle); padding: 1.25rem 0; } @@ -61,7 +61,7 @@ top: 50%; transform: translateY(-50%); font-size: 0.9375rem; - color: var(--color-text-4); + color: var(--c-text-subtle); pointer-events: none; } @@ -69,20 +69,20 @@ width: 100%; padding: 0.4rem 0.6rem 0.4rem 1.9rem; font-size: 0.8125rem; - color: var(--color-text-1); + color: var(--c-text); background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-md); outline: none; } .portal-docs__search-input:focus { - border-color: var(--color-blue); + border-color: var(--c-primary); } .portal-docs__nav-empty { font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); padding: 0.5rem 0.75rem; margin: 0; } @@ -96,7 +96,7 @@ .portal-docs__results-count { font-size: 0.6875rem; font-weight: 500; - color: var(--color-text-4); + color: var(--c-text-subtle); padding: 0 0.75rem 0.5rem; } @@ -110,7 +110,7 @@ /* Hairline divider between results for clear, calm separation. */ .portal-docs__results-list li + li { - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } .portal-docs__result { @@ -121,7 +121,7 @@ .portal-docs__result:hover, .portal-docs__result.is-active { - background: var(--color-bg-hover); + background: var(--c-hover); } .portal-docs__result-body { @@ -145,7 +145,7 @@ .portal-docs__result-title { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); line-height: 1.3; min-width: 0; overflow: hidden; @@ -156,13 +156,13 @@ .portal-docs__result-section { flex-shrink: 0; font-size: 0.6875rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-docs__result-snippet { font-size: 0.75rem; line-height: 1.4; - color: var(--color-text-4); + color: var(--c-text-subtle); display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; @@ -171,7 +171,7 @@ /* Subtle match emphasis — coloured text, not a filled block. */ .portal-docs__hl { - color: var(--color-blue); + color: var(--c-primary); font-weight: 600; background: none; } @@ -190,13 +190,13 @@ font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Collapsible section header (Overview stays a static label). */ .portal-docs__nav-head--button:hover { - background: var(--color-bg-hover); - color: var(--color-text-2); + background: var(--c-hover); + color: var(--c-text-muted); } .portal-docs__nav-head-main { @@ -214,7 +214,7 @@ .portal-docs__nav-chevron { font-size: 0.625rem; - color: var(--color-text-4); + color: var(--c-text-subtle); transition: transform var(--motion-fast); } @@ -225,7 +225,7 @@ .portal-docs__nav-count { font-size: 0.625rem; font-weight: 600; - color: var(--color-text-4); + color: var(--c-text-subtle); background: var(--color-bg-subtle); border-radius: var(--radius-pill); padding: 0.05rem 0.4rem; @@ -240,7 +240,7 @@ .portal-docs__nav-children { margin: 0.125rem 0 0.25rem 0.85rem; padding-left: 0.4rem; - border-left: 1px solid var(--color-border-light); + border-left: 1px solid var(--c-border-subtle); display: flex; flex-direction: column; gap: 0.0625rem; @@ -266,7 +266,7 @@ background: transparent; border-radius: 0; font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); cursor: pointer; text-align: left; transition: @@ -275,13 +275,13 @@ } .portal-docs__nav-link:hover { - background: var(--color-bg-hover); - color: var(--color-text-1); + background: var(--c-hover); + color: var(--c-text); } .portal-docs__nav-link.is-active { - background: var(--color-blue-light); - color: var(--color-blue); + background: color-mix(in srgb, var(--c-primary) 12%, var(--c-surface)); + color: var(--c-primary); font-weight: 600; } @@ -317,7 +317,7 @@ min-height: 0; height: 100%; overflow-y: auto; - border-left: 1px solid var(--color-border-light); + border-left: 1px solid var(--c-border-subtle); padding: 1.5rem 0.75rem; } @@ -331,7 +331,7 @@ font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; - color: var(--color-text-4); + color: var(--c-text-subtle); padding: 0 0.5rem 0.5rem; } @@ -350,7 +350,7 @@ border-left: 2px solid transparent; font-size: 0.8125rem; line-height: 1.35; - color: var(--color-text-3); + color: var(--c-text-subtle); text-decoration: none; transition: color var(--motion-fast); } @@ -361,12 +361,12 @@ } .portal-docs__toc-link:hover { - color: var(--color-text-1); + color: var(--c-text); } .portal-docs__toc-link.is-active { - color: var(--color-blue); - border-left-color: var(--color-blue); + color: var(--c-primary); + border-left-color: var(--c-primary); font-weight: 600; } @@ -392,9 +392,9 @@ padding: 0.5rem 0.75rem; font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-md); cursor: pointer; } @@ -404,7 +404,7 @@ height: auto; max-height: 60vh; border-right: none; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .portal-docs__sidebar.is-open { @@ -426,7 +426,7 @@ font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.08em; - color: var(--color-blue); + color: var(--c-primary); } .portal-docs__section-title { @@ -434,7 +434,7 @@ font-size: 1.75rem; font-weight: 700; line-height: 1.15; - color: var(--color-text-1); + color: var(--c-text); } .portal-docs__section-lead { @@ -442,13 +442,13 @@ max-width: 46rem; font-size: 0.9375rem; line-height: 1.6; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-docs__callout { font-size: 0.875rem; line-height: 1.55; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-docs__callout code { @@ -483,7 +483,7 @@ width: 1.75rem; height: 1.75rem; border-radius: var(--radius-pill); - background: var(--color-blue); + background: var(--c-primary); color: var(--color-text-on-accent); font-size: 0.8125rem; font-weight: 700; @@ -500,14 +500,14 @@ margin: 0; font-size: 1rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-docs__step-body p { margin: 0; font-size: 0.875rem; line-height: 1.55; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-docs__snippet { @@ -529,7 +529,7 @@ align-items: center; gap: 0.75rem; font-size: 0.875rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } /* ── Rate limits ───────────────────────────────────────────────────────── */ @@ -548,14 +548,14 @@ .portal-docs__limit-label { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); margin-bottom: 0.25rem; } .portal-docs__limit-value { font-size: 1.25rem; font-weight: 700; - color: var(--color-text-1); + color: var(--c-text); } /* ── Endpoint reference ────────────────────────────────────────────────── */ @@ -569,7 +569,7 @@ .portal-docs__endpoint-group { display: flex; flex-direction: column; - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-lg); overflow: hidden; } @@ -581,9 +581,9 @@ padding: 0.625rem 0.875rem; font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); background: var(--color-bg-subtle); - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .portal-docs__endpoint-dot { @@ -597,7 +597,7 @@ align-items: center; gap: 0.75rem; padding: 0.5rem 0.875rem; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); font-size: 0.8125rem; } @@ -608,12 +608,12 @@ .portal-docs__endpoint-path { font-family: var(--font-mono, monospace); font-size: 0.8125rem; - color: var(--color-text-1); + color: var(--c-text); min-width: 11rem; } .portal-docs__endpoint-name { - color: var(--color-text-3); + color: var(--c-text-subtle); flex: 1; min-width: 0; overflow: hidden; @@ -623,7 +623,7 @@ .portal-docs__endpoint-fields { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); white-space: nowrap; } @@ -646,7 +646,7 @@ align-items: center; gap: 0.75rem; font-size: 0.875rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } /* ── SDK grid ──────────────────────────────────────────────────────────── */ @@ -678,7 +678,7 @@ margin: 0; font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); flex: 1; } @@ -715,7 +715,7 @@ margin: 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); } /* ── Playbooks ─────────────────────────────────────────────────────────── */ @@ -736,14 +736,14 @@ margin: 0 0 0.375rem; font-size: 1rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-docs__playbook-blurb { margin: 0 0 0.875rem; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-docs__playbook-flow { @@ -761,7 +761,7 @@ } .portal-docs__playbook-arrow { - color: var(--color-text-4); + color: var(--c-text-subtle); font-size: 0.75rem; } @@ -808,20 +808,20 @@ margin: 0; font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-docs__skill-blurb { margin: 0 0 0.625rem; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-docs__skill-ops { font-family: var(--font-mono, monospace); font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* ── Markdown content ──────────────────────────────────────────────────── */ @@ -829,14 +829,14 @@ .portal-docs__md { font-size: 0.9375rem; line-height: 1.65; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-docs__md h1, .portal-docs__md h2, .portal-docs__md h3, .portal-docs__md h4 { - color: var(--color-text-1); + color: var(--c-text); font-weight: 650; line-height: 1.25; margin: 1.75rem 0 0.75rem; @@ -845,7 +845,7 @@ .portal-docs__md h2 { font-size: 1.3125rem; padding-bottom: 0.3rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .portal-docs__md h3 { @@ -871,7 +871,7 @@ } .portal-docs__md a { - color: var(--color-blue); + color: var(--c-primary); text-decoration: none; } @@ -890,10 +890,10 @@ .portal-docs__md blockquote { margin: 0 0 0.875rem; padding: 0.125rem 0.875rem; - border-left: 3px solid var(--color-blue); + border-left: 3px solid var(--c-primary); background: var(--color-bg-subtle); border-radius: 0 var(--radius-md) var(--radius-md) 0; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-docs__md blockquote p { @@ -904,12 +904,12 @@ max-width: 100%; height: auto; border-radius: var(--radius-md); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); } .portal-docs__md hr { border: none; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); margin: 1.5rem 0; } @@ -922,7 +922,7 @@ margin: 0; padding: 0.875rem 4rem 0.875rem 0.875rem; background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-md); overflow-x: auto; font-size: 0.8125rem; @@ -954,7 +954,7 @@ .portal-docs__md-tablewrap th, .portal-docs__md-tablewrap td { - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); padding: 0.4rem 0.625rem; text-align: left; } @@ -967,16 +967,16 @@ .portal-docs__source { margin-top: 2rem; padding-top: 1rem; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); font-size: 0.8125rem; } .portal-docs__source a { - color: var(--color-text-3); + color: var(--c-text-subtle); text-decoration: none; } .portal-docs__source a:hover { - color: var(--color-blue); + color: var(--c-primary); text-decoration: underline; } diff --git a/frontend/editor/src/portal/views/Documents.css b/frontend/editor/src/portal/views/Documents.css index 13cbf33c3c..f363037981 100644 --- a/frontend/editor/src/portal/views/Documents.css +++ b/frontend/editor/src/portal/views/Documents.css @@ -25,14 +25,14 @@ margin: 0; font-size: 1.375rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-documents__sub { margin: 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); max-width: 46rem; } @@ -81,12 +81,12 @@ .portal-documents__name { font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-documents__note { font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-documents__lock { @@ -97,18 +97,18 @@ .portal-documents__muted { font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-documents__action { font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-documents__editor-action { font-size: 0.8125rem; font-style: italic; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Drawer body */ @@ -137,7 +137,7 @@ .portal-documents__field { font-weight: 500; - color: var(--color-text-1); + color: var(--c-text); } /* Masked / sensitive placeholder */ @@ -149,7 +149,7 @@ padding: 2rem 1rem; text-align: center; background: var(--color-bg-subtle); - border: 1px dashed var(--color-border); + border: 1px dashed var(--c-border); border-radius: var(--radius-lg); } @@ -160,7 +160,7 @@ .portal-documents__masked-text { margin: 0; font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); max-width: 22rem; } @@ -192,7 +192,7 @@ height: 0.5rem; margin-top: 0.375rem; border-radius: 50%; - background: var(--color-blue); + background: var(--c-primary); } /* Connecting line between successive timeline dots. */ @@ -205,7 +205,7 @@ transform: translateX(-50%); width: 1px; height: calc(100% + 1rem); - background: var(--color-border); + background: var(--c-border); } .portal-documents__timeline-body { @@ -223,18 +223,18 @@ .portal-documents__timeline-time { font-size: 0.6875rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-documents__timeline-detail { margin: 0; font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); line-height: 1.45; } .portal-documents__timeline-actor { font-family: var(--font-mono); font-size: 0.6875rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } diff --git a/frontend/editor/src/portal/views/EditorAdmin.css b/frontend/editor/src/portal/views/EditorAdmin.css index 61ef2834dd..1ccd0d63b1 100644 --- a/frontend/editor/src/portal/views/EditorAdmin.css +++ b/frontend/editor/src/portal/views/EditorAdmin.css @@ -19,14 +19,14 @@ margin: 0; font-size: 1.375rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-editor__sub { margin: 0.25rem 0 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); max-width: 52rem; } @@ -39,14 +39,14 @@ margin: 0; font-size: 1rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-editor__section-sub { margin: 0.1875rem 0 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-4); + color: var(--c-text-subtle); max-width: 52rem; } @@ -92,11 +92,11 @@ .portal-editor__target-icon--neutral { background: var(--color-bg-subtle); - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-editor__target-icon--blue { - background: var(--color-blue-light); - color: var(--color-blue); + background: var(--c-primary-tint); + color: var(--c-primary); } .portal-editor__target-icon--purple { background: var(--color-purple-light); @@ -112,21 +112,21 @@ margin: 0; font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-editor__target-tagline { margin: 0.1875rem 0 0; font-size: 0.75rem; line-height: 1.45; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-editor__target-meta { margin: 0; font-size: 0.75rem; font-family: var(--font-mono); - color: var(--color-text-3); + color: var(--c-text-subtle); } /* ──────────────────────────────────────────────────────────────────────── */ @@ -140,7 +140,7 @@ gap: 0.625rem; padding: 0.875rem; background: var(--color-bg-subtle); - border: 1px dashed var(--color-border); + border: 1px dashed var(--c-border); border-radius: var(--radius-md); } @@ -148,7 +148,7 @@ margin: 0; font-size: 0.8125rem; line-height: 1.45; - color: var(--color-text-3); + color: var(--c-text-subtle); } /* ──────────────────────────────────────────────────────────────────────── */ @@ -191,8 +191,8 @@ } .portal-editor__pairing-icon--blue { - background: var(--color-blue-light); - color: var(--color-blue); + background: color-mix(in srgb, var(--c-primary) 12%, var(--c-surface)); + color: var(--c-primary); } .portal-editor__pairing-icon--purple { background: var(--color-purple-light); @@ -212,27 +212,27 @@ margin: 0; font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-editor__pairing-desc { margin: 0.1875rem 0 0; font-size: 0.75rem; line-height: 1.45; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-editor__pairing-value { padding: 0.625rem 0.75rem; background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-md); } .portal-editor__pairing-value code { font-family: var(--font-mono); font-size: 0.8125rem; - color: var(--color-text-1); + color: var(--c-text); word-break: break-all; } @@ -258,7 +258,7 @@ .portal-editor__cell-strong { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-editor__cell-muted { @@ -268,12 +268,12 @@ .portal-editor__mono { font-family: var(--font-mono); font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-editor__muted { font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* ──────────────────────────────────────────────────────────────────────── */ @@ -313,14 +313,14 @@ margin: 0; font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-editor__panel-sub { margin: 0.25rem 0 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-editor__enterprise-tag { diff --git a/frontend/editor/src/portal/views/Home.css b/frontend/editor/src/portal/views/Home.css index 3027dfa1bc..732bd617a5 100644 --- a/frontend/editor/src/portal/views/Home.css +++ b/frontend/editor/src/portal/views/Home.css @@ -16,12 +16,12 @@ font-size: 1.5rem; font-weight: 700; letter-spacing: -0.02em; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-home__greeting-date { margin: 0; font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Two-column dashboard row (activity + quick actions) */ @@ -47,12 +47,12 @@ margin: 0; font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-home__quick-sub { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-home__quick-list { @@ -65,7 +65,7 @@ shared Button's leftSection / label / rightSection, not overridden here. */ .portal-home__quick-row { background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-md); text-align: left; transition: @@ -74,8 +74,8 @@ } .portal-home__quick-row:hover { - background: var(--color-bg-hover); - border-color: var(--color-border); + background: var(--c-hover); + border-color: var(--c-border); } /* Let the label grow so the arrow (rightSection) is pushed to the far right, @@ -109,18 +109,19 @@ .portal-home__quick-text strong { font-size: 0.8125rem; - color: var(--color-text-1); + color: var(--c-text); font-weight: 600; } .portal-home__quick-text span { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-home__quick-arrow { display: inline-flex; - color: var(--color-text-5); + font-size: 0.875rem; + color: var(--c-text-subtle); } .portal-home__quick-arrow svg { width: 1rem; @@ -128,5 +129,5 @@ } .portal-home__quick-row:hover .portal-home__quick-arrow { - color: var(--color-blue); + color: var(--c-primary); } diff --git a/frontend/editor/src/portal/views/Infrastructure.css b/frontend/editor/src/portal/views/Infrastructure.css index 1d98dee925..2bff218e96 100644 --- a/frontend/editor/src/portal/views/Infrastructure.css +++ b/frontend/editor/src/portal/views/Infrastructure.css @@ -24,13 +24,13 @@ margin: 0; font-size: 1.375rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-infra__sub { margin: 0; font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); max-width: 48rem; } @@ -62,13 +62,13 @@ margin: 0; font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-infra__section-sub { margin: 0.125rem 0 0; font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Audit tab header row: section heading + Export action */ @@ -95,7 +95,7 @@ .portal-infra__export-label { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-infra__export-fields { @@ -113,7 +113,7 @@ .portal-infra__export-error { margin: 0; font-size: 0.8125rem; - color: var(--color-danger, #e5484d); + color: var(--c-danger); } .portal-infra__export-actions { @@ -146,13 +146,13 @@ .portal-infra__cell-strong { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-infra__cell-code { font-family: var(--font-mono); font-size: 0.6875rem; - color: var(--color-text-3); + color: var(--c-text-subtle); background: var(--color-bg-code); padding: 0.0625rem 0.3125rem; border-radius: var(--radius-sm); @@ -162,12 +162,12 @@ .portal-infra__mono { font-family: var(--font-mono); font-size: 0.75rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-infra__muted { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Region load cell */ @@ -180,7 +180,7 @@ .portal-infra__load-pct { font-family: var(--font-mono); font-size: 0.6875rem; - color: var(--color-text-3); + color: var(--c-text-subtle); min-width: 2.25rem; text-align: right; } @@ -226,7 +226,7 @@ } .portal-infra__key-head:hover { - background: var(--color-bg-hover); + background: var(--c-hover); } .portal-infra__key-id { @@ -244,7 +244,7 @@ .portal-infra__chevron { font-size: 1.125rem; - color: var(--color-text-5); + color: var(--c-text-subtle); transition: transform var(--motion-fast); line-height: 1; } @@ -255,7 +255,7 @@ .portal-infra__key-body { padding: 0 1.125rem 1.125rem; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } .portal-infra__kv { @@ -279,14 +279,14 @@ font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--color-text-5); + color: var(--c-text-subtle); margin-bottom: 0.25rem; } .portal-infra__kv dd { margin: 0; font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-infra__chips { @@ -342,7 +342,7 @@ .portal-infra__cert-detail { margin: 0; font-size: 0.6875rem; - color: var(--color-text-4); + color: var(--c-text-subtle); line-height: 1.4; } @@ -392,7 +392,7 @@ .portal-infra__attestation-link { font-size: 0.75rem; font-weight: 600; - color: var(--color-blue); + color: var(--c-primary); text-decoration: none; } @@ -412,7 +412,7 @@ .portal-infra__usage-value { font-size: 1.25rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-infra__usage-value .portal-infra__muted { @@ -436,7 +436,7 @@ gap: 0.75rem; padding: 0.625rem 0.75rem; background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-md); } @@ -447,8 +447,8 @@ width: 1.75rem; height: 1.75rem; border-radius: var(--radius-md); - background: var(--color-blue-light); - color: var(--color-blue); + background: var(--c-primary-tint); + color: var(--c-primary); font-size: 0.875rem; } @@ -480,7 +480,7 @@ gap: 0.25rem; padding: 0.625rem 0.75rem; background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-md); } @@ -493,7 +493,7 @@ width: 0.5rem; height: 0.5rem; border-radius: 50%; - background: var(--color-text-5); + background: var(--c-text-subtle); } .portal-infra__lifecycle-stage.is-active .portal-infra__lifecycle-dot { @@ -503,13 +503,13 @@ .portal-infra__lifecycle-label { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-infra__lifecycle-arrow { display: flex; align-items: center; - color: var(--color-text-5); + color: var(--c-text-subtle); font-size: 0.875rem; } @@ -522,7 +522,7 @@ .portal-infra__event span { font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } /* ── Table skeleton ─────────────────────────────────────────────────────── */ diff --git a/frontend/editor/src/portal/views/PipelineBuilder.css b/frontend/editor/src/portal/views/PipelineBuilder.css index c7e273eec1..b56b199676 100644 --- a/frontend/editor/src/portal/views/PipelineBuilder.css +++ b/frontend/editor/src/portal/views/PipelineBuilder.css @@ -20,7 +20,7 @@ gap: 0.75rem; flex-wrap: wrap; padding-bottom: 1rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .portal-builder__back { @@ -31,13 +31,13 @@ background: none; padding: 0; font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); cursor: pointer; white-space: nowrap; } .portal-builder__back:hover { - color: var(--color-text-1); + color: var(--c-text); } .portal-builder__head-main { @@ -75,13 +75,13 @@ font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--color-text-5); + color: var(--c-text-subtle); font-weight: 600; } .portal-builder__empty { font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); margin: 0; padding: 0.5rem 0; } @@ -100,8 +100,8 @@ display: flex; align-items: center; gap: 0.5rem; - background: var(--color-surface); - border: 1px solid var(--color-border-light); + background: var(--c-surface); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-lg); padding: 0.5rem 0.625rem; transition: @@ -110,8 +110,8 @@ } .portal-builder__step--active { - border-color: var(--color-blue); - background: var(--color-blue-light); + border-color: var(--c-primary); + background: var(--c-primary-tint); } .portal-builder__step-main { @@ -138,12 +138,12 @@ border-radius: 50%; font-size: 0.6875rem; font-weight: 600; - background: var(--color-blue-light); - color: var(--color-blue); + background: var(--c-primary-tint); + color: var(--c-primary); } .portal-builder__step--active .portal-builder__step-index { - background: var(--color-blue); + background: var(--c-primary); color: #fff; } @@ -156,12 +156,12 @@ .portal-builder__step-name { font-size: 0.875rem; font-weight: 500; - color: var(--color-text-1); + color: var(--c-text); } .portal-builder__step-note { font-size: 0.6875rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-builder__step-actions { @@ -177,9 +177,9 @@ height: 1.5rem; padding: 0; border-radius: var(--radius-md); - border: 1px solid var(--color-border); - background: var(--color-surface); - color: var(--color-text-3); + border: 1px solid var(--c-border); + background: var(--c-surface); + color: var(--c-text-subtle); cursor: pointer; transition: background var(--motion-fast), @@ -187,8 +187,8 @@ } .portal-builder__step-actions button:hover:not(:disabled) { - background: var(--color-bg-hover); - color: var(--color-text-1); + background: var(--c-hover); + color: var(--c-text); } .portal-builder__step-actions button:disabled { @@ -203,10 +203,10 @@ gap: 0.375rem; width: 100%; padding: 0.625rem; - border: 1px dashed var(--color-border); + border: 1px dashed var(--c-border); border-radius: var(--radius-lg); background: none; - color: var(--color-text-3); + color: var(--c-text-subtle); font-size: 0.8125rem; cursor: pointer; transition: @@ -215,8 +215,8 @@ } .portal-builder__add-step:hover { - border-color: var(--color-blue); - color: var(--color-blue); + border-color: var(--c-primary); + color: var(--c-primary); } /* Pipeline settings (above the operation list) */ @@ -225,7 +225,7 @@ flex-direction: column; gap: 0.75rem; background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-lg); padding: 1.125rem; } @@ -259,8 +259,8 @@ } .portal-builder__inspector { - background: var(--color-surface); - border: 1px solid var(--color-border); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: 1.125rem; @@ -268,9 +268,9 @@ /* Tool picker */ .portal-pipelines__picker { - border: 1px solid var(--color-border); + border: 1px solid var(--c-border); border-radius: var(--radius-lg); - background: var(--color-surface); + background: var(--c-surface); overflow: hidden; } @@ -278,7 +278,7 @@ display: flex; align-items: center; padding: 0.5rem 0.75rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .portal-pipelines__picker-search input { @@ -287,7 +287,7 @@ background: none; padding: 0; font-size: 0.875rem; - color: var(--color-text-1); + color: var(--c-text); outline: none; } @@ -300,7 +300,7 @@ .portal-pipelines__picker-group-label { padding: 0.5rem 0.75rem 0.25rem; font-size: 0.6875rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-pipelines__picker-item { @@ -313,18 +313,18 @@ padding: 0.4375rem 0.75rem; text-align: left; cursor: pointer; - color: var(--color-text-1); + color: var(--c-text); transition: background var(--motion-fast); } .portal-pipelines__picker-item:hover { - background: var(--color-bg-hover); + background: var(--c-hover); } .portal-pipelines__picker-icon { display: inline-flex; align-items: center; - color: var(--color-text-3); + color: var(--c-text-subtle); font-size: 1.125rem; } @@ -335,7 +335,7 @@ .portal-pipelines__picker-empty { padding: 1rem 0.75rem; font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); margin: 0; } @@ -349,11 +349,11 @@ padding: 0; font-weight: 400; font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-builder__back.sui-btn:hover { - color: var(--color-text-1); + color: var(--c-text); } .portal-builder__step-main.sui-btn { @@ -369,16 +369,16 @@ height: auto; min-height: 0; padding: 0.625rem; - border: 1px dashed var(--color-border); + border: 1px dashed var(--c-border); background: none; font-weight: 400; font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-builder__add-step.sui-btn:hover { - border-color: var(--color-blue); - color: var(--color-blue); + border-color: var(--c-primary); + color: var(--c-primary); } .portal-pipelines__picker-item.sui-btn { @@ -386,11 +386,11 @@ min-height: 0; padding: 0.4375rem 0.75rem; font-weight: 400; - color: var(--color-text-1); + color: var(--c-text); } .portal-pipelines__picker-item.sui-btn:hover { - background: var(--color-bg-hover); + background: var(--c-hover); } .portal-builder__step-actions .sui-ai { diff --git a/frontend/editor/src/portal/views/Pipelines.css b/frontend/editor/src/portal/views/Pipelines.css index 5c99f6a224..989feab4fe 100644 --- a/frontend/editor/src/portal/views/Pipelines.css +++ b/frontend/editor/src/portal/views/Pipelines.css @@ -20,14 +20,14 @@ margin: 0; font-size: 1.375rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-pipelines__sub { margin: 0.25rem 0 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); max-width: 46rem; } @@ -49,7 +49,7 @@ .portal-pipelines__name-text strong { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-pipelines__pipe-dot { @@ -61,25 +61,25 @@ flex-shrink: 0; border-radius: var(--radius-md); font-size: 0.875rem; - background: var(--color-blue-light); - color: var(--color-blue); + background: var(--c-primary-tint); + color: var(--c-primary); } .portal-pipelines__muted { font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); margin: 0; } .portal-pipelines__caret { display: inline-block; - color: var(--color-text-5); + color: var(--c-text-subtle); transition: transform var(--motion-fast); } .portal-pipelines__caret.is-open { transform: rotate(90deg); - color: var(--color-blue); + color: var(--c-primary); } /* Table skeleton */ @@ -94,7 +94,7 @@ font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--color-text-5); + color: var(--c-text-subtle); font-weight: 600; } @@ -113,7 +113,7 @@ overflow-y: auto; padding: 0.625rem; background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-md); } diff --git a/frontend/editor/src/portal/views/Policies.css b/frontend/editor/src/portal/views/Policies.css index e58d5522a8..e1a821ee27 100644 --- a/frontend/editor/src/portal/views/Policies.css +++ b/frontend/editor/src/portal/views/Policies.css @@ -18,14 +18,14 @@ margin: 0; font-size: 1.375rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-policies__sub { margin: 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); max-width: 46rem; } @@ -49,14 +49,14 @@ flex: 1; font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-3); + color: var(--c-text-subtle); } /* "Set up" underline link inside the active-row button's rightSection */ .portal-policies__setup-link { font-size: 0.8125rem; font-weight: 600; - color: var(--color-blue); + color: var(--c-primary); text-decoration: underline; text-underline-offset: 2px; } @@ -83,7 +83,7 @@ .portal-policies__card-enforces { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -106,13 +106,13 @@ .portal-policies__card-statval { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); line-height: 1.2; } .portal-policies__card-statlbl { font-size: 0.6875rem; - color: var(--color-text-4); + color: var(--c-text-subtle); line-height: 1.2; } @@ -124,19 +124,19 @@ height: 2rem; flex-shrink: 0; font-size: 1.125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-policies__card-title { margin: 0; font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-policies__card-blurb { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); line-height: 1.4; } @@ -144,7 +144,7 @@ margin: 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-policies__card-foot { @@ -165,7 +165,7 @@ .portal-policies__card-cta { font-size: 0.75rem; font-weight: 600; - color: var(--color-blue); + color: var(--c-primary); } .portal-policies__chevron-right { @@ -180,7 +180,7 @@ gap: 0.5rem; margin-top: auto; padding-top: 0.75rem; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } @media (max-width: 30rem) { @@ -219,7 +219,7 @@ margin: 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-policies__wizard-heading { @@ -227,7 +227,7 @@ font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--color-text-5); + color: var(--c-text-subtle); font-weight: 600; } @@ -260,13 +260,13 @@ } .portal-policies__capability + .portal-policies__capability { - border-top: 1px solid var(--color-border); + border-top: 1px solid var(--c-border); } /* An enabled row with config gets a faint tint so the revealed settings read as * belonging to it. */ .portal-policies__capability[data-on] .portal-policies__capability-config { - border-top: 1px dashed var(--color-border); + border-top: 1px dashed var(--c-border); padding-top: 0.75rem; margin-top: 0.75rem; } @@ -282,7 +282,7 @@ } .portal-policies__source--on { - border-color: var(--color-blue); + border-color: var(--c-primary); } .portal-policies__source-label { @@ -297,7 +297,7 @@ padding: 0; font-size: 0.75rem; font-weight: 600; - color: var(--color-blue); + color: var(--c-primary); cursor: pointer; } @@ -320,17 +320,17 @@ } .portal-policies__detail-sep { - color: var(--color-text-5); + color: var(--c-text-subtle); font-size: 0.75rem; } .portal-policies__detail-meta { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-policies__enforce-arrow { - color: var(--color-text-5); + color: var(--c-text-subtle); font-size: 0.75rem; } @@ -344,7 +344,7 @@ .portal-policies__detail-inline-label { font-size: 0.6875rem; font-weight: 600; - color: var(--color-text-4); + color: var(--c-text-subtle); text-transform: uppercase; letter-spacing: 0.04em; flex-shrink: 0; @@ -353,7 +353,7 @@ .portal-policies__detail-inline-value { font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); line-height: 1.5; } @@ -366,7 +366,7 @@ } .portal-policies__activity-row + .portal-policies__activity-row { - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } .portal-policies__activity-icon { @@ -384,7 +384,7 @@ color: var(--color-amber); } .portal-policies__activity-icon--info { - color: var(--color-blue); + color: var(--c-primary); } @keyframes portal-policies-spin { @@ -408,17 +408,17 @@ .portal-policies__activity-doc { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-policies__activity-action { font-size: 0.75rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-policies__activity-time { font-size: 0.6875rem; - color: var(--color-text-5); + color: var(--c-text-subtle); white-space: nowrap; } @@ -457,7 +457,7 @@ } .portal-policies__detail-stats .sui-stat + .sui-stat { - border-left: 1px solid var(--color-border-light); + border-left: 1px solid var(--c-border-subtle); } /* ── Catalogue table (replaces the stacked category cards) ──────────────── */ @@ -471,7 +471,7 @@ .portal-policies__cell-name { font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); min-width: 0; } @@ -483,13 +483,13 @@ .portal-policies__muted { font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-policies__docs { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); font-variant-numeric: tabular-nums; } /* The .pcat-badge icon styles live with the PolicyCategoryIcon component diff --git a/frontend/editor/src/portal/views/Procurement.css b/frontend/editor/src/portal/views/Procurement.css index f733b2c5a3..e26fd74a31 100644 --- a/frontend/editor/src/portal/views/Procurement.css +++ b/frontend/editor/src/portal/views/Procurement.css @@ -19,13 +19,13 @@ margin: 0; font-size: 1.375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__subtitle { margin: 0.25rem 0 0; font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Eyebrow label shared by the journey header + SE block */ @@ -35,7 +35,7 @@ font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; - color: var(--color-text-5); + color: var(--c-text-subtle); margin-bottom: 0.25rem; } @@ -47,7 +47,7 @@ justify-content: space-between; gap: 1rem; padding: 1.25rem 1.5rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); flex-wrap: wrap; } @@ -55,7 +55,7 @@ margin: 0; font-size: 1.0625rem; font-weight: 700; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__journey-sub { @@ -63,7 +63,7 @@ max-width: 36rem; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-proc__se { @@ -80,12 +80,12 @@ .portal-proc__se-name { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__se-email { font-size: 0.75rem; - color: var(--color-blue); + color: var(--c-primary); text-decoration: none; } @@ -96,7 +96,7 @@ /* Stepper band */ .portal-proc__journey-stepper { padding: 1.125rem 1.5rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .portal-proc__steps { @@ -122,7 +122,7 @@ width: 0.875rem; height: 0.875rem; border-radius: 50%; - background: var(--color-border-input); + background: var(--c-border); } .portal-proc__step--complete .portal-proc__step-dot { @@ -139,16 +139,16 @@ font-weight: 500; text-align: center; white-space: nowrap; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-proc__step--complete .portal-proc__step-label { - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-proc__step--current .portal-proc__step-label { font-weight: 700; - color: var(--color-text-1); + color: var(--c-text); } /* Connector aligns with the 0.875rem dots: (14px − 2px) / 2 = 6px down */ @@ -156,7 +156,7 @@ flex: 1; height: 2px; margin: 0.375rem 0.375rem 0; - background: var(--color-border-light); + background: var(--c-border-subtle); } .portal-proc__step-line[data-filled="true"] { @@ -170,28 +170,28 @@ gap: 0.625rem; flex-wrap: wrap; padding: 0.75rem 1.5rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); background: var(--color-bg-code); } .portal-proc__trial-title { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__trial-dim { font-size: 0.78125rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-proc__trial-key { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; font-size: 0.6875rem; - color: var(--color-text-4); - background: var(--color-surface); - border: 1px solid var(--color-border-input); + color: var(--c-text-subtle); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: 0.375rem; padding: 0.1875rem 0.5rem; } @@ -212,7 +212,7 @@ gap: 0.625rem; font-size: 0.84375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__next-dot { @@ -230,20 +230,20 @@ /* ── Documents card ───────────────────────────────────────────────────── */ .portal-proc__docs-head { padding: 1.125rem 1.5rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .portal-proc__docs-title { margin: 0; font-size: 0.9375rem; font-weight: 700; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__docs-sub { margin: 0.25rem 0 0; font-size: 0.78125rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-proc__docs-body { @@ -273,7 +273,7 @@ } .portal-proc__stage-dot[data-state="upcoming"] { - background: var(--color-border-input); + background: var(--c-border); } .portal-proc__stage-label { @@ -281,30 +281,30 @@ font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-proc__stage-label[data-current] { - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__stage-hint { font-size: 0.71875rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-proc__stage-count { font-size: 0.6875rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } /* Document lists inside the accordion */ .portal-proc__doc-list { - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } .portal-proc__doc-list--boxed { - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: 0.5rem; overflow: hidden; } @@ -326,20 +326,20 @@ font-size: 0.71875rem; font-weight: 400; line-height: 1.45; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-proc__acc-toggle-label { font-size: 0.75rem; font-weight: 600; - color: var(--color-blue); + color: var(--c-primary); } .portal-proc__supporting-groups { display: flex; flex-direction: column; gap: 1rem; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); padding: 0.875rem; } @@ -348,7 +348,7 @@ font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; - color: var(--color-text-5); + color: var(--c-text-subtle); margin-bottom: 0.5rem; } @@ -359,7 +359,7 @@ justify-content: space-between; gap: 1rem; padding: 0.75rem 0.875rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .portal-proc__doc:last-child { @@ -384,14 +384,14 @@ .portal-proc__doc-name { font-size: 0.84375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__doc-sub { margin: 0.0625rem 0 0; font-size: 0.71875rem; line-height: 1.4; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-proc__doc-actions { @@ -413,7 +413,7 @@ margin: 0 0 1rem; font-size: 0.875rem; line-height: 1.55; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-proc__modal-actions { @@ -435,7 +435,7 @@ .portal-proc__upload-name { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } @media (max-width: 48rem) { @@ -466,8 +466,8 @@ font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; - color: var(--color-primary, #2383e2); - background: var(--color-primary-light, #eaf2fb); + color: var(--c-primary); + background: var(--c-primary-subtle); padding: 0.15rem 0.5rem; border-radius: 0.375rem; margin-bottom: 0.4rem; @@ -476,11 +476,11 @@ margin: 0; font-size: 0.8125rem; line-height: 1.45; - color: var(--color-text-3); + color: var(--c-text-subtle); max-width: 44rem; } .portal-proc__upsell-copy strong { - color: var(--color-text-1); + color: var(--c-text); } /* ── Quote builder ────────────────────────────────────────────────────────── */ @@ -494,11 +494,11 @@ margin: 0; font-size: 1rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__builder-step { font-size: 0.75rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-proc__builder-body { display: flex; @@ -510,23 +510,23 @@ flex-direction: column; gap: 0.3rem; font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-proc__field input, .portal-proc__field select { padding: 0.45rem 0.6rem; - border: 1px solid var(--color-border, #eae8e3); + border: 1px solid var(--c-border); border-radius: 0.5rem; font-size: 0.875rem; - background: var(--color-bg-elevated, #fff); - color: var(--color-text-1); + background: var(--c-input-bg); + color: var(--c-text); } .portal-proc__builder-addons { display: flex; flex-direction: column; gap: 0.4rem; font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-proc__builder-addons label { display: flex; @@ -543,16 +543,16 @@ display: flex; align-items: baseline; justify-content: space-between; - border-bottom: 1px solid var(--color-border, #eae8e3); + border-bottom: 1px solid var(--c-border); padding-bottom: 0.5rem; } .portal-proc__quote-number { font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__quote-valid { font-size: 0.75rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-proc__quote-lines { list-style: none; @@ -564,11 +564,11 @@ justify-content: space-between; padding: 0.4rem 0; font-size: 0.8125rem; - color: var(--color-text-2); - border-bottom: 1px solid var(--color-border-light, #f0eee9); + color: var(--c-text-muted); + border-bottom: 1px solid var(--c-border-subtle); } .portal-proc__quote-lines li[data-kind="DISCOUNT"] { - color: var(--color-success, #0f7b6c); + color: var(--c-success); } .portal-proc__quote-total { display: flex; @@ -579,19 +579,19 @@ } .portal-proc__quote-total strong { font-size: 1.25rem; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__quote-tcv { font-size: 0.75rem; - color: var(--color-text-5); + color: var(--c-text-subtle); } /* ══ Quote builder — copied from the marketing prototype (tight density) ═════ */ .portal-qb { - background: #ffffff; - border: 1px solid #e3e1dc; + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: 14px; - box-shadow: inset 0 0 0 1px #eae8e3; + box-shadow: inset 0 0 0 1px var(--c-border-subtle); overflow: hidden; } .portal-qb__head { @@ -599,10 +599,10 @@ align-items: center; justify-content: space-between; padding: 18px 24px 14px; - border-bottom: 1px solid #f0eee9; + border-bottom: 1px solid var(--c-border-subtle); background: linear-gradient( 180deg, - rgba(35, 131, 226, 0.055) 0%, + color-mix(in srgb, var(--c-primary) 5.5%, transparent) 0%, transparent 100% ); } @@ -610,13 +610,13 @@ margin: 0; font-size: 16px; font-weight: 700; - color: #37352f; + color: var(--c-text); } .portal-qb__stepchip { font-size: 11px; font-weight: 700; - color: #9b9a97; - background: #f5f4f1; + color: var(--c-text-subtle); + background: var(--c-surface-sunken); padding: 3px 10px; border-radius: 999px; } @@ -629,11 +629,11 @@ flex: 1; height: 6px; border-radius: 999px; - background: #f0eee9; + background: var(--c-surface-sunken); transition: background 0.3s; } .portal-qb__progress span[data-on] { - background: #2383e2; + background: var(--c-primary); } .portal-qb__body { padding: 20px 24px; @@ -650,7 +650,7 @@ width: 38px; height: 38px; border-radius: 10px; - background: #eaf2fb; + background: var(--c-primary-tint); display: flex; align-items: center; justify-content: center; @@ -660,11 +660,11 @@ .portal-qb__intro-title { font-size: 15px; font-weight: 700; - color: #37352f; + color: var(--c-text); } .portal-qb__intro-sub { font-size: 12.5px; - color: #9b9a97; + color: var(--c-text-subtle); margin-top: 1px; } .portal-qb__field { @@ -675,7 +675,7 @@ display: block; font-size: 12px; font-weight: 600; - color: #787774; + color: var(--c-text-muted); margin-bottom: 6px; } .portal-qb__field input, @@ -685,11 +685,11 @@ padding: 9px 11px; font-size: 13.5px; border-radius: 8px; - border: 1px solid #e3e1dc; + border: 1px solid var(--c-border); font-family: inherit; outline: none; - background: #fff; - color: #37352f; + background: var(--c-input-bg); + color: var(--c-text); } .portal-qb__row { display: flex; @@ -703,7 +703,7 @@ .portal-qb__hint { margin: 7px 0 0; font-size: 11.5px; - color: #9b9a97; + color: var(--c-text-subtle); line-height: 1.4; } .portal-qb__pills { @@ -716,20 +716,20 @@ font-size: 13px; font-weight: 600; border-radius: 8px; - border: 1px solid #e3e1dc; - background: #fff; - color: #37352f; + border: 1px solid var(--c-border); + background: var(--c-surface); + color: var(--c-text); cursor: pointer; } .portal-qb__pills button[data-on] { - background: #2383e2; - border-color: #2383e2; - color: #fff; + background: var(--c-primary); + border-color: var(--c-primary); + color: var(--c-text-on-primary); } .portal-qb__discount { margin: 6px 0 0; font-size: 11.5px; - color: #0f7b6c; + color: var(--c-success); } .portal-qb__opts { display: flex; @@ -742,28 +742,28 @@ min-width: 150px; padding: 12px 14px; border-radius: 9px; - border: 1px solid #e3e1dc; - background: #fff; + border: 1px solid var(--c-border); + background: var(--c-surface); cursor: pointer; display: flex; flex-direction: column; gap: 2px; } .portal-qb__opt[data-on] { - border-color: #2383e2; - background: #eaf2fb; + border-color: var(--c-primary); + background: var(--c-primary-tint); } .portal-qb__opt-title { font-size: 13px; font-weight: 700; - color: #37352f; + color: var(--c-text); } .portal-qb__opt[data-on] .portal-qb__opt-title { - color: #1b6ec2; + color: var(--c-primary); } .portal-qb__opt-sub { font-size: 11.5px; - color: #9b9a97; + color: var(--c-text-muted); line-height: 1.4; } .portal-qb__addons { @@ -777,43 +777,43 @@ gap: 11px; padding: 11px 13px; border-radius: 9px; - border: 1px solid #e3e1dc; - background: #fff; + border: 1px solid var(--c-border); + background: var(--c-surface); cursor: pointer; text-align: left; } .portal-qb__addon[data-on] { - border-color: #2383e2; - background: #eaf2fb; + border-color: var(--c-primary); + background: var(--c-primary-tint); } .portal-qb__addon-box { width: 18px; height: 18px; flex-shrink: 0; border-radius: 5px; - border: 1px solid #d3d1cb; + border: 1px solid var(--c-border); display: flex; align-items: center; justify-content: center; font-size: 12px; color: transparent; - background: #fff; + background: var(--c-surface); } .portal-qb__addon[data-on] .portal-qb__addon-box { - background: #2383e2; - border-color: #2383e2; - color: #fff; + background: var(--c-primary); + border-color: var(--c-primary); + color: var(--c-text-on-primary); } .portal-qb__addon-title { display: block; font-size: 13px; font-weight: 600; - color: #37352f; + color: var(--c-text); } .portal-qb__addon-sub { display: block; font-size: 11.5px; - color: #9b9a97; + color: var(--c-text-subtle); margin-top: 1px; } .portal-qb__eula { @@ -822,10 +822,10 @@ gap: 10px; padding: 12px; border-radius: 9px; - border: 1px solid #f0eee9; - background: #f5f4f1; + border: 1px solid var(--c-border-subtle); + background: var(--c-surface-sunken); font-size: 12.5px; - color: #37352f; + color: var(--c-text); line-height: 1.5; cursor: pointer; } @@ -835,12 +835,12 @@ justify-content: space-between; gap: 12px; padding: 14px 24px; - border-top: 1px solid #f0eee9; + border-top: 1px solid var(--c-border-subtle); flex-wrap: wrap; } .portal-qb__running { font-size: 11.5px; - color: #9b9a97; + color: var(--c-text-subtle); } .portal-qb__foot-btns { display: flex; @@ -848,34 +848,34 @@ } /* Step 4 — the itemised quote paper */ .portal-qb__papertray { - background: #f5f4f1; + background: var(--c-surface-sunken); padding: 18px; max-height: 56vh; overflow-y: auto; margin: -20px -24px; } .portal-qb__paper { - background: #fff; - border: 1px solid #f0eee9; + background: var(--c-surface); + border: 1px solid var(--c-border-subtle); border-radius: 12px; overflow: hidden; - box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06); } .portal-qb__paper-head { display: flex; align-items: flex-start; justify-content: space-between; padding: 20px 24px; - border-bottom: 1px solid #f0eee9; + border-bottom: 1px solid var(--c-border-subtle); } .portal-qb__paper-brand { font-size: 13.5px; font-weight: 800; - color: #37352f; + color: var(--c-text); } .portal-qb__paper-eyebrow { font-size: 11px; - color: #9b9a97; + color: var(--c-text-subtle); } .portal-qb__paper-meta { text-align: right; @@ -883,11 +883,11 @@ .portal-qb__quote-number { font-size: 12.5px; font-weight: 700; - color: #37352f; + color: var(--c-text); } .portal-qb__paper-meta div:not(.portal-qb__quote-number) { font-size: 11px; - color: #9b9a97; + color: var(--c-text-subtle); } .portal-qb__paper-for { padding: 18px 24px 0; @@ -895,7 +895,7 @@ .portal-qb__paper-company { font-size: 14px; font-weight: 700; - color: #37352f; + color: var(--c-text); } .portal-qb__lines { list-style: none; @@ -907,16 +907,16 @@ justify-content: space-between; gap: 14px; padding: 10px 0; - border-bottom: 1px solid #f0eee9; + border-bottom: 1px solid var(--c-border-subtle); font-size: 13px; font-weight: 600; - color: #37352f; + color: var(--c-text); } .portal-qb__lines li[data-kind="DISCOUNT"] { - color: #0f7b6c; + color: var(--c-success); } .portal-qb__lines li[data-kind="INCLUDED"] span:last-child { - color: #9b9a97; + color: var(--c-text-subtle); font-weight: 500; } .portal-qb__total { @@ -926,17 +926,17 @@ margin: 16px 24px 24px; padding: 16px 18px; border-radius: 10px; - background: #eaf2fb; - border: 1px solid #b8d5f2; + background: var(--c-primary-tint); + border: 1px solid var(--c-primary-border); } .portal-qb__total-label { font-size: 13px; font-weight: 700; - color: #37352f; + color: var(--c-text); } .portal-qb__total-tcv { font-size: 11.5px; - color: #787774; + color: var(--c-text-muted); margin-top: 2px; } .portal-qb__total-num { @@ -946,12 +946,12 @@ display: block; font-size: 23px; font-weight: 800; - color: #37352f; + color: var(--c-text); line-height: 1; } .portal-qb__total-num span { font-size: 11px; - color: #9b9a97; + color: var(--c-text-subtle); margin-top: 3px; } @@ -962,16 +962,16 @@ /* ── Deal-status hero (Home, active deal) ─────────────────────────────────── */ .portal-hero { - border: 1px solid var(--color-border); + border: 1px solid var(--c-border); border-radius: 12px; padding: 1.1rem 1.25rem; background: radial-gradient( 120% 140% at 100% 0%, - rgba(124, 58, 237, 0.08), + color-mix(in srgb, var(--c-hue-violet) 8%, transparent), transparent 55% ), - var(--color-surface); + var(--c-surface); display: flex; flex-direction: column; gap: 1rem; @@ -989,13 +989,13 @@ font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; - color: var(--color-primary, #2383e2); + color: var(--c-primary); } .portal-hero__company { display: block; font-size: 1.0625rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); margin-top: 0.2rem; } .portal-hero__chips { @@ -1006,8 +1006,8 @@ .portal-hero__chip { font-size: 0.6875rem; font-weight: 600; - color: var(--color-text-3); - background: var(--color-border-light); + color: var(--c-text-subtle); + background: var(--c-border-subtle); border-radius: 999px; padding: 0.2rem 0.6rem; } @@ -1021,7 +1021,7 @@ gap: 0.75rem; flex-wrap: wrap; padding-top: 0.85rem; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } .portal-hero__next-label { display: inline-flex; @@ -1029,14 +1029,14 @@ gap: 0.45rem; font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-hero__next-dot { width: 0.5rem; height: 0.5rem; border-radius: 999px; - background: var(--color-primary, #2383e2); - box-shadow: 0 0 0 3px rgba(35, 131, 226, 0.18); + background: var(--c-primary); + box-shadow: 0 0 0 3px var(--c-primary-subtle); } /* ── Full-screen takeover modal (procurement flow) ────────────────────────── */ @@ -1049,7 +1049,7 @@ justify-content: center; padding: clamp(0.5rem, 4vh, 3rem) 1rem; overflow-y: auto; - background: rgba(15, 23, 42, 0.55); + background: var(--c-overlay); backdrop-filter: blur(6px) saturate(160%); -webkit-backdrop-filter: blur(6px) saturate(160%); animation: portal-procmodal-fade 0.15s ease-out; @@ -1066,10 +1066,10 @@ position: relative; width: 100%; max-width: 62rem; - background: var(--color-surface); - border: 1px solid var(--color-border); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: 14px; - box-shadow: 0 24px 64px rgba(15, 23, 42, 0.28); + box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28); padding: 1.5rem 1.5rem 1.75rem; } .portal-procmodal__close { @@ -1077,8 +1077,8 @@ top: 0.85rem; right: 0.85rem; border: none; - background: var(--color-border-light); - color: var(--color-text-3); + background: var(--c-border-subtle); + color: var(--c-text-subtle); width: 1.9rem; height: 1.9rem; border-radius: 8px; @@ -1086,8 +1086,8 @@ cursor: pointer; } .portal-procmodal__close:hover { - background: var(--color-border); - color: var(--color-text-1); + background: var(--c-border); + color: var(--c-text); } .portal-procmodal__header { margin-bottom: 1.25rem; @@ -1097,12 +1097,12 @@ margin: 0; font-size: 1.35rem; font-weight: 700; - color: var(--color-text-1); + color: var(--c-text); } .portal-procmodal__sub { margin: 0.3rem 0 0; font-size: 0.875rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-procmodal__body { display: flex; @@ -1122,7 +1122,7 @@ .portal-proc__license { margin-top: 1.25rem; padding: 1rem; - border: 1px solid var(--color-border, rgba(0, 0, 0, 0.1)); + border: 1px solid var(--c-border); border-radius: 0.6rem; background: var(--color-surface-2, rgba(0, 0, 0, 0.02)); } @@ -1132,7 +1132,7 @@ font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-proc__license-key { display: block; @@ -1143,18 +1143,18 @@ font-family: var(--font-mono, monospace); font-size: 0.85rem; word-break: break-all; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__license-hint { margin: 0.6rem 0 0; font-size: 0.75rem; - color: var(--color-text-3, var(--color-text-2)); + color: var(--c-text-subtle, var(--c-text-muted)); } .portal-proc__milestone-for { margin: 0.15rem 0 0; font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-proc__milestone-lines { margin: 0.85rem 0 0.5rem; @@ -1169,16 +1169,16 @@ .portal-proc__milestone-annual { font-size: 1.75rem; font-weight: 700; - color: var(--color-text-1); + color: var(--c-text); } .portal-proc__milestone-annual small { font-size: 0.8125rem; font-weight: 500; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-proc__milestone-tcv { font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } /* Hero next-step action row (primary CTA + optional extend-trial). */ @@ -1190,7 +1190,7 @@ /* Hero quick-action chips (clickable pills next to the company name). */ .portal-hero__chip--action { - border: 1px solid var(--color-border); + border: 1px solid var(--c-border); cursor: pointer; transition: background 0.12s, @@ -1198,8 +1198,8 @@ transform 0.12s; } .portal-hero__chip--action:hover { - background: var(--color-surface); - box-shadow: 0 2px 5px rgba(15, 23, 42, 0.1); + background: var(--c-surface); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); transform: translateY(-1px); } @@ -1208,10 +1208,10 @@ list-style: none; margin: 0; padding: 0; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } .portal-hero__checklist li { - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .portal-hero__checklist button { display: flex; @@ -1225,13 +1225,13 @@ text-align: left; } .portal-hero__checklist button:hover { - background: var(--color-bg-hover, var(--color-border-light)); + background: var(--c-hover, var(--c-border-subtle)); } .portal-hero__check-dot { width: 0.5rem; height: 0.5rem; border-radius: 999px; - background: var(--color-border); + background: var(--c-border); flex-shrink: 0; } .portal-hero__check-text { @@ -1242,19 +1242,19 @@ display: block; font-size: 0.85rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-hero__check-sub { display: block; font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); margin-top: 0.05rem; } .portal-hero__check-pill { font-size: 0.6875rem; font-weight: 600; - color: var(--color-text-5); - background: var(--color-border-light); + color: var(--c-text-subtle); + background: var(--c-border-subtle); border-radius: 999px; padding: 0.15rem 0.55rem; flex-shrink: 0; @@ -1270,7 +1270,7 @@ justify-content: center; padding: 1rem; overflow-y: auto; - background: rgba(15, 23, 42, 0.55); + background: var(--c-overlay); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); animation: portal-procmodal-fade 0.15s ease-out; @@ -1281,10 +1281,10 @@ position: relative; width: 100%; max-width: 30rem; - background: var(--color-surface); - border: 1px solid var(--color-border); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: 14px; - box-shadow: 0 24px 64px rgba(15, 23, 42, 0.28); + box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28); padding: 1.35rem 1.4rem 1.4rem; max-height: 86vh; overflow-y: auto; @@ -1302,18 +1302,18 @@ margin: 0; font-size: 1.05rem; font-weight: 700; - color: var(--color-text-1); + color: var(--c-text); } .portal-sidemodal__sub { margin: 0.25rem 0 0; font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); line-height: 1.5; } .portal-sidemodal__text { margin: 0; font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); line-height: 1.55; } .portal-sidemodal__footer { @@ -1323,17 +1323,17 @@ gap: 0.75rem; margin-top: 1.1rem; padding-top: 0.9rem; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } .portal-sidemodal__ghost { border: none; background: none; font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); cursor: pointer; } .portal-sidemodal__ghost:hover:not(:disabled) { - color: var(--color-text-2); + color: var(--c-text-muted); } /* Key documents ledger. */ @@ -1345,7 +1345,7 @@ font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; - color: var(--color-text-5); + color: var(--c-text-subtle); margin-bottom: 0.4rem; } .portal-docs__list { @@ -1358,7 +1358,7 @@ align-items: center; gap: 0.75rem; padding: 0.55rem 0; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } .portal-docs__row-text { flex: 1; @@ -1368,12 +1368,12 @@ display: block; font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-docs__row-sub { display: block; font-size: 0.72rem; - color: var(--color-text-4); + color: var(--c-text-subtle); margin-top: 0.05rem; } .portal-docs__row-action { @@ -1382,15 +1382,15 @@ border-radius: 999px; padding: 0.2rem 0.6rem; flex-shrink: 0; - color: var(--color-text-3); - background: var(--color-border-light); + color: var(--c-text-subtle); + background: var(--c-border-subtle); } .portal-docs__row-action[data-status="action"] { - color: var(--color-primary, #2383e2); - background: var(--color-primary-light, #eaf2fb); + color: var(--c-primary); + background: var(--c-primary-subtle); } .portal-docs__row-action[data-status="request"] { - color: var(--color-text-5); + color: var(--c-text-subtle); } /* Calendly scheduler embed (Schedule a call). The widget is always light (Calendly renders inputs on @@ -1423,18 +1423,18 @@ max-height: 22rem; overflow-y: auto; padding: 1rem 1.1rem; - border: 1px solid var(--color-border); + border: 1px solid var(--c-border); border-radius: 10px; - background: var(--color-bg-subtle, var(--color-bg)); + background: var(--color-bg-subtle, var(--c-bg)); font-size: 0.8125rem; line-height: 1.55; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-agreement__doc h4 { margin: 1rem 0 0.35rem; font-size: 0.8125rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-agreement__doc h4:first-child { margin-top: 0; @@ -1443,7 +1443,7 @@ margin: 0 0 0.5rem; } .portal-agreement__doc strong { - color: var(--color-text-1); + color: var(--c-text); } .portal-agreement__accept { margin-top: 0.25rem; @@ -1460,12 +1460,12 @@ border: none; background: none; font-size: 0.75rem; - color: var(--color-text-5); + color: var(--c-text-subtle); cursor: pointer; text-decoration: underline; } .portal-proc__reset button:hover:not(:disabled) { - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-proc__reset button:disabled { opacity: 0.5; diff --git a/frontend/editor/src/portal/views/SourceBuilder.css b/frontend/editor/src/portal/views/SourceBuilder.css index 7a964a2c86..ec6b9fe4a4 100644 --- a/frontend/editor/src/portal/views/SourceBuilder.css +++ b/frontend/editor/src/portal/views/SourceBuilder.css @@ -31,7 +31,7 @@ .portal-source-builder__title { font-size: 1.375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); margin: 0; } @@ -67,7 +67,7 @@ .portal-source-builder__type-card.is-selected { border-color: var(--color-accent, var(--color-brand)); - background: var(--color-bg-hover); + background: var(--c-hover); } .portal-source-builder__type-icon { diff --git a/frontend/editor/src/portal/views/Sources.css b/frontend/editor/src/portal/views/Sources.css index f0dea22e1c..96bd2dc5f3 100644 --- a/frontend/editor/src/portal/views/Sources.css +++ b/frontend/editor/src/portal/views/Sources.css @@ -26,14 +26,14 @@ margin: 0; font-size: 1.375rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-sources__sub { margin: 0.25rem 0 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); max-width: 46rem; } @@ -58,7 +58,7 @@ .portal-sources__name-text strong { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-sources__type-dot { @@ -70,21 +70,21 @@ flex-shrink: 0; border-radius: var(--radius-md); font-size: 0.875rem; - color: var(--dot-c, var(--color-text-3)); + color: var(--dot-c, var(--c-text-subtle)); background: color-mix( in srgb, - var(--dot-c, var(--color-text-3)) 14%, + var(--dot-c, var(--c-text-subtle)) 14%, transparent ); } /* Neutral keeps a plain muted surface rather than an accent tint. */ .portal-sources__type-dot--neutral { - background: var(--color-bg-muted); - color: var(--color-text-3); + background: var(--c-surface-sunken); + color: var(--c-text-subtle); } .portal-sources__type-dot--default { - --dot-c: var(--color-blue-dark); + --dot-c: var(--c-primary-hover); } .portal-sources__type-dot--premium { --dot-c: var(--color-purple-dark); @@ -106,24 +106,24 @@ .portal-sources__muted { font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-sources__caret { display: inline-block; - color: var(--color-text-5); + color: var(--c-text-subtle); transition: transform var(--motion-fast); } .portal-sources__caret.is-open { transform: rotate(90deg); - color: var(--color-blue); + color: var(--c-primary); } /* Expanded detail panel */ .portal-sources__expanded { - background: var(--color-surface); - border: 1px solid var(--color-border); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: 1.25rem; @@ -147,19 +147,19 @@ gap: 0.75rem; padding-bottom: 0.875rem; margin-bottom: 1rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .portal-sources__expanded-title { margin: 0; font-size: 1rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-sources__expanded-sub { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-sources__expanded-close { @@ -167,9 +167,9 @@ width: 1.75rem; height: 1.75rem; border-radius: var(--radius-md); - border: 1px solid var(--color-border); - background: var(--color-surface); - color: var(--color-text-4); + border: 1px solid var(--c-border); + background: var(--c-surface); + color: var(--c-text-subtle); font-size: 1.125rem; line-height: 1; cursor: pointer; @@ -179,8 +179,8 @@ } .portal-sources__expanded-close:hover { - background: var(--color-bg-hover); - color: var(--color-text-1); + background: var(--c-hover); + color: var(--c-text); } /* Detail body */ @@ -213,7 +213,7 @@ .portal-sources__url { font-family: var(--font-mono); font-size: 0.75rem; - color: var(--color-text-2); + color: var(--c-text-muted); word-break: break-all; } @@ -229,12 +229,12 @@ align-items: baseline; justify-content: space-between; font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-sources__bar-head strong { font-size: 0.8125rem; - color: var(--color-text-1); + color: var(--c-text); font-family: var(--font-mono); } @@ -249,7 +249,7 @@ font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--color-text-5); + color: var(--c-text-subtle); font-weight: 600; } @@ -257,7 +257,7 @@ display: block; width: 100%; margin-top: 0.5rem; - color: var(--color-blue); + color: var(--c-primary); } .portal-sources__chips { @@ -280,7 +280,7 @@ gap: 0.625rem; padding: 0.4375rem 0.625rem; background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); border-radius: var(--radius-md); } @@ -291,7 +291,7 @@ .portal-sources__endpoint-path { font-family: var(--font-mono); font-size: 0.75rem; - color: var(--color-text-2); + color: var(--c-text-muted); min-width: 0; overflow: hidden; text-overflow: ellipsis; @@ -299,7 +299,7 @@ .portal-sources__endpoint-calls { font-size: 0.6875rem; - color: var(--color-text-4); + color: var(--c-text-subtle); white-space: nowrap; font-family: var(--font-mono); } @@ -343,22 +343,22 @@ gap: 0.4375rem; flex: 1; font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); padding: 0.5rem 0.625rem; border-radius: var(--radius-md); background: var(--color-bg-subtle); - border: 1px solid var(--color-border-light); + border: 1px solid var(--c-border-subtle); } .portal-sources__step.is-active { - color: var(--color-text-1); + color: var(--c-text); font-weight: 600; - border-color: color-mix(in srgb, var(--color-blue) 40%, transparent); - background: var(--color-blue-light); + border-color: color-mix(in srgb, var(--c-primary) 40%, transparent); + background: color-mix(in srgb, var(--c-primary) 12%, var(--c-surface)); } .portal-sources__step.is-done { - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-sources__step-mark { @@ -370,14 +370,14 @@ border-radius: 50%; font-size: 0.6875rem; font-weight: 600; - background: var(--color-surface); - border: 1px solid var(--color-border); - color: var(--color-text-4); + background: var(--c-surface); + border: 1px solid var(--c-border); + color: var(--c-text-subtle); } .portal-sources__step.is-active .portal-sources__step-mark { - background: var(--color-blue); - border-color: var(--color-blue); + background: var(--c-primary); + border-color: var(--c-primary); color: var(--color-text-on-accent); } @@ -415,8 +415,8 @@ align-items: center; gap: 0.5rem; padding: 1rem 0.5rem; - background: var(--color-surface); - border: 1px solid var(--color-border); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-md); cursor: pointer; transition: @@ -425,14 +425,14 @@ } .portal-sources__type-card:hover { - border-color: var(--color-border-strong, var(--color-border)); - background: var(--color-bg-hover); + border-color: var(--color-border-strong, var(--c-border)); + background: var(--c-hover); } .portal-sources__type-card.is-selected { - border-color: var(--color-blue); - background: var(--color-blue-light); - box-shadow: 0 0 0 1px var(--color-blue) inset; + border-color: var(--c-primary); + background: color-mix(in srgb, var(--c-primary) 12%, var(--c-surface)); + box-shadow: 0 0 0 1px var(--c-primary) inset; } /* Icon inside the type picker: a plain stroke icon above the label (no badge @@ -441,11 +441,11 @@ display: inline-flex; align-items: center; justify-content: center; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-sources__type-card.is-selected .portal-sources__type-icon { - color: var(--color-blue); + color: var(--c-primary); } .portal-sources__type-icon .portal-sources__type-svg { @@ -463,7 +463,7 @@ .portal-sources__type-name { font-size: 0.75rem; font-weight: 500; - color: var(--color-text-1); + color: var(--c-text); } .portal-sources__wizard-body { @@ -476,13 +476,13 @@ margin: 0; font-size: 0.875rem; line-height: 1.55; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-sources__wizard-note { margin: 0; font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-sources__wizard-footer { @@ -533,7 +533,7 @@ .portal-sources__connections-title { font-size: 0.875rem; font-weight: 600; - color: var(--color-text-2); + color: var(--c-text-muted); margin: 0 0 0.5rem; } @@ -556,11 +556,11 @@ .portal-sources__connections-name { font-weight: 500; - color: var(--color-text-1); + color: var(--c-text); } .portal-sources__connections-bucket { - color: var(--color-text-4); + color: var(--c-text-subtle); font-size: 0.8125rem; } @@ -579,7 +579,7 @@ } .portal-sources__connections-sub { - color: var(--color-text-4); + color: var(--c-text-subtle); font-size: 0.875rem; margin: 0; } diff --git a/frontend/editor/src/portal/views/Usage.css b/frontend/editor/src/portal/views/Usage.css index c03e790680..47c035f83e 100644 --- a/frontend/editor/src/portal/views/Usage.css +++ b/frontend/editor/src/portal/views/Usage.css @@ -11,8 +11,8 @@ position: sticky; top: 0; z-index: 5; - background: var(--color-sidebar-bg); - border-bottom: 1px solid var(--color-border); + background: var(--c-bg-raised); + border-bottom: 1px solid var(--c-border); } .portal-usage__header-inner { display: flex; @@ -35,13 +35,13 @@ margin: 0; font-size: 1.375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-usage__subtitle { margin: 0.25rem 0 0; font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Two-column row: current plan + spend cap */ @@ -67,13 +67,13 @@ margin: 0; font-size: 0.9375rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-usage__section-sub { margin: 0.25rem 0 0; font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Current plan card */ @@ -96,14 +96,14 @@ font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--color-text-5); + color: var(--c-text-subtle); } .portal-usage__plan-name { margin: 0.125rem 0 0; font-size: 1.125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } /* Wallet contract card */ @@ -139,13 +139,13 @@ font-size: 2.25rem; font-weight: 600; line-height: 1; - color: var(--color-text-1); + color: var(--c-text); font-variant-numeric: tabular-nums; } .portal-usage__wallet-hero-unit { font-size: 0.875rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Cap progress (free) */ @@ -160,12 +160,12 @@ align-items: center; justify-content: space-between; font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-usage__cap-pct { font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); font-variant-numeric: tabular-nums; } @@ -183,7 +183,7 @@ gap: 0.75rem; padding: 0.5rem 0; font-size: 0.8125rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); } .portal-usage__breakdown-row:last-child { @@ -191,24 +191,24 @@ } .portal-usage__breakdown-label { - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-usage__breakdown-value { font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); font-variant-numeric: tabular-nums; } .portal-usage__breakdown-row--total { margin-top: 0.25rem; padding-top: 0.625rem; - border-top: 1px solid var(--color-border); + border-top: 1px solid var(--c-border); font-size: 0.875rem; } .portal-usage__breakdown-row--total .portal-usage__breakdown-label { - color: var(--color-text-1); + color: var(--c-text); font-weight: 600; } @@ -254,7 +254,7 @@ margin: 0; font-size: 1rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-usage__plan-card-price { @@ -267,19 +267,19 @@ .portal-usage__plan-card-amount { font-size: 1.5rem; font-weight: 700; - color: var(--color-text-1); + color: var(--c-text); } .portal-usage__plan-card-cadence { font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-usage__plan-card-blurb { margin: 0; font-size: 0.8125rem; line-height: 1.45; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-usage__plan-card-features { @@ -297,7 +297,7 @@ align-items: flex-start; gap: 0.5rem; font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-usage__plan-card-check { @@ -338,18 +338,18 @@ align-items: center; gap: 0.625rem; font-size: 0.75rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* Billing history */ .portal-usage__hist-date { font-variant-numeric: tabular-nums; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-usage__hist-amount { font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); font-variant-numeric: tabular-nums; } @@ -370,7 +370,7 @@ margin: 0 0 1rem; font-size: 0.875rem; line-height: 1.55; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-usage__modal-bullets { @@ -387,7 +387,7 @@ align-items: flex-start; gap: 0.5rem; font-size: 0.8125rem; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-usage__modal-actions { diff --git a/frontend/editor/src/portal/views/Users.css b/frontend/editor/src/portal/views/Users.css index 62c72549bf..75591cc8d8 100644 --- a/frontend/editor/src/portal/views/Users.css +++ b/frontend/editor/src/portal/views/Users.css @@ -19,14 +19,14 @@ margin: 0; font-size: 1.375rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-users__sub { margin: 0.25rem 0 0; font-size: 0.8125rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); max-width: 46rem; } @@ -39,18 +39,18 @@ margin: 0; font-size: 1rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-users__section-sub { margin: 0.25rem 0 0; font-size: 0.8125rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-users__muted { font-size: 0.8125rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } /* ──────────────────────────────────────────────────────────────────────── */ @@ -74,7 +74,7 @@ .portal-users__member-text strong { font-size: 0.8125rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-users__row-action { @@ -86,7 +86,7 @@ border-radius: var(--radius-md); border: 1px solid transparent; background: transparent; - color: var(--color-text-4); + color: var(--c-text-subtle); font-size: 1.125rem; line-height: 1; cursor: pointer; @@ -97,9 +97,9 @@ } .portal-users__row-action:hover { - background: var(--color-bg-hover); - border-color: var(--color-border); - color: var(--color-text-1); + background: var(--c-hover); + border-color: var(--c-border); + color: var(--c-text); } .portal-users__table-skeleton { @@ -144,7 +144,7 @@ margin: 0; font-size: 0.75rem; line-height: 1.45; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-users__role-perms { @@ -161,7 +161,7 @@ padding-left: 0.875rem; font-size: 0.6875rem; line-height: 1.4; - color: var(--color-text-3); + color: var(--c-text-subtle); } .portal-users__role-perms li::before { @@ -172,7 +172,7 @@ width: 0.25rem; height: 0.25rem; border-radius: 50%; - background: var(--color-text-5); + background: var(--c-text-subtle); } /* ──────────────────────────────────────────────────────────────────────── */ @@ -209,14 +209,14 @@ margin: 0; font-size: 0.875rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-users__access-note { margin: 0.5rem 0 0; font-size: 0.75rem; line-height: 1.45; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-users__access-stats { @@ -264,8 +264,8 @@ margin: 0.75rem 0 0; padding: 0.5rem 0.75rem; border-radius: 8px; - background: color-mix(in srgb, var(--sui-danger, #dc2626) 12%, transparent); - color: var(--sui-danger, #dc2626); + background: color-mix(in srgb, var(--c-danger) 12%, transparent); + color: var(--c-danger); font-size: 0.85rem; } @@ -279,7 +279,7 @@ } .portal-users__link { - color: var(--color-blue); + color: var(--c-primary); text-decoration: none; } .portal-users__link:hover { @@ -293,8 +293,8 @@ } .portal-users__group { - background: var(--color-surface); - border: 1px solid var(--color-border); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: var(--radius-lg); overflow: hidden; } @@ -305,7 +305,7 @@ justify-content: space-between; gap: 1rem; padding: 0.75rem 1.25rem; - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--c-border-subtle); background: var(--color-bg-subtle); } @@ -319,15 +319,15 @@ .portal-users__group-title > strong { font-size: 0.9rem; font-weight: 650; - color: var(--color-text-1); + color: var(--c-text); } .portal-users__group-desc { font-size: 0.8rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-users__group-count { font-size: 0.78rem; - color: var(--color-text-4); + color: var(--c-text-subtle); white-space: nowrap; } .portal-users__group-action { @@ -337,7 +337,7 @@ background: none; border: none; cursor: pointer; - color: var(--color-blue); + color: var(--c-primary); font-size: 0.8rem; font-weight: 500; white-space: nowrap; @@ -353,7 +353,7 @@ padding: 0.7rem 1.25rem; } .portal-users__row + .portal-users__row { - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } .portal-users__row-main { display: flex; @@ -371,15 +371,15 @@ .portal-users__row-name { font-size: 0.875rem; font-weight: 600; - color: var(--color-text-1); + color: var(--c-text); } .portal-users__row-you { font-weight: 400; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-users__row-email { font-size: 0.78rem; - color: var(--color-text-4); + color: var(--c-text-subtle); overflow: hidden; text-overflow: ellipsis; } @@ -398,7 +398,7 @@ } .portal-users__row-active { font-size: 0.78rem; - color: var(--color-text-4); + color: var(--c-text-subtle); white-space: nowrap; } .portal-users__row-role { @@ -420,24 +420,24 @@ .portal-users__invite-hint { margin: 0; font-size: 0.78rem; - color: var(--color-text-4); + color: var(--c-text-subtle); } .portal-users__invite-access { display: flex; flex-direction: column; gap: 0.6rem; padding-top: 0.75rem; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--c-border-subtle); } .portal-users__invite-access-label { font-size: 0.78rem; font-weight: 600; - color: var(--color-text-2); + color: var(--c-text-muted); } .portal-users__form-note { margin: 0; font-size: 0.8rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } @media (max-width: 720px) { @@ -469,7 +469,7 @@ border-radius: var(--radius-md); border: 1px solid transparent; background: transparent; - color: var(--color-text-4); + color: var(--c-text-subtle); font-size: 1.125rem; line-height: 1; cursor: pointer; @@ -479,9 +479,9 @@ border-color var(--motion-fast); } .portal-users__row-kebab:hover { - background: var(--color-bg-hover); - border-color: var(--color-border); - color: var(--color-text-1); + background: var(--c-hover); + border-color: var(--c-border); + color: var(--c-text); } .portal-users__show-more { @@ -491,14 +491,14 @@ text-align: center; background: none; border: none; - border-top: 1px solid var(--color-border-light); - color: var(--color-blue); + border-top: 1px solid var(--c-border-subtle); + color: var(--c-primary); font-size: 0.8rem; font-weight: 500; cursor: pointer; } .portal-users__show-more:hover { - background: var(--color-bg-hover); + background: var(--c-hover); } .portal-users__row-tag { @@ -525,5 +525,5 @@ margin: 0; font-size: 0.875rem; line-height: 1.5; - color: var(--color-text-3); + color: var(--c-text-subtle); } diff --git a/frontend/editor/src/proprietary/auth/ui/AuthDefaultCredentials.tsx b/frontend/editor/src/proprietary/auth/ui/AuthDefaultCredentials.tsx index 9d7c7858ed..9f1a6dd3f4 100644 --- a/frontend/editor/src/proprietary/auth/ui/AuthDefaultCredentials.tsx +++ b/frontend/editor/src/proprietary/auth/ui/AuthDefaultCredentials.tsx @@ -10,30 +10,17 @@ export default function AuthDefaultCredentials() { return ( - + {t("login.defaultCredentials", "Default Login Credentials")} - - + + {t("login.username", "Username")}: {" "} admin - - + + {t("login.password", "Password")}: {" "} stirling @@ -42,7 +29,7 @@ export default function AuthDefaultCredentials() { size="xs" ta="center" mt="xs" - style={{ color: "var(--text-muted)" }} + style={{ color: "var(--c-text-subtle)" }} > {t( "login.changePasswordWarning", diff --git a/frontend/editor/src/proprietary/auth/ui/auth-theme.css b/frontend/editor/src/proprietary/auth/ui/auth-theme.css index c1b843e804..8580d59e0b 100644 --- a/frontend/editor/src/proprietary/auth/ui/auth-theme.css +++ b/frontend/editor/src/proprietary/auth/ui/auth-theme.css @@ -33,20 +33,20 @@ } [data-mantine-color-scheme="dark"] { - --auth-bg-color: var(--bg-muted); - --auth-card-bg: var(--bg-surface); - --auth-label-text: var(--text-secondary); - --auth-input-border: var(--border-default); - --auth-input-bg: var(--bg-raised); - --auth-input-text: var(--text-primary); + --auth-bg-color: var(--c-surface-sunken); + --auth-card-bg: var(--c-surface); + --auth-label-text: var(--c-text-muted); + --auth-input-border: var(--c-border); + --auth-input-bg: var(--c-surface-raised); + --auth-input-text: var(--c-text); --auth-border-focus: var(--p-blue-500); --auth-focus-ring: color-mix(in srgb, var(--p-blue-500) 20%, transparent); --auth-button-bg: var(--p-red-600); --auth-button-text: #ffffff; - --auth-magic-button-bg: var(--bg-raised); - --auth-magic-button-text: var(--text-primary); - --auth-text-primary: var(--text-primary); - --auth-text-secondary: var(--text-secondary); + --auth-magic-button-bg: var(--c-surface-raised); + --auth-magic-button-text: var(--c-text); + --auth-text-primary: var(--c-text); + --auth-text-secondary: var(--c-text-muted); --auth-error-bg: color-mix(in srgb, var(--p-red-500) 12%, transparent); --auth-error-border: color-mix(in srgb, var(--p-red-500) 35%, transparent); --auth-error-text: var(--p-red-400); @@ -59,6 +59,6 @@ --auth-success-text: var(--p-green-500); --text-divider-rule-rgb-light: 28, 35, 64; --text-divider-label-rgb-light: 91, 98, 128; - --tool-subcategory-rule-color-light: var(--border-default); - --tool-subcategory-text-color-light: var(--text-secondary); + --tool-subcategory-rule-color-light: var(--c-border); + --tool-subcategory-text-color-light: var(--c-text-muted); } diff --git a/frontend/editor/src/proprietary/auth/ui/auth.css b/frontend/editor/src/proprietary/auth/ui/auth.css index 1745e1d6b3..e4337af2d6 100644 --- a/frontend/editor/src/proprietary/auth/ui/auth.css +++ b/frontend/editor/src/proprietary/auth/ui/auth.css @@ -139,7 +139,7 @@ .auth-checkbox { width: 1rem; /* 16px */ height: 1rem; /* 16px */ - accent-color: #af3434; + accent-color: var(--c-brand); } .auth-terms-label { @@ -267,25 +267,25 @@ } .oauth-button-vertical:hover:not(:disabled) { - background-color: var(--hover-bg); + background-color: var(--c-hover); box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.12); transform: translateY(-1px); - border-color: var(--border-default); + border-color: var(--c-border); } .oauth-button-vertical-tinted { background: linear-gradient( 90deg, - color-mix(in srgb, var(--oauth-accent) 65%, #0f172a) 0 6px, - #0f172a 6px 100% + color-mix(in srgb, var(--oauth-accent) 65%, var(--c-text)) 0 6px, + var(--c-text) 6px 100% ); } .oauth-button-vertical-tinted:hover:not(:disabled) { background: linear-gradient( 90deg, - color-mix(in srgb, var(--oauth-accent) 75%, #111827) 0 6px, - #111827 6px 100% + color-mix(in srgb, var(--oauth-accent) 75%, var(--c-text)) 0 6px, + var(--c-text) 6px 100% ); } @@ -293,7 +293,7 @@ min-height: 0; justify-content: flex-start; padding: 0.75rem 1rem; /* 12px 16px */ - border: 1px solid #d1d5db; + border: 1px solid var(--c-border); border-radius: 0.75rem; /* 12px */ background-color: var(--auth-card-bg); font-weight: 500; @@ -302,7 +302,7 @@ } .oauth-button-vertical-legacy:hover:not(:disabled) { - background-color: #f3f4f6; + background-color: var(--c-hover); color: var(--auth-text-primary); box-shadow: none; } @@ -331,28 +331,28 @@ .oauth-button-vertical-outline { background: transparent; - border: 2px solid #0f172a; - color: #0f172a; + border: 2px solid var(--c-text); + color: var(--c-text); box-shadow: none; } .oauth-button-vertical-outline:hover:not(:disabled) { - background: #0f172a; - color: #f8fafc; - box-shadow: 0 0.35rem 0.9rem rgba(15, 23, 42, 0.2); + background: var(--c-text); + color: var(--c-surface); + box-shadow: 0 0.35rem 0.9rem rgba(0, 0, 0, 0.2); } .oauth-button-vertical-light { - background: #f8fafc; - color: #0f172a; - border: 1px solid rgba(15, 23, 42, 0.12); - box-shadow: 0 0.25rem 0.75rem rgba(15, 23, 42, 0.12); + background: var(--c-surface); + color: var(--c-text); + border: 1px solid var(--c-border); + box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.12); } .oauth-button-vertical-light:hover:not(:disabled) { - background: #eef2f7; - color: #0f172a; - box-shadow: 0 0.35rem 0.9rem rgba(15, 23, 42, 0.16); + background: var(--c-hover); + color: var(--c-text); + box-shadow: 0 0.35rem 0.9rem rgba(0, 0, 0, 0.16); } .oauth-button-vertical:disabled { @@ -363,7 +363,7 @@ } .oauth-button-vertical:focus-visible { - outline: 3px solid rgba(59, 130, 246, 0.5); + outline: 3px solid color-mix(in srgb, var(--c-primary) 50%, transparent); outline-offset: 2px; } @@ -441,7 +441,7 @@ display: flex; align-items: center; justify-content: center; - background: var(--bg-muted); + background: var(--c-surface-sunken); border: 1px solid var(--auth-input-border); } @@ -460,8 +460,8 @@ .oauth-button-vertical-outline .oauth-icon-wrapper, .oauth-button-vertical-light .oauth-icon-wrapper { - background: rgba(15, 23, 42, 0.06); - border-color: rgba(15, 23, 42, 0.14); + background: var(--c-surface-sunken); + border-color: var(--c-border); } .oauth-button-right { display: flex; @@ -616,7 +616,7 @@ .auth-input-error:focus { border-color: var(--auth-error-text) !important; - box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1) !important; + box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-danger) 10%, transparent) !important; } /* Shared auth styles extracted from inline */ @@ -680,18 +680,18 @@ /* Email login button - red CTA style matching SaaS version */ .auth-cta-button { - background-color: #af3434 !important; + background-color: var(--c-brand) !important; color: white !important; border: none !important; font-weight: 600 !important; } .auth-cta-button:hover:not(:disabled) { - background-color: #9a2e2e !important; + background-color: var(--c-brand-hover) !important; } .auth-cta-button:disabled { - background-color: #af3434 !important; + background-color: var(--c-brand) !important; opacity: 0.6 !important; } @@ -742,8 +742,8 @@ } .auth-expandable-trigger--active { - border-color: #af3434 !important; - box-shadow: 0 0 0 3px rgba(175, 52, 52, 0.12); + border-color: var(--c-brand) !important; + box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-brand) 12%, transparent); } /* ── Animated expand/collapse via grid-template-rows ───────────────── */ @@ -781,12 +781,12 @@ own padding-block); horizontal stays in the shorthand. */ --sui-btn-py: 0.625rem; /* 10px */ padding: 0.625rem 1rem; /* 10px 16px */ - border: 1px solid #d1d5db; + border: 1px solid var(--c-border); border-radius: 0.625rem; /* 10px */ - background-color: #ffffff; + background-color: var(--c-surface); font-size: 0.9375rem; /* 15px */ font-weight: 600; - color: #000000; + color: var(--c-text); cursor: pointer; gap: 0.5rem; box-shadow: 0 0.125rem 0.375rem rgba(0, 0, 0, 0.04); @@ -802,20 +802,20 @@ } .oauth-button-fullwidth:hover:not(:disabled) { - background-color: #fafafa; + background-color: var(--c-hover); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); } [data-mantine-color-scheme="dark"] .oauth-button-fullwidth { - background-color: var(--bg-surface); - color: var(--text-primary); - border-color: var(--border-default); + background-color: var(--c-surface); + color: var(--c-text); + border-color: var(--c-border); box-shadow: none; } [data-mantine-color-scheme="dark"] .oauth-button-fullwidth:hover:not(:disabled) { - background-color: var(--bg-raised); + background-color: var(--c-surface-raised); box-shadow: none; } diff --git a/frontend/editor/src/proprietary/billing/MeterBar.tsx b/frontend/editor/src/proprietary/billing/MeterBar.tsx index bb15fa44aa..ee03d62885 100644 --- a/frontend/editor/src/proprietary/billing/MeterBar.tsx +++ b/frontend/editor/src/proprietary/billing/MeterBar.tsx @@ -1,5 +1,13 @@ import type { ReactNode } from "react"; import type { MeterState } from "@app/billing/format"; +import { StatusBadge, type StatusTone } from "@app/ui/StatusBadge"; + +// Meter state → the shared StatusBadge tone (contrast-tuned per theme). +const STATE_TONE: Record = { + FULL: "success", + WARNED: "warning", + DEGRADED: "danger", +}; interface MeterBarProps { state: MeterState; @@ -41,10 +49,9 @@ export function MeterBar({ {capSuffix}
{statusLabel != null && ( - - + {statusLabel} - + )}
{showBar && ( diff --git a/frontend/editor/src/proprietary/components/LoginLandingRedirect.tsx b/frontend/editor/src/proprietary/components/LoginLandingRedirect.tsx index 82dd48ed5a..1df1995d02 100644 --- a/frontend/editor/src/proprietary/components/LoginLandingRedirect.tsx +++ b/frontend/editor/src/proprietary/components/LoginLandingRedirect.tsx @@ -107,7 +107,7 @@ export function LoginLandingRedirect() { position: "fixed", inset: 0, zIndex: Z_INDEX_SIGN_IN_MODAL, - background: "var(--bg-surface)", + background: "var(--c-surface)", }} > diff --git a/frontend/editor/src/proprietary/components/chat/ChatPanel.css b/frontend/editor/src/proprietary/components/chat/ChatPanel.css index 58c3ea4619..e95078bcdf 100644 --- a/frontend/editor/src/proprietary/components/chat/ChatPanel.css +++ b/frontend/editor/src/proprietary/components/chat/ChatPanel.css @@ -8,7 +8,7 @@ /* Match the right-rail toolbar background so dark-mode doesn't show a lighter card behind the chat, and so the agent-card → pill morph doesn't flash a different colour mid-transition. */ - background: var(--bg-toolbar); + background: var(--c-bg-raised); } .chat-panel--embedded { @@ -31,7 +31,7 @@ flex: 1; min-width: 0; padding: 0.4rem 0.75rem 0.4rem 0.4rem; - border: 1px solid var(--border-subtle); + border: 1px solid var(--c-border-subtle); border-radius: 9999px; background: var(--mantine-color-body); cursor: pointer; @@ -103,7 +103,7 @@ border-color: color-mix( in srgb, var(--mantine-color-blue-5) 60%, - var(--border-subtle) + var(--c-border-subtle) ); } @@ -111,7 +111,7 @@ border-color: color-mix( in srgb, var(--mantine-color-blue-4) 55%, - var(--border-subtle) + var(--c-border-subtle) ); } @@ -119,14 +119,14 @@ so it doesn't read as a clashing lighter card on the dark toolbar. */ [data-mantine-color-scheme="dark"] .chat-panel__agent-pill { background: transparent; - border-color: var(--border-subtle); + border-color: var(--c-border-subtle); } /* The default tertiary accent is blue — use the surface text colour instead so the pill label and close icon don't look like interactive links. Overrides the Mantine button colour var the shared Button sets inline. */ .chat-panel__header .sui-btn--tertiary { - --button-color: var(--text-primary) !important; + --button-color: var(--c-text) !important; } [data-mantine-color-scheme="dark"] .chat-panel__agent-pill:hover { @@ -146,7 +146,7 @@ [data-mantine-color-scheme="dark"] .chat-panel-input { background: transparent; box-shadow: - 0 0 0 1px var(--border-subtle), + 0 0 0 1px var(--c-border-subtle), 0 6px 16px rgba(0, 0, 0, 0.25); } @@ -162,7 +162,7 @@ [data-mantine-color-scheme="dark"] .chat-quick-action:hover { background: rgba(255, 255, 255, 0.04); - border-color: var(--border-subtle); + border-color: var(--c-border-subtle); } .chat-panel__agent-pill-label { @@ -271,8 +271,8 @@ .chat-file-pill--more { background: transparent; - border: 1px dashed var(--border-subtle); - color: var(--text-muted); + border: 1px dashed var(--c-border-subtle); + color: var(--c-text-subtle); cursor: pointer; padding: 0.2rem 0.55rem; } @@ -285,7 +285,7 @@ display: block; width: 100%; padding: 0.6rem 0.75rem; - border: 1px solid var(--border-subtle); + border: 1px solid var(--c-border-subtle); border-radius: 0.65rem; background: var(--mantine-color-body); transition: @@ -310,6 +310,14 @@ flex-shrink: 0; } +/* Let the label fill the row and align left so the badge sits flush left and + the chevron (rightSection) is pushed to the far right. */ +.chat-quick-action .mantine-Button-label { + flex: 1; + min-width: 0; + text-align: left; +} + /* Input area: send button on the left, textarea fills the rest — one compact row so the composer stays short when the welcome screen is fully populated. */ .chat-panel-input { @@ -325,7 +333,7 @@ flex-shrink: 0; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.04), - 0 4px 14px rgba(15, 23, 42, 0.08); + 0 4px 14px rgba(0, 0, 0, 0.08); transition: box-shadow 160ms ease-out; } @@ -365,7 +373,7 @@ align-items: center; gap: 0.45rem; flex-shrink: 0; - color: var(--text-muted); + color: var(--c-text-subtle); } .chat-panel-disclaimer__icon { @@ -377,7 +385,7 @@ .chat-panel-disclaimer--banner { margin: 0.35rem 0.75rem 0; padding: 0.6rem 0.75rem; - border: 1px solid var(--border-subtle); + border: 1px solid var(--c-border-subtle); border-radius: 0.65rem; background: var(--mantine-color-gray-light); font-size: 0.78rem; @@ -440,7 +448,7 @@ border: none; border-radius: 0.375rem; background: transparent; - color: var(--text-muted); + color: var(--c-text-subtle); cursor: pointer; transition: background 100ms ease-out, @@ -458,7 +466,7 @@ .chat-message-timestamp { font-size: 0.7rem; - color: var(--text-muted); + color: var(--c-text-subtle); padding: 0 0.25rem; white-space: nowrap; } @@ -526,11 +534,11 @@ line-height: 1.35; background: linear-gradient( 90deg, - var(--text-muted) 0%, - var(--text-muted) 40%, + var(--c-text-subtle) 0%, + var(--c-text-subtle) 40%, var(--mantine-color-text) 50%, - var(--text-muted) 60%, - var(--text-muted) 100% + var(--c-text-subtle) 60%, + var(--c-text-subtle) 100% ); background-size: 200% 100%; background-clip: text; @@ -548,7 +556,7 @@ height: 20px; flex-shrink: 0; overflow: hidden; - color: var(--text-muted); + color: var(--c-text-subtle); animation: chat-phase-pulse 1.6s ease-in-out infinite; } @@ -603,7 +611,7 @@ align-items: center; padding: 0.1rem 0.25rem 0.1rem 0.1rem; border-radius: 0.35rem; - color: var(--text-muted); + color: var(--c-text-subtle); transition: background 120ms ease-out; } @@ -640,7 +648,7 @@ min-width: 1.1rem; text-align: right; font-size: 0.75rem; - color: var(--text-muted); + color: var(--c-text-subtle); font-variant-numeric: tabular-nums; } @@ -652,7 +660,7 @@ height: 18px; flex-shrink: 0; overflow: hidden; - color: var(--text-muted); + color: var(--c-text-subtle); } .chat-completed-log__tool-name { @@ -676,8 +684,8 @@ .chat-progress-live__label { animation: none; background: none; - -webkit-text-fill-color: var(--text-muted); - color: var(--text-muted); + -webkit-text-fill-color: var(--c-text-subtle); + color: var(--c-text-subtle); } .chat-progress-live__phase-icon { animation: none; diff --git a/frontend/editor/src/proprietary/components/chat/ChatQuickActions.tsx b/frontend/editor/src/proprietary/components/chat/ChatQuickActions.tsx index f650c953fd..408cb757f3 100644 --- a/frontend/editor/src/proprietary/components/chat/ChatQuickActions.tsx +++ b/frontend/editor/src/proprietary/components/chat/ChatQuickActions.tsx @@ -1,6 +1,6 @@ import { useMemo } from "react"; import { useTranslation } from "react-i18next"; -import { Box, Group, Stack, Text } from "@mantine/core"; +import { Box, Stack, Text } from "@mantine/core"; import { Button } from "@app/ui/Button"; import { ActionIcon } from "@app/ui/ActionIcon"; import CloseIcon from "@mui/icons-material/Close"; @@ -32,30 +32,37 @@ function QuickActionCard({ action }: { action: QuickAction }) { type="button" variant="tertiary" hover={false} + fullWidth + py="sm" + justify="start" className="chat-quick-action" onClick={action.onClick} aria-label={action.title} - > - - {action.icon} - - - {action.title} - - {action.subtitle && ( - - {action.subtitle} - - )} + leftSection={ + + {action.icon} + } + rightSection={ - + } + > + + + {action.title} + + {action.subtitle && ( + + {action.subtitle} + + )} + ); } diff --git a/frontend/editor/src/proprietary/components/policies/ClassificationCategoryManager.css b/frontend/editor/src/proprietary/components/policies/ClassificationCategoryManager.css index b967707164..3917f482e6 100644 --- a/frontend/editor/src/proprietary/components/policies/ClassificationCategoryManager.css +++ b/frontend/editor/src/proprietary/components/policies/ClassificationCategoryManager.css @@ -17,17 +17,17 @@ display: inline-flex; align-items: center; flex: none; - color: var(--color-text-2); + color: var(--c-text-muted); } .category-visibility-name { flex: 1; min-width: 0; font-size: 0.875rem; - color: var(--color-text-1); + color: var(--c-text); } .category-visibility-count { font-size: 0.75rem; - color: var(--color-text-3); + color: var(--c-text-subtle); } /* Hidden categories read as dimmed until re-shown. */ .category-visibility-row--hidden .category-visibility-icon, diff --git a/frontend/editor/src/proprietary/components/shared/PolicyEnforcingOverlay.tsx b/frontend/editor/src/proprietary/components/shared/PolicyEnforcingOverlay.tsx index 92cc4a556f..45dea92070 100644 --- a/frontend/editor/src/proprietary/components/shared/PolicyEnforcingOverlay.tsx +++ b/frontend/editor/src/proprietary/components/shared/PolicyEnforcingOverlay.tsx @@ -40,7 +40,7 @@ export function PolicyEnforcingOverlay({ if (!enforcing) return null; return ( @@ -159,8 +159,8 @@ export default function ApiKeys() { style={{ padding: 18, borderRadius: 12, - background: "var(--api-keys-card-bg)", - border: "1px solid var(--api-keys-card-border)", + background: "var(--c-surface)", + border: "1px solid var(--c-border)", boxShadow: "0 2px 8px var(--api-keys-card-shadow)", }} > diff --git a/frontend/editor/src/proprietary/components/shared/config/configSections/PeopleSection.tsx b/frontend/editor/src/proprietary/components/shared/config/configSections/PeopleSection.tsx index 68c2f49536..10e9f39fb0 100644 --- a/frontend/editor/src/proprietary/components/shared/config/configSections/PeopleSection.tsx +++ b/frontend/editor/src/proprietary/components/shared/config/configSections/PeopleSection.tsx @@ -640,7 +640,10 @@ export default function PeopleSection() { key={user.id} style={ isCurrentUser(user) - ? { backgroundColor: "rgba(34, 139, 230, 0.08)" } + ? { + backgroundColor: + "color-mix(in srgb, var(--c-primary) 8%, transparent)", + } : undefined } > diff --git a/frontend/editor/src/proprietary/components/shared/config/configSections/apiKeys/ApiKeySection.tsx b/frontend/editor/src/proprietary/components/shared/config/configSections/apiKeys/ApiKeySection.tsx index f05817a957..6a57c9a1e0 100644 --- a/frontend/editor/src/proprietary/components/shared/config/configSections/apiKeys/ApiKeySection.tsx +++ b/frontend/editor/src/proprietary/components/shared/config/configSections/apiKeys/ApiKeySection.tsx @@ -27,8 +27,8 @@ export default function ApiKeySection({ radius="md" p={18} style={{ - background: "var(--api-keys-card-bg)", - border: "1px solid var(--api-keys-card-border)", + background: "var(--c-surface)", + border: "1px solid var(--c-border)", boxShadow: "0 2px 8px var(--api-keys-card-shadow)", }} > @@ -36,8 +36,8 @@ export default function ApiKeySection({ @@ -221,14 +221,14 @@ export function CardExpansionModal({ display: "flex", flexDirection: "column", minHeight: 0, - backgroundColor: "var(--bg-toolbar)", + backgroundColor: "var(--c-bg-raised)", }} > {toolbar && (
{toolbar} @@ -251,7 +251,7 @@ export function CardExpansionModal({
{children} @@ -262,7 +262,7 @@ export function CardExpansionModal({
diff --git a/frontend/editor/src/proprietary/components/watchedFolders/StatCard.tsx b/frontend/editor/src/proprietary/components/watchedFolders/StatCard.tsx index a6a983ca3d..a8d7499878 100644 --- a/frontend/editor/src/proprietary/components/watchedFolders/StatCard.tsx +++ b/frontend/editor/src/proprietary/components/watchedFolders/StatCard.tsx @@ -30,9 +30,9 @@ export function StatCard({ style={{ padding: "0.5rem 0.75rem 2rem", borderRadius: "var(--mantine-radius-sm)", - border: `0.0625rem solid ${isActive && hoverColor ? hoverColor : "var(--border-subtle)"}`, + border: `0.0625rem solid ${isActive && hoverColor ? hoverColor : "var(--c-border-subtle)"}`, backgroundColor: - isActive && hoverColor ? `${hoverColor}10` : "var(--bg-toolbar)", + isActive && hoverColor ? `${hoverColor}10` : "var(--c-bg-raised)", textAlign: "center", cursor: isClickable ? "pointer" : "default", transition: "border-color 0.15s ease, background-color 0.15s ease", @@ -43,7 +43,7 @@ export function StatCard({ }} onMouseLeave={(e) => { if (isClickable && !isActive) - e.currentTarget.style.borderColor = "var(--border-subtle)"; + e.currentTarget.style.borderColor = "var(--c-border-subtle)"; }} >
{icon}
diff --git a/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderCard.tsx b/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderCard.tsx index 44b2b0c657..90e083fb23 100644 --- a/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderCard.tsx +++ b/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderCard.tsx @@ -78,7 +78,8 @@ export function WatchedFolderCard({ style={ isDragOver ? { - backgroundColor: "rgba(59,130,246,0.10)", + backgroundColor: + "color-mix(in srgb, var(--c-primary) 10%, transparent)", borderRadius: "var(--mantine-radius-sm)", } : undefined diff --git a/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderHomePage.tsx b/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderHomePage.tsx index f1110c9a2a..0f0b2b5bd5 100644 --- a/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderHomePage.tsx +++ b/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderHomePage.tsx @@ -120,7 +120,7 @@ function FolderCard({ ? "var(--mantine-color-blue-filled)" : isDone ? "var(--color-green-500)" - : "var(--text-muted)"; + : "var(--c-text-subtle)"; const statusDotPulse = isActive; const statusLabel = isPaused @@ -197,7 +197,7 @@ function FolderCard({
diff --git a/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderManagementModal.tsx b/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderManagementModal.tsx index 362d4cf7b0..9093c84d4b 100644 --- a/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderManagementModal.tsx +++ b/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderManagementModal.tsx @@ -58,7 +58,7 @@ function SectionLabel({ children }: { children: string }) { tt="uppercase" style={{ letterSpacing: "0.06em", - color: "var(--tool-subcategory-text-color)", + color: "var(--c-text-subtle)", marginBottom: "0.5rem", }} > @@ -330,7 +330,7 @@ export function WatchedFolderManagementModal({ style={{ width: "28rem", flexShrink: 0, - borderRight: "0.0625rem solid var(--border-subtle)", + borderRight: "0.0625rem solid var(--c-border-subtle)", display: "flex", flexDirection: "column", overflow: "hidden", @@ -439,7 +439,7 @@ export function WatchedFolderManagementModal({ style={{ marginLeft: "0.75rem", paddingLeft: "0.75rem", - borderLeft: "2px solid var(--border-subtle)", + borderLeft: "2px solid var(--c-border-subtle)", }} > diff --git a/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderSection.tsx b/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderSection.tsx index 67073a023a..94783a0929 100644 --- a/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderSection.tsx +++ b/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolderSection.tsx @@ -78,8 +78,8 @@ export function WatchedFolderSection() { return ( @@ -893,7 +893,7 @@ export function WatchedFolderWorkbenchView({ width: "0.75rem", height: "0.75rem", borderRadius: "50%", - backgroundColor: "var(--bg-toolbar)", + backgroundColor: "var(--c-bg-raised)", textAlign: "center", display: "flex", alignItems: "center", @@ -1221,7 +1221,7 @@ export function WatchedFolderWorkbenchView({ style={{ height: "0.1875rem", borderRadius: "999px", - backgroundColor: "var(--border-subtle)", + backgroundColor: "var(--c-border-subtle)", overflow: "hidden", }} > @@ -1263,7 +1263,7 @@ export function WatchedFolderWorkbenchView({ flex: 1, color: isDragOver ? "var(--mantine-color-blue-filled)" - : "var(--tool-subcategory-text-color)", + : "var(--c-text-subtle)", textTransform: "uppercase", letterSpacing: "0.05em", }} @@ -1361,8 +1361,8 @@ export function WatchedFolderWorkbenchView({ {[0, 25, 50, 75].map((pct) => ( @@ -2205,7 +2205,7 @@ export function WatchedFolderWorkbenchView({ top: `${pct}%`, left: 0, right: 0, - borderTop: "0.0625rem dashed var(--border-subtle)", + borderTop: "0.0625rem dashed var(--c-border-subtle)", pointerEvents: "none", }} /> @@ -2245,8 +2245,9 @@ export function WatchedFolderWorkbenchView({ ? `calc(100% - ${chartHover.relX}px + 12px)` : undefined, top: Math.max(chartHover.relY - 36, 4), - backgroundColor: "var(--bg-toolbar)", - border: "0.0625rem solid var(--border-subtle)", + backgroundColor: "var(--c-bg-raised)", + border: + "0.0625rem solid var(--c-border-subtle)", borderRadius: "var(--mantine-radius-sm)", padding: "0.3rem 0.5rem", pointerEvents: "none", diff --git a/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolders.css b/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolders.css index d41693db12..86c20d5b6e 100644 --- a/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolders.css +++ b/frontend/editor/src/proprietary/components/watchedFolders/WatchedFolders.css @@ -26,8 +26,8 @@ position: relative; display: flex; flex-direction: column; - background: var(--bg-surface); - border: 1px solid var(--border-subtle); + background: var(--c-surface); + border: 1px solid var(--c-border-subtle); border-radius: 0.85rem; overflow: hidden; cursor: pointer; @@ -42,8 +42,8 @@ transform: translateY(-2px); border-color: color-mix( in srgb, - var(--accent-interactive, #6366f1) 35%, - var(--border-subtle) + var(--c-primary) 35%, + var(--c-border-subtle) ); box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.08), @@ -51,25 +51,21 @@ } .wf-card:focus-visible { - outline: 2px solid var(--accent-interactive, #6366f1); + outline: 2px solid var(--c-primary); outline-offset: 2px; } .wf-card.is-drop-target { - background: color-mix( - in srgb, - var(--accent-interactive, #6366f1) 10%, - var(--bg-surface) - ); - box-shadow: 0 0 0 2px var(--accent-interactive, #6366f1); - border-color: var(--accent-interactive, #6366f1); + background: color-mix(in srgb, var(--c-primary) 10%, var(--c-surface)); + box-shadow: 0 0 0 2px var(--c-primary); + border-color: var(--c-primary); } /* Dragging a file the folder already contains — signal it's a no-op, not an add. */ .wf-card.is-already-member { - background: color-mix(in srgb, #f59e0b 8%, var(--bg-surface)); - box-shadow: 0 0 0 2px #f59e0b; - border-color: #f59e0b; + background: color-mix(in srgb, var(--c-warning) 8%, var(--c-surface)); + box-shadow: 0 0 0 2px var(--c-warning); + border-color: var(--c-warning); } .wf-card-drag-message { @@ -83,8 +79,8 @@ padding: 0.5rem; font-size: 0.8rem; font-weight: 600; - color: var(--text-primary); - background: color-mix(in srgb, var(--bg-surface) 72%, transparent); + color: var(--c-text); + background: color-mix(in srgb, var(--c-surface) 72%, transparent); backdrop-filter: blur(1px); border-radius: inherit; /* Let drag/drop events pass through to the card underneath. */ @@ -97,8 +93,8 @@ justify-content: center; background: linear-gradient( 180deg, - color-mix(in srgb, var(--text-muted) 5%, var(--bg-surface)), - var(--bg-surface) + color-mix(in srgb, var(--c-text-subtle) 5%, var(--c-surface)), + var(--c-surface) ); aspect-ratio: 1.6 / 1; padding: 0.75rem; @@ -118,13 +114,13 @@ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - color: var(--text-primary); + color: var(--c-text); letter-spacing: -0.005em; } .wf-card-meta { font-size: 0.76rem; - color: var(--text-muted); + color: var(--c-text-subtle); display: flex; align-items: center; gap: 0.4rem; @@ -166,12 +162,12 @@ justify-content: center; gap: 0.5rem; text-align: center; - background: var(--bg-surface); - border: 1.5px dashed var(--border-subtle); + background: var(--c-surface); + border: 1.5px dashed var(--c-border-subtle); border-radius: 0.85rem; padding: 1rem; cursor: pointer; - color: var(--text-muted); + color: var(--c-text-subtle); min-height: 9rem; transition: border-color 0.14s ease, @@ -180,13 +176,9 @@ } .wf-new-tile:hover { - border-color: var(--accent-interactive, #6366f1); - color: var(--accent-interactive, #6366f1); - background: color-mix( - in srgb, - var(--accent-interactive, #6366f1) 6%, - var(--bg-surface) - ); + border-color: var(--c-primary); + color: var(--c-primary); + background: color-mix(in srgb, var(--c-primary) 6%, var(--c-surface)); } .wf-new-tile-icon { @@ -196,12 +188,8 @@ width: 3rem; height: 3rem; border-radius: 50%; - background: color-mix( - in srgb, - var(--accent-interactive, #6366f1) 12%, - transparent - ); - color: var(--accent-interactive, #6366f1); + background: color-mix(in srgb, var(--c-primary) 12%, transparent); + color: var(--c-primary); } .wf-empty { @@ -211,7 +199,7 @@ justify-content: center; gap: 0.75rem; padding: 4rem 1.5rem; - color: var(--text-muted); + color: var(--c-text-subtle); text-align: center; } @@ -222,25 +210,21 @@ width: 5rem; height: 5rem; border-radius: 50%; - background: color-mix( - in srgb, - var(--accent-interactive, #6366f1) 12%, - transparent - ); - color: var(--accent-interactive, #6366f1); + background: color-mix(in srgb, var(--c-primary) 12%, transparent); + color: var(--c-primary); margin-bottom: 0.25rem; } .wf-empty-title { font-size: 1.15rem; - color: var(--text-primary); + color: var(--c-text); font-weight: 600; letter-spacing: -0.01em; } .wf-empty-hint { font-size: 0.9rem; - color: var(--text-muted); + color: var(--c-text-subtle); max-width: 30rem; line-height: 1.5; } diff --git a/frontend/editor/src/proprietary/routes/Landing.tsx b/frontend/editor/src/proprietary/routes/Landing.tsx index c377df1794..acb6a6e9c8 100644 --- a/frontend/editor/src/proprietary/routes/Landing.tsx +++ b/frontend/editor/src/proprietary/routes/Landing.tsx @@ -142,11 +142,13 @@ export default function Landing() { padding: "1.5rem", marginTop: "1rem", borderRadius: "0.75rem", - backgroundColor: "rgba(37, 99, 235, 0.08)", - border: "1px solid rgba(37, 99, 235, 0.2)", + backgroundColor: + "color-mix(in srgb, var(--c-primary) 8%, transparent)", + border: + "1px solid color-mix(in srgb, var(--c-primary) 20%, transparent)", }} > -

+

{t( "backendStartup.unreachable", "The application cannot currently connect to the backend. Verify the backend status and network connectivity, then try again.", diff --git a/frontend/editor/src/proprietary/routes/Login.tsx b/frontend/editor/src/proprietary/routes/Login.tsx index b21b9e1dd6..3e6764bf60 100644 --- a/frontend/editor/src/proprietary/routes/Login.tsx +++ b/frontend/editor/src/proprietary/routes/Login.tsx @@ -440,11 +440,13 @@ export default function Login() { padding: "1.5rem", marginTop: "1rem", borderRadius: "0.75rem", - backgroundColor: "rgba(37, 99, 235, 0.08)", - border: "1px solid rgba(37, 99, 235, 0.2)", + backgroundColor: + "color-mix(in srgb, var(--c-primary) 8%, transparent)", + border: + "1px solid color-mix(in srgb, var(--c-primary) 20%, transparent)", }} > -

+

{t( "backendStartup.unreachable", "The application cannot currently connect to the backend. Verify the backend status and network connectivity, then try again.", @@ -480,10 +482,12 @@ export default function Login() { style={{ padding: "1rem", marginBottom: "1rem", - backgroundColor: "rgba(34, 197, 94, 0.1)", - border: "1px solid rgba(34, 197, 94, 0.3)", + backgroundColor: + "color-mix(in srgb, var(--c-success) 10%, transparent)", + border: + "1px solid color-mix(in srgb, var(--c-success) 30%, transparent)", borderRadius: "0.5rem", - color: "#16a34a", + color: "var(--c-success)", }} >

@@ -32,7 +32,7 @@ export default function LoggedInState() { style={{ maxWidth: "400px", width: "100%", - backgroundColor: "#ffffff", + backgroundColor: "var(--c-surface)", borderRadius: "16px", boxShadow: "0 10px 25px rgba(0, 0, 0, 0.1)", padding: "32px", @@ -55,19 +55,19 @@ export default function LoggedInState() { style={{ fontSize: "24px", fontWeight: "bold", - color: "#059669", + color: "var(--c-success)", marginBottom: "8px", }} > {t("login.youAreLoggedIn")} -

+

{t("login.email")}: {user?.email}

-

+

Redirecting to home...

diff --git a/frontend/editor/src/saas/components/auth/GuestUserBanner.css b/frontend/editor/src/saas/components/auth/GuestUserBanner.css index 40ef91adc7..2dc1ba528d 100644 --- a/frontend/editor/src/saas/components/auth/GuestUserBanner.css +++ b/frontend/editor/src/saas/components/auth/GuestUserBanner.css @@ -3,8 +3,8 @@ top: 1rem; right: 4.5rem; z-index: 1000; - background: var(--modal-content-bg, #111418); - border: 1px solid var(--api-keys-card-border, rgba(255, 255, 255, 0.08)); + background: var(--c-surface); + border: 1px solid var(--c-border); border-radius: 12px; box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35); padding: 12px 16px; diff --git a/frontend/editor/src/saas/components/shared/AppConfigModal.tsx b/frontend/editor/src/saas/components/shared/AppConfigModal.tsx index 32def0b196..3f7b4de5ab 100644 --- a/frontend/editor/src/saas/components/shared/AppConfigModal.tsx +++ b/frontend/editor/src/saas/components/shared/AppConfigModal.tsx @@ -130,13 +130,13 @@ const AppConfigModal: React.FC = ({ const colors = useMemo( () => ({ - navBg: "var(--modal-nav-bg)", - sectionTitle: "var(--modal-nav-section-title)", + navBg: "var(--c-bg-raised)", + sectionTitle: "var(--c-text-subtle)", navItem: "var(--modal-nav-item)", - navItemActive: "var(--modal-nav-item-active)", - navItemActiveBg: "var(--modal-nav-item-active-bg)", - contentBg: "var(--modal-content-bg)", - headerBorder: "var(--modal-header-border)", + navItemActive: "var(--c-accent-fg)", + navItemActiveBg: "var(--c-primary-subtle)", + contentBg: "var(--c-surface)", + headerBorder: "var(--c-border-subtle)", }), [], ); diff --git a/frontend/editor/src/saas/components/shared/charts/StackedBarChart.css b/frontend/editor/src/saas/components/shared/charts/StackedBarChart.css index afb382969b..04c19f5f02 100644 --- a/frontend/editor/src/saas/components/shared/charts/StackedBarChart.css +++ b/frontend/editor/src/saas/components/shared/charts/StackedBarChart.css @@ -1,6 +1,6 @@ .chart-tooltip { - background: var(--bg-surface); - color: var(--text-primary); + background: var(--c-surface); + color: var(--c-text); border: 1px solid transparent; box-shadow: var(--shadow-md); padding: 8px 10px; @@ -9,6 +9,6 @@ border-radius: 8px; } [data-mantine-color-scheme="dark"] .chart-tooltip { - border-color: var(--border-subtle); + border-color: var(--c-border-subtle); box-shadow: none; } diff --git a/frontend/editor/src/saas/components/shared/charts/StackedBarChart.tsx b/frontend/editor/src/saas/components/shared/charts/StackedBarChart.tsx index b1ba0ed3ac..5f56843dae 100644 --- a/frontend/editor/src/saas/components/shared/charts/StackedBarChart.tsx +++ b/frontend/editor/src/saas/components/shared/charts/StackedBarChart.tsx @@ -108,7 +108,7 @@ export default function StackedBarChart({ .attr("rx", radius) .attr("ry", radius) .attr("fill", "var(--usage-inactive)") - .attr("stroke", "var(--api-keys-card-border)"); + .attr("stroke", "var(--c-border)"); // Define a clipPath that will reveal the used portion from left to right const defs = svg.append("defs"); @@ -308,7 +308,7 @@ export default function StackedBarChart({ background: "var(--usage-inactive)", display: "inline-block", borderRadius: 2, - outline: "1px solid var(--api-keys-card-border)", + outline: "1px solid var(--c-border)", }} /> {t("common.remaining", "Remaining")} diff --git a/frontend/editor/src/saas/components/shared/config/configSections/ApiKeys.tsx b/frontend/editor/src/saas/components/shared/config/configSections/ApiKeys.tsx index 4d65073f71..19883e5531 100644 --- a/frontend/editor/src/saas/components/shared/config/configSections/ApiKeys.tsx +++ b/frontend/editor/src/saas/components/shared/config/configSections/ApiKeys.tsx @@ -74,8 +74,8 @@ export default function ApiKeys() { radius="md" p={18} style={{ - background: "var(--api-keys-card-bg)", - border: "1px solid var(--api-keys-card-border)", + background: "var(--c-surface)", + border: "1px solid var(--c-border)", boxShadow: "0 2px 8px var(--api-keys-card-shadow)", }} > @@ -111,8 +111,8 @@ export default function ApiKeys() { style={{ padding: 18, borderRadius: 12, - background: "var(--api-keys-card-bg)", - border: "1px solid var(--api-keys-card-border)", + background: "var(--c-surface)", + border: "1px solid var(--c-border)", boxShadow: "0 2px 8px var(--api-keys-card-shadow)", }} > diff --git a/frontend/editor/src/saas/routes/Login.tsx b/frontend/editor/src/saas/routes/Login.tsx index 3a18322d06..ab75b7bb79 100644 --- a/frontend/editor/src/saas/routes/Login.tsx +++ b/frontend/editor/src/saas/routes/Login.tsx @@ -334,7 +334,7 @@ export default function Login() {

@@ -429,7 +429,7 @@ export default function Login() { cursor: "pointer", fontSize: "1rem", fontWeight: 700, - color: "var(--text-primary)", + color: "var(--c-text)", }} > {isSigningIn @@ -454,7 +454,7 @@ export default function Login() { border: "none", cursor: "pointer", fontSize: "0.875rem", - color: "#9ca3af", + color: "var(--c-text-subtle)", }} > {t("login.createAccount", "Create an account")} diff --git a/frontend/editor/src/saas/routes/Signup.tsx b/frontend/editor/src/saas/routes/Signup.tsx index 3c34626168..942cfefb5a 100644 --- a/frontend/editor/src/saas/routes/Signup.tsx +++ b/frontend/editor/src/saas/routes/Signup.tsx @@ -260,7 +260,7 @@ export default function Signup() { cursor: "pointer", fontSize: "1rem", fontWeight: 700, - color: "var(--text-primary)", + color: "var(--c-text)", }} > {isSigningUp @@ -285,7 +285,7 @@ export default function Signup() { border: "none", cursor: "pointer", fontSize: "0.875rem", - color: "#9ca3af", + color: "var(--c-text-subtle)", }} > {t("signup.alreadyHaveAccount", "I already have an account")} diff --git a/frontend/editor/src/saas/routes/authShared/saas-auth.css b/frontend/editor/src/saas/routes/authShared/saas-auth.css index 96d97f695c..23067d77f9 100644 --- a/frontend/editor/src/saas/routes/authShared/saas-auth.css +++ b/frontend/editor/src/saas/routes/authShared/saas-auth.css @@ -14,9 +14,9 @@ z-index: 40; margin-top: 0.5rem; min-width: 16rem; - background-color: #ffffff; - color: #000000; - border: 1px solid #e5e7eb; + background-color: var(--c-surface); + color: var(--c-text); + border: 1px solid var(--c-border); border-radius: 0.5rem; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), @@ -25,9 +25,6 @@ } [data-mantine-color-scheme="dark"] .auth-dropdown { - background-color: var(--bg-surface); - color: var(--text-primary); - border-color: var(--border-default); box-shadow: var(--shadow-md); } @@ -39,17 +36,13 @@ border: none; padding: 0.5rem 0.75rem; border-radius: 0.375rem; - color: #000; + color: var(--c-text); cursor: pointer; } -[data-mantine-color-scheme="dark"] .auth-dropdown-item { - color: var(--text-primary); -} - .auth-guest-button { - background-color: #ffffff; - color: #9c2f30; + background-color: var(--c-surface); + color: var(--c-brand); border: 2px solid currentColor; } @@ -93,8 +86,8 @@ } .auth-expandable-trigger--active { - border-color: #af3434 !important; - box-shadow: 0 0 0 3px rgba(175, 52, 52, 0.12); + border-color: var(--c-brand) !important; + box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-brand) 12%, transparent); } /* ── Animated expand/collapse via grid-template-rows ───────────────── */ diff --git a/frontend/editor/src/saas/styles/saas-theme.css b/frontend/editor/src/saas/styles/saas-theme.css index 44a016eb5d..0d6b0d4940 100644 --- a/frontend/editor/src/saas/styles/saas-theme.css +++ b/frontend/editor/src/saas/styles/saas-theme.css @@ -119,20 +119,20 @@ --color-orange-400: var(--p-red-600); /* Auth page colors (dark mode) — mirror proprietary so the auth card themes dark */ - --auth-bg-color: var(--bg-muted); - --auth-card-bg: var(--bg-surface); - --auth-label-text: var(--text-secondary); - --auth-input-border: var(--border-default); - --auth-input-bg: var(--bg-raised); - --auth-input-text: var(--text-primary); + --auth-bg-color: var(--c-surface-sunken); + --auth-card-bg: var(--c-surface); + --auth-label-text: var(--c-text-muted); + --auth-input-border: var(--c-border); + --auth-input-bg: var(--c-surface-raised); + --auth-input-text: var(--c-text); --auth-border-focus: var(--p-blue-500); --auth-focus-ring: color-mix(in srgb, var(--p-blue-500) 20%, transparent); --auth-button-bg: var(--p-red-600); --auth-button-text: #ffffff; - --auth-magic-button-bg: var(--bg-raised); - --auth-magic-button-text: var(--text-primary); - --auth-text-primary: var(--text-primary); - --auth-text-secondary: var(--text-secondary); + --auth-magic-button-bg: var(--c-surface-raised); + --auth-magic-button-text: var(--c-text); + --auth-text-primary: var(--c-text); + --auth-text-secondary: var(--c-text-muted); --auth-error-bg: color-mix(in srgb, var(--p-red-500) 12%, transparent); --auth-error-border: color-mix(in srgb, var(--p-red-500) 35%, transparent); --auth-error-text: var(--p-red-400);