From f9f255e08ab57fab1d2d6b33dd0223f7a111978b Mon Sep 17 00:00:00 2001 From: limit_yan Date: Sat, 13 Jun 2026 18:43:43 +0800 Subject: [PATCH 1/2] fix(flow-chat): resolve diff card text truncation on long lines InlineDiffPreview used fixed-height virtualization rows (22px) while CSS allowed text wrapping (pre-wrap). Wrapped content beyond 22px was hidden by overflow:hidden, making long diff lines unreadable. Changes: - Switch virtualizer to dynamic measurement (measureElement) so wrapped rows report their real height instead of a fixed 22px estimate - Add ResizeObserver to invalidate cached measurements when the container width changes (wrapping depends on width) - Add content truncation for very large diffs (500 lines / 50k chars) with head+tail preview and a visible truncation notice - Remove overflow:hidden on diff-line__content; use overflow-wrap:anywhere - Apply measureElement ref to context-separator rows for measurement consistency --- .../components/InlineDiffPreview.scss | 12 +- .../components/InlineDiffPreview.tsx | 109 ++++++++++++++++-- 2 files changed, 109 insertions(+), 12 deletions(-) diff --git a/src/web-ui/src/flow_chat/components/InlineDiffPreview.scss b/src/web-ui/src/flow_chat/components/InlineDiffPreview.scss index 055acdeb7..c379f1def 100644 --- a/src/web-ui/src/flow_chat/components/InlineDiffPreview.scss +++ b/src/web-ui/src/flow_chat/components/InlineDiffPreview.scss @@ -51,6 +51,15 @@ color: var(--color-text-muted, #888); font-style: italic; } + + &__truncation-notice { + padding: 0.25rem 0.625rem; + font-size: var(--flowchat-font-size-xs); + color: var(--color-text-muted, #888); + background: var(--color-bg-tertiary, rgba(255, 255, 255, 0.03)); + border-bottom: 1px solid var(--color-border-subtle, rgba(255, 255, 255, 0.06)); + font-style: italic; + } } .diff-line { @@ -187,8 +196,7 @@ flex: 1; padding: 0 8px; white-space: pre-wrap; - word-break: break-word; - overflow: hidden; + overflow-wrap: anywhere; // Strip global and SyntaxHighlighter borders/backgrounds. pre, code, span { diff --git a/src/web-ui/src/flow_chat/components/InlineDiffPreview.tsx b/src/web-ui/src/flow_chat/components/InlineDiffPreview.tsx index c69ed0dd2..d4a8f074f 100644 --- a/src/web-ui/src/flow_chat/components/InlineDiffPreview.tsx +++ b/src/web-ui/src/flow_chat/components/InlineDiffPreview.tsx @@ -11,7 +11,7 @@ * 5. Row virtualization via @tanstack/react-virtual: only visible rows are in the DOM */ -import React, { useMemo, memo, useRef, useCallback, useState, CSSProperties } from 'react'; +import React, { useMemo, memo, useRef, useCallback, useState, useEffect, CSSProperties } from 'react'; import Prism from 'prismjs'; import { useVirtualizer } from '@tanstack/react-virtual'; import { diffLines, Change } from 'diff'; @@ -26,6 +26,61 @@ const log = createLogger('InlineDiffPreview'); /** Estimated row height in px — must match CSS line-height × font-size. */ const ROW_HEIGHT = 22; +/** + * Maximum total lines (original + modified) before content is truncated. + * Keeps diffLines() + Prism.tokenize() cost bounded for large files. + * The caller may also pre-truncate; this is a safety net inside the component. + */ +const MAX_TOTAL_LINES = 500; +/** Character budget that complements MAX_TOTAL_LINES for very long single lines. */ +const MAX_TOTAL_CHARS = 50_000; + +/** Result of truncation: possibly shortened content + metadata. */ +interface TruncationResult { + originalContent: string; + modifiedContent: string; + truncated: boolean; + omittedLines: number; +} + +/** + * Truncate original/modified content when combined line or char count exceeds + * thresholds. Returns head + tail so both ends of the diff remain visible. + */ +function truncateForDiff(original: string, modified: string): TruncationResult { + const origLines = original ? original.split('\n') : []; + const modLines = modified ? modified.split('\n') : []; + const totalLines = origLines.length + modLines.length; + const totalChars = original.length + modified.length; + + if (totalLines <= MAX_TOTAL_LINES && totalChars <= MAX_TOTAL_CHARS) { + return { originalContent: original, modifiedContent: modified, truncated: false, omittedLines: 0 }; + } + + // Budget per side, per half (head/tail). + const perSide = Math.max(50, Math.floor(MAX_TOTAL_LINES / 4)); + + const slice = (lines: string[]): { text: string; kept: number; dropped: number } => { + if (lines.length <= perSide * 2) return { text: lines.join('\n'), kept: lines.length, dropped: 0 }; + const head = lines.slice(0, perSide); + const tail = lines.slice(lines.length - perSide); + return { + text: [...head, '', `... truncated ${lines.length - perSide * 2} lines ...`, '', ...tail].join('\n'), + kept: perSide * 2, + dropped: lines.length - perSide * 2, + }; + }; + + const o = slice(origLines); + const m = slice(modLines); + return { + originalContent: o.text, + modifiedContent: m.text, + truncated: true, + omittedLines: o.dropped + m.dropped, + }; +} + export interface InlineDiffPreviewProps { /** Original content. */ originalContent: string; @@ -302,25 +357,31 @@ export const InlineDiffPreview: React.FC = memo(({ return 'text'; }, [language, filePath]); + // Truncate very large inputs before diff/tokenization to protect the main thread. + const truncated = useMemo( + () => truncateForDiff(originalContent, modifiedContent), + [originalContent, modifiedContent], + ); + // Compute diff line list (fast, O(ND)) const diffLineList = useMemo(() => { try { - const rawDiff = computeLineDiff(originalContent, modifiedContent); + const rawDiff = computeLineDiff(truncated.originalContent, truncated.modifiedContent); return applyContextCollapsing(rawDiff, contextLines); } catch (error) { log.error('Diff computation failed', error); return [{ type: 'context-separator' as const, content: 'Diff computation failed; file may be too large.' }]; } - }, [originalContent, modifiedContent, contextLines]); + }, [truncated.originalContent, truncated.modifiedContent, contextLines]); // Tokenize each content once — O(content_length), not O(lines²) const originalLineTokens = useMemo( - () => tokenizeContent(originalContent, detectedLanguage), - [originalContent, detectedLanguage], + () => tokenizeContent(truncated.originalContent, detectedLanguage), + [truncated.originalContent, detectedLanguage], ); const modifiedLineTokens = useMemo( - () => tokenizeContent(modifiedContent, detectedLanguage), - [modifiedContent, detectedLanguage], + () => tokenizeContent(truncated.modifiedContent, detectedLanguage), + [truncated.modifiedContent, detectedLanguage], ); // Build stylesheet from prism style for token coloring @@ -355,14 +416,35 @@ export const InlineDiffPreview: React.FC = memo(({ [originalLineTokens, modifiedLineTokens], ); - // Virtualizer + // Virtualizer with dynamic measurement so wrapped long lines get correct height. const virtualizer = useVirtualizer({ count: diffLineList.length, getScrollElement: () => containerRef.current, estimateSize: () => ROW_HEIGHT, overscan: 3, + measureElement: (el) => el.getBoundingClientRect().height, }); + // Re-measure all rows when the container width changes (wrapping may differ). + const [containerWidth, setContainerWidth] = useState(0); + useEffect(() => { + const el = containerRef.current; + if (!el) return; + const ro = new ResizeObserver((entries) => { + const entry = entries[0]; + if (entry) { + const w = Math.round(entry.contentRect.width); + setContainerWidth((prev) => (prev === w ? prev : w)); + } + }); + ro.observe(el); + return () => ro.disconnect(); + }, []); + // When width changes, invalidate cached measurements so rows re-measure. + useEffect(() => { + virtualizer.measure(); + }, [containerWidth]); // eslint-disable-line react-hooks/exhaustive-deps + const handleLineClick = useCallback( (index: number, line: DiffLine) => { if (line.type === 'context-separator') return; @@ -389,6 +471,11 @@ export const InlineDiffPreview: React.FC = memo(({ return (
+ {truncated.truncated && ( +
+ Content too large; showing first and last portions ({truncated.omittedLines} lines omitted). +
+ )}
= memo(({ return (
@@ -436,14 +524,15 @@ export const InlineDiffPreview: React.FC = memo(({ return (
handleLineClick(virtualRow.index, line)} > From 675e8c9aa789e81e333c5c1ea5d40e94a2184eb1 Mon Sep 17 00:00:00 2001 From: limit_yan Date: Sat, 13 Jun 2026 20:54:02 +0800 Subject: [PATCH 2/2] refactor(theme): align tokens, token-ize hardcoded colors, clean up legacy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase P1-P7 theme token system cleanup across Web UI, Mobile Web, and Installer: P1: Fix Mobile Web sessions.scss referencing non-existent --color-error-* tokens P2: Unify CodeReviewToolCard fallback values and fix --color-danger → --color-error P3: Token-ize TurnHistoryPanel (~35 hardcoded Tailwind grays), remove @media dark block P4: Complete Installer variables.css with 13 missing tokens, align fallbacks to bitfun-dark P5: Align tokens.scss SCSS fallbacks with dark-theme.ts runtime values (34 properties) P6: Token-ize ~130+ hardcoded colors across 20 component files (semantic colors → tokens) P7: Remove unused legacy -gray-* series and orphaned -text-default Additional fixes found during review: - Fix --color-text-disabled misused as background (→ opacity-disabled) - Fix --color-scrollbar-thumb wrong variable name (→ --scrollbar-thumb) - Fix --shadow-sm fallback mismatch - Fix --color-danger-600/--color-error-600/--color-error-alpha/--color-error-rgb references - Fix InlineDiffPreview light theme gutter using dark-only hover variants Verified: type-check 0 errors, lint 0 errors, 12 theme/layout tests passed --- BitFun-Installer/src/styles/variables.css | 59 ++++++--- .../src/styles/components/sessions.scss | 10 +- .../components/AboutDialog/AboutDialog.scss | 22 ++-- .../src/app/components/NavPanel/NavPanel.scss | 10 +- .../components/panels/BranchSelectModal.scss | 8 +- .../panels/DiffFullscreenViewer.css | 30 ++--- .../src/app/components/panels/FilesPanel.scss | 2 +- .../mission-control/ThumbnailCard.scss | 2 +- .../tab-bar/TabOverflowMenu.scss | 2 +- .../review-platform/ReviewPlatformPanel.scss | 114 ++++++++--------- .../miniapps/components/MiniAppCard.scss | 10 +- .../app/scenes/profile/views/NurseryView.scss | 26 ++-- .../src/component-library/styles/tokens.scss | 112 +++++++--------- .../src/flow_chat/components/ChatInput.scss | 2 +- .../components/InlineDiffPreview.scss | 74 +++++------ .../components/TurnHistoryPanel.scss | 120 +++--------------- .../components/TurnRollbackButton.scss | 41 ++---- .../tool-cards/CodeReviewToolCard.scss | 22 ++-- .../tools/editor/components/DiffEditor.scss | 8 +- .../editor/components/EditorStatusBar.scss | 12 +- .../tools/editor/components/PlanViewer.scss | 14 +- .../CreateBranchDialog.scss | 4 +- .../GitBranchHistoryView.scss | 4 +- .../components/GitGraphView/GitGraphView.scss | 54 ++++---- 24 files changed, 330 insertions(+), 432 deletions(-) diff --git a/BitFun-Installer/src/styles/variables.css b/BitFun-Installer/src/styles/variables.css index 67d3d42c7..ff5e39d44 100644 --- a/BitFun-Installer/src/styles/variables.css +++ b/BitFun-Installer/src/styles/variables.css @@ -1,12 +1,17 @@ :root { --color-bg-primary: #121214; --color-bg-secondary: #18181a; + --color-bg-tertiary: #121214; --color-bg-quaternary: #202024; + --color-bg-elevated: #18181a; + --color-bg-workbench: #121214; + --color-bg-flowchat: #121214; + --color-bg-tooltip: rgba(30, 30, 32, 0.92); --color-text-primary: #e8e8e8; - --color-text-secondary: #e5e5e5; - --color-text-muted: #a0a0a0; - --color-text-disabled: #666666; + --color-text-secondary: #b0b0b0; + --color-text-muted: #858585; + --color-text-disabled: #555555; --color-accent-50: rgba(96, 165, 250, 0.04); --color-accent-100: rgba(96, 165, 250, 0.08); @@ -15,24 +20,38 @@ --color-accent-400: rgba(96, 165, 250, 0.4); --color-accent-500: #60a5fa; --color-accent-600: #3b82f6; + --color-accent-700: rgba(59, 130, 246, 0.8); + --color-accent-800: rgba(59, 130, 246, 0.9); - --color-success: #6eb88c; - --color-success-bg: rgba(110, 184, 140, 0.1); - --color-success-border: rgba(110, 184, 140, 0.3); - --color-error: #c77070; - --color-error-bg: rgba(199, 112, 112, 0.1); - --color-error-border: rgba(199, 112, 112, 0.3); - - --element-bg-subtle: rgba(255, 255, 255, 0.05); - --element-bg-soft: rgba(255, 255, 255, 0.08); - --element-bg-base: rgba(255, 255, 255, 0.11); - --element-bg-medium: rgba(255, 255, 255, 0.14); - --element-bg-strong: rgba(255, 255, 255, 0.17); - - --border-subtle: rgba(255, 255, 255, 0.10); - --border-base: rgba(255, 255, 255, 0.14); - --border-medium: rgba(255, 255, 255, 0.20); - --border-strong: rgba(255, 255, 255, 0.26); + --color-purple-50: rgba(139, 92, 246, 0.04); + --color-purple-100: rgba(139, 92, 246, 0.08); + --color-purple-200: rgba(139, 92, 246, 0.15); + --color-purple-300: rgba(139, 92, 246, 0.25); + --color-purple-400: rgba(139, 92, 246, 0.4); + --color-purple-500: #8b5cf6; + --color-purple-600: #7c3aed; + --color-purple-700: rgba(124, 58, 237, 0.8); + --color-purple-800: rgba(124, 58, 237, 0.9); + + --color-success: #34d399; + --color-warning: #f59e0b; + --color-error: #ef4444; + --color-info: #E1AB80; + --color-highlight: #d4a574; + --color-highlight-bg: rgba(212, 165, 116, 0.15); + + --element-bg-subtle: rgba(255, 255, 255, 0.06); + --element-bg-soft: rgba(255, 255, 255, 0.10); + --element-bg-base: rgba(255, 255, 255, 0.13); + --element-bg-medium: rgba(255, 255, 255, 0.17); + --element-bg-strong: rgba(255, 255, 255, 0.21); + --element-bg-elevated: rgba(255, 255, 255, 0.25); + + --border-subtle: rgba(255, 255, 255, 0.12); + --border-base: rgba(255, 255, 255, 0.18); + --border-medium: rgba(255, 255, 255, 0.24); + --border-strong: rgba(255, 255, 255, 0.32); + --border-prominent: rgba(225, 171, 128, 0.50); --radius-sm: 6px; --radius-base: 8px; diff --git a/src/mobile-web/src/styles/components/sessions.scss b/src/mobile-web/src/styles/components/sessions.scss index dffd45eb7..8ebdc2e18 100644 --- a/src/mobile-web/src/styles/components/sessions.scss +++ b/src/mobile-web/src/styles/components/sessions.scss @@ -1050,11 +1050,11 @@ } &--danger { - color: var(--color-error-500, #dc3545); - background: var(--color-error-50, #fef2f2); + color: var(--color-error); + background: var(--color-error-bg); &:active { - background: var(--color-error-100, #fee2e2); + background: color-mix(in srgb, var(--color-error) 12%, transparent); } } } @@ -1171,7 +1171,7 @@ } .session-list__confirm-icon { - color: var(--color-error-500, #dc3545); + color: var(--color-error); margin-bottom: var(--size-gap-1); } @@ -1221,7 +1221,7 @@ } &--danger { - background: var(--color-error-500, #dc3545); + background: var(--color-error); color: #fff; &:active:not(:disabled) { diff --git a/src/web-ui/src/app/components/AboutDialog/AboutDialog.scss b/src/web-ui/src/app/components/AboutDialog/AboutDialog.scss index 2b0aef8e5..ebb381764 100644 --- a/src/web-ui/src/app/components/AboutDialog/AboutDialog.scss +++ b/src/web-ui/src/app/components/AboutDialog/AboutDialog.scss @@ -555,23 +555,23 @@ // Frontend tag - blue &--frontend { - background: rgba(59, 130, 246, 0.12); - color: #60A5FA; - border: 1px solid rgba(59, 130, 246, 0.2); + background: var(--color-accent-100); + color: var(--color-accent-500, #60a5fa); + border: 1px solid var(--color-accent-200, rgba(59, 130, 246, 0.2)); } - + // Backend tag - green &--backend { - background: rgba(34, 197, 94, 0.12); - color: #4ADE80; - border: 1px solid rgba(34, 197, 94, 0.2); + background: var(--color-success-bg, rgba(52, 211, 153, 0.12)); + color: var(--color-success, #34d399); + border: 1px solid var(--color-success-border, rgba(52, 211, 153, 0.2)); } - + // General tag - purple &--general { - background: rgba(168, 85, 247, 0.12); - color: #C084FC; - border: 1px solid rgba(168, 85, 247, 0.2); + background: var(--color-purple-100); + color: var(--color-purple-500, #8b5cf6); + border: 1px solid var(--color-purple-200, rgba(139, 92, 246, 0.2)); } } diff --git a/src/web-ui/src/app/components/NavPanel/NavPanel.scss b/src/web-ui/src/app/components/NavPanel/NavPanel.scss index f8ffda3da..925cce6a9 100644 --- a/src/web-ui/src/app/components/NavPanel/NavPanel.scss +++ b/src/web-ui/src/app/components/NavPanel/NavPanel.scss @@ -738,10 +738,10 @@ $_section-header-height: 24px; width: 7px; height: 7px; border-radius: 999px; - background: #60a5fa; + background: var(--color-accent-500, #60a5fa); box-shadow: 0 0 0 2px var(--color-bg-primary), - 0 0 8px rgba(96, 165, 250, 0.75); + 0 0 8px color-mix(in srgb, var(--color-accent-500, #60a5fa) 75%, transparent); pointer-events: none; } } @@ -847,8 +847,8 @@ $_section-header-height: 24px; width: 6px; height: 6px; border-radius: 999px; - background: #60a5fa; - box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.28), 0 0 7px rgba(96, 165, 250, 0.72); + background: var(--color-accent-500, #60a5fa); + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.28), 0 0 7px color-mix(in srgb, var(--color-accent-500, #60a5fa) 72%, transparent); } &--more { @@ -1489,7 +1489,7 @@ $_section-header-height: 24px; // Footer notification: yellow only when there are unread messages (BellDot) .bitfun-nav-panel__footer .bitfun-notification-btn .bitfun-notification-btn__icon--has-message { - color: #ca8a04; + color: var(--color-warning, #ca8a04); } .bitfun-nav-panel__footer .bitfun-notification-btn.bitfun-notification-btn--nav-hover-icon:not(.bitfun-notification-btn--has-progress) { diff --git a/src/web-ui/src/app/components/panels/BranchSelectModal.scss b/src/web-ui/src/app/components/panels/BranchSelectModal.scss index d4edfe430..6ffb46a73 100644 --- a/src/web-ui/src/app/components/panels/BranchSelectModal.scss +++ b/src/web-ui/src/app/components/panels/BranchSelectModal.scss @@ -125,10 +125,10 @@ .branch-select-dialog__error { padding: 8px 12px; - background: rgba(244, 67, 54, 0.08); - border: 1px solid rgba(244, 67, 54, 0.2); + background: var(--color-error-bg, rgba(239, 68, 68, 0.08)); + border: 1px solid var(--color-error-border, rgba(239, 68, 68, 0.2)); border-radius: 6px; - color: #f44336; + color: var(--color-error, #ef4444); font-size: 12px; } @@ -261,7 +261,7 @@ &--worktree { color: var(--color-warning); - background: rgba(255, 152, 0, 0.1); + background: var(--color-warning-bg, rgba(245, 158, 11, 0.1)); } } diff --git a/src/web-ui/src/app/components/panels/DiffFullscreenViewer.css b/src/web-ui/src/app/components/panels/DiffFullscreenViewer.css index 593ee0caf..6d5f83656 100644 --- a/src/web-ui/src/app/components/panels/DiffFullscreenViewer.css +++ b/src/web-ui/src/app/components/panels/DiffFullscreenViewer.css @@ -133,33 +133,33 @@ } .header-btn.accept-btn { - background: rgba(110, 184, 140, 0.15); - color: #6eb88c; - border-color: rgba(110, 184, 140, 0.3); + background: var(--color-success-bg, rgba(52, 211, 153, 0.15)); + color: var(--color-success, #34d399); + border-color: var(--color-success-border, rgba(52, 211, 153, 0.3)); } .header-btn.accept-btn:hover:not(:disabled) { - background: rgba(110, 184, 140, 0.25); - border-color: rgba(110, 184, 140, 0.5); - box-shadow: 0 4px 12px rgba(110, 184, 140, 0.2); + background: color-mix(in srgb, var(--color-success, #34d399) 25%, transparent); + border-color: color-mix(in srgb, var(--color-success, #34d399) 50%, transparent); + box-shadow: 0 4px 12px color-mix(in srgb, var(--color-success, #34d399) 20%, transparent); } .header-btn.reject-btn { - background: rgba(199, 112, 112, 0.15); - color: #c77070; - border-color: rgba(199, 112, 112, 0.3); + background: var(--color-error-bg, rgba(239, 68, 68, 0.15)); + color: var(--color-error, #ef4444); + border-color: var(--color-error-border, rgba(239, 68, 68, 0.3)); } .header-btn.reject-btn:hover:not(:disabled) { - background: rgba(199, 112, 112, 0.25); - border-color: rgba(199, 112, 112, 0.5); - box-shadow: 0 4px 12px rgba(199, 112, 112, 0.2); + background: color-mix(in srgb, var(--color-error, #ef4444) 25%, transparent); + border-color: color-mix(in srgb, var(--color-error, #ef4444) 50%, transparent); + box-shadow: 0 4px 12px color-mix(in srgb, var(--color-error, #ef4444) 20%, transparent); } .header-btn.close-btn:hover:not(:disabled) { - background: rgba(199, 112, 112, 0.2); - color: #c77070; - border-color: rgba(199, 112, 112, 0.3); + background: color-mix(in srgb, var(--color-error, #ef4444) 20%, transparent); + color: var(--color-error, #ef4444); + border-color: var(--color-error-border, rgba(239, 68, 68, 0.3)); } .header-divider { diff --git a/src/web-ui/src/app/components/panels/FilesPanel.scss b/src/web-ui/src/app/components/panels/FilesPanel.scss index 755bbb786..99ca73b5c 100644 --- a/src/web-ui/src/app/components/panels/FilesPanel.scss +++ b/src/web-ui/src/app/components/panels/FilesPanel.scss @@ -137,7 +137,7 @@ } &__search-index-error-text { - color: var(--color-error-600); + color: var(--color-error, #ef4444); } &__search-index-actions { diff --git a/src/web-ui/src/app/components/panels/content-canvas/mission-control/ThumbnailCard.scss b/src/web-ui/src/app/components/panels/content-canvas/mission-control/ThumbnailCard.scss index 01d55f170..b7ef29cf5 100644 --- a/src/web-ui/src/app/components/panels/content-canvas/mission-control/ThumbnailCard.scss +++ b/src/web-ui/src/app/components/panels/content-canvas/mission-control/ThumbnailCard.scss @@ -139,7 +139,7 @@ } &__close-btn:hover { - background: var(--color-error-alpha, rgba(239, 68, 68, 0.15)); + background: var(--color-error-bg, rgba(239, 68, 68, 0.15)); color: var(--color-error, #ef4444); } diff --git a/src/web-ui/src/app/components/panels/content-canvas/tab-bar/TabOverflowMenu.scss b/src/web-ui/src/app/components/panels/content-canvas/tab-bar/TabOverflowMenu.scss index 5e95cd242..c2cd6a366 100644 --- a/src/web-ui/src/app/components/panels/content-canvas/tab-bar/TabOverflowMenu.scss +++ b/src/web-ui/src/app/components/panels/content-canvas/tab-bar/TabOverflowMenu.scss @@ -228,7 +228,7 @@ transition: all 0.1s ease; &:hover { - background: var(--color-error-alpha); + background: var(--color-error-bg, rgba(239, 68, 68, 0.1)); color: var(--color-error); } } diff --git a/src/web-ui/src/app/components/panels/review-platform/ReviewPlatformPanel.scss b/src/web-ui/src/app/components/panels/review-platform/ReviewPlatformPanel.scss index 859e26e7b..7d8382659 100644 --- a/src/web-ui/src/app/components/panels/review-platform/ReviewPlatformPanel.scss +++ b/src/web-ui/src/app/components/panels/review-platform/ReviewPlatformPanel.scss @@ -128,20 +128,20 @@ } &__account--connected { - color: color-mix(in srgb, #3fb950 92%, var(--color-text-secondary)); + color: color-mix(in srgb, var(--color-success, #3fb950) 92%, var(--color-text-secondary)); } &__account--not_required { - color: color-mix(in srgb, #58a6ff 90%, var(--color-text-secondary)); + color: color-mix(in srgb, var(--color-accent-500, #58a6ff) 90%, var(--color-text-secondary)); } &__account--expired, &__account--error { - color: #f85149; + color: var(--color-error, #f85149); } &__account--unsupported { - color: #d29922; + color: var(--color-warning, #d29922); } &__icon-button.icon-btn { @@ -204,9 +204,9 @@ gap: 12px; margin: 10px 12px; padding: 12px; - border: 1px solid color-mix(in srgb, #d29922 42%, var(--border-base)); + border: 1px solid color-mix(in srgb, var(--color-warning, #d29922) 42%, var(--border-base)); border-radius: 10px; - background: color-mix(in srgb, #d29922 10%, var(--color-bg-elevated)); + background: color-mix(in srgb, var(--color-warning, #d29922) 10%, var(--color-bg-elevated)); } &__auth-gate--detail { @@ -221,10 +221,10 @@ width: 34px; height: 34px; flex: 0 0 auto; - border: 1px solid color-mix(in srgb, #d29922 42%, var(--border-base)); + border: 1px solid color-mix(in srgb, var(--color-warning, #d29922) 42%, var(--border-base)); border-radius: 8px; - color: #d29922; - background: color-mix(in srgb, #d29922 14%, transparent); + color: var(--color-warning, #d29922); + background: color-mix(in srgb, var(--color-warning, #d29922) 14%, transparent); } &__auth-gate-copy { @@ -403,7 +403,7 @@ display: grid; justify-items: center; gap: 10px; - color: #f85149; + color: var(--color-error, #f85149); } &__pr-row { @@ -484,31 +484,31 @@ } &__decision--approved { - color: #3fb950; - background: rgba(63, 185, 80, 0.12); + color: var(--color-success, #3fb950); + background: var(--color-success-bg, rgba(52, 211, 153, 0.1)); } &__decision--changes_requested { - color: #f85149; - background: rgba(248, 81, 73, 0.12); + color: var(--color-error, #f85149); + background: var(--color-error-bg, rgba(239, 68, 68, 0.1)); } &__decision--commented, &__decision--pending { - color: #d29922; - background: rgba(210, 153, 34, 0.13); + color: var(--color-warning, #d29922); + background: var(--color-warning-bg, rgba(245, 158, 11, 0.1)); } &__state-icon--open { - color: #3fb950; + color: var(--color-success, #3fb950); } &__state-icon--merged { - color: #a371f7; + color: var(--color-purple-500, #a371f7); } &__state-icon--closed { - color: #f85149; + color: var(--color-error, #f85149); } &__detail { @@ -878,11 +878,11 @@ } &__review-session--completed &__review-session-icon { - color: #3fb950; + color: var(--color-success, #3fb950); } &__review-session--error &__review-session-icon { - color: #f85149; + color: var(--color-error, #f85149); } &__review-session-icon { @@ -981,11 +981,11 @@ } &__additions { - color: #3fb950 !important; + color: var(--color-success, #3fb950) !important; } &__deletions { - color: #f85149 !important; + color: var(--color-error, #f85149) !important; } &__file-list, @@ -1053,19 +1053,19 @@ } &__file-status--added { - color: #3fb950; - background: rgba(63, 185, 80, 0.12); + color: var(--color-success, #3fb950); + background: var(--color-success-bg, rgba(52, 211, 153, 0.1)); } &__file-status--modified, &__file-status--renamed { - color: #58a6ff; - background: rgba(88, 166, 255, 0.12); + color: var(--color-accent-500, #58a6ff); + background: var(--color-accent-100, rgba(96, 165, 250, 0.12)); } &__file-status--deleted { - color: #f85149; - background: rgba(248, 81, 73, 0.12); + color: var(--color-error, #f85149); + background: var(--color-error-bg, rgba(239, 68, 68, 0.1)); } &__file-delta { @@ -1100,22 +1100,22 @@ } &__diff-line--hunk { - color: #a371f7; - background: rgba(163, 113, 247, 0.1); + color: var(--color-purple-500, #a371f7); + background: var(--color-purple-100, rgba(139, 92, 246, 0.1)); } &__diff-line--add { - color: #7ee787; - background: rgba(63, 185, 80, 0.1); + color: var(--color-success, #3fb950); + background: var(--color-success-bg, rgba(52, 211, 153, 0.1)); } &__diff-line--delete { - color: #ffa198; - background: rgba(248, 81, 73, 0.1); + color: var(--color-error, #f85149); + background: var(--color-error-bg, rgba(239, 68, 68, 0.1)); } &__diff-line--meta { - color: #79c0ff; + color: var(--color-accent-500, #79c0ff); } &__diff-empty { @@ -1130,10 +1130,10 @@ gap: 8px; min-height: 36px; padding: 8px 10px; - border: 1px solid color-mix(in srgb, #f85149 34%, var(--border-base)); + border: 1px solid color-mix(in srgb, var(--color-error, #f85149) 34%, var(--border-base)); border-radius: 7px; - background: rgba(248, 81, 73, 0.08); - color: #f85149; + background: var(--color-error-bg, rgba(239, 68, 68, 0.08)); + color: var(--color-error, #f85149); font-size: 11px; span { @@ -1179,18 +1179,18 @@ } &__ci-item--passed { - border-color: color-mix(in srgb, #3fb950 28%, var(--border-base)); - background: color-mix(in srgb, #3fb950 8%, var(--color-bg-elevated)); + border-color: color-mix(in srgb, var(--color-success, #3fb950) 28%, var(--border-base)); + background: color-mix(in srgb, var(--color-success, #3fb950) 8%, var(--color-bg-elevated)); } &__ci-item--failed { - border-color: color-mix(in srgb, #f85149 30%, var(--border-base)); - background: color-mix(in srgb, #f85149 8%, var(--color-bg-elevated)); + border-color: color-mix(in srgb, var(--color-error, #f85149) 30%, var(--border-base)); + background: color-mix(in srgb, var(--color-error, #f85149) 8%, var(--color-bg-elevated)); } &__ci-item--pending { - border-color: color-mix(in srgb, #d29922 24%, var(--border-base)); - background: color-mix(in srgb, #d29922 7%, var(--color-bg-elevated)); + border-color: color-mix(in srgb, var(--color-warning, #d29922) 24%, var(--border-base)); + background: color-mix(in srgb, var(--color-warning, #d29922) 7%, var(--color-bg-elevated)); } &__ci-head { @@ -1268,18 +1268,18 @@ } &__ci-status--passed { - color: #3fb950; - background: rgba(63, 185, 80, 0.12); + color: var(--color-success, #3fb950); + background: var(--color-success-bg, rgba(52, 211, 153, 0.1)); } &__ci-status--failed { - color: #f85149; - background: rgba(248, 81, 73, 0.12); + color: var(--color-error, #f85149); + background: var(--color-error-bg, rgba(239, 68, 68, 0.1)); } &__ci-status--pending { - color: #d29922; - background: rgba(210, 153, 34, 0.13); + color: var(--color-warning, #d29922); + background: var(--color-warning-bg, rgba(245, 158, 11, 0.1)); } &__ci-meta { @@ -1458,15 +1458,15 @@ } &__thread-tag--resolved { - color: color-mix(in srgb, #3fb950 90%, var(--color-text-secondary)); - border-color: color-mix(in srgb, #3fb950 24%, var(--border-base)); - background: color-mix(in srgb, #3fb950 10%, transparent); + color: color-mix(in srgb, var(--color-success, #3fb950) 90%, var(--color-text-secondary)); + border-color: color-mix(in srgb, var(--color-success, #3fb950) 24%, var(--border-base)); + background: color-mix(in srgb, var(--color-success, #3fb950) 10%, transparent); } &__thread-tag--open { - color: color-mix(in srgb, #f1c40f 82%, var(--color-text-secondary)); - border-color: color-mix(in srgb, #f1c40f 24%, var(--border-base)); - background: color-mix(in srgb, #f1c40f 10%, transparent); + color: color-mix(in srgb, var(--color-warning, #f1c40f) 82%, var(--color-text-secondary)); + border-color: color-mix(in srgb, var(--color-warning, #f1c40f) 24%, var(--border-base)); + background: color-mix(in srgb, var(--color-warning, #f1c40f) 10%, transparent); } &__thread-meta { diff --git a/src/web-ui/src/app/scenes/miniapps/components/MiniAppCard.scss b/src/web-ui/src/app/scenes/miniapps/components/MiniAppCard.scss index 38c8f7c9c..f1019ead5 100644 --- a/src/web-ui/src/app/scenes/miniapps/components/MiniAppCard.scss +++ b/src/web-ui/src/app/scenes/miniapps/components/MiniAppCard.scss @@ -113,14 +113,14 @@ } &__run-dot { - background: #34d399; - box-shadow: 0 0 6px rgba(52, 211, 153, 0.65); + background: var(--color-success, #34d399); + box-shadow: 0 0 6px color-mix(in srgb, var(--color-success, #34d399) 65%, transparent); animation: pulse 2s ease-in-out infinite; } &__customize-dot { - background: #60a5fa; - box-shadow: 0 0 6px rgba(96, 165, 250, 0.68); + background: var(--color-accent-500, #60a5fa); + box-shadow: 0 0 6px color-mix(in srgb, var(--color-accent-500, #60a5fa) 68%, transparent); } // ── Body ── @@ -263,7 +263,7 @@ &--stop:hover { background: rgba(247, 234, 234, 0.6); - color: #34d399; + color: var(--color-success, #34d399); } } } diff --git a/src/web-ui/src/app/scenes/profile/views/NurseryView.scss b/src/web-ui/src/app/scenes/profile/views/NurseryView.scss index a97b81dc8..ffd9b92b1 100644 --- a/src/web-ui/src/app/scenes/profile/views/NurseryView.scss +++ b/src/web-ui/src/app/scenes/profile/views/NurseryView.scss @@ -110,7 +110,7 @@ $nursery-scene-gutter: clamp(40px, 6vw, 80px); } &:focus-visible { - outline: 2px solid #34d399; + outline: 2px solid var(--color-success, #34d399); outline-offset: 2px; } @@ -151,7 +151,7 @@ $nursery-scene-gutter: clamp(40px, 6vw, 80px); margin-top: 2px; font-size: var(--font-size-xs); font-weight: $font-weight-medium; - color: #34d399; + color: var(--color-success, #34d399); opacity: 0.72; transition: opacity $motion-fast $easing-standard, @@ -1730,7 +1730,7 @@ $nursery-scene-gutter: clamp(40px, 6vw, 80px); &__error { margin: 0; font-size: var(--font-size-2xs); - color: var(--color-danger-600, #e11d48); + color: var(--color-error, #e11d48); line-height: $line-height-relaxed; } @@ -1933,7 +1933,7 @@ $nursery-scene-gutter: clamp(40px, 6vw, 80px); color: var(--color-text-muted); &--mcp { - color: #fb923c; + color: var(--color-warning, #fb923c); background: rgba(251, 146, 60, 0.1); border-color: transparent; } @@ -2212,7 +2212,7 @@ $nursery-scene-gutter: clamp(40px, 6vw, 80px); font-weight: $font-weight-semibold; text-transform: uppercase; letter-spacing: 0.8px; - color: #34d399; + color: var(--color-success, #34d399); opacity: 0.85; } @@ -2330,8 +2330,8 @@ $nursery-scene-gutter: clamp(40px, 6vw, 80px); font-weight: $font-weight-semibold; color: var(--color-text-secondary); - &--warn { color: #f59e0b; } - &--danger { color: #f87171; } + &--warn { color: var(--color-warning, #f59e0b); } + &--danger { color: var(--color-error, #f87171); } } // Segmented bar @@ -2468,7 +2468,7 @@ $nursery-scene-gutter: clamp(40px, 6vw, 80px); flex-shrink: 0; color: var(--color-text-muted); - &--mcp { color: #fb923c; } + &--mcp { color: var(--color-warning, #fb923c); } } &__name { @@ -2493,14 +2493,14 @@ $nursery-scene-gutter: clamp(40px, 6vw, 80px); &--connected, &--healthy { - color: #34d399; + color: var(--color-success, #34d399); background: rgba(52, 211, 153, 0.08); border-color: rgba(52, 211, 153, 0.22); } &--starting, &--reconnecting { - color: #f59e0b; + color: var(--color-warning, #f59e0b); background: rgba(245, 158, 11, 0.08); border-color: rgba(245, 158, 11, 0.22); } @@ -2508,7 +2508,7 @@ $nursery-scene-gutter: clamp(40px, 6vw, 80px); &--failed, &--stopped, &--stopping { - color: #f87171; + color: var(--color-error, #f87171); background: rgba(248, 113, 113, 0.08); border-color: rgba(248, 113, 113, 0.22); } @@ -2603,7 +2603,7 @@ $nursery-scene-gutter: clamp(40px, 6vw, 80px); color: var(--color-text-muted); &--mcp { - color: #fb923c; + color: var(--color-warning, #fb923c); background: rgba(251, 146, 60, 0.1); } } @@ -3370,7 +3370,7 @@ $acp-content-top: clamp(40px, 4.5vh, 52px); &__error { margin: 0 0 $size-gap-3; font-size: var(--font-size-xs); - color: var(--color-danger-600, #e11d48); + color: var(--color-error, #e11d48); line-height: $line-height-relaxed; } diff --git a/src/web-ui/src/component-library/styles/tokens.scss b/src/web-ui/src/component-library/styles/tokens.scss index 5eb26430d..ddbe0692b 100644 --- a/src/web-ui/src/component-library/styles/tokens.scss +++ b/src/web-ui/src/component-library/styles/tokens.scss @@ -3,20 +3,20 @@ */ // ==================== Base color system ==================== -$color-bg-primary: #121214; -$color-bg-secondary: #18181a; -$color-bg-tertiary: #121214; -$color-bg-quaternary: #202024; -$color-bg-elevated: #18181a; -$color-bg-workbench: #121214; -$color-bg-flowchat: #121214; -$color-bg-scene: #16161a; -$color-bg-tooltip: rgba(30, 30, 32, 0.92); +$color-bg-primary: #0e0e10; +$color-bg-secondary: #1c1c1f; +$color-bg-tertiary: #0e0e10; +$color-bg-quaternary: #252528; +$color-bg-elevated: #1c1c1f; +$color-bg-workbench: #0e0e10; +$color-bg-flowchat: #0e0e10; +$color-bg-scene: #1c1c1f; +$color-bg-tooltip: rgba(28, 28, 31, 0.96); $color-text-primary: #e8e8e8; -$color-text-secondary: #e5e5e5; -$color-text-muted: #a0a0a0; -$color-text-disabled: #666666; +$color-text-secondary: #b0b0b0; +$color-text-muted: #858585; +$color-text-disabled: #555555; // ==================== Neutral surface system ==================== $element-bg-subtle: rgba(255, 255, 255, 0.05); @@ -48,58 +48,47 @@ $color-purple-600: #7c3aed; $color-purple-700: rgba(124, 58, 237, 0.8); $color-purple-800: rgba(124, 58, 237, 0.9); -// ==================== Gray system (legacy) ==================== -$color-gray-50: rgba(255, 255, 255, 0.02); -$color-gray-100: rgba(255, 255, 255, 0.04); -$color-gray-200: rgba(255, 255, 255, 0.06); -$color-gray-300: rgba(255, 255, 255, 0.08); -$color-gray-400: rgba(255, 255, 255, 0.12); -$color-gray-500: rgba(255, 255, 255, 0.16); -$color-gray-600: rgba(255, 255, 255, 0.24); -$color-gray-700: rgba(255, 255, 255, 0.32); -$color-gray-800: rgba(255, 255, 255, 0.48); - // ==================== Semantic colors ==================== -$color-success: #6eb88c; -$color-success-bg: rgba(110, 184, 140, 0.1); -$color-success-border: rgba(110, 184, 140, 0.3); +$color-success: #34d399; +$color-success-bg: rgba(52, 211, 153, 0.1); +$color-success-border: rgba(52, 211, 153, 0.3); -$color-warning: #c9944d; -$color-warning-bg: rgba(201, 148, 77, 0.1); -$color-warning-border: rgba(201, 148, 77, 0.3); +$color-warning: #f59e0b; +$color-warning-bg: rgba(245, 158, 11, 0.1); +$color-warning-border: rgba(245, 158, 11, 0.3); -$color-error: #c77070; -$color-error-bg: rgba(199, 112, 112, 0.1); -$color-error-border: rgba(199, 112, 112, 0.3); +$color-error: #ef4444; +$color-error-bg: rgba(239, 68, 68, 0.1); +$color-error-border: rgba(239, 68, 68, 0.3); -$color-info: #7096c4; -$color-info-bg: rgba(112, 150, 196, 0.1); -$color-info-border: rgba(112, 150, 196, 0.3); +$color-info: #a1a1aa; +$color-info-bg: rgba(255, 255, 255, 0.08); +$color-info-border: rgba(255, 255, 255, 0.22); // ==================== Git-specific color system ==================== -$git-color-branch: rgb(112, 150, 196); -$git-color-branch-bg: rgba(112, 150, 196, 0.08); -$git-color-branch-bg-hover: rgba(112, 150, 196, 0.15); -$git-color-branch-border: rgba(112, 150, 196, 0.3); +$git-color-branch: #a1a1aa; +$git-color-branch-bg: rgba(255, 255, 255, 0.06); +$git-color-branch-bg-hover: rgba(255, 255, 255, 0.12); +$git-color-branch-border: rgba(255, 255, 255, 0.18); -$git-color-changes: rgb(201, 148, 77); -$git-color-changes-bg: rgba(201, 148, 77, 0.1); -$git-color-changes-bg-hover: rgba(201, 148, 77, 0.15); -$git-color-changes-border: rgba(201, 148, 77, 0.3); +$git-color-changes: rgb(245, 158, 11); +$git-color-changes-bg: rgba(245, 158, 11, 0.1); +$git-color-changes-bg-hover: rgba(245, 158, 11, 0.15); +$git-color-changes-border: rgba(245, 158, 11, 0.3); -$git-color-staged: rgb(110, 184, 140); -$git-color-staged-bg: rgba(110, 184, 140, 0.1); -$git-color-staged-bg-hover: rgba(110, 184, 140, 0.15); -$git-color-staged-border: rgba(110, 184, 140, 0.3); +$git-color-staged: rgb(34, 197, 94); +$git-color-staged-bg: rgba(34, 197, 94, 0.1); +$git-color-staged-bg-hover: rgba(34, 197, 94, 0.15); +$git-color-staged-border: rgba(34, 197, 94, 0.3); $git-color-added: $git-color-staged; $git-color-added-bg: $git-color-staged-bg; $git-color-added-bg-hover: $git-color-staged-bg-hover; -$git-color-deleted: rgb(199, 112, 112); -$git-color-deleted-bg: rgba(199, 112, 112, 0.1); -$git-color-deleted-bg-hover: rgba(199, 112, 112, 0.15); -$git-color-deleted-border: rgba(199, 112, 112, 0.3); +$git-color-deleted: rgb(239, 68, 68); +$git-color-deleted-bg: rgba(239, 68, 68, 0.1); +$git-color-deleted-bg-hover: rgba(239, 68, 68, 0.15); +$git-color-deleted-border: rgba(239, 68, 68, 0.3); $git-color-pull: $git-color-branch; $git-color-pull-bg: $git-color-branch-bg; @@ -110,11 +99,11 @@ $git-color-push-bg: $git-color-staged-bg; $git-color-push-bg-hover: $git-color-staged-bg-hover; // ==================== Border system ==================== -$border-subtle: rgba(255, 255, 255, 0.10); -$border-base: rgba(255, 255, 255, 0.14); -$border-medium: rgba(255, 255, 255, 0.20); -$border-strong: rgba(255, 255, 255, 0.26); -$border-prominent: rgba(200, 200, 200, 0.45); +$border-subtle: rgba(255, 255, 255, 0.12); +$border-base: rgba(255, 255, 255, 0.18); +$border-medium: rgba(255, 255, 255, 0.24); +$border-strong: rgba(255, 255, 255, 0.32); +$border-prominent: rgba(255, 255, 255, 0.4); $border-hover: $border-medium; $border-focus: $border-strong; @@ -342,7 +331,6 @@ $button-bg-default: linear-gradient(135deg, rgba(255, 255, 255, 0.10) 100% ); $button-border-default: rgba(255, 255, 255, 0.08); -$button-text-default: #e5e5e5; $button-bg-hover: linear-gradient(135deg, rgba(59, 130, 246, 0.15) 0%, @@ -780,16 +768,6 @@ $badge-info-text: $color-info; --color-purple-700: #{$color-purple-700}; --color-purple-800: #{$color-purple-800}; - --color-gray-50: #{$color-gray-50}; - --color-gray-100: #{$color-gray-100}; - --color-gray-200: #{$color-gray-200}; - --color-gray-300: #{$color-gray-300}; - --color-gray-400: #{$color-gray-400}; - --color-gray-500: #{$color-gray-500}; - --color-gray-600: #{$color-gray-600}; - --color-gray-700: #{$color-gray-700}; - --color-gray-800: #{$color-gray-800}; - --color-success: #{$color-success}; --color-success-bg: #{$color-success-bg}; --color-success-border: #{$color-success-border}; diff --git a/src/web-ui/src/flow_chat/components/ChatInput.scss b/src/web-ui/src/flow_chat/components/ChatInput.scss index bc044fc11..6d8ba9a82 100644 --- a/src/web-ui/src/flow_chat/components/ChatInput.scss +++ b/src/web-ui/src/flow_chat/components/ChatInput.scss @@ -1640,7 +1640,7 @@ height: 11px; padding: 0 3px; border-radius: 999px; - background: #ef4444; + background: var(--color-error, #ef4444); color: white; display: inline-flex; align-items: center; diff --git a/src/web-ui/src/flow_chat/components/InlineDiffPreview.scss b/src/web-ui/src/flow_chat/components/InlineDiffPreview.scss index c379f1def..69680d990 100644 --- a/src/web-ui/src/flow_chat/components/InlineDiffPreview.scss +++ b/src/web-ui/src/flow_chat/components/InlineDiffPreview.scss @@ -28,11 +28,11 @@ } &::-webkit-scrollbar-thumb { - background: var(--color-scrollbar-thumb, rgba(255, 255, 255, 0.15)); + background: var(--scrollbar-thumb, rgba(255, 255, 255, 0.15)); border-radius: 3px; - + &:hover { - background: var(--color-scrollbar-thumb-hover, rgba(255, 255, 255, 0.25)); + background: var(--scrollbar-thumb-hover, rgba(255, 255, 255, 0.25)); } } } @@ -83,27 +83,27 @@ } &--added { - background: rgba(63, 185, 80, 0.12); - + background: var(--git-color-staged-bg, rgba(34, 197, 94, 0.1)); + .diff-line__gutter { - background: rgba(63, 185, 80, 0.18); + background: var(--git-color-staged-bg-hover, rgba(34, 197, 94, 0.15)); } - + .diff-line__prefix { - color: #3fb950; + color: var(--git-color-staged, #34d399); font-weight: 500; } } - + &--removed { - background: rgba(248, 81, 73, 0.12); - + background: var(--git-color-deleted-bg, rgba(239, 68, 68, 0.1)); + .diff-line__gutter { - background: rgba(248, 81, 73, 0.18); + background: var(--git-color-deleted-bg-hover, rgba(239, 68, 68, 0.15)); } - + .diff-line__prefix { - color: #f85149; + color: var(--git-color-deleted, #ef4444); font-weight: 500; } @@ -114,10 +114,10 @@ // Highlighted row (selected). &--highlighted { - background: rgba(136, 182, 255, 0.15) !important; - + background: var(--color-accent-200, rgba(96, 165, 250, 0.15)) !important; + .diff-line__gutter { - background: rgba(136, 182, 255, 0.22) !important; + background: var(--color-accent-300, rgba(96, 165, 250, 0.22)) !important; } } @@ -224,48 +224,48 @@ .light .inline-diff-preview { .diff-line { &--added { - background: rgba(91, 154, 111, 0.12); - + background: var(--git-color-staged-bg); + .diff-line__gutter { - background: rgba(91, 154, 111, 0.18); + background: color-mix(in srgb, var(--git-color-staged) 18%, transparent); } - + .diff-line__prefix { - color: #4a8560; + color: var(--git-color-staged); } } - + &--removed { - background: rgba(194, 101, 101, 0.12); - + background: var(--git-color-deleted-bg); + .diff-line__gutter { - background: rgba(194, 101, 101, 0.18); + background: color-mix(in srgb, var(--git-color-deleted) 18%, transparent); } - + .diff-line__prefix { - color: #a85454; + color: var(--git-color-deleted); } } - + &--highlighted { - background: rgba(90, 123, 178, 0.10) !important; - + background: var(--color-accent-200) !important; + .diff-line__gutter { - background: rgba(90, 123, 178, 0.15) !important; + background: var(--color-accent-300) !important; } } } - + .diff-line__gutter { - background: rgba(0, 0, 0, 0.03); - border-right-color: rgba(0, 0, 0, 0.08); + background: var(--element-bg-subtle); + border-right-color: var(--border-subtle); } .diff-line__num { - color: #6e7781; + color: var(--color-text-muted); &--original { - border-right-color: rgba(0, 0, 0, 0.1); + border-right-color: var(--border-subtle); } } } diff --git a/src/web-ui/src/flow_chat/components/TurnHistoryPanel.scss b/src/web-ui/src/flow_chat/components/TurnHistoryPanel.scss index 19b31242e..6f3658cd0 100644 --- a/src/web-ui/src/flow_chat/components/TurnHistoryPanel.scss +++ b/src/web-ui/src/flow_chat/components/TurnHistoryPanel.scss @@ -4,7 +4,7 @@ padding: 16px; background: var(--color-bg-primary); border-radius: 8px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + box-shadow: var(--shadow-sm, 0 2px 4px rgba(0, 0, 0, 0.8)); .turn-history-header { display: flex; @@ -12,19 +12,19 @@ align-items: center; margin-bottom: 16px; padding-bottom: 12px; - border-bottom: 1px solid #e5e7eb; + border-bottom: 1px solid var(--border-base); h3 { margin: 0; font-size: 16px; font-weight: 600; - color: #111827; + color: var(--color-text-primary); } .turn-count { font-size: var(--tool-card-action-font-size, var(--flowchat-font-size-sm)); - color: #6b7280; - background: #f3f4f6; + color: var(--color-text-secondary); + background: var(--element-bg-soft); padding: 4px 8px; border-radius: 4px; } @@ -41,18 +41,18 @@ .turn-history-item { padding: 12px; - border: 1px solid #e5e7eb; + border: 1px solid var(--border-base); border-radius: 6px; transition: all 0.2s ease; &:hover { - border-color: #3b82f6; - box-shadow: 0 2px 4px rgba(59, 130, 246, 0.1); + border-color: var(--color-accent-600, #3b82f6); + box-shadow: 0 2px 4px color-mix(in srgb, var(--color-accent-600, #3b82f6) 10%, transparent); } &.current { - background: #f0f9ff; - border-color: #3b82f6; + background: var(--color-accent-100); + border-color: var(--color-accent-600, #3b82f6); } .turn-item-header { @@ -64,19 +64,19 @@ .turn-index { font-size: 14px; font-weight: 600; - color: #111827; + color: var(--color-text-primary); } } .turn-item-files { margin: 8px 0; padding: 8px; - background: #f9fafb; + background: var(--element-bg-subtle); border-radius: 4px; .files-label { font-size: var(--tool-card-action-font-size, var(--flowchat-font-size-sm)); - color: #6b7280; + color: var(--color-text-secondary); font-weight: 500; display: block; margin-bottom: 4px; @@ -88,14 +88,14 @@ .file-item { font-size: var(--tool-card-action-font-size, var(--flowchat-font-size-sm)); - color: #374151; + color: var(--color-text-secondary); margin: 2px 0; - font-family: 'Monaco', 'Consolas', monospace; + font-family: var(--font-family-mono, 'JetBrains Mono', 'FiraCode', ui-monospace, monospace); } .file-item-more { font-size: var(--tool-card-action-font-size, var(--flowchat-font-size-sm)); - color: #6b7280; + color: var(--color-text-muted); font-style: italic; list-style: none; margin-left: -16px; @@ -105,7 +105,7 @@ .turn-item-time { font-size: var(--flowchat-font-size-xs); - color: #9ca3af; + color: var(--color-text-muted); margin-top: 8px; } } @@ -114,100 +114,22 @@ .turn-history-panel-loading { padding: 40px; text-align: center; - color: #6b7280; + color: var(--color-text-secondary); font-size: 14px; } .turn-history-panel-empty { padding: 40px; text-align: center; - + p { margin: 8px 0; - color: #6b7280; + color: var(--color-text-secondary); font-size: 14px; &.hint { font-size: var(--tool-card-action-font-size, var(--flowchat-font-size-sm)); - color: #9ca3af; + color: var(--color-text-muted); } } } - -// Dark theme -@media (prefers-color-scheme: dark) { - .turn-history-panel { - background: #1f2937; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); - - .turn-history-header { - border-bottom-color: #374151; - - h3 { - color: #f9fafb; - } - - .turn-count { - background: #374151; - color: #d1d5db; - } - } - - .turn-history-list { - } - - .turn-history-item { - border-color: #374151; - - &:hover { - border-color: #3b82f6; - } - - &.current { - background: #1e3a8a; - border-color: #3b82f6; - } - - .turn-item-header .turn-index { - color: #f9fafb; - } - - .turn-item-files { - background: #111827; - - .files-label { - color: #d1d5db; - } - - .files-list { - .file-item { - color: #e5e7eb; - } - - .file-item-more { - color: #9ca3af; - } - } - } - - .turn-item-time { - color: #6b7280; - } - } - } - - .turn-history-panel-loading, - .turn-history-panel-empty { - color: #9ca3af; - - p { - color: #9ca3af; - - &.hint { - color: #6b7280; - } - } - } -} - - diff --git a/src/web-ui/src/flow_chat/components/TurnRollbackButton.scss b/src/web-ui/src/flow_chat/components/TurnRollbackButton.scss index 31cd2e482..49138ce6b 100644 --- a/src/web-ui/src/flow_chat/components/TurnRollbackButton.scss +++ b/src/web-ui/src/flow_chat/components/TurnRollbackButton.scss @@ -2,26 +2,26 @@ padding: 4px 12px; font-size: var(--tool-card-action-font-size, var(--flowchat-font-size-sm)); font-weight: 500; - background: #3b82f6; - color: white; + background: var(--color-accent-600, #3b82f6); + color: #ffffff; border: none; border-radius: 4px; cursor: pointer; transition: all 0.2s ease; white-space: nowrap; - + &:hover { - background: #2563eb; + background: var(--color-accent-700, #2563eb); transform: translateY(-1px); - box-shadow: 0 2px 4px rgba(59, 130, 246, 0.3); + box-shadow: 0 2px 4px color-mix(in srgb, var(--color-accent-600, #3b82f6) 30%, transparent); } - + &:active { transform: translateY(0); } - + &:disabled { - background: #94a3b8; + opacity: var(--opacity-disabled, 0.5); cursor: default; transform: none; box-shadow: none; @@ -32,30 +32,9 @@ padding: 4px 12px; font-size: var(--tool-card-action-font-size, var(--flowchat-font-size-sm)); font-weight: 500; - background: #22c55e; - color: white; + background: var(--color-success, #22c55e); + color: #ffffff; border-radius: 4px; display: inline-block; white-space: nowrap; } - -// Dark theme support -@media (prefers-color-scheme: dark) { - .turn-rollback-button { - background: #2563eb; - - &:hover { - background: #1d4ed8; - } - - &:disabled { - background: #64748b; - } - } - - .turn-rollback-button-current { - background: #059669; - } -} - - diff --git a/src/web-ui/src/flow_chat/tool-cards/CodeReviewToolCard.scss b/src/web-ui/src/flow_chat/tool-cards/CodeReviewToolCard.scss index 5ac5d3e1e..ff22eed30 100644 --- a/src/web-ui/src/flow_chat/tool-cards/CodeReviewToolCard.scss +++ b/src/web-ui/src/flow_chat/tool-cards/CodeReviewToolCard.scss @@ -117,7 +117,7 @@ } &--action { - border-left-color: var(--color-danger, #ef4444); + border-left-color: var(--color-error, #ef4444); } } @@ -558,7 +558,7 @@ } &.severity-high { - border-left: 3px solid var(--color-warning, #f97316); + border-left: 3px solid var(--color-warning, #f59e0b); } &.severity-medium { @@ -566,7 +566,7 @@ } &.severity-low { - border-left: 3px solid var(--color-info, #22c55e); + border-left: 3px solid var(--color-info, #a1a1aa); } &.severity-info { @@ -667,7 +667,7 @@ .suggestion-label { font-weight: 600; - color: var(--color-success, #16a34a); + color: var(--color-success, #34d399); flex-shrink: 0; font-size: var(--flowchat-font-size-xs); } @@ -783,7 +783,7 @@ } &.severity-high { - border-left: 3px solid var(--color-warning, #f97316); + border-left: 3px solid var(--color-warning, #f59e0b); } &.severity-medium { @@ -791,7 +791,7 @@ } &.severity-low { - border-left: 3px solid var(--color-info, #22c55e); + border-left: 3px solid var(--color-info, #a1a1aa); } &.severity-info { @@ -891,7 +891,7 @@ .suggestion-label { font-weight: 600; - color: var(--color-success, #16a34a); + color: var(--color-success, #34d399); flex-shrink: 0; font-size: var(--flowchat-font-size-xs); } @@ -1091,11 +1091,11 @@ .remediation-item__suggestion { display: flex; gap: 6px; - background: color-mix(in srgb, var(--color-success, #22c55e) 8%, transparent); - border: 1px solid color-mix(in srgb, var(--color-success, #22c55e) 16%, transparent); + background: color-mix(in srgb, var(--color-success, #34d399) 8%, transparent); + border: 1px solid color-mix(in srgb, var(--color-success, #34d399) 16%, transparent); span { - color: var(--color-success, #16a34a); + color: var(--color-success, #34d399); font-weight: 650; flex-shrink: 0; } @@ -1160,7 +1160,7 @@ .positive-header { font-size: var(--tool-card-action-font-size, var(--flowchat-font-size-sm)); font-weight: 600; - color: var(--color-success, #22c55e); + color: var(--color-success, #34d399); margin-bottom: 8px; padding-bottom: 6px; border-bottom: 1px dashed var(--border-base); diff --git a/src/web-ui/src/tools/editor/components/DiffEditor.scss b/src/web-ui/src/tools/editor/components/DiffEditor.scss index e964310a7..f04aa7d38 100644 --- a/src/web-ui/src/tools/editor/components/DiffEditor.scss +++ b/src/web-ui/src/tools/editor/components/DiffEditor.scss @@ -56,13 +56,13 @@ $_diff-error-max-width: 400px; font-size: var(--font-size-xs); &--add { - color: #3fb950; + color: var(--git-color-staged, #3fb950); background: rgba(63, 185, 80, 0.15); border: 1px solid rgba(63, 185, 80, 0.3); } &--del { - color: #f85149; + color: var(--git-color-deleted, #f85149); background: rgba(248, 81, 73, 0.15); border: 1px solid rgba(248, 81, 73, 0.3); } @@ -547,12 +547,12 @@ $_diff-error-max-width: 400px; .monaco-diff-editor { .line-insert { background-color: rgba(63, 185, 80, 0.2) !important; - border-left: 3px solid #3fb950; + border-left: 3px solid var(--git-color-staged, #3fb950); } .line-delete { background-color: rgba(248, 81, 73, 0.2) !important; - border-left: 3px solid #f85149; + border-left: 3px solid var(--git-color-deleted, #f85149); } } } diff --git a/src/web-ui/src/tools/editor/components/EditorStatusBar.scss b/src/web-ui/src/tools/editor/components/EditorStatusBar.scss index 0fadaaa72..0d6170e6e 100644 --- a/src/web-ui/src/tools/editor/components/EditorStatusBar.scss +++ b/src/web-ui/src/tools/editor/components/EditorStatusBar.scss @@ -77,7 +77,7 @@ $_section-gap: 12px; // Read-only Badge &__readonly { background: rgba(251, 191, 36, 0.15); - color: #fbbf24; + color: var(--color-warning, #f59e0b); padding: 1px 6px; border-radius: 3px; font-size: 10px; @@ -91,15 +91,15 @@ $_section-gap: 12px; padding: 2px 4px; &--connected { - color: #10b981; + color: var(--color-success, #10b981); } &--connecting { - color: #f59e0b; + color: var(--color-warning, #f59e0b); } &--disconnected { - color: #6b7280; + color: var(--color-text-muted, #6b7280); opacity: 0.6; } } @@ -142,8 +142,8 @@ $_section-gap: 12px; border-top-width: 2px; &__indicator--modified { - fill: #fbbf24; - color: #fbbf24; + fill: var(--color-warning, #f59e0b); + color: var(--color-warning, #f59e0b); } &__indicator--saved { diff --git a/src/web-ui/src/tools/editor/components/PlanViewer.scss b/src/web-ui/src/tools/editor/components/PlanViewer.scss index f60ce1323..dc62dc26c 100644 --- a/src/web-ui/src/tools/editor/components/PlanViewer.scss +++ b/src/web-ui/src/tools/editor/components/PlanViewer.scss @@ -196,7 +196,7 @@ font-size: 12px; font-weight: 500; color: #fff; - background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); + background: linear-gradient(135deg, var(--color-warning, #f59e0b) 0%, var(--color-warning, #f59e0b) 100%); border: none; border-radius: 4px; cursor: pointer; @@ -204,7 +204,7 @@ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); &:hover:not(:disabled) { - background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%); + background: linear-gradient(135deg, var(--color-warning, #f59e0b) 0%, var(--color-warning, #f59e0b) 100%); box-shadow: 0 2px 4px rgba(245, 158, 11, 0.3); } @@ -223,16 +223,16 @@ } &--building { - background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); + background: linear-gradient(135deg, var(--color-warning, #f59e0b) 0%, var(--color-warning, #f59e0b) 100%); cursor: wait; } &--built { - background: linear-gradient(135deg, #10b981 0%, #059669 100%); + background: linear-gradient(135deg, var(--color-success, #10b981) 0%, var(--color-success, #10b981) 100%); cursor: default; &:hover { - background: linear-gradient(135deg, #10b981 0%, #059669 100%); + background: linear-gradient(135deg, var(--color-success, #10b981) 0%, var(--color-success, #10b981) 100%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } } @@ -399,8 +399,8 @@ &:hover { color: var(--color-error); - background: rgba(var(--color-error-rgb), 0.1); - border-color: rgba(var(--color-error-rgb), 0.3); + background: var(--color-error-bg, rgba(239, 68, 68, 0.1)); + border-color: var(--color-error-border, rgba(239, 68, 68, 0.3)); } } diff --git a/src/web-ui/src/tools/git/components/CreateBranchDialog/CreateBranchDialog.scss b/src/web-ui/src/tools/git/components/CreateBranchDialog/CreateBranchDialog.scss index 47944ecd4..7b3ee2dad 100644 --- a/src/web-ui/src/tools/git/components/CreateBranchDialog/CreateBranchDialog.scss +++ b/src/web-ui/src/tools/git/components/CreateBranchDialog/CreateBranchDialog.scss @@ -124,7 +124,7 @@ } &__required { - color: #ef4444; + color: var(--color-error, #ef4444); } &__input { @@ -173,7 +173,7 @@ background: rgba(239, 68, 68, 0.08); border: 1px solid rgba(239, 68, 68, 0.25); border-radius: $size-radius-sm; - color: #ef4444; + color: var(--color-error, #ef4444); font-size: var(--font-size-xs); animation: bitfun-create-branch-dialog-shake 0.4s ease-in-out; } diff --git a/src/web-ui/src/tools/git/components/GitBranchHistoryView/GitBranchHistoryView.scss b/src/web-ui/src/tools/git/components/GitBranchHistoryView/GitBranchHistoryView.scss index b0577a102..077713979 100644 --- a/src/web-ui/src/tools/git/components/GitBranchHistoryView/GitBranchHistoryView.scss +++ b/src/web-ui/src/tools/git/components/GitBranchHistoryView/GitBranchHistoryView.scss @@ -231,7 +231,7 @@ height: 24px; border-radius: 50%; background: rgba(96, 165, 250, 0.15); - color: #60a5fa; + color: var(--color-accent-500, #60a5fa); flex-shrink: 0; font-size: 11px; font-weight: 600; @@ -304,7 +304,7 @@ &--copied { background: rgba(16, 185, 129, 0.15); - color: #10b981; + color: var(--color-success, #10b981); .git-branch-history-view__copy-icon { opacity: 1; diff --git a/src/web-ui/src/tools/git/components/GitGraphView/GitGraphView.scss b/src/web-ui/src/tools/git/components/GitGraphView/GitGraphView.scss index 10d5f1a0e..0aa6d269f 100644 --- a/src/web-ui/src/tools/git/components/GitGraphView/GitGraphView.scss +++ b/src/web-ui/src/tools/git/components/GitGraphView/GitGraphView.scss @@ -161,51 +161,51 @@ } &--selected { - background: rgba(96, 165, 250, 0.08); - border-left: 2px solid #60a5fa; + background: var(--color-accent-100); + border-left: 2px solid var(--color-accent-500, #60a5fa); z-index: 2; - + &:hover { - background: rgba(96, 165, 250, 0.12); + background: var(--color-accent-200); } } &--search-match { - background: rgba(251, 191, 36, 0.06); - border-left: 2px solid rgba(251, 191, 36, 0.4); - + background: color-mix(in srgb, var(--color-warning, #fbbf24) 6%, transparent); + border-left: 2px solid color-mix(in srgb, var(--color-warning, #fbbf24) 40%, transparent); + &:hover { - background: rgba(251, 191, 36, 0.1); + background: color-mix(in srgb, var(--color-warning, #fbbf24) 10%, transparent); } } &--current-search-match { - background: rgba(251, 191, 36, 0.15); - border-left: 3px solid #fbbf24; - box-shadow: inset 0 0 0 1px rgba(251, 191, 36, 0.3); + background: color-mix(in srgb, var(--color-warning, #fbbf24) 15%, transparent); + border-left: 3px solid var(--color-warning, #fbbf24); + box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-warning, #fbbf24) 30%, transparent); animation: search-highlight 0.4s ease-out; z-index: 3; - + &:hover { - background: rgba(251, 191, 36, 0.2); + background: color-mix(in srgb, var(--color-warning, #fbbf24) 20%, transparent); } &.git-graph-view__hit-area--selected { background: linear-gradient( 90deg, - rgba(251, 191, 36, 0.2), - rgba(96, 165, 250, 0.15) + color-mix(in srgb, var(--color-warning, #fbbf24) 20%, transparent), + var(--color-accent-200) ); - border-left: 3px solid #fbbf24; - box-shadow: - inset 0 0 0 1px rgba(251, 191, 36, 0.3), - inset 3px 0 0 0 #60a5fa; + border-left: 3px solid var(--color-warning, #fbbf24); + box-shadow: + inset 0 0 0 1px color-mix(in srgb, var(--color-warning, #fbbf24) 30%, transparent), + inset 3px 0 0 0 var(--color-accent-500, #60a5fa); &:hover { background: linear-gradient( 90deg, - rgba(251, 191, 36, 0.25), - rgba(96, 165, 250, 0.2) + color-mix(in srgb, var(--color-warning, #fbbf24) 25%, transparent), + var(--color-accent-200) ); } } @@ -269,18 +269,18 @@ } &--branch { - background: #42a5f5; - color: #fff; + background: var(--color-accent-600, #42a5f5); + color: #ffffff; } &--remote { - background: #9c27b0; - color: #fff; + background: var(--color-purple-600, #9c27b0); + color: #ffffff; } &--tag { - background: #ff7043; - color: #fff; + background: var(--git-color-changes, #ff7043); + color: #ffffff; } &--current {