diff --git a/docs/testing.md b/docs/testing.md index 83dd19dd27..d94cf63f64 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -64,6 +64,9 @@ pnpm --filter @fusion/dashboard test:build # built client output contra Run `test:deep` when changing broad dashboard architecture, shared modal/view infrastructure, or route registration. Run `test:browser-smoke` for layout/responsive/navigation/modal/CSS changes. Run `test:build` for Vite output, lazy-loading, chunking, or client-dist changes. + +The dashboard CSS contract lane includes `app/__tests__/dashboard-css-token-validity.css.test.ts`, which scans raw component/app CSS and fails any `var(--token)` reference that is not defined by CSS, assigned by React inline style, or explicitly allowlisted as runtime-local. Run it with `component-css-no-raw-rgba`, `dashboard-component-color-tokenization`, and `text-token-canonicalization` when touching design-token usage. + Command Center responsive chart fixes need evidence beyond jsdom. Keep the jsdom scroll-owner tests for rule/structure coverage, but pair them with `packages/dashboard/app/components/command-center/__tests__/CommandCenter.mobile-chart-layout.test.ts`, which reads the co-located Command Center CSS files directly and asserts the mobile shrink/height/border rules that real layout depends on. For visible defects, also capture a real browser/device (or headless Chrome/Blink) reproduction with `scrollWidth > clientWidth`, zero/clipped `clientHeight`, or stretch measurements; do not close a Command Center mobile chart bug on jsdom-green assertions alone. The local `pnpm --filter @fusion/dashboard test:browser-smoke --require-browser` lane now includes `[data-smoke="command-center-charts"]` and gates representative Command Center recharts pie, line, and empty states at 390×844 mobile plus desktop viewports for visible SVG/container height, overflow containment, empty-state text, and chart scroll-owner violations. diff --git a/packages/dashboard/app/__tests__/dashboard-css-token-validity.css.test.ts b/packages/dashboard/app/__tests__/dashboard-css-token-validity.css.test.ts new file mode 100644 index 0000000000..ddfe96641e --- /dev/null +++ b/packages/dashboard/app/__tests__/dashboard-css-token-validity.css.test.ts @@ -0,0 +1,165 @@ +import { readdirSync, readFileSync, statSync } from "node:fs"; +import path from "node:path"; +import { describe, expect, it } from "vitest"; + +const APP_ROOT = path.resolve(__dirname, ".."); +const COMPONENTS_ROOT = path.join(APP_ROOT, "components"); + +const JS_SET_PROPERTY_ALLOWLIST = new Set([ + "--cc-radial-value", + "--mobile-wf-depth", + "--icb-bottom-offset", + "--icb-right-offset", + "--quick-chat-fab-lift", + "--quick-chat-fab-shadow", + "--quick-chat-fab-shadow-hover", + "--selection-comment-panel-width", + "--task-chat-composer-max-height", + "--layout-content-max-width", + "--opacity-disabled", + "--provider-icon-color", +]); + +/** + * FNXC:DashboardStyling 2026-06-19-00:00: + * FN-6690/FN-6693 proved jsdom style assertions miss undefined CSS custom-property references because jsdom does not resolve `var()` at computed-value time. + * Scan raw dashboard CSS instead: a bare `var(--missing-token)` can silently invalidate a declaration or depend on a stale fallback, so every referenced custom property must be defined by CSS, assigned by React inline style, or documented as a runtime-local allowlist entry. + */ +function stripCssComments(source: string): string { + return source.replace(/\/\*[\s\S]*?\*\//g, ""); +} + +function collectFiles(dir: string, predicate: (fileName: string) => boolean): string[] { + const out: string[] = []; + + for (const entry of readdirSync(dir)) { + if (entry === "node_modules" || entry === "dist" || entry === "public" || entry.startsWith(".")) continue; + + const fullPath = path.join(dir, entry); + const info = statSync(fullPath); + + if (info.isDirectory()) { + out.push(...collectFiles(fullPath, predicate)); + continue; + } + + if (info.isFile() && predicate(entry)) out.push(fullPath); + } + + return out.sort((left, right) => formatAppPath(left).localeCompare(formatAppPath(right))); +} + +function collectCssFilesToScan(): string[] { + const componentCss = collectFiles(COMPONENTS_ROOT, (fileName) => fileName.endsWith(".css")); + const appLevelCss = readdirSync(APP_ROOT) + .filter((entry) => entry.endsWith(".css") && entry !== "styles.css") + .map((entry) => path.join(APP_ROOT, entry)); + + return [...componentCss, ...appLevelCss].sort((left, right) => formatAppPath(left).localeCompare(formatAppPath(right))); +} + +function collectAllCssFiles(): string[] { + return collectFiles(APP_ROOT, (fileName) => fileName.endsWith(".css")); +} + +function collectSourceFiles(): string[] { + return collectFiles(APP_ROOT, (fileName) => /\.(tsx?|jsx?)$/.test(fileName)); +} + +function collectDefinedProperties(cssFiles: string[]): Set { + const properties = new Set(); + + for (const filePath of cssFiles) { + const source = stripCssComments(readFileSync(filePath, "utf8")); + for (const match of source.matchAll(/(^|[\s{;])(--[A-Za-z0-9_-]+)\s*:/g)) { + properties.add(match[2]); + } + } + + return properties; +} + +function collectInlineSetProperties(sourceFiles: string[]): Set { + const properties = new Set(); + + for (const filePath of sourceFiles) { + const source = readFileSync(filePath, "utf8"); + for (const match of source.matchAll(/\[\s*["'`](--[A-Za-z0-9_-]+)["'`]\s*(?:as\s+string)?\s*\]\s*:/g)) { + properties.add(match[1]); + } + for (const match of source.matchAll(/["'`](--[A-Za-z0-9_-]+)["'`]\s*:/g)) { + properties.add(match[1]); + } + } + + return properties; +} + +function collectReferencedProperties(source: string): Set { + const references = new Set(); + const uncommented = stripCssComments(source); + + for (const match of uncommented.matchAll(/var\(\s*(--[A-Za-z0-9_-]+)/g)) { + references.add(match[1]); + } + + return references; +} + +function formatAppPath(filePath: string): string { + return path.relative(APP_ROOT, filePath).split(path.sep).join("/"); +} + +function findUndefinedReferences(args: { + cssFilesToScan: string[]; + definedProperties: Set; + inlineSetProperties: Set; + allowlist?: Set; + sourceByFile?: Map; +}): string[] { + const { + cssFilesToScan, + definedProperties, + inlineSetProperties, + allowlist = JS_SET_PROPERTY_ALLOWLIST, + sourceByFile = new Map(), + } = args; + const violations: string[] = []; + + for (const filePath of cssFilesToScan) { + const source = sourceByFile.get(filePath) ?? readFileSync(filePath, "utf8"); + for (const property of collectReferencedProperties(source)) { + if (definedProperties.has(property) || inlineSetProperties.has(property) || allowlist.has(property)) continue; + violations.push(`${formatAppPath(filePath)} references ${property}`); + } + } + + return violations.sort(); +} + +describe("dashboard CSS token validity", () => { + it("flags a synthetic undefined custom-property reference", () => { + const fixturePath = path.join(APP_ROOT, "fixture.css"); + const fixtureSource = "/* var(--commented-out) */ .x { color: var(--does-not-exist); }"; + const violations = findUndefinedReferences({ + cssFilesToScan: [fixturePath], + definedProperties: new Set(["--defined-token"]), + inlineSetProperties: new Set(), + allowlist: new Set(), + sourceByFile: new Map([[fixturePath, fixtureSource]]), + }); + + expect(collectReferencedProperties(fixtureSource)).toEqual(new Set(["--does-not-exist"])); + expect(violations).toEqual(["fixture.css references --does-not-exist"]); + }); + + it("keeps component and app-level CSS references backed by defined or runtime-set properties", () => { + const violations = findUndefinedReferences({ + cssFilesToScan: collectCssFilesToScan(), + definedProperties: collectDefinedProperties(collectAllCssFiles()), + inlineSetProperties: collectInlineSetProperties(collectSourceFiles()), + }); + + expect(violations, [`Undefined CSS custom-property references found:`, ...violations].join("\n")).toEqual([]); + }); +}); diff --git a/packages/dashboard/app/components/ActiveAgentsPanel.css b/packages/dashboard/app/components/ActiveAgentsPanel.css index bf56321747..8035c789f3 100644 --- a/packages/dashboard/app/components/ActiveAgentsPanel.css +++ b/packages/dashboard/app/components/ActiveAgentsPanel.css @@ -33,12 +33,12 @@ } .live-agent-card:hover { - background: var(--bg-hover); - border-color: var(--border-strong, var(--border)); + background: var(--surface-hover); + border-color: color-mix(in srgb, var(--border) 65%, var(--text) 35%); } .live-agent-card:focus-visible { - outline: 2px solid var(--accent, var(--color-primary)); + outline: 2px solid var(--accent); outline-offset: 2px; } @@ -152,9 +152,9 @@ } .live-agent-card-logs-btn:hover { - background: var(--bg-hover); + background: var(--surface-hover); color: var(--text); - border-color: var(--border-strong, var(--border)); + border-color: color-mix(in srgb, var(--border) 65%, var(--text) 35%); } @media (max-width: 768px) { diff --git a/packages/dashboard/app/components/AgentLogViewer.css b/packages/dashboard/app/components/AgentLogViewer.css index 90ec4b3047..df6c7df981 100644 --- a/packages/dashboard/app/components/AgentLogViewer.css +++ b/packages/dashboard/app/components/AgentLogViewer.css @@ -298,7 +298,7 @@ .agent-log-summary { padding: var(--space-xs) var(--space-md); - font-size: var(--text-xs, 12px); + font-size: 0.75rem; color: var(--text-muted); border-bottom: 1px solid var(--border); text-align: center; diff --git a/packages/dashboard/app/components/AgentReflectionsTab.css b/packages/dashboard/app/components/AgentReflectionsTab.css index 7f8f2da012..707ca58947 100644 --- a/packages/dashboard/app/components/AgentReflectionsTab.css +++ b/packages/dashboard/app/components/AgentReflectionsTab.css @@ -109,7 +109,7 @@ } .reflection-card:hover { - border-color: var(--border-active); + border-color: var(--border); background: var(--card-hover); } @@ -119,7 +119,7 @@ } .reflection-card--expanded { - border-color: var(--color-primary); + border-color: var(--accent); } .reflection-card-header { @@ -149,8 +149,8 @@ } .reflection-trigger-manual { - background: color-mix(in srgb, var(--color-primary) 15%, transparent); - color: var(--color-primary); + background: color-mix(in srgb, var(--accent) 15%, transparent); + color: var(--accent); } .reflection-trigger-user-requested { @@ -221,7 +221,7 @@ content: "→"; position: absolute; left: 0; - color: var(--color-primary); + color: var(--accent); } .reflection-metrics { diff --git a/packages/dashboard/app/components/AgentsView.css b/packages/dashboard/app/components/AgentsView.css index b7ec8b9e3c..57b72b6348 100644 --- a/packages/dashboard/app/components/AgentsView.css +++ b/packages/dashboard/app/components/AgentsView.css @@ -1135,7 +1135,7 @@ height: var(--org-chart-children-offset, var(--space-md)); left: var(--org-chart-first-child-center-offset); right: var(--org-chart-last-child-center-offset); - border-top: 1px solid var(--border-color, currentColor); + border-top: 1px solid var(--border); pointer-events: none; } @@ -1146,7 +1146,7 @@ left: 50%; width: 1px; height: var(--org-chart-children-offset); - border-left: 1px solid var(--border-color, currentColor); + border-left: 1px solid var(--border); pointer-events: none; } @@ -1158,7 +1158,7 @@ width: 1px; height: auto; border-top: none; - border-left: 1px solid var(--border-color, currentColor); + border-left: 1px solid var(--border); } .agent-org-chart--vertical { diff --git a/packages/dashboard/app/components/BranchGroupCard.css b/packages/dashboard/app/components/BranchGroupCard.css index edc625c28c..86278c28c9 100644 --- a/packages/dashboard/app/components/BranchGroupCard.css +++ b/packages/dashboard/app/components/BranchGroupCard.css @@ -28,7 +28,7 @@ } .branch-group-card-badge { - background: var(--surface-elevated); + background: var(--surface-1); } .branch-group-card-header-meta .btn { @@ -45,14 +45,14 @@ .branch-group-card-progress-text { color: var(--text-muted); - font-size: var(--font-size-sm); + font-size: 0.875rem; } .branch-group-card-progress { width: 100%; height: var(--space-xs); border-radius: var(--radius-pill); - background: var(--surface-elevated); + background: var(--surface-1); overflow: hidden; } diff --git a/packages/dashboard/app/components/ChatView.css b/packages/dashboard/app/components/ChatView.css index ae437dc1b2..b302e8b1a0 100644 --- a/packages/dashboard/app/components/ChatView.css +++ b/packages/dashboard/app/components/ChatView.css @@ -353,7 +353,7 @@ /* Context menu for session items */ .chat-session-context-menu { position: fixed; - background: var(--bg-elevated, var(--bg)); + background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); @@ -639,7 +639,7 @@ Mobile chat session switching needs a dedicated rename tap target beside each se display: block; margin-bottom: var(--space-xs); color: var(--text-muted); - font-size: var(--font-size-sm); + font-size: 0.875rem; } .chat-rename-input { @@ -680,7 +680,7 @@ Mobile chat session switching needs a dedicated rename tap target beside each se } .chat-thread-header-render-toggle:hover { - background: var(--bg-hover, var(--bg-secondary)); + background: var(--surface-hover); color: var(--text); } @@ -755,7 +755,7 @@ Mobile chat session switching needs a dedicated rename tap target beside each se .chat-message--assistant { align-self: flex-start; - background: var(--bg-elevated, var(--bg-secondary)); + background: var(--surface-1); color: var(--text); border-bottom-left-radius: var(--radius-sm); } @@ -829,7 +829,7 @@ Mobile chat session switching needs a dedicated rename tap target beside each se font-size: 11px; padding: 1px 6px; border-radius: 4px; - background: var(--surface-bg, color-mix(in srgb, var(--surface) 55%, transparent)); + background: var(--surface); color: var(--text-muted); margin-left: 6px; white-space: nowrap; @@ -1358,7 +1358,7 @@ Mobile chat session switching needs a dedicated rename tap target beside each se /* Streaming indicator */ .chat-message--streaming { align-self: flex-start; - background: var(--bg-elevated, var(--bg-secondary)); + background: var(--surface-1); color: var(--text); border-bottom-left-radius: 4px; opacity: 0.9; diff --git a/packages/dashboard/app/components/CliBinaryInstallBanner.css b/packages/dashboard/app/components/CliBinaryInstallBanner.css index 956b212793..2aa9253cfc 100644 --- a/packages/dashboard/app/components/CliBinaryInstallBanner.css +++ b/packages/dashboard/app/components/CliBinaryInstallBanner.css @@ -63,7 +63,7 @@ } .cli-binary-banner__primary:hover:not(:disabled) { - background: var(--accent-hover, #2563eb); + background: color-mix(in srgb, var(--accent) 88%, var(--text) 12%); } .cli-binary-banner__primary:disabled { diff --git a/packages/dashboard/app/components/CliBinaryPanel.css b/packages/dashboard/app/components/CliBinaryPanel.css index 79a501f4a6..935d56e1c8 100644 --- a/packages/dashboard/app/components/CliBinaryPanel.css +++ b/packages/dashboard/app/components/CliBinaryPanel.css @@ -137,7 +137,7 @@ } .cli-binary-install-btn:hover:not(:disabled) { - background: var(--accent-hover, #2563eb); + background: color-mix(in srgb, var(--accent) 88%, var(--text) 12%); } .cli-binary-install-btn:disabled, diff --git a/packages/dashboard/app/components/ConversationHistory.css b/packages/dashboard/app/components/ConversationHistory.css index 94411c5622..0fbaafa3e2 100644 --- a/packages/dashboard/app/components/ConversationHistory.css +++ b/packages/dashboard/app/components/ConversationHistory.css @@ -1,6 +1,6 @@ /* === Conversation History Timeline === */ .conversation-history { - border-left: 2px solid var(--border-primary); + border-left: 2px solid var(--border); padding: 0 0 0 12px; margin: 0 0 16px; max-height: 280px; @@ -33,7 +33,7 @@ padding: 2px 8px; border-radius: 999px; background: color-mix(in srgb, var(--bg-secondary) 80%, transparent); - border: 1px solid var(--border-primary); + border: 1px solid var(--border); color: var(--text); font-size: 11px; font-weight: 600; @@ -42,7 +42,7 @@ } .conversation-entry-response { - border: 1px solid var(--border-primary); + border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); padding: 8px 10px; @@ -68,7 +68,7 @@ .conversation-entry-thinking pre { margin: 0; - border: 1px solid var(--border-primary); + border: 1px solid var(--border); border-radius: 8px; background: color-mix(in srgb, var(--bg-secondary) 88%, transparent); padding: 10px; @@ -86,7 +86,7 @@ display: inline-flex; align-items: center; gap: 6px; - border: 1px solid var(--border-primary); + border: 1px solid var(--border); border-radius: 8px; background: transparent; color: var(--text-muted); @@ -108,7 +108,7 @@ } .conversation-separator { - border-top: 1px solid var(--border-primary); + border-top: 1px solid var(--border); margin: 4px 0 16px; } diff --git a/packages/dashboard/app/components/DashboardLoader.css b/packages/dashboard/app/components/DashboardLoader.css index 4d3bbcd08a..b98937328d 100644 --- a/packages/dashboard/app/components/DashboardLoader.css +++ b/packages/dashboard/app/components/DashboardLoader.css @@ -74,7 +74,7 @@ } .dashboard-loader__step--done { - color: var(--success, #22c55e); + color: var(--color-success); } .dashboard-loader__step--active { diff --git a/packages/dashboard/app/components/DesktopLaunchGate.css b/packages/dashboard/app/components/DesktopLaunchGate.css index c951c668ba..6fcb6850c3 100644 --- a/packages/dashboard/app/components/DesktopLaunchGate.css +++ b/packages/dashboard/app/components/DesktopLaunchGate.css @@ -4,7 +4,7 @@ display: flex; align-items: center; justify-content: center; - background: var(--bg-primary, #0f1117); + background: var(--bg); color: var(--text); z-index: 9999; padding: 1.5rem; @@ -14,7 +14,7 @@ max-width: 420px; width: 100%; text-align: center; - background: var(--bg-elevated, #1a1d27); + background: var(--surface-1); border: 1px solid var(--border-subtle, #2a2f3a); border-radius: 12px; padding: 2rem 1.75rem; diff --git a/packages/dashboard/app/components/DirectoryPicker.css b/packages/dashboard/app/components/DirectoryPicker.css index d33e5226ea..b60a07d41f 100644 --- a/packages/dashboard/app/components/DirectoryPicker.css +++ b/packages/dashboard/app/components/DirectoryPicker.css @@ -230,5 +230,5 @@ border: 1px solid var(--color-error); border-radius: var(--radius-md); color: var(--color-error); - font-size: var(--text-sm); + font-size: 0.875rem; } diff --git a/packages/dashboard/app/components/FileMentionPopup.css b/packages/dashboard/app/components/FileMentionPopup.css index ac3af26905..6c5ea8216c 100644 --- a/packages/dashboard/app/components/FileMentionPopup.css +++ b/packages/dashboard/app/components/FileMentionPopup.css @@ -233,7 +233,7 @@ } .chat-new-dialog { - background: var(--bg-elevated, var(--bg)); + background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-xl); @@ -357,7 +357,7 @@ } .chat-new-dialog-agent-item:hover { - background: var(--bg-hover); + background: var(--surface-hover); } .chat-new-dialog-agent-item--selected { diff --git a/packages/dashboard/app/components/GitHubImportModal.css b/packages/dashboard/app/components/GitHubImportModal.css index 6650c5ef8e..f7cb4da344 100644 --- a/packages/dashboard/app/components/GitHubImportModal.css +++ b/packages/dashboard/app/components/GitHubImportModal.css @@ -39,8 +39,8 @@ } .github-import-toolbar__zone--filter input:focus { - border-color: var(--color-primary); - box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 20%, transparent); + border-color: var(--accent); + box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 20%, transparent); outline: none; } @@ -105,8 +105,8 @@ .github-import-remote-select select:focus { outline: none; - border-color: var(--color-primary); - box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 20%, transparent); + border-color: var(--accent); + box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 20%, transparent); } /* Load button */ @@ -704,7 +704,7 @@ } [data-theme="light"] .github-import-toolbar__zone--filter input:focus { - border-color: var(--color-primary, var(--todo)); + border-color: var(--accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--in-progress) 15%, transparent); } diff --git a/packages/dashboard/app/components/GoalsView.css b/packages/dashboard/app/components/GoalsView.css index bdc96c26b5..7d6052279b 100644 --- a/packages/dashboard/app/components/GoalsView.css +++ b/packages/dashboard/app/components/GoalsView.css @@ -226,7 +226,7 @@ padding: calc(var(--space-xs) / 2); border: calc(var(--space-xs) / 4) solid var(--border); border-radius: var(--radius-pill); - background: var(--surface-elevated); + background: var(--surface-1); } .goals-linked-mission-link { diff --git a/packages/dashboard/app/components/GroupTaskModal.css b/packages/dashboard/app/components/GroupTaskModal.css index 7591fa4bd7..08a1be8aad 100644 --- a/packages/dashboard/app/components/GroupTaskModal.css +++ b/packages/dashboard/app/components/GroupTaskModal.css @@ -1,17 +1,17 @@ .group-task-modal { - max-width: min(var(--layout-content-max-width), calc(100vw - var(--spacing-2xl))); + max-width: min(var(--layout-content-max-width), calc(100vw - var(--space-2xl))); } .group-task-modal-body { display: flex; flex-direction: column; - gap: var(--spacing-md); + gap: var(--space-md); } .group-task-modal-state { display: flex; align-items: center; - gap: var(--spacing-sm); + gap: var(--space-sm); } .group-task-modal-error { @@ -24,22 +24,22 @@ .group-task-modal-actions { display: flex; flex-direction: column; - gap: var(--spacing-sm); + gap: var(--space-sm); } .group-task-modal-summary-row { display: flex; justify-content: space-between; align-items: center; - gap: var(--spacing-sm); + gap: var(--space-sm); } .group-task-modal-label { - color: var(--color-text-secondary); + color: var(--text-muted); } .group-task-modal-progress-text { - color: var(--color-text-secondary); + color: var(--text-muted); } .group-task-modal-members { @@ -48,13 +48,13 @@ margin: 0; display: flex; flex-direction: column; - gap: var(--spacing-xs); + gap: var(--space-xs); } .group-task-modal-member { display: grid; grid-template-columns: auto 1fr auto auto auto; - gap: var(--spacing-sm); + gap: var(--space-sm); align-items: center; } diff --git a/packages/dashboard/app/components/InsightsView.css b/packages/dashboard/app/components/InsightsView.css index c410ce102d..ffefb864d6 100644 --- a/packages/dashboard/app/components/InsightsView.css +++ b/packages/dashboard/app/components/InsightsView.css @@ -51,7 +51,7 @@ gap: var(--space-sm); padding: var(--space-sm) var(--space-lg); border-bottom: 1px solid var(--border); - background: var(--bg-subtle, var(--bg)); + background: var(--surface-subtle); } .insights-model-label { @@ -244,7 +244,7 @@ } .insights-category-item:hover { - background: var(--surface-elevated); + background: var(--surface-1); } .insights-category-item--active { @@ -271,7 +271,7 @@ flex-shrink: 0; font-size: 0.75rem; color: var(--text-muted); - background: var(--surface-elevated); + background: var(--surface-1); padding: var(--space-xs) var(--space-sm); border-radius: var(--radius-pill); border: 1px solid var(--border); @@ -328,7 +328,7 @@ .insights-section-count { font-size: 0.75rem; color: var(--text-muted); - background: var(--surface-elevated); + background: var(--surface-1); padding: var(--space-xs) var(--space-sm); border-radius: var(--radius-pill); border: 1px solid var(--border); @@ -401,7 +401,7 @@ } .insight-item-action-btn:hover:not(:disabled) { - background: var(--surface-elevated); + background: var(--surface-1); color: var(--accent); } diff --git a/packages/dashboard/app/components/Lane.css b/packages/dashboard/app/components/Lane.css index 6f34d7aae5..6fc0dc98cc 100644 --- a/packages/dashboard/app/components/Lane.css +++ b/packages/dashboard/app/components/Lane.css @@ -98,7 +98,7 @@ } .lane-header:focus-visible { - outline: 2px solid var(--focus-ring, var(--color-primary)); + outline: 2px solid var(--todo); outline-offset: -2px; } @@ -155,9 +155,9 @@ margin: 4px 12px 0; padding: 6px 8px; font-size: 0.8rem; - color: var(--danger, #d9534f); - background: color-mix(in srgb, var(--danger, #d9534f) 12%, transparent); - border: 1px solid color-mix(in srgb, var(--danger, #d9534f) 35%, transparent); + color: var(--color-error); + background: color-mix(in srgb, var(--color-error) 12%, transparent); + border: 1px solid color-mix(in srgb, var(--color-error) 35%, transparent); border-radius: var(--radius-sm, 6px); } diff --git a/packages/dashboard/app/components/LanguageSelector.css b/packages/dashboard/app/components/LanguageSelector.css index 6ea675059c..a73efb3468 100644 --- a/packages/dashboard/app/components/LanguageSelector.css +++ b/packages/dashboard/app/components/LanguageSelector.css @@ -22,7 +22,7 @@ display: inline-flex; align-items: center; padding: 6px 12px; - border: 1px solid var(--border-color, #333); + border: 1px solid var(--border); border-radius: 6px; background: var(--bg-secondary, transparent); color: var(--text); @@ -32,11 +32,11 @@ } .language-option:hover { - border-color: var(--accent-color, #4a9eff); + border-color: var(--accent); } .language-option.active { - border-color: var(--accent-color, #4a9eff); - background: var(--accent-color-subtle, color-mix(in srgb, #4a9eff 12%, transparent)); + border-color: var(--accent); + background: color-mix(in srgb, var(--accent) 12%, transparent); font-weight: 600; } diff --git a/packages/dashboard/app/components/MailboxModal.css b/packages/dashboard/app/components/MailboxModal.css index 35cdbadca8..61c4cee806 100644 --- a/packages/dashboard/app/components/MailboxModal.css +++ b/packages/dashboard/app/components/MailboxModal.css @@ -31,7 +31,7 @@ border-radius: var(--radius-pill); background: var(--color-error); color: var(--fab-text); - font-size: var(--font-size-3xs, 0.7rem); + font-size: 0.7rem; font-weight: 700; } @@ -80,7 +80,7 @@ border-radius: var(--radius-md); background: var(--color-error); color: var(--fab-text); - font-size: var(--font-size-4xs, 0.65rem); + font-size: 0.65rem; font-weight: 700; } @@ -112,7 +112,7 @@ .mailbox-empty p { margin: 0; - font-size: var(--font-size-base, 0.9rem); + font-size: 0.9rem; } .mailbox-item { @@ -161,7 +161,7 @@ .mailbox-item-from, .mailbox-item-to { - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; color: var(--text); white-space: nowrap; overflow: hidden; @@ -169,14 +169,14 @@ } .mailbox-item-time { - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; color: var(--text-muted); white-space: nowrap; flex-shrink: 0; } .mailbox-item-preview { - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; @@ -187,7 +187,7 @@ display: flex; flex-direction: column; gap: var(--space-xs); - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; color: var(--text-muted); margin-bottom: var(--space-xs); } @@ -235,7 +235,7 @@ min-width: 1.25rem; height: 1.25rem; padding: 0 var(--space-xs); - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; font-weight: 600; background: var(--todo); color: var(--fab-text); @@ -263,7 +263,7 @@ display: flex; align-items: center; gap: var(--space-sm); - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; color: var(--text-muted); } @@ -278,12 +278,12 @@ padding: var(--btn-border-width) var(--space-sm); border-radius: var(--radius-sm); background: var(--bg-tertiary); - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; color: var(--text-muted); } .mailbox-message-time { - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; } .mailbox-message-participants { @@ -298,7 +298,7 @@ display: flex; align-items: center; gap: var(--space-xs); - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; } .mailbox-participant-label { @@ -316,7 +316,7 @@ padding: var(--space-lg); background: var(--bg-secondary); border-radius: var(--radius-md); - font-size: var(--font-size-base, 0.9rem); + font-size: 0.9rem; line-height: 1.5; word-break: break-word; } @@ -399,7 +399,7 @@ border-radius: var(--radius-md); background: color-mix(in srgb, var(--text-muted) 12%, transparent); color: var(--text-muted); - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; line-height: 1.4; text-align: left; cursor: pointer; @@ -445,7 +445,7 @@ } .mailbox-conversation-label { - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; color: var(--text-muted); font-weight: 600; } @@ -468,12 +468,12 @@ justify-content: space-between; gap: var(--space-sm); margin-bottom: var(--btn-border-width); - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; color: var(--text-muted); } .mailbox-conversation-msg-body { - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; line-height: 1.4; word-break: break-word; } @@ -526,7 +526,7 @@ justify-content: center; min-height: calc(var(--space-lg) + var(--space-sm) - var(--btn-border-width)); padding: var(--space-xs) var(--space-md); - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; color: var(--text-muted); border-color: var(--border); background: var(--surface); @@ -545,7 +545,7 @@ .mailbox-agent-subtab .mailbox-tab-badge { margin-left: var(--btn-border-width); - font-size: var(--font-size-3xs, 0.7rem); + font-size: 0.7rem; } .mailbox-approval-filters { @@ -577,7 +577,7 @@ .mailbox-approval-status { text-transform: capitalize; - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; color: var(--text-muted); } @@ -789,7 +789,7 @@ .mailbox-modal .mailbox-tab { flex-shrink: 0; padding: var(--space-sm) var(--space-md); - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; } .mailbox-modal .mailbox-content { @@ -881,7 +881,7 @@ .mailbox-view .mailbox-tab { flex-shrink: 0; padding: var(--space-sm) var(--space-md); - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; } .mailbox-view .mailbox-content { @@ -1001,7 +1001,7 @@ align-items: center; justify-content: space-between; font-weight: 600; - font-size: var(--font-size-md, 0.95rem); + font-size: 0.95rem; } .message-composer-body { @@ -1021,7 +1021,7 @@ } .message-composer-label { - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; color: var(--text-muted); min-width: calc(var(--space-xl) + var(--space-lg) + var(--space-sm) + var(--btn-border-width)); padding-top: var(--space-xs); @@ -1035,7 +1035,7 @@ border-radius: var(--radius-sm); background: var(--bg-secondary); color: var(--text); - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; font-family: var(--font-primary); outline: none; transition: border-color var(--transition-fast), box-shadow var(--transition-fast); @@ -1058,7 +1058,7 @@ padding: var(--space-sm) var(--space-md); background: var(--bg-tertiary); border-radius: var(--radius-sm); - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; color: var(--text); } @@ -1069,7 +1069,7 @@ border-radius: var(--radius-sm); background: var(--bg-secondary); color: var(--text); - font-size: var(--font-size-base, 0.9rem); + font-size: 0.9rem; font-family: var(--font-primary); min-height: calc(var(--space-2xl) + var(--space-xl) + var(--space-md)); max-height: calc(var(--space-2xl) * 10); @@ -1091,7 +1091,7 @@ .message-composer-charcount { text-align: right; - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; color: var(--text-muted); } @@ -1107,7 +1107,7 @@ display: flex; align-items: center; gap: var(--space-sm); - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; color: var(--text-muted); cursor: pointer; } @@ -1122,7 +1122,7 @@ .message-composer-wake-hint { margin-left: var(--space-xs); - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; color: var(--text-muted); } @@ -1134,7 +1134,7 @@ background: color-mix(in srgb, var(--color-error) 10%, transparent); border-radius: var(--radius-sm); color: var(--color-error); - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; } .message-composer-footer { diff --git a/packages/dashboard/app/components/MergeAdvanceNotice.css b/packages/dashboard/app/components/MergeAdvanceNotice.css index 0aea2b1e7c..1709f35424 100644 --- a/packages/dashboard/app/components/MergeAdvanceNotice.css +++ b/packages/dashboard/app/components/MergeAdvanceNotice.css @@ -57,7 +57,7 @@ gap: var(--space-xs); margin-top: var(--space-sm); padding-top: var(--space-sm); - border-top: var(--border-width-thin) solid color-mix(in srgb, var(--color-warning) 25%, transparent); + border-top: 1px solid color-mix(in srgb, var(--color-warning) 25%, transparent); } .merge-advance-notice__push-heading { diff --git a/packages/dashboard/app/components/MissionManager.css b/packages/dashboard/app/components/MissionManager.css index a32ffe67e1..83fa01c864 100644 --- a/packages/dashboard/app/components/MissionManager.css +++ b/packages/dashboard/app/components/MissionManager.css @@ -882,7 +882,7 @@ .mission-list__item-run-help { font-size: calc(var(--space-sm) + var(--space-xs) * 0.75); color: var(--text-muted); - max-width: calc(var(--space-3xl) * 5); + max-width: calc(calc(var(--space-2xl) + var(--space-md)) * 5); } .mission-list__item-summary { @@ -1127,7 +1127,7 @@ padding: calc(var(--space-xs) / 2); border: calc(var(--space-xs) / 4) solid var(--border); border-radius: var(--radius-pill); - background: var(--surface-elevated); + background: var(--surface-1); } .mission-detail__linked-goal-chip-link { @@ -1327,9 +1327,9 @@ } .mission-detail__tab--active { - background: var(--button-primary-bg); - color: var(--button-primary-text); - border-color: var(--button-primary-bg); + background: var(--accent); + color: var(--accent-text); + border-color: var(--accent); } .mission-detail__activity { diff --git a/packages/dashboard/app/components/MobileWorkflowGraphView.css b/packages/dashboard/app/components/MobileWorkflowGraphView.css index 31c4854f46..39aefd523f 100644 --- a/packages/dashboard/app/components/MobileWorkflowGraphView.css +++ b/packages/dashboard/app/components/MobileWorkflowGraphView.css @@ -171,7 +171,7 @@ Simple-editor step order is editable on touch and compact desktop surfaces, so m .mobile-wf-connect-label { color: var(--text-muted); - font-size: var(--font-size-sm); + font-size: 0.875rem; } .mobile-wf-connect-select { diff --git a/packages/dashboard/app/components/ModelOnboardingModal.css b/packages/dashboard/app/components/ModelOnboardingModal.css index f3030c1526..866796b06d 100644 --- a/packages/dashboard/app/components/ModelOnboardingModal.css +++ b/packages/dashboard/app/components/ModelOnboardingModal.css @@ -42,7 +42,7 @@ .model-onboarding-header .modal-close:hover { color: var(--text); - background: var(--bg-hover); + background: var(--surface-hover); } .model-onboarding-title { @@ -62,7 +62,7 @@ font-size: 11px; font-weight: 500; color: var(--text-muted); - background: var(--bg-hover); + background: var(--surface-hover); padding: 2px 8px; border-radius: 10px; margin-left: 8px; @@ -141,7 +141,7 @@ display: flex; align-items: center; justify-content: center; - background: var(--bg-hover); + background: var(--surface-hover); font-weight: 600; font-size: 12px; } @@ -978,7 +978,7 @@ width: calc(var(--space-xl) * 2); height: calc(var(--space-xl) * 2); border-radius: var(--radius-lg); - background: var(--bg-hover); + background: var(--surface-hover); display: flex; align-items: center; justify-content: center; @@ -1043,7 +1043,7 @@ } .onboarding-skip-note code { - background: var(--bg-hover); + background: var(--surface-hover); padding: 2px 6px; border-radius: 4px; font-size: 12px; @@ -1166,7 +1166,7 @@ .onboarding-skip-step-link:hover { color: var(--text); - background: var(--bg-hover); + background: var(--surface-hover); } @media (max-width: 768px) { diff --git a/packages/dashboard/app/components/OnboardingDisclosure.css b/packages/dashboard/app/components/OnboardingDisclosure.css index 0a6f64f2c2..e20d3be922 100644 --- a/packages/dashboard/app/components/OnboardingDisclosure.css +++ b/packages/dashboard/app/components/OnboardingDisclosure.css @@ -12,7 +12,7 @@ background: none; border: none; color: var(--text-muted); - font-size: var(--font-size-sm, 12px); + font-size: 0.875rem; cursor: pointer; padding: var(--space-xs) 0; transition: color var(--transition-fast); @@ -43,7 +43,7 @@ .onboarding-disclosure-content { padding: var(--space-sm) 0 var(--space-sm) calc(var(--space-sm) + var(--space-lg) - var(--space-xs)); color: var(--text-muted); - font-size: var(--font-size-sm, 12px); + font-size: 0.875rem; line-height: 1.5; animation: onboarding-disclosure-enter var(--duration-fast) ease-out; } diff --git a/packages/dashboard/app/components/PlanningModeModal.css b/packages/dashboard/app/components/PlanningModeModal.css index 9c5ea253a2..9b0c932b6c 100644 --- a/packages/dashboard/app/components/PlanningModeModal.css +++ b/packages/dashboard/app/components/PlanningModeModal.css @@ -630,7 +630,7 @@ display: block; margin-bottom: var(--space-xs); color: var(--text-muted); - font-size: var(--font-size-xs, 12px); + font-size: 0.8rem; } .planning-comment-section .planning-textarea { diff --git a/packages/dashboard/app/components/PluginManager.css b/packages/dashboard/app/components/PluginManager.css index 191d2391e7..7bf8ee3824 100644 --- a/packages/dashboard/app/components/PluginManager.css +++ b/packages/dashboard/app/components/PluginManager.css @@ -19,7 +19,7 @@ } .plugin-manager-header-title { - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; font-weight: 600; color: var(--text); flex: 1; @@ -43,7 +43,7 @@ .plugin-install-hint { margin: 0; - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; color: var(--text-muted); line-height: 1.45; } @@ -113,7 +113,7 @@ } .plugin-version { - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; } .plugin-state-badge { @@ -121,7 +121,7 @@ align-items: center; padding: var(--space-xs) var(--space-sm); border-radius: var(--radius-pill); - font-size: var(--font-size-3xs, 0.7rem); + font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; @@ -169,7 +169,7 @@ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; font-family: var(--font-mono); color: var(--color-error); background: color-mix(in srgb, var(--color-error) 10%, transparent); @@ -202,7 +202,7 @@ } .plugin-description { - font-size: var(--font-size-md, 0.95rem); + font-size: 0.95rem; color: var(--text-muted); line-height: 1.5; } @@ -211,7 +211,7 @@ display: flex; align-items: center; gap: var(--space-xs); - font-size: var(--font-size-base, 0.9rem); + font-size: 0.9rem; color: var(--text-muted); } @@ -225,7 +225,7 @@ align-items: center; gap: var(--space-xs); color: var(--color-info); - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; flex-wrap: wrap; overflow-wrap: anywhere; } @@ -234,7 +234,7 @@ margin: 0; padding: 0; border: 0; - font-size: var(--font-size-md, 0.95rem); + font-size: 0.95rem; } .plugin-settings-form { @@ -257,7 +257,7 @@ .plugin-settings-group-heading { margin: 0; - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; @@ -362,12 +362,12 @@ .plugin-builtins-heading { margin: 0; - font-size: var(--font-size-md, 0.95rem); + font-size: 0.95rem; } .plugin-builtins-description { margin: 0; - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; color: var(--text-muted); } @@ -401,7 +401,7 @@ .plugin-builtins-name { color: var(--text); - font-size: var(--font-size-base, 0.9rem); + font-size: 0.9rem; font-weight: 500; } @@ -412,7 +412,7 @@ border-radius: var(--radius-pill); background: var(--status-in-review-bg); color: var(--in-review); - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; font-weight: 600; text-transform: uppercase; } @@ -422,7 +422,7 @@ align-items: center; padding: var(--btn-border-width) var(--space-xs); border-radius: var(--radius-pill); - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; font-weight: 600; text-transform: uppercase; } @@ -442,7 +442,7 @@ align-items: center; padding: var(--btn-border-width) var(--space-xs); border-radius: var(--radius-pill); - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; font-weight: 600; text-transform: uppercase; } @@ -470,12 +470,12 @@ .plugin-builtins-description-text { flex: 1 1 100%; color: var(--text-muted); - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; } .plugin-builtins-metadata-only { color: var(--text-muted); - font-size: var(--font-size-xs, 0.8rem); + font-size: 0.8rem; font-weight: 600; text-transform: uppercase; } @@ -502,12 +502,12 @@ .plugin-registry-heading { margin: 0; - font-size: var(--font-size-md, 0.95rem); + font-size: 0.95rem; } .plugin-registry-description { margin: 0; - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; color: var(--text-muted); } @@ -581,7 +581,7 @@ .plugin-registry-name { color: var(--text); - font-size: var(--font-size-base, 0.9rem); + font-size: 0.9rem; font-weight: 500; } @@ -589,7 +589,7 @@ .plugin-registry-author, .plugin-registry-description-text { color: var(--text-muted); - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; } .plugin-registry-description-text { @@ -606,7 +606,7 @@ align-items: center; padding: var(--btn-border-width) var(--space-xs); border-radius: var(--radius-pill); - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; font-weight: 600; text-transform: uppercase; } @@ -644,7 +644,7 @@ border-radius: var(--radius-md); background: var(--surface); color: var(--text-muted); - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; text-align: center; } @@ -684,7 +684,7 @@ .plugin-bundled-runtime-name { color: var(--text); - font-size: var(--font-size-base, 0.9rem); + font-size: 0.9rem; font-weight: 500; } @@ -695,7 +695,7 @@ border-radius: var(--radius-pill); background: var(--status-in-review-bg); color: var(--in-review); - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; font-weight: 600; text-transform: uppercase; } @@ -714,12 +714,12 @@ .plugin-bundled-runtime-heading { margin: 0; - font-size: var(--font-size-md, 0.95rem); + font-size: 0.95rem; } .plugin-bundled-runtime-description { margin: 0; - font-size: var(--font-size-sm, 0.85rem); + font-size: 0.85rem; color: var(--text-muted); } @@ -728,7 +728,7 @@ align-items: center; padding: var(--btn-border-width) var(--space-xs); border-radius: var(--radius-pill); - font-size: var(--font-size-2xs, 0.75rem); + font-size: 0.75rem; font-weight: 600; text-transform: uppercase; } diff --git a/packages/dashboard/app/components/PostOnboardingRecommendations.css b/packages/dashboard/app/components/PostOnboardingRecommendations.css index 8c7edcd782..868e5dfe4f 100644 --- a/packages/dashboard/app/components/PostOnboardingRecommendations.css +++ b/packages/dashboard/app/components/PostOnboardingRecommendations.css @@ -26,8 +26,8 @@ width: calc(var(--space-lg) * 2 + var(--space-xs)); height: calc(var(--space-lg) * 2 + var(--space-xs)); border-radius: var(--radius-pill); - background: color-mix(in srgb, var(--primary) 15%, var(--surface)); - color: var(--primary); + background: color-mix(in srgb, var(--accent) 15%, var(--surface)); + color: var(--accent); flex-shrink: 0; } diff --git a/packages/dashboard/app/components/PullRequestView.css b/packages/dashboard/app/components/PullRequestView.css index 0efb859410..ef23d55c19 100644 --- a/packages/dashboard/app/components/PullRequestView.css +++ b/packages/dashboard/app/components/PullRequestView.css @@ -19,7 +19,7 @@ } .pr-view--error { - color: var(--danger, #e5534b); + color: var(--color-error); } /* identity header */ @@ -62,12 +62,12 @@ } .pr-identity-state--failed { - background: var(--pr-failed-bg, color-mix(in srgb, #e5534b 18%, transparent)); - color: var(--danger, #e5534b); + background: color-mix(in srgb, var(--color-error) 12%, transparent); + color: var(--color-error); } .pr-identity-state--merged { - background: var(--pr-merged-bg, color-mix(in srgb, #8250df 18%, transparent)); + background: color-mix(in srgb, var(--color-success) 12%, transparent); } /* placeholders / banners / notices */ @@ -84,16 +84,16 @@ } .pr-banner--responding { - background: var(--pr-responding-bg, color-mix(in srgb, #3682dc 14%, transparent)); + background: color-mix(in srgb, var(--color-info) 12%, transparent); } .pr-notice--unverified { - background: var(--pr-unverified-bg, color-mix(in srgb, #dcaa36 14%, transparent)); + background: color-mix(in srgb, var(--color-warning) 12%, transparent); } .pr-error-reason { - background: var(--pr-error-bg, color-mix(in srgb, #e5534b 14%, transparent)); - color: var(--danger, #e5534b); + background: color-mix(in srgb, var(--color-error) 12%, transparent); + color: var(--color-error); } /* action bar */ @@ -133,7 +133,7 @@ } .pr-action--close { - border-color: var(--pr-close-border, color-mix(in srgb, #e5534b 40%, transparent)); + border-color: color-mix(in srgb, var(--color-error) 45%, transparent); } .pr-automerge-toggle { @@ -155,7 +155,7 @@ display: inline-flex; align-items: center; gap: 4px; - color: var(--danger, #e5534b); + color: var(--color-error); text-decoration: none; font-size: 0.85em; } @@ -179,15 +179,15 @@ } .pr-icon-success { - color: var(--success, #3fb950); + color: var(--color-success); } .pr-icon-failure { - color: var(--danger, #e5534b); + color: var(--color-error); } .pr-icon-pending { - color: var(--warning, #d29922); + color: var(--color-warning); } /* threads */ @@ -209,8 +209,8 @@ } .pr-thread--agent-disagreement { - border-left: 3px solid var(--warning, #d29922); - background: var(--pr-disagreement-bg, color-mix(in srgb, #d29922 8%, transparent)); + border-left: 3px solid var(--color-warning); + background: color-mix(in srgb, var(--color-warning) 12%, transparent); } .pr-thread--pending { @@ -249,6 +249,6 @@ } .pr-inline-error { - color: var(--danger, #e5534b); + color: var(--color-error); font-size: 0.85em; } diff --git a/packages/dashboard/app/components/QuickChatFAB.css b/packages/dashboard/app/components/QuickChatFAB.css index 57416f421e..b7c5ed96db 100644 --- a/packages/dashboard/app/components/QuickChatFAB.css +++ b/packages/dashboard/app/components/QuickChatFAB.css @@ -374,7 +374,7 @@ .quick-chat-rename-label { color: var(--text-muted); - font-size: var(--font-size-sm); + font-size: 0.875rem; } .quick-chat-rename-input { @@ -1351,7 +1351,7 @@ Quick chat session rows include a separate rename button so selecting a session, /* Streaming indicator */ .quick-chat-panel .chat-message--streaming { align-self: flex-start; - background: var(--bg-elevated, var(--bg-secondary)); + background: var(--surface-1); color: var(--text); border-bottom-left-radius: var(--radius-sm); opacity: 0.9; diff --git a/packages/dashboard/app/components/QuickEntryBox.css b/packages/dashboard/app/components/QuickEntryBox.css index a19682340e..e7a7f1d22c 100644 --- a/packages/dashboard/app/components/QuickEntryBox.css +++ b/packages/dashboard/app/components/QuickEntryBox.css @@ -244,11 +244,11 @@ } .model-menu-item:hover { - background: var(--bg-hover); + background: var(--surface-hover); } .model-menu-item--active { - color: var(--text-accent, var(--todo)); + color: var(--accent); } .model-menu-item-label { @@ -306,7 +306,7 @@ justify-content: space-between; gap: 8px; font-size: 0.6875rem; - color: var(--text-error, #e53e3e); + color: var(--color-error); padding-top: 4px; } diff --git a/packages/dashboard/app/components/ReliabilityView.css b/packages/dashboard/app/components/ReliabilityView.css index 742194c895..7338802f96 100644 --- a/packages/dashboard/app/components/ReliabilityView.css +++ b/packages/dashboard/app/components/ReliabilityView.css @@ -12,7 +12,7 @@ .reliability-card { padding: var(--space-lg); - border: var(--border-width-thin, 0.0625rem) solid var(--border); + border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--card); } @@ -55,7 +55,7 @@ } .reliability-headline { - font-size: var(--font-size-2xl, 1.75rem); + font-size: 1.75rem; font-weight: 700; } @@ -82,7 +82,7 @@ .reliability-table td { text-align: left; padding: var(--space-xs) var(--space-sm); - border-bottom: var(--border-width-thin, 0.0625rem) solid var(--border); + border-bottom: 1px solid var(--border); } .reliability-stat-row { diff --git a/packages/dashboard/app/components/ScriptsModal.css b/packages/dashboard/app/components/ScriptsModal.css index 2232e54fd5..ffd31364a7 100644 --- a/packages/dashboard/app/components/ScriptsModal.css +++ b/packages/dashboard/app/components/ScriptsModal.css @@ -90,7 +90,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy display: inline-flex; align-items: center; gap: var(--space-xs); - font-size: var(--text-xs, 12px); + font-size: 0.75rem; color: var(--text-muted); white-space: nowrap; } @@ -130,7 +130,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy align-items: center; gap: var(--space-xs); padding: var(--space-xs) var(--space-md); - font-size: var(--text-xs, 12px); + font-size: 0.75rem; font-weight: 500; border: none; border-radius: var(--radius-sm); @@ -288,12 +288,12 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy border: 1px solid var(--border); border-radius: var(--radius-md); padding: calc(var(--space-md) + var(--space-xs) / 2) var(--space-lg); - background: var(--card-bg); + background: var(--card); transition: border-color var(--transition-fast); } .schedule-card:hover { - border-color: var(--border-hover, var(--border)); + border-color: color-mix(in srgb, var(--border) 70%, var(--text) 30%); } .schedule-card.disabled { @@ -671,7 +671,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy .step-card { border: 1px solid var(--border); border-radius: var(--radius-sm); - background: var(--bg-primary); + background: var(--bg); } .step-card-row { @@ -900,7 +900,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy } .routine-card:hover { - border-color: var(--border-hover, var(--border)); + border-color: color-mix(in srgb, var(--border) 70%, var(--text) 30%); } .routine-card.disabled { @@ -1116,7 +1116,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy } .routine-trigger-btn:hover { - border-color: var(--border-hover, var(--border)); + border-color: color-mix(in srgb, var(--border) 70%, var(--text) 30%); background: var(--bg-secondary); color: var(--text); } @@ -1959,7 +1959,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy } .gm-status-conflict { - color: var(--danger, #c0392b); + color: var(--color-error); font-weight: 600; } @@ -1969,8 +1969,8 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy gap: var(--space-sm); padding: var(--space-md); margin-top: var(--space-md); - background: color-mix(in srgb, var(--warning, #f4b400) 12%, transparent); - border: 1px solid color-mix(in srgb, var(--warning, #f4b400) 40%, transparent); + background: color-mix(in srgb, var(--color-warning) 12%, transparent); + border: 1px solid color-mix(in srgb, var(--color-warning) 40%, transparent); border-radius: var(--radius-md); font-size: 13px; line-height: 1.4; @@ -1979,7 +1979,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy .gm-status-warning svg { flex-shrink: 0; margin-top: 2px; - color: var(--warning, #f4b400); + color: var(--color-warning); } .gm-status-warning code { @@ -2061,11 +2061,11 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy } .gm-status-advances .gm-advance-needs-action { - background: color-mix(in srgb, var(--warning, #f4b400) 8%, transparent); + background: color-mix(in srgb, var(--color-warning) 8%, transparent); } .gm-status-advances .gm-advance-handled { - background: color-mix(in srgb, var(--success, #27ae60) 6%, transparent); + background: color-mix(in srgb, var(--color-success) 6%, transparent); color: var(--text-muted); } @@ -3124,7 +3124,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy gap: var(--space-sm); padding: var(--space-xs) var(--space-sm); border-radius: var(--radius-pill); - font-size: var(--text-xs, 12px); + font-size: 0.75rem; font-weight: 500; } @@ -3407,7 +3407,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy display: flex; align-items: center; gap: var(--space-xs); - font-size: var(--text-xs, 12px); + font-size: 0.75rem; font-weight: 600; color: var(--text-muted); } @@ -3422,7 +3422,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy display: flex; align-items: flex-start; gap: var(--space-sm); - font-size: var(--text-xs, 12px); + font-size: 0.75rem; font-family: var(--font-mono); } @@ -3586,7 +3586,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy font-size: 13px; font-weight: 600; color: var(--text); - background: var(--bg-surface, var(--surface-subtle)); + background: var(--surface-1); border-bottom: 1px solid var(--border); white-space: pre-wrap; word-break: break-word; diff --git a/packages/dashboard/app/components/SessionTerminal.css b/packages/dashboard/app/components/SessionTerminal.css index eb4253030f..70a4d32671 100644 --- a/packages/dashboard/app/components/SessionTerminal.css +++ b/packages/dashboard/app/components/SessionTerminal.css @@ -45,8 +45,8 @@ } .cli-posture-chip--elevated { - color: var(--warning, var(--color-warning)); - border-color: var(--warning, var(--color-warning)); + color: var(--color-warning); + border-color: var(--color-warning); } .cli-posture-chip__mode { @@ -91,7 +91,7 @@ margin-top: var(--space-sm); padding: 2px var(--space-sm); font-size: 0.75rem; - color: var(--accent, var(--color-primary)); + color: var(--accent); background: transparent; border: 1px solid var(--border); border-radius: var(--radius-sm); @@ -164,8 +164,8 @@ Recurrence #5 requires the attach terminal to mirror TerminalModal: xterm receiv .cli-session-terminal__advance-btn { padding: 4px var(--space-md); font-size: 0.8125rem; - color: var(--button-primary-text, var(--accent-text)); - background: var(--button-primary-bg, var(--accent)); + color: var(--accent-text); + background: var(--accent); border: 1px solid transparent; border-radius: var(--radius-sm); cursor: pointer; @@ -241,14 +241,14 @@ Recurrence #5 requires the attach terminal to mirror TerminalModal: xterm receiv } .cli-terminal-key--ctrl.cli-terminal-key--active { - color: var(--accent-text, var(--button-primary-text)); - background: var(--accent, var(--color-primary)); - border-color: var(--accent, var(--color-primary)); + color: var(--accent-text); + background: var(--accent); + border-color: var(--accent); } .cli-terminal-key--ctrlc { - color: var(--warning, var(--color-warning)); - border-color: var(--warning, var(--color-warning)); + color: var(--color-warning); + border-color: var(--color-warning); } .cli-session-terminal__input-row { @@ -263,14 +263,14 @@ Recurrence #5 requires the attach terminal to mirror TerminalModal: xterm receiv padding: var(--space-xs) var(--space-sm); font-size: 16px; /* >=16px avoids iOS focus zoom */ color: var(--text); - background: var(--input-bg, var(--bg)); + background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius-sm); } .cli-session-terminal__mobile-input:focus { outline: none; - border-color: var(--accent, var(--color-primary)); + border-color: var(--accent); } .cli-session-terminal__mobile-send { @@ -278,8 +278,8 @@ Recurrence #5 requires the attach terminal to mirror TerminalModal: xterm receiv min-height: 38px; padding: var(--space-xs) var(--space-md); font-size: 0.8125rem; - color: var(--button-primary-text, var(--accent-text)); - background: var(--button-primary-bg, var(--accent)); + color: var(--accent-text); + background: var(--accent); border: 1px solid transparent; border-radius: var(--radius-sm); cursor: pointer; diff --git a/packages/dashboard/app/components/SettingsModal.css b/packages/dashboard/app/components/SettingsModal.css index d82c8f8ea5..0af76997d0 100644 --- a/packages/dashboard/app/components/SettingsModal.css +++ b/packages/dashboard/app/components/SettingsModal.css @@ -1591,7 +1591,7 @@ align-items: center; } .auth-apikey-input { - background: var(--bg-input); + background: var(--surface-1); border: 1px solid var(--border); border-radius: 6px; color: var(--text); @@ -2157,7 +2157,7 @@ border-radius: var(--radius-md); background: color-mix(in srgb, var(--color-warning) 12%, transparent); color: var(--text); - font-size: var(--font-sm, 0.875rem); + font-size: 0.875rem; line-height: 1.4; } @@ -2169,7 +2169,7 @@ /* KTD-8: informational note at the bottom of the Node Sync section. */ .settings-sync-workflow-note { margin-top: var(--space-md); - font-size: var(--font-size-sm); + font-size: 0.875rem; color: var(--text-muted); } diff --git a/packages/dashboard/app/components/SkillMultiselect.css b/packages/dashboard/app/components/SkillMultiselect.css index 2540670e3a..ca6f6e64d1 100644 --- a/packages/dashboard/app/components/SkillMultiselect.css +++ b/packages/dashboard/app/components/SkillMultiselect.css @@ -55,7 +55,7 @@ .skill-chip-remove:hover:not(:disabled) { color: var(--text); - background: var(--bg-hover); + background: var(--surface-hover); } .skill-chip-remove:disabled { diff --git a/packages/dashboard/app/components/TaskCard.css b/packages/dashboard/app/components/TaskCard.css index 4534204583..d432ae81fc 100644 --- a/packages/dashboard/app/components/TaskCard.css +++ b/packages/dashboard/app/components/TaskCard.css @@ -221,9 +221,9 @@ The global mobile touch-action reset applies to descendants, and browsers inters /* DISTINCT error badge for the failed node-state (never the open-PR badge). */ .card-pr-node-badge--failed { - background: color-mix(in srgb, var(--color-danger, #e5534b) 18%, transparent); - border-color: color-mix(in srgb, var(--color-danger, #e5534b) 35%, transparent); - color: var(--color-danger, #e5534b); + background: color-mix(in srgb, var(--color-error) 18%, transparent); + border-color: color-mix(in srgb, var(--color-error) 35%, transparent); + color: var(--color-error); } .card-status-badge.stalled-review { @@ -894,7 +894,7 @@ The execution-time badge is part of the footer's bottom-right chip cluster, so i .card-duplicate-keep { border-color: color-mix(in srgb, var(--color-warning) 45%, transparent); - background: color-mix(in srgb, var(--surface-secondary) 90%, transparent); + background: color-mix(in srgb, var(--surface-2) 90%, transparent); color: var(--text); cursor: pointer; appearance: none; @@ -1195,10 +1195,10 @@ The execution-time badge is part of the footer's bottom-right chip cluster, so i display: inline-flex; align-items: center; padding: 2px 8px; - font-size: var(--font-size-xs, 11px); + font-size: 0.8rem; font-weight: 600; background: var(--todo); - color: var(--background, #fff); + color: var(--bg); border: none; border-radius: var(--radius-sm); cursor: pointer; @@ -1290,7 +1290,7 @@ The execution-time badge is part of the footer's bottom-right chip cluster, so i .card-unarchive-btn:hover { background: var(--card-hover); color: var(--text); - border-color: var(--border-hover); + border-color: color-mix(in srgb, var(--border) 70%, var(--text) 30%); } .card-archive-btn:focus, @@ -1331,7 +1331,7 @@ The execution-time badge is part of the footer's bottom-right chip cluster, so i .card-send-back-btn:hover { background: var(--card-hover); color: var(--text); - border-color: var(--border-hover); + border-color: color-mix(in srgb, var(--border) 70%, var(--text) 30%); } .card-send-back-btn:focus { @@ -1579,9 +1579,9 @@ The execution-time badge is part of the footer's bottom-right chip cluster, so i align-items: center; gap: 3px; padding: 1px 7px; - border: 1px solid var(--border-color, #2a2d34); + border: 1px solid var(--border); border-radius: 999px; - background: var(--chip-bg, #1c1f26); + background: var(--surface-2); color: var(--text-muted, #b4b8c0); font-size: 11px; line-height: 1.5; @@ -1607,8 +1607,8 @@ The execution-time badge is part of the footer's bottom-right chip cluster, so i align-items: center; padding: 0 5px; border-radius: 999px; - border: 1px solid var(--border-color, #2a2d34); - background: var(--chip-bg, #1c1f26); + border: 1px solid var(--border); + background: var(--surface-2); } .card-field-badge--overflow { diff --git a/packages/dashboard/app/components/TaskDocumentsTab.css b/packages/dashboard/app/components/TaskDocumentsTab.css index 4b3edefb1a..b53165b686 100644 --- a/packages/dashboard/app/components/TaskDocumentsTab.css +++ b/packages/dashboard/app/components/TaskDocumentsTab.css @@ -15,7 +15,7 @@ } .task-document-card:hover { - border-color: var(--border-hover); + border-color: color-mix(in srgb, var(--border) 70%, var(--text) 30%); } .task-document-card-header { @@ -62,7 +62,7 @@ .task-document-content { margin: var(--space-md) 0; padding: var(--space-md); - background: var(--bg-primary); + background: var(--bg); border-radius: 4px; border: 1px solid var(--border); max-height: 400px; @@ -112,7 +112,7 @@ .task-document-revisions { margin: var(--space-md) 0; padding: var(--space-md); - background: var(--bg-primary); + background: var(--bg); border-radius: 4px; border: 1px solid var(--border); } @@ -138,7 +138,7 @@ } .task-document-revision-item:hover { - background: var(--bg-hover); + background: var(--surface-hover); } .revision-header { diff --git a/packages/dashboard/app/components/TaskFieldsSection.css b/packages/dashboard/app/components/TaskFieldsSection.css index cce33d7786..bb2f0b28b8 100644 --- a/packages/dashboard/app/components/TaskFieldsSection.css +++ b/packages/dashboard/app/components/TaskFieldsSection.css @@ -22,7 +22,7 @@ } .task-field-required { - color: var(--accent-danger, #e5484d); + color: var(--color-error); } .task-field-control { @@ -38,9 +38,9 @@ width: 100%; box-sizing: border-box; padding: 6px 8px; - border: 1px solid var(--border-color, #2a2d34); + border: 1px solid var(--border); border-radius: 6px; - background: var(--input-bg, #16181d); + background: var(--surface-1); color: var(--text); font-size: 13px; font-family: inherit; @@ -67,9 +67,9 @@ .task-field-chip { padding: 3px 10px; - border: 1px solid var(--border-color, #2a2d34); + border: 1px solid var(--border); border-radius: 999px; - background: var(--chip-bg, #1c1f26); + background: var(--surface-2); color: var(--text-muted, #b4b8c0); font-size: 12px; cursor: pointer; @@ -126,7 +126,7 @@ width: 34px; height: 18px; border-radius: 999px; - background: var(--border-color, #2a2d34); + background: var(--border); position: relative; transition: background 0.15s ease; } @@ -158,19 +158,19 @@ /* Inline validation error */ .task-field-error { font-size: 12px; - color: var(--accent-danger, #e5484d); + color: var(--color-error); } .task-field-row.has-error .task-field-input, .task-field-row.has-error .task-field-textarea, .task-field-row.has-error .task-field-select { - border-color: var(--accent-danger, #e5484d); + border-color: var(--color-error); } /* Collapsible detail-section group */ .task-fields-group, .task-fields-orphaned { - border-top: 1px solid var(--border-color, #2a2d34); + border-top: 1px solid var(--border); padding-top: 8px; } @@ -201,7 +201,7 @@ .task-fields-orphaned-count { margin-left: auto; - background: var(--chip-bg, #1c1f26); + background: var(--surface-2); border-radius: 999px; padding: 0 8px; font-size: 11px; diff --git a/packages/dashboard/app/components/TerminalModal.css b/packages/dashboard/app/components/TerminalModal.css index c1114f9ddf..8d6080a47d 100644 --- a/packages/dashboard/app/components/TerminalModal.css +++ b/packages/dashboard/app/components/TerminalModal.css @@ -415,7 +415,7 @@ FN-6603 found that unicode-range scoping is not enough when the symbols face is } .terminal-prompt { - color: var(--success); + color: var(--color-success); font-weight: 600; flex-shrink: 0; } @@ -438,7 +438,7 @@ FN-6603 found that unicode-range scoping is not enough when the symbols face is .terminal-output-error { background: color-mix(in srgb, var(--color-error) 10%, transparent); - border-left: 3px solid var(--failed); + border-left: 3px solid var(--color-error); } .terminal-running-indicator { @@ -478,7 +478,7 @@ FN-6603 found that unicode-range scoping is not enough when the symbols face is } .terminal-input-prompt { - color: var(--success); + color: var(--color-success); font-weight: 600; font-family: var(--font-mono); font-size: 13px; @@ -513,7 +513,7 @@ FN-6603 found that unicode-range scoping is not enough when the symbols face is .terminal-kill-btn { padding: var(--space-sm) var(--space-lg); - background: var(--failed); + background: var(--color-error); border: none; border-radius: var(--radius); color: white; @@ -662,7 +662,7 @@ FN-6659 keeps the loaded symbols @font-face out of xterm's measured font option } .terminal-status.disconnected { - background: var(--error); + background: var(--color-error); } @keyframes terminal-pulse { @@ -748,7 +748,7 @@ FN-6659 keeps the loaded symbols @font-face out of xterm's measured font option flex-direction: column; gap: var(--space-xs); color: var(--text-muted); - font-size: var(--font-size-sm); + font-size: 0.875rem; } .terminal-preference-field--checkbox { @@ -765,7 +765,7 @@ FN-6659 keeps the loaded symbols @font-face out of xterm's measured font option .terminal-preference-note { color: var(--text-muted); - font-size: var(--font-size-xs); + font-size: 0.8rem; } .terminal-preferences-reset { @@ -798,11 +798,11 @@ FN-6659 keeps the loaded symbols @font-face out of xterm's measured font option } .terminal-connection-status.disconnected { - color: var(--error); + color: var(--color-error); } .terminal-exit-code { - color: var(--error); + color: var(--color-error); font-weight: 500; } @@ -871,7 +871,7 @@ FN-6659 keeps the loaded symbols @font-face out of xterm's measured font option padding: var(--space-md) var(--space-lg); background: color-mix(in srgb, var(--color-error) 10%, transparent); border-bottom: 1px solid var(--border); - color: var(--error); + color: var(--color-error); font-size: 13px; } @@ -883,7 +883,7 @@ FN-6659 keeps the loaded symbols @font-face out of xterm's measured font option } .terminal-error-content span { - color: var(--error, #f48771); + color: var(--color-error); text-align: center; } diff --git a/packages/dashboard/app/components/WorkflowFieldsPanel.css b/packages/dashboard/app/components/WorkflowFieldsPanel.css index 6cc9b74770..d49352b1ed 100644 --- a/packages/dashboard/app/components/WorkflowFieldsPanel.css +++ b/packages/dashboard/app/components/WorkflowFieldsPanel.css @@ -69,7 +69,7 @@ .wf-field-id-static { font-family: var(--font-mono, monospace); font-size: 0.7rem; - color: var(--text-tertiary); + color: var(--text-dim); background: var(--surface-2, color-mix(in srgb, #ffffff 4%, transparent)); padding: 1px 6px; border-radius: var(--radius-sm); @@ -113,7 +113,7 @@ .wf-field-sub > span { font-size: 0.65rem; text-transform: uppercase; - color: var(--text-tertiary); + color: var(--text-dim); } .wf-field--checkbox { @@ -140,7 +140,7 @@ .wf-field-options-label { font-size: 0.65rem; text-transform: uppercase; - color: var(--text-tertiary); + color: var(--text-dim); } .wf-field-option-row { diff --git a/packages/dashboard/app/components/WorkflowNodeEditor.css b/packages/dashboard/app/components/WorkflowNodeEditor.css index 4dca2a2475..c2ba523966 100644 --- a/packages/dashboard/app/components/WorkflowNodeEditor.css +++ b/packages/dashboard/app/components/WorkflowNodeEditor.css @@ -48,7 +48,7 @@ justify-content: space-between; gap: var(--space-sm); padding: var(--space-sm) var(--space-md); - background: var(--accent-subtle, color-mix(in srgb, #3b82f6 12%, transparent)); + background: color-mix(in srgb, var(--accent) 12%, transparent); border-bottom: 1px solid var(--border); color: var(--text); font-size: 0.85rem; @@ -398,7 +398,7 @@ .wf-editor-readonly-note { font-size: 0.75rem; - color: var(--text-tertiary); + color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; } @@ -473,7 +473,7 @@ font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--text-tertiary); + color: var(--text-dim); } .wf-templates-entries { @@ -507,7 +507,7 @@ .wf-templates-badge { padding: 0 var(--space-xs); - background: var(--accent-subtle, color-mix(in srgb, #3b82f6 12%, transparent)); + background: color-mix(in srgb, var(--accent) 12%, transparent); border-radius: var(--radius-sm); color: var(--text-muted); font-size: 0.7rem; @@ -903,7 +903,7 @@ .wf-inspector-note { margin: 0; font-size: 0.78rem; - color: var(--text-tertiary); + color: var(--text-dim); } .wf-inspector-note--info { @@ -1219,7 +1219,7 @@ .wf-workflow-description, .wf-workflow-description--readonly { font-size: 0.78rem; - color: var(--text-tertiary); + color: var(--text-dim); background: none; border: 1px solid transparent; border-radius: var(--radius-sm); @@ -1266,7 +1266,7 @@ font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--text-tertiary); + color: var(--text-dim); } .wf-template-option { @@ -1281,12 +1281,12 @@ } .wf-template-option:hover { - background: var(--bg-hover); + background: var(--surface-hover); } .wf-template-option.selected { border-color: var(--accent); - background: var(--bg-active); + background: var(--surface-hover-strong); } .wf-template-option:focus-visible { @@ -1309,7 +1309,7 @@ .wf-template-option-count { font-size: 0.72rem; - color: var(--text-tertiary); + color: var(--text-dim); } .wf-create-error { @@ -1393,7 +1393,7 @@ cursor: not-allowed; border-color: var(--border); background: var(--bg-tertiary); - color: var(--text-tertiary); + color: var(--text-dim); } .wf-column-panel-empty { @@ -1489,7 +1489,7 @@ font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--text-tertiary); + color: var(--text-dim); } .wf-column-agent-select { @@ -1517,7 +1517,7 @@ .wf-column-agent-select:disabled { background: var(--bg-tertiary); - color: var(--text-tertiary); + color: var(--text-dim); cursor: not-allowed; } @@ -1586,7 +1586,7 @@ .wf-column-agent-mode-option:has(input:disabled) { background: var(--bg-tertiary); - color: var(--text-tertiary); + color: var(--text-dim); cursor: not-allowed; } @@ -1619,7 +1619,7 @@ } .wf-ai-toggle:hover { - background: var(--bg-hover); + background: var(--surface-hover); } .wf-ai-create-body { diff --git a/packages/dashboard/app/components/WorkspaceSelector.css b/packages/dashboard/app/components/WorkspaceSelector.css index 93be25a542..68892271cb 100644 --- a/packages/dashboard/app/components/WorkspaceSelector.css +++ b/packages/dashboard/app/components/WorkspaceSelector.css @@ -50,7 +50,7 @@ padding: 8px; border: 1px solid var(--border); border-radius: var(--radius-lg); - background: var(--surface-elevated, var(--surface)); + background: var(--surface-1); box-shadow: var(--shadow-lg); } diff --git a/packages/dashboard/app/components/command-center/CommandCenter.css b/packages/dashboard/app/components/command-center/CommandCenter.css index 372d069cb4..bb65859a3b 100644 --- a/packages/dashboard/app/components/command-center/CommandCenter.css +++ b/packages/dashboard/app/components/command-center/CommandCenter.css @@ -11,10 +11,10 @@ The FN-4286 dashboard text-token guard requires command-center secondary copy to display: flex; flex: 1; flex-direction: column; - gap: var(--space-4); + gap: var(--space-lg); min-height: 0; inline-size: 100%; - padding: var(--space-4); + padding: var(--space-lg); } /* @@ -26,15 +26,15 @@ The Command Center must remain scrollable on mobile inside the overflow-hidden . flex-shrink: 0; align-items: center; justify-content: space-between; - gap: var(--space-3); + gap: var(--space-md); } .cc-title { display: flex; align-items: center; - gap: var(--space-2); + gap: var(--space-sm); margin: 0; - font-size: var(--font-size-lg); + font-size: 1rem; } /* ---- Tabs ---- */ @@ -42,19 +42,19 @@ The Command Center must remain scrollable on mobile inside the overflow-hidden . display: flex; flex-shrink: 0; flex-wrap: wrap; - gap: var(--space-1); - border-bottom: var(--border-width) solid var(--border-subtle); + gap: var(--space-xs); + border-bottom: 1px solid var(--border-subtle); } .cc-tab { appearance: none; background: none; border: none; - border-bottom: var(--border-width-thick) solid transparent; + border-bottom: 2px solid transparent; color: var(--text-muted); - padding: var(--space-2) var(--space-3); + padding: var(--space-sm) var(--space-md); cursor: pointer; - font-size: var(--font-size-sm); + font-size: 0.875rem; transition: color var(--transition-fast), border-color var(--transition-fast); } @@ -80,7 +80,7 @@ The Command Center must remain scrollable on mobile inside the overflow-hidden . @media (max-width: 768px) { .cc-tabpanel { - padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0) + var(--standalone-bottom-gap)); + padding-bottom: calc(var(--space-lg) + env(safe-area-inset-bottom, 0) + var(--standalone-bottom-gap)); } } @@ -89,13 +89,13 @@ The Command Center must remain scrollable on mobile inside the overflow-hidden . min-inline-size: 0; display: flex; flex-direction: column; - gap: var(--space-4); + gap: var(--space-lg); } .cc-stat-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(var(--space-20) * 2)), 1fr)); - gap: var(--space-3); + grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(calc(var(--space-2xl) * 2 + var(--space-lg)) * 2)), 1fr)); + gap: var(--space-md); } /* @@ -105,21 +105,21 @@ FN-6680 standardizes the Command Center card rhythm across overview, area, table .cc-stat-card { display: flex; flex-direction: column; - gap: var(--space-2); + gap: var(--space-sm); min-inline-size: 0; - padding: var(--space-3); - border: var(--border-width) solid var(--border-subtle); + padding: var(--space-md); + border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--surface-1); } .cc-stat-label { - font-size: var(--font-size-sm); + font-size: 0.875rem; color: var(--text-muted); } .cc-stat-value { - font-size: var(--font-size-xl); + font-size: 1.25rem; font-variant-numeric: tabular-nums; color: var(--text); } @@ -137,15 +137,15 @@ The GitHub closed-at backfill control lives inside the existing Fixed by Fusion display: flex; flex-wrap: wrap; align-items: center; - gap: var(--space-2); + gap: var(--space-sm); } .cc-github-backfill-status { display: flex; flex-direction: column; - gap: var(--space-1); + gap: var(--space-xs); color: var(--text-muted); - font-size: var(--font-size-xs); + font-size: 0.8rem; } .cc-github-backfill-status--error { @@ -175,18 +175,18 @@ FN-6680 keeps the FN-6664 live/chart shrink contract but replaces hardcoded trac .cc-live-strip { position: relative; display: grid; - grid-template-columns: minmax(calc(var(--space-20) * 2), 1fr) minmax(calc((var(--space-20) * 3) + var(--space-4)), 2fr) minmax(calc(var(--space-20) * 2), 1fr); + grid-template-columns: minmax(calc(calc(var(--space-2xl) * 2 + var(--space-lg)) * 2), 1fr) minmax(calc((calc(var(--space-2xl) * 2 + var(--space-lg)) * 3) + var(--space-lg)), 2fr) minmax(calc(calc(var(--space-2xl) * 2 + var(--space-lg)) * 2), 1fr); align-items: center; - gap: var(--space-3); - padding: var(--space-3); - border: var(--border-width) solid var(--border-subtle); + gap: var(--space-md); + padding: var(--space-md); + border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 14%, transparent), transparent), var(--surface-1); - box-shadow: 0 0 var(--space-4) color-mix(in srgb, var(--accent) 18%, transparent); + box-shadow: 0 0 var(--space-lg) color-mix(in srgb, var(--accent) 18%, transparent); overflow: hidden; - font-size: var(--font-size-sm); + font-size: 0.875rem; } .cc-live-strip::before { @@ -211,7 +211,7 @@ FN-6680 keeps the FN-6664 live/chart shrink contract but replaces hardcoded trac .cc-live-strip-heading { display: flex; align-items: center; - gap: var(--space-2); + gap: var(--space-sm); } .cc-live-strip-label { @@ -223,15 +223,15 @@ FN-6680 keeps the FN-6664 live/chart shrink contract but replaces hardcoded trac min-inline-size: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); - gap: var(--space-2); + gap: var(--space-sm); } .cc-live-metric { min-inline-size: 0; display: flex; flex-direction: column; - gap: var(--space-1); - padding: var(--space-2); + gap: var(--space-xs); + padding: var(--space-sm); border-radius: var(--radius-sm); background: color-mix(in srgb, var(--surface-2) 70%, transparent); animation: cc-live-signal-pulse calc(var(--duration-slow) * 6) ease-in-out infinite; @@ -239,7 +239,7 @@ FN-6680 keeps the FN-6664 live/chart shrink contract but replaces hardcoded trac .cc-live-metric-value { color: var(--text); - font-size: var(--font-size-lg); + font-size: 1rem; font-weight: 700; font-variant-numeric: tabular-nums; } @@ -254,7 +254,7 @@ Overview token totals now live-poll and should visibly count up on change in bot @keyframes cc-token-count-pop { from { - transform: translateY(var(--space-1)); + transform: translateY(var(--space-xs)); opacity: 0.7; } to { @@ -266,7 +266,7 @@ Overview token totals now live-poll and should visibly count up on change in bot .cc-live-metric-label, .cc-live-trend-label { color: var(--text-muted); - font-size: var(--font-size-xs); + font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.04em; } @@ -275,15 +275,15 @@ Overview token totals now live-poll and should visibly count up on change in bot min-inline-size: 0; display: flex; flex-direction: column; - gap: var(--space-2); + gap: var(--space-sm); } .cc-live-trend .cc-sparkline { - block-size: var(--space-10); + block-size: calc(var(--space-2xl) + var(--space-sm)); } .cc-live-trend .cc-sparkline-bar { - box-shadow: 0 0 var(--space-2) color-mix(in srgb, var(--accent) 28%, transparent); + box-shadow: 0 0 var(--space-sm) color-mix(in srgb, var(--accent) 28%, transparent); animation: cc-live-signal-pulse calc(var(--duration-slow) * 5) ease-in-out infinite; } @@ -323,7 +323,7 @@ Overview charts must use dashboard tokens only and keep motion decorative; anima min-inline-size: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: var(--space-3); + gap: var(--space-md); align-items: stretch; } @@ -332,14 +332,14 @@ Overview charts must use dashboard tokens only and keep motion decorative; anima position: relative; display: flex; flex-direction: column; - gap: var(--space-3); - padding: var(--space-3); - border: var(--border-width) solid var(--border-subtle); + gap: var(--space-md); + padding: var(--space-md); + border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: linear-gradient(145deg, color-mix(in srgb, var(--accent) 10%, transparent), transparent), var(--surface-1); - box-shadow: 0 0 var(--space-4) color-mix(in srgb, var(--accent) 12%, transparent); + box-shadow: 0 0 var(--space-lg) color-mix(in srgb, var(--accent) 12%, transparent); overflow: hidden; animation: cc-overview-chart-rise var(--duration-normal) ease-out both; } @@ -363,13 +363,13 @@ Overview charts must use dashboard tokens only and keep motion decorative; anima z-index: 1; display: flex; flex-direction: column; - gap: var(--space-1); + gap: var(--space-xs); } .cc-overview-chart-header p { margin: 0; color: var(--text-muted); - font-size: var(--font-size-sm); + font-size: 0.875rem; } .cc-overview-chart-card .cc-bar-chart, @@ -387,23 +387,23 @@ Overview recharts cards use token-derived height so ResponsiveContainer can rend .cc-overview-chart-card .cc-recharts-chart, .cc-overview-chart-card .cc-recharts-empty { inline-size: 100%; - block-size: calc(var(--space-20) * 3); + block-size: calc(calc(var(--space-2xl) * 2 + var(--space-lg)) * 3); min-inline-size: 0; } .cc-overview-chart-card .cc-sparkline { - block-size: var(--space-16); + block-size: calc(var(--space-2xl) * 2); } .cc-overview-chart-card .cc-bar-fill, .cc-overview-chart-card .cc-sparkline-bar { - box-shadow: 0 0 var(--space-2) color-mix(in srgb, var(--accent) 30%, transparent); + box-shadow: 0 0 var(--space-sm) color-mix(in srgb, var(--accent) 30%, transparent); } @keyframes cc-overview-chart-rise { from { opacity: 0; - transform: translateY(var(--space-2)); + transform: translateY(var(--space-sm)); } to { opacity: 1; @@ -470,7 +470,7 @@ The Command Center subtree previously had no tablet tier, so at 769px–1024px t .cc-stat-grid, .cc-area .cc-stat-grid { - grid-template-columns: repeat(auto-fit, minmax(min(100%, calc(var(--space-20) * 2)), 1fr)); + grid-template-columns: repeat(auto-fit, minmax(min(100%, calc(calc(var(--space-2xl) * 2 + var(--space-lg)) * 2)), 1fr)); } } @@ -502,8 +502,8 @@ The Command Center subtree previously had no tablet tier, so at 769px–1024px t flex-direction: column; align-items: center; justify-content: center; - gap: var(--space-2); - padding: var(--space-6); + gap: var(--space-sm); + padding: var(--space-xl); color: var(--text-muted); text-align: center; } @@ -513,7 +513,7 @@ The Command Center subtree previously had no tablet tier, so at 769px–1024px t } .cc-loading .cc-chart-skeleton { - block-size: var(--space-4); + block-size: var(--space-lg); border-radius: var(--radius-sm); background: var(--surface-2); animation: cc-shell-pulse var(--duration-slow) ease-in-out infinite; diff --git a/packages/dashboard/app/components/command-center/DateRangePicker.css b/packages/dashboard/app/components/command-center/DateRangePicker.css index 52a1dd9fcc..dfc2844dc5 100644 --- a/packages/dashboard/app/components/command-center/DateRangePicker.css +++ b/packages/dashboard/app/components/command-center/DateRangePicker.css @@ -6,7 +6,7 @@ .cc-date-range-trigger { display: inline-flex; align-items: center; - gap: var(--space-1, 0.25rem); + gap: var(--space-xs); } /* @@ -18,38 +18,38 @@ Raw rgba fallbacks are replaced with byte-equivalent concrete-hex color-mix fall */ .cc-date-range-popover { position: absolute; - top: calc(100% + var(--space-1, 0.25rem)); + top: calc(100% + var(--space-xs)); right: 0; z-index: 20; min-width: 16rem; - padding: var(--space-3, 0.75rem); + padding: var(--space-md); background: var(--surface-1, #1c1c1c); border: 1px solid var(--border-subtle, color-mix(in srgb, #7f7f7f 25%, transparent)); border-radius: var(--radius-md, 8px); box-shadow: var(--shadow-md); display: flex; flex-direction: column; - gap: var(--space-3, 0.75rem); + gap: var(--space-md); } .cc-date-range-presets { display: flex; flex-wrap: wrap; - gap: var(--space-2, 0.5rem); + gap: var(--space-sm); } .cc-date-range-custom { display: flex; flex-direction: column; - gap: var(--space-2, 0.5rem); + gap: var(--space-sm); } .cc-date-range-field { display: flex; align-items: center; justify-content: space-between; - gap: var(--space-2, 0.5rem); - font-size: var(--font-size-sm, 0.85rem); + gap: var(--space-sm); + font-size: 0.85rem; color: var(--text-muted); } @@ -58,5 +58,5 @@ Raw rgba fallbacks are replaced with byte-equivalent concrete-hex color-mix fall border: 1px solid var(--border-subtle, color-mix(in srgb, #7f7f7f 25%, transparent)); border-radius: var(--radius-sm, 4px); color: var(--text); - padding: var(--space-1, 0.25rem) var(--space-2, 0.5rem); + padding: var(--space-xs) var(--space-sm); } diff --git a/packages/dashboard/app/components/command-center/MissionControlPanel.css b/packages/dashboard/app/components/command-center/MissionControlPanel.css index 8e408737e1..72a478334f 100644 --- a/packages/dashboard/app/components/command-center/MissionControlPanel.css +++ b/packages/dashboard/app/components/command-center/MissionControlPanel.css @@ -14,19 +14,19 @@ Raw rgba fallbacks are replaced with byte-equivalent concrete-hex color-mix fall .cc-mission-control { display: flex; flex-direction: column; - gap: var(--space-4, 16px); + gap: var(--space-lg); } .cc-mc-columns { display: grid; grid-template-columns: 1fr 1fr; - gap: var(--space-4, 16px); + gap: var(--space-lg); } .cc-mc-section { display: flex; flex-direction: column; - gap: var(--space-2, 8px); + gap: var(--space-sm); min-width: 0; } @@ -42,7 +42,7 @@ Raw rgba fallbacks are replaced with byte-equivalent concrete-hex color-mix fall padding: 0; display: flex; flex-direction: column; - gap: var(--space-1, 4px); + gap: var(--space-xs); } .cc-mc-session, @@ -50,8 +50,8 @@ Raw rgba fallbacks are replaced with byte-equivalent concrete-hex color-mix fall display: flex; align-items: center; justify-content: space-between; - gap: var(--space-2, 8px); - padding: var(--space-2, 8px); + gap: var(--space-sm); + padding: var(--space-sm); border: 1px solid var(--border-subtle, color-mix(in srgb, #ffffff 8%, transparent)); border-radius: var(--radius-sm, 6px); background: var(--surface-1, color-mix(in srgb, #ffffff 2%, transparent)); @@ -74,7 +74,7 @@ Raw rgba fallbacks are replaced with byte-equivalent concrete-hex color-mix fall .cc-mc-node-meta { display: flex; align-items: center; - gap: var(--space-2, 8px); + gap: var(--space-sm); flex-shrink: 0; } diff --git a/packages/dashboard/app/components/command-center/SdlcFunnel.css b/packages/dashboard/app/components/command-center/SdlcFunnel.css index d58a5d4cc8..a81b9d4e40 100644 --- a/packages/dashboard/app/components/command-center/SdlcFunnel.css +++ b/packages/dashboard/app/components/command-center/SdlcFunnel.css @@ -4,5 +4,5 @@ * adds spacing between the funnel and the throughput cards. */ .cc-area[data-testid="cc-area-funnel"] .cc-area-section + .cc-area-section { - margin-top: var(--space-4, 1rem); + margin-top: var(--space-lg); } diff --git a/packages/dashboard/app/components/command-center/areas/SystemStatsArea.css b/packages/dashboard/app/components/command-center/areas/SystemStatsArea.css index eb3ff44119..e104978f13 100644 --- a/packages/dashboard/app/components/command-center/areas/SystemStatsArea.css +++ b/packages/dashboard/app/components/command-center/areas/SystemStatsArea.css @@ -7,9 +7,9 @@ The Command Center System area replaces the standalone System Stats modal with g display: flex; align-items: center; justify-content: flex-end; - gap: var(--space-2); + gap: var(--space-sm); color: var(--text-muted); - font-size: var(--font-size-sm); + font-size: 0.875rem; } .cc-system-refresh .btn-icon { @@ -24,17 +24,17 @@ The Command Center System area replaces the standalone System Stats modal with g min-inline-size: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: var(--space-3); + gap: var(--space-md); } .cc-system-chart-grid .cc-stat-card { - gap: var(--space-3); + gap: var(--space-md); } .cc-system-section-title-with-icon { display: inline-flex; align-items: center; - gap: var(--space-2); + gap: var(--space-sm); } .cc-system-section-title-with-icon svg { @@ -49,9 +49,9 @@ System control cards sit beside chart/stat cards, so FN-6680 gives them the same display: flex; flex-wrap: wrap; align-items: center; - gap: var(--space-3); - padding: var(--space-3); - border: var(--border-width) solid var(--border-subtle); + gap: var(--space-md); + padding: var(--space-md); + border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--surface-1); } @@ -59,7 +59,7 @@ System control cards sit beside chart/stat cards, so FN-6680 gives them the same .cc-system-vitest-card .btn { display: inline-flex; align-items: center; - gap: var(--space-2); + gap: var(--space-sm); } .cc-system-toggle-row, @@ -67,13 +67,13 @@ System control cards sit beside chart/stat cards, so FN-6680 gives them the same .cc-system-threshold-controls { display: inline-flex; align-items: center; - gap: var(--space-2); + gap: var(--space-sm); } .cc-system-toggle-row, .cc-system-threshold-row { color: var(--text); - font-size: var(--font-size-sm); + font-size: 0.875rem; } .cc-system-threshold-controls input[type="range"] { @@ -87,7 +87,7 @@ System control cards sit beside chart/stat cards, so FN-6680 gives them the same .cc-system-note { margin: 0; color: var(--text-muted); - font-size: var(--font-size-sm); + font-size: 0.875rem; } .cc-system-note--error, diff --git a/packages/dashboard/app/components/command-center/areas/areas.css b/packages/dashboard/app/components/command-center/areas/areas.css index a5d1227a89..866f6a84ec 100644 --- a/packages/dashboard/app/components/command-center/areas/areas.css +++ b/packages/dashboard/app/components/command-center/areas/areas.css @@ -10,7 +10,7 @@ Area headings, table metadata, and empty states use --text-muted so the analytic .cc-area { display: flex; flex-direction: column; - gap: var(--space-4); + gap: var(--space-lg); min-inline-size: 0; } @@ -21,7 +21,7 @@ FN-6680 preserves the FN-6664 section rhythm while adding real-layout shrink gua .cc-area-section { display: flex; flex-direction: column; - gap: var(--space-3); + gap: var(--space-md); min-inline-size: 0; } @@ -29,12 +29,12 @@ FN-6680 preserves the FN-6664 section rhythm while adding real-layout shrink gua display: flex; align-items: center; justify-content: space-between; - gap: var(--space-2); + gap: var(--space-sm); } .cc-area-section-title { margin: 0; - font-size: var(--font-size-sm); + font-size: 0.875rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; @@ -48,19 +48,19 @@ FN-6683 recharts wrappers must stay responsive without creating an inner scroll .cc-area .cc-recharts-chart, .cc-area .cc-recharts-empty { inline-size: 100%; - block-size: calc(var(--space-20) * 3); + block-size: calc(calc(var(--space-2xl) * 2 + var(--space-lg)) * 3); min-inline-size: 0; } /* Reuse the shell's stat-grid/stat-card look. */ .cc-area .cc-stat-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(var(--space-20) * 2)), 1fr)); - gap: var(--space-3); + grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(calc(var(--space-2xl) * 2 + var(--space-lg)) * 2)), 1fr)); + gap: var(--space-md); } .cc-stat-sub { - font-size: var(--font-size-xs); + font-size: 0.8rem; color: var(--text-muted); } @@ -72,7 +72,7 @@ The Tokens area needs a real hour/day/week control and live token-number motion. display: flex; flex-wrap: wrap; justify-content: flex-end; - gap: var(--space-1); + gap: var(--space-xs); } .cc-token-granularity .btn.active { @@ -87,7 +87,7 @@ The Tokens area needs a real hour/day/week control and live token-number motion. @keyframes cc-token-count-pop { from { - transform: translateY(var(--space-1)); + transform: translateY(var(--space-xs)); opacity: 0.7; } to { @@ -121,7 +121,7 @@ FN-6680 keeps table-heavy chart areas on the same --border-width/--border-subtle */ .cc-table-wrap { max-inline-size: 100%; - border: var(--border-width) solid var(--border-subtle); + border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--surface-1); overflow-x: auto; @@ -131,15 +131,15 @@ FN-6680 keeps table-heavy chart areas on the same --border-width/--border-subtle .cc-table { inline-size: 100%; border-collapse: collapse; - font-size: var(--font-size-sm); + font-size: 0.875rem; font-variant-numeric: tabular-nums; } .cc-table th, .cc-table td { - padding: var(--space-2) var(--space-3); + padding: var(--space-sm) var(--space-md); text-align: right; - border-bottom: var(--border-width) solid var(--border-subtle); + border-bottom: 1px solid var(--border-subtle); white-space: nowrap; } @@ -175,7 +175,7 @@ FN-6680 keeps table-heavy chart areas on the same --border-width/--border-subtle } .cc-sort-caret { - margin-inline-start: var(--space-1); + margin-inline-start: var(--space-xs); font-size: 0.7em; color: var(--accent); } @@ -184,14 +184,14 @@ FN-6680 keeps table-heavy chart areas on the same --border-width/--border-subtle .cc-unavailable { color: var(--text-muted); cursor: help; - border-bottom: var(--border-width) dotted var(--border-subtle); + border-bottom: 1px dotted var(--border-subtle); } .cc-loading-inline { display: flex; align-items: center; - gap: var(--space-2); - padding: var(--space-4); + gap: var(--space-sm); + padding: var(--space-lg); color: var(--text-muted); } @@ -200,8 +200,8 @@ FN-6680 keeps table-heavy chart areas on the same --border-width/--border-subtle display: flex; flex-direction: column; align-items: center; - gap: var(--space-2); - padding: var(--space-6); + gap: var(--space-sm); + padding: var(--space-xl); color: var(--text-muted); text-align: center; } @@ -211,7 +211,7 @@ FN-6680 keeps table-heavy chart areas on the same --border-width/--border-subtle } .cc-pricing-note { - font-size: var(--font-size-xs); + font-size: 0.8rem; color: var(--text-muted); } @@ -222,16 +222,16 @@ The Team view must use dashboard design tokens only, preserve .cc-tabpanel as th .cc-team-chart-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: var(--space-3); + gap: var(--space-md); } .cc-team-chart-panel { display: flex; flex-direction: column; - gap: var(--space-3); + gap: var(--space-md); min-inline-size: 0; - padding: var(--space-3); - border: var(--border-width) solid var(--border-subtle); + padding: var(--space-md); + border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--surface-1); animation: cc-team-panel-reveal var(--duration-fast) ease-out both; @@ -248,13 +248,13 @@ The Team view must use dashboard design tokens only, preserve .cc-tabpanel as th .cc-muted-hint { margin: 0; - font-size: var(--font-size-sm); + font-size: 0.875rem; } .cc-team-agent-cell { display: inline-flex; align-items: center; - gap: var(--space-2); + gap: var(--space-sm); min-inline-size: 0; } @@ -269,14 +269,14 @@ The Team view must use dashboard design tokens only, preserve .cc-tabpanel as th } .cc-team-agent-role { - font-size: var(--font-size-xs); + font-size: 0.8rem; text-transform: capitalize; } @keyframes cc-team-panel-reveal { from { opacity: 0; - transform: translateY(var(--space-1)); + transform: translateY(var(--space-xs)); } to { opacity: 1; @@ -296,7 +296,7 @@ Tablet Command Center areas share the FN-6679 overflow fix with the shell: area */ @media (min-width: 769px) and (max-width: 1024px) { .cc-area .cc-stat-grid { - grid-template-columns: repeat(auto-fit, minmax(min(100%, calc(var(--space-20) * 2)), 1fr)); + grid-template-columns: repeat(auto-fit, minmax(min(100%, calc(calc(var(--space-2xl) * 2 + var(--space-lg)) * 2)), 1fr)); } .cc-team-chart-grid { @@ -320,6 +320,6 @@ Tablet Command Center areas share the FN-6679 overflow fix with the shell: area } .cc-team-chart-panel { - padding: var(--space-2); + padding: var(--space-sm); } } diff --git a/packages/dashboard/app/components/command-center/charts/charts.css b/packages/dashboard/app/components/command-center/charts/charts.css index 900b630581..4bc21b021d 100644 --- a/packages/dashboard/app/components/command-center/charts/charts.css +++ b/packages/dashboard/app/components/command-center/charts/charts.css @@ -40,19 +40,19 @@ FN-6680 re-checked FN-6664 in a real Blink layout engine because jsdom does not padding: 0; display: flex; flex-direction: column; - gap: var(--space-2); + gap: var(--space-sm); } .cc-bar-row { display: grid; - grid-template-columns: minmax(var(--space-20), 32%) minmax(0, 1fr) auto; + grid-template-columns: minmax(calc(var(--space-2xl) * 2 + var(--space-lg)), 32%) minmax(0, 1fr) auto; align-items: center; - gap: var(--space-2); + gap: var(--space-sm); } .cc-bar-label { min-inline-size: 0; - font-size: var(--font-size-sm); + font-size: 0.875rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; @@ -62,7 +62,7 @@ FN-6680 re-checked FN-6664 in a real Blink layout engine because jsdom does not .cc-bar-track { min-inline-size: 0; position: relative; - block-size: var(--space-3); + block-size: var(--space-md); background: var(--surface-2); border-radius: var(--radius-sm); overflow: hidden; @@ -77,7 +77,7 @@ FN-6680 re-checked FN-6664 in a real Blink layout engine because jsdom does not .cc-bar-value { min-inline-size: 0; - font-size: var(--font-size-sm); + font-size: 0.875rem; font-variant-numeric: tabular-nums; color: var(--text); overflow-wrap: anywhere; @@ -88,12 +88,12 @@ FN-6680 re-checked FN-6664 in a real Blink layout engine because jsdom does not .cc-stacked-bar { display: flex; flex-direction: column; - gap: var(--space-2); + gap: var(--space-sm); } .cc-stacked-track { display: flex; - block-size: var(--space-3); + block-size: var(--space-md); background: var(--surface-2); border-radius: var(--radius-sm); overflow: hidden; @@ -111,22 +111,22 @@ FN-6680 re-checked FN-6664 in a real Blink layout engine because jsdom does not padding: 0; display: flex; flex-wrap: wrap; - gap: var(--space-3); + gap: var(--space-md); } .cc-stacked-legend-item { min-inline-size: 0; display: flex; align-items: center; - gap: var(--space-1); - font-size: var(--font-size-sm); + gap: var(--space-xs); + font-size: 0.875rem; color: var(--text-muted); overflow-wrap: anywhere; } .cc-stacked-swatch { - inline-size: var(--space-2); - block-size: var(--space-2); + inline-size: var(--space-sm); + block-size: var(--space-sm); border-radius: var(--radius-sm); background: var(--accent); display: inline-block; @@ -136,15 +136,15 @@ FN-6680 re-checked FN-6664 in a real Blink layout engine because jsdom does not .cc-sparkline { display: flex; align-items: flex-end; - gap: var(--border-width); - block-size: var(--space-8); + gap: 1px; + block-size: var(--space-2xl); } .cc-sparkline-bar { flex: 1 1 0; - min-inline-size: var(--border-width); + min-inline-size: 1px; background: var(--accent); - border-radius: var(--border-width); + border-radius: 1px; transition: height var(--transition-normal); } @@ -156,17 +156,17 @@ The token-over-time chart is live-updated and animated, but the motion is decora .cc-token-series { display: flex; flex-direction: column; - gap: var(--space-2); + gap: var(--space-sm); min-inline-size: 0; } .cc-token-series-plot { display: flex; align-items: flex-end; - gap: var(--space-1); - block-size: clamp(var(--space-16), 24vw, calc(var(--space-20) * 2)); - padding: var(--space-3); - border: var(--border-width) solid var(--border-subtle); + gap: var(--space-xs); + block-size: clamp(calc(var(--space-2xl) * 2), 24vw, calc(calc(var(--space-2xl) * 2 + var(--space-lg)) * 2)); + padding: var(--space-md); + border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 10%, transparent), transparent), var(--surface-1); overflow: hidden; @@ -174,17 +174,17 @@ The token-over-time chart is live-updated and animated, but the motion is decora .cc-token-series-bar { flex: 1 1 0; - min-inline-size: var(--space-1); + min-inline-size: var(--space-xs); border-radius: var(--radius-sm) var(--radius-sm) 0 0; background: linear-gradient(180deg, var(--accent), color-mix(in srgb, var(--accent) 45%, var(--surface-2))); - box-shadow: 0 0 var(--space-2) color-mix(in srgb, var(--accent) 24%, transparent); + box-shadow: 0 0 var(--space-sm) color-mix(in srgb, var(--accent) 24%, transparent); transition: height var(--transition-normal); animation: cc-token-series-rise var(--duration-normal) ease-out both; } .cc-token-series-empty { inline-size: 100%; - block-size: var(--border-width-thick); + block-size: 2px; align-self: flex-end; border-radius: var(--radius-pill); background: var(--border-subtle); @@ -193,9 +193,9 @@ The token-over-time chart is live-updated and animated, but the motion is decora .cc-token-series-axis { display: flex; justify-content: space-between; - gap: var(--space-2); + gap: var(--space-sm); color: var(--text-muted); - font-size: var(--font-size-xs); + font-size: 0.8rem; font-variant-numeric: tabular-nums; } @@ -230,8 +230,8 @@ The token-over-time chart is live-updated and animated, but the motion is decora @media (max-width: 768px) { .cc-token-series-plot { - block-size: clamp(var(--space-14), 38vw, calc(var(--space-20) + var(--space-12))); - padding: var(--space-2); + block-size: clamp(calc(var(--space-2xl) + var(--space-xl)), 38vw, calc(calc(var(--space-2xl) * 2 + var(--space-lg)) + calc(var(--space-2xl) + var(--space-lg)))); + padding: var(--space-sm); } } @@ -243,7 +243,7 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us .cc-line-chart { display: block; inline-size: 100%; - block-size: clamp(var(--space-16), 22vw, calc(var(--space-20) * 2)); + block-size: clamp(calc(var(--space-2xl) * 2), 22vw, calc(calc(var(--space-2xl) * 2 + var(--space-lg)) * 2)); aspect-ratio: 5 / 2; color: var(--accent); overflow: hidden; @@ -264,7 +264,7 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us .cc-line-chart-path { fill: none; stroke: currentColor; - stroke-width: var(--border-width-thick, var(--border-width)); + stroke-width: 2px; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 100; @@ -275,7 +275,7 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us .cc-line-chart-point { fill: var(--surface-1); stroke: currentColor; - stroke-width: var(--border-width-thick, var(--border-width)); + stroke-width: 2px; } @keyframes cc-line-chart-draw { @@ -293,7 +293,7 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us @media (max-width: 768px) { .cc-line-chart { - block-size: clamp(var(--space-16), 44vw, calc(var(--space-20) + var(--space-12))); + block-size: clamp(calc(var(--space-2xl) * 2), 44vw, calc(calc(var(--space-2xl) * 2 + var(--space-lg)) + calc(var(--space-2xl) + var(--space-lg)))); aspect-ratio: auto; } } @@ -303,7 +303,7 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us min-inline-size: 0; display: grid; place-items: center; - gap: var(--space-2); + gap: var(--space-sm); color: var(--text); } @@ -311,13 +311,13 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us position: relative; display: grid; place-items: center; - inline-size: clamp(var(--space-24), 32vw, var(--space-36)); + inline-size: clamp(calc(var(--space-2xl) * 3), 32vw, calc(var(--space-2xl) * 4 + var(--space-lg))); aspect-ratio: 1; border-radius: 50%; background: radial-gradient(circle at center, var(--surface-1) 0 54%, transparent 55%), conic-gradient(var(--accent) var(--cc-radial-value), var(--surface-2) 0); - box-shadow: 0 0 var(--space-4) color-mix(in srgb, var(--accent) 35%, transparent); + box-shadow: 0 0 var(--space-lg) color-mix(in srgb, var(--accent) 35%, transparent); isolation: isolate; animation: cc-radial-gauge-pulse calc(var(--duration-slow) * 6) ease-in-out infinite; } @@ -325,10 +325,10 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us .cc-radial-gauge-ring::before { content: ""; position: absolute; - inset: var(--space-2); + inset: var(--space-sm); border-radius: inherit; - border: var(--border-width) solid color-mix(in srgb, var(--accent) 45%, transparent); - box-shadow: inset 0 0 var(--space-3) color-mix(in srgb, var(--accent) 22%, transparent); + border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); + box-shadow: inset 0 0 var(--space-md) color-mix(in srgb, var(--accent) 22%, transparent); animation: cc-radial-gauge-sweep calc(var(--duration-slow) * 8) linear infinite; } @@ -341,11 +341,11 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us aspect-ratio: 1; background: var(--surface-1); border-radius: 50%; - box-shadow: inset 0 0 var(--space-3) var(--surface-2); + box-shadow: inset 0 0 var(--space-md) var(--surface-2); } .cc-radial-gauge-value { - font-size: var(--font-size-xl); + font-size: 1.25rem; font-weight: 700; font-variant-numeric: tabular-nums; } @@ -353,7 +353,7 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us .cc-radial-gauge-label { max-inline-size: 100%; color: var(--text-muted); - font-size: var(--font-size-sm); + font-size: 0.875rem; overflow-wrap: anywhere; text-align: center; } @@ -391,21 +391,21 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us padding: 0; display: flex; flex-direction: column; - gap: var(--space-2); + gap: var(--space-sm); } .cc-funnel-stage { display: flex; flex-direction: column; - gap: var(--space-1); + gap: var(--space-xs); } .cc-funnel-header { min-inline-size: 0; display: flex; justify-content: space-between; - gap: var(--space-2); - font-size: var(--font-size-sm); + gap: var(--space-sm); + font-size: 0.875rem; color: var(--text-muted); } @@ -426,7 +426,7 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us } .cc-funnel-track { - block-size: var(--space-4); + block-size: var(--space-lg); background: var(--surface-2); border-radius: var(--radius-sm); overflow: hidden; @@ -440,14 +440,14 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us } .cc-funnel-value { - font-size: var(--font-size-sm); + font-size: 0.875rem; font-variant-numeric: tabular-nums; color: var(--text); } /* ---- Loading shimmer (used by chart skeletons) ---- */ .cc-chart-skeleton { - block-size: var(--space-3); + block-size: var(--space-md); border-radius: var(--radius-sm); background: var(--surface-2); animation: cc-chart-pulse var(--duration-slow) ease-in-out infinite; @@ -466,7 +466,7 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us @media (max-width: 768px) { .cc-bar-row { - grid-template-columns: minmax(0, 1fr) minmax(var(--space-12), 2fr); + grid-template-columns: minmax(0, 1fr) minmax(calc(var(--space-2xl) + var(--space-lg)), 2fr); align-items: start; } @@ -477,10 +477,10 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us } .cc-radial-gauge-ring { - inline-size: clamp(var(--space-20), 44vw, var(--space-32)); + inline-size: clamp(calc(var(--space-2xl) * 2 + var(--space-lg)), 44vw, calc(var(--space-2xl) * 4)); } .cc-sparkline { - block-size: clamp(var(--space-8), 18vw, var(--space-14)); + block-size: clamp(var(--space-2xl), 18vw, calc(var(--space-2xl) + var(--space-xl))); } } diff --git a/packages/dashboard/vitest.config.ts b/packages/dashboard/vitest.config.ts index f6654551bf..4a28861228 100644 --- a/packages/dashboard/vitest.config.ts +++ b/packages/dashboard/vitest.config.ts @@ -52,6 +52,7 @@ const qualityAppFoundationUiTests = [ "app/__tests__/column-fixed-width.test.ts", "app/__tests__/component-css-no-raw-rgba.test.ts", "app/__tests__/dashboard-component-color-tokenization.test.ts", + "app/__tests__/dashboard-css-token-validity.css.test.ts", "app/__tests__/dashboard-footer-mobile-layout.test.ts", "app/__tests__/detail-body-mobile-overflow.test.ts", "app/__tests__/dev-server-layout-css.test.ts",