Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Color Unification Mapping for --
- **[2025-06-09] - Created comprehensive color mapping system for strategy builder theme customization**
- ## Overview
- This document maps all color usage locations across the -- platform and proposes a unified color system for customizable themes. The color customization will apply to:
- - ✅ Strategy Builder (node editor)
- - ✅ Results Charts (Chart.jsx, MultiChart.jsx)
- - ✅ Global Strategy Options panel
- - ❌ Documentation, Pricing, Landing pages (excluded from customization)
- ## Proposed Color System
- ### Brand Colors (Primary System)
- ```javascript
- const brandColors = {
- light: {
- primary: '#2d3e4f',
- secondary: '#006064',
- tertiary: '#219f3d',
- alternate: '#48a3fe'
- },
- dark: {
- primary: '#2d4f48',
- secondary: '#006064',
- tertiary: '#0d47a1',
- alternate: '#2d3e4f'
- }
- }
- ```
- ### Utility Colors
- ```javascript
- const utilityColors = {
- light: {
- primaryText: '#363636',
- secondaryText: '#6f6f6f',
- primaryBackground: '#f8f8f8',
- secondaryBackground: '#a4a4a4'
- },
- dark: {
- primaryText: '#d9d9d9',
- secondaryText: '#6f6f6f',
- primaryBackground: '#121212',
- secondaryBackground: '#292929'
- }
- }
- ```
- ### Accent Colors
- ```javascript
- const accentColors = {
- light: {
- accent1: '#2e7d32', // Success green
- accent2: '#420e60', // Deep purple
- accent3: '#00bcd4', // Cyan
- accent4: '#795548' // Brown
- },
- dark: {
- accent1: '#2e7d32', // Success green
- accent2: '#420e60', // Deep purple
- accent3: '#17004f', // Dark blue
- accent4: '#4e342e' // Dark brown
- }
- }
- ```
- ### Semantic Colors
- ```javascript
- const semanticColors = {
- light: {
- success: '#8bc34a',
- error: '#f44336',
- warning: '#ffeb3b',
- info: '#219f3d'
- },
- dark: {
- success: '#558b2f',
- error: '#771c1c',
- warning: '#fbc02d',
- info: '#0d47a1'
- }
- }
- ```
- ## Current Color Usage Locations
- ### 1. Strategy Builder & Node Editor
- #### Core Node Colors
- - **File:** `frontend-react/src/components/StrategyFlowEditor.jsx`
- - Line 100: `boxShadow: selected ? '0 0 0 2px #006064, 0 2px 12px #0008' : '0 2px 12px #0008'`
- - Line 101: `background: '#23272f'`
- - Line 103: `border: selected ? '2px solid #006064' : '1.5px solid #333'`
- - Line 120: `Handle` background: `#006064`
- - Line 642: Edge stroke colors: `#DC2626`, `#FFD700`, `#56657F`, `#B0BEC5`
- - **Proposed Mapping:**
- - `#006064` → `brandColors.secondary`
- - `#23272f` → `utilityColors.primaryBackground`
- - `#333` → `utilityColors.secondaryBackground`
- #### Portfolio Node Colors
- - **Files:** `frontend-react/src/components/nodes/portfolio/*.jsx`
- - Header Background: `#250827` (consistent across all portfolio nodes)
- - Border Color: `#250827`
- - Handle Color: `#420E60`
- - **Proposed Mapping:**
- - `#250827` → `accentColors.accent2` (portfolio category color)
- - `#420E60` → `accentColors.accent2` (handle color)
- #### Operator Node Colors
- - **Files:** `frontend-react/src/components/nodes/operator/*.jsx`
- - Header Background: `#006064` (consistent across operator nodes)
- - Handle Color: `#420E60`
- - **Proposed Mapping:**
- - `#006064` → `brandColors.secondary`
- - `#420E60` → `accentColors.accent2`
- ### 2. Chart Components
- #### Main Chart (Chart.jsx)
- - **File:** `frontend-react/src/components/Chart.jsx`
- - Line 55: Background gradient: `linear-gradient(135deg, #0B1426 0%, #1A1F2E 30%, #0F1419 100%)`
- - Line 89: Indicator color fallback: `#FFD700`
- - Line 127: Text color: `#E8EAED`
- - Line 194: Secondary text: `#B0B7C3`
- - Line 305: Accent color: `#00D4FF`
- - **Proposed Mapping:**
- - Background gradient → `utilityColors.primaryBackground` (adaptive)
- - `#FFD700` → `accentColors.accent3` (chart indicators)
- - `#E8EAED` → `utilityColors.primaryText`
- - `#B0B7C3` → `utilityColors.secondaryText`
- - `#00D4FF` → `brandColors.tertiary`
- #### Multi Chart (MultiChart.jsx)
- - **File:** `frontend-react/src/components/MultiChart.jsx`
- - Line 41: Buy/sell signal colors: `#26FF7F`, `#FF4757`
- - Line 108: Background gradient: `linear-gradient(135deg, #0B1426 0%, #1A1F2E 30%, #0F1419 100%)`
- - Line 220: Signal border colors: `#26FF7F`, `#FF4757`
- - Line 591: Accent color: `#00D4FF`
- - **Proposed Mapping:**
- - `#26FF7F` → `semanticColors.success` (buy signals)
- - `#FF4757` → `semanticColors.error` (sell signals)
- - `#00D4FF` → `brandColors.tertiary`
- ### 3. Global Strategy Options
- #### Global Strategy Options Panel
- - **File:** `frontend-react/src/components/sections/GlobalStrategyOptions.jsx`
- - Line 121: Accent color: `theme.palette.mode === 'dark' ? '#00E5C7' : '#009688'`
- - Line 800: Button background: `theme.palette.mode === 'dark' ? '#00BFA5' : '#00796B'`
- - Line 890-891: Error colors: `#771c1c`, `#5a1515`
- - **Proposed Mapping:**
- - `#00E5C7`/`#009688` → `brandColors.secondary`
- - `#00BFA5`/`#00796B` → `brandColors.secondary` (button variant)
- - `#771c1c` → `semanticColors.error`
- #### Action Buttons
- - **File:** `frontend-react/src/components/sections/ActionButtons.jsx`
- - Line 80-81: Border/text colors: `#0FF4C6`, `#006064`
- - Line 148: Hover colors: `#0FF4C6`, `#006064`
- - **Proposed Mapping:**
- - `#0FF4C6` → `brandColors.primary` (dark mode)
- - `#006064` → `brandColors.secondary`
- ### 4. Backend Chart Configuration
- #### Graph Executor Chart Colors
- - **File:** `backend/utils/graph_executor.py`
- - Line 749: Default indicator color: `#FFD700`
- - Line 751: Moving average color: `#87CEEB`
- - Line 755: RSI color: `#FF6347`
- - Line 760: MACD color: `#00CED1`
- - Line 766: Stochastic color: `#DDA0DD`
- - Line 776: Bollinger Bands colors: `#9370DB`, `#BA55D3`
- - **Proposed Mapping:**
- - `#FFD700` → `accentColors.accent3` (default indicator)
- - `#87CEEB` → `brandColors.tertiary` (moving averages)
- - `#FF6347` → `semanticColors.warning` (oscillators)
- - `#00CED1` → `brandColors.secondary` (momentum)
- - `#DDA0DD` → `accentColors.accent1` (stochastic)
- - `#9370DB` → `accentColors.accent2` (bands)
- ### 5. Sidebar Components
- #### Sliding Sidebar
- - **File:** `frontend-react/src/components/sidebar/SlidingSidebar.jsx`
- - Line 80: Menu highlight: `#2d3e4f`
- - Various lines: Themed text colors using conditional logic
- - **Proposed Mapping:**
- - `#2d3e4f` → `brandColors.primary`
- ### 6. Utility Components
- #### Enhanced Tooltip
- - **File:** `frontend-react/src/components/utils/EnhancedTooltip.jsx`
- - Line 15: Accent color: `theme.palette.mode === 'dark' ? '#00E5C7' : '#009688'`
- - **Proposed Mapping:**
- - `#00E5C7`/`#009688` → `brandColors.secondary`
- #### Edge Types
- - **File:** `frontend-react/src/components/utils/edgeTypes.jsx`
- - Line 45: Hover stroke: `#6b0f1a`
- - Line 62: Delete icon colors: `#6b0f1a`, `#fff`
- - **Proposed Mapping:**
- - `#6b0f1a` → `semanticColors.error`
- ## Database Integration & Serialization
- ### User Colors Database Schema
- The color customization data is stored in the `user_profiles.user_colors` JSONB column with the following structure:
- ```json
- {
- "light": {
- "brand": {
- "primary": "#2d3e4f",
- "secondary": "#006064",
- "tertiary": "#219f3d",
- "alternate": "#48a3fe"
- },
- "utility": {
- "primaryText": "#363636",
- "secondaryText": "#6f6f6f",
- "primaryBackground": "#f8f8f8",
- "secondaryBackground": "#a4a4a4"
- },
- "accent": {
- "accent1": "#2e7d32",
- "accent2": "#420e60",
- "accent3": "#00bcd4",
- "accent4": "#795548"
- },
- "semantic": {
- "success": "#8bc34a",
- "error": "#f44336",
- "warning": "#ffeb3b",
- "info": "#219f3d"
- },
- "nodeEditor": {
- "canvasBackground": "#f8f9fa",
- "gridLines": "#e9ecef40",
- "nodeIndicator": "#ffa500",
- "nodeOperator": "#006064",
- "nodePortfolio": "#6f42c1",
- "nodeAction": "#dc3545",
- "nodeEvent": "#7c3aed",
- "nodeSelected": "#007bff",
- "nodeHover": "#00000010",
- "handleDefault": "#6c757d",
- "handleConnected": "#28a745",
- "edgeDefault": "#adb5bd",
- "edgeActive": "#007bff",
- "selectionBox": "#007bff40"
- },
- "resultsCharts": {
- "priceUp": "#198754",
- "priceDown": "#dc3545",
- "priceNeutral": "#495057",
- "volumeHigh": "#0dcaf0",
- "volumeLow": "#0dcaf040",
- "indicatorPrimary": "#fd7e14",
- "indicatorSecondary": "#6610f2",
- "indicatorTertiary": "#d63384",
- "buySignal": "#198754",
- "sellSignal": "#dc3545",
- "chartBackground": "#ffffff",
- "chartGrid": "#f8f9fa",
- "chartAxis": "#6c757d",
- "tooltipBackground": "#f8f9fa",
- "tooltipText": "#212529"
- }
- },
- "dark": {
- "brand": {
- "primary": "#2d4f48",
- "secondary": "#006064",
- "tertiary": "#0d47a1",
- "alternate": "#2d3e4f"
- },
- "utility": {
- "primaryText": "#d9d9d9",
- "secondaryText": "#6f6f6f",
- "primaryBackground": "#121212",
- "secondaryBackground": "#292929"
- },
- "accent": {
- "accent1": "#2e7d32",
- "accent2": "#420e60",
- "accent3": "#17004f",
- "accent4": "#4e342e"
- },
- "semantic": {
- "success": "#558b2f",
- "error": "#771c1c",
- "warning": "#fbc02d",
- "info": "#0d47a1"
- },
- "nodeEditor": {
- "canvasBackground": "#0f1419",
- "gridLines": "#1a1f2e",
- "nodeIndicator": "#ffd700",
- "nodeOperator": "#006064",
- "nodePortfolio": "#250827",
- "nodeAction": "#dc2626",
- "nodeEvent": "#7c3aed",
- "nodeSelected": "#00e5c7",
- "nodeHover": "#ffffff20",
- "handleDefault": "#420e60",
- "handleConnected": "#00ff7f",
- "edgeDefault": "#56657f",
- "edgeActive": "#00e5c7",
- "selectionBox": "#00e5c740"
- },
- "resultsCharts": {
- "priceUp": "#26ff7f",
- "priceDown": "#ff4757",
- "priceNeutral": "#e8eaed",
- "volumeHigh": "#00d4ff",
- "volumeLow": "#00d4ff40",
- "indicatorPrimary": "#ffd700",
- "indicatorSecondary": "#87ceeb",
- "indicatorTertiary": "#ff6347",
- "buySignal": "#26ff7f",
- "sellSignal": "#ff4757",
- "chartBackground": "#0b1426",
- "chartGrid": "#1a1f2e40",
- "chartAxis": "#b0b7c3",
- "tooltipBackground": "#1a1f2e",
- "tooltipText": "#e8eaed"
- }
- }
- }
- ```
- ### Backend API Integration
- #### Update User Colors Endpoint
- ```python
- # backend/utils/supabase_profiles.py - EXISTING FUNCTION
- def update_user_colors(user_id: str, user_colors: Dict[str, str]) -> Dict[str, Any]:
- """
- Update user's color customization settings.
- Args:
- user_id: UUID of the user
- user_colors: Complete color configuration object
- Returns:
- Updated profile data dict
- """
- ```
- #### FastAPI Endpoint Addition
- ```python
- # backend/auth/routes.py - NEW ENDPOINT NEEDED
- @router.put("/user/colors")
- async def update_user_colors(
- colors_data: Dict[str, Any],
- current_user = Depends(get_current_user)
- ):
- """Update user's color customization settings."""
- try:
- updated_profile = update_user_colors(current_user.id, colors_data)
- return {"success": True, "user_colors": updated_profile.get("user_colors")}
- except Exception as e:
- raise HTTPException(status_code=500, detail=str(e))
- @router.get("/user/colors")
- async def get_user_colors(current_user = Depends(get_current_user)):
- """Get user's current color settings."""
- try:
- profile = get_user_profile(current_user.id)
- return {"user_colors": profile.get("user_colors") if profile else None}
- except Exception as e:
- raise HTTPException(status_code=500, detail=str(e))
- ```
- ### Frontend Integration Strategy
- #### 1. Color Context System
- ```javascript
- // frontend-react/src/context/ColorContext.jsx - NEW FILE NEEDED
- import { createContext, useContext, useState, useEffect } from 'react';
- const ColorContext = createContext();
- export const useColors = () => {
- const context = useContext(ColorContext);
- if (!context) {
- throw new Error('useColors must be used within ColorProvider');
- }
- return context;
- };
- export const ColorProvider = ({ children }) => {
- const [userColors, setUserColors] = useState(null);
- const [isLoading, setIsLoading] = useState(true);
- // Load colors on login
- useEffect(() => {
- loadUserColors();
- }, []);
- const loadUserColors = async () => {
- try {
- const response = await fetch('/api/auth/user/colors');
- const data = await response.json();
- setUserColors(data.user_colors || getDefaultColors());
- } catch (error) {
- console.error('Failed to load user colors:', error);
- setUserColors(getDefaultColors());
- } finally {
- setIsLoading(false);
- }
- };
- const updateColors = async (newColors) => {
- try {
- const response = await fetch('/api/auth/user/colors', {
- method: 'PUT',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(newColors)
- });
- if (response.ok) {
- setUserColors(newColors);
- applyColorsToDOM(newColors);
- }
- } catch (error) {
- console.error('Failed to update colors:', error);
- }
- };
- const applyColorsToDOM = (colors) => {
- const root = document.documentElement;
- const currentTheme = getCurrentTheme(); // 'light' or 'dark'
- const themeColors = colors[currentTheme];
- // Apply CSS custom properties
- Object.entries(themeColors.brand).forEach(([key, value]) => {
- root.style.setProperty(`--brand-${key}`, value);
- });
- Object.entries(themeColors.utility).forEach(([key, value]) => {
- root.style.setProperty(`--utility-${key}`, value);
- });
- Object.entries(themeColors.accent).forEach(([key, value]) => {
- root.style.setProperty(`--accent-${key}`, value);
- });
- Object.entries(themeColors.semantic).forEach(([key, value]) => {
- root.style.setProperty(`--semantic-${key}`, value);
- });
- };
- return (
- <ColorContext.Provider value={{
- userColors,
- updateColors,
- loadUserColors,
- isLoading,
- getColor: (theme, category, colorName) => {
- return userColors?.[theme]?.[category]?.[colorName] || '#000000';
- }
- }}>
- {children}
- </ColorContext.Provider>
- );
- };
- ```
- #### 2. CSS Custom Properties Integration
- ```css
- /* frontend-react/src/styles/colors.css - NEW FILE NEEDED */
- :root {
- /* Default colors - will be overridden by ColorContext */
- --brand-primary: #2d3e4f;
- --brand-secondary: #006064;
- --brand-tertiary: #219f3d;
- --brand-alternate: #48a3fe;
- --utility-primaryText: #363636;
- --utility-secondaryText: #6f6f6f;
- --utility-primaryBackground: #f8f8f8;
- --utility-secondaryBackground: #a4a4a4;
- --accent-accent1: #2e7d32;
- --accent-accent2: #420e60;
- --accent-accent3: #00bcd4;
- --accent-accent4: #795548;
- --semantic-success: #8bc34a;
- --semantic-error: #f44336;
- --semantic-warning: #ffeb3b;
- --semantic-info: #219f3d;
- }
- [data-theme="dark"] {
- --brand-primary: #2d4f48;
- --brand-secondary: #006064;
- --brand-tertiary: #0d47a1;
- --brand-alternate: #2d3e4f;
- --utility-primaryText: #d9d9d9;
- --utility-secondaryText: #6f6f6f;
- --utility-primaryBackground: #121212;
- --utility-secondaryBackground: #292929;
- --accent-accent1: #2e7d32;
- --accent-accent2: #420e60;
- --accent-accent3: #17004f;
- --accent-accent4: #4e342e;
- --semantic-success: #558b2f;
- --semantic-error: #771c1c;
- --semantic-warning: #fbc02d;
- --semantic-info: #0d47a1;
- }
- ```
- #### 3. User Interface Component
- ```javascript
- // frontend-react/src/components/ColorCustomization.jsx - NEW FILE NEEDED
- import { useState } from 'react';
- import { useColors } from '../context/ColorContext';
- import {
- Box,
- Typography,
- Paper,
- Grid,
- Button,
- TextField,
- Switch,
- FormControlLabel
- } from '@mui/material';
- const ColorPicker = ({ label, value, onChange, category, colorKey }) => {
- return (
- <Box sx={{ mb: 2 }}>
- <Typography variant="body2" sx={{ mb: 1 }}>
- {label}
- </Typography>
- <TextField
- type="color"
- value={value}
- onChange={(e) => onChange(category, colorKey, e.target.value)}
- size="small"
- sx={{ width: 60 }}
- />
- <TextField
- value={value}
- onChange={(e) => onChange(category, colorKey, e.target.value)}
- size="small"
- sx={{ ml: 1, width: 100 }}
- placeholder="#000000"
- />
- </Box>
- );
- };
- export const ColorCustomization = () => {
- const { userColors, updateColors, isLoading } = useColors();
- const [isDarkMode, setIsDarkMode] = useState(false);
- const [localColors, setLocalColors] = useState(userColors);
- const handleColorChange = (category, colorKey, newValue) => {
- const theme = isDarkMode ? 'dark' : 'light';
- setLocalColors(prev => ({
- ...prev,
- [theme]: {
- ...prev[theme],
- [category]: {
- ...prev[theme][category],
- [colorKey]: newValue
- }
- }
- }));
- };
- const handleSave = async () => {
- await updateColors(localColors);
- };
- const handleReset = () => {
- setLocalColors(getDefaultColors());
- };
- if (isLoading) return <Typography>Loading color settings...</Typography>;
- const currentTheme = isDarkMode ? 'dark' : 'light';
- const colors = localColors?.[currentTheme] || {};
- return (
- <Box sx={{ p: 3 }}>
- <Typography variant="h5" sx={{ mb: 3 }}>
- Color Customization
- </Typography>
- <FormControlLabel
- control={
- <Switch
- checked={isDarkMode}
- onChange={(e) => setIsDarkMode(e.target.checked)}
- />
- }
- label={`${isDarkMode ? 'Dark' : 'Light'} Mode Preview`}
- />
- <Grid container spacing={3} sx={{ mt: 2 }}>
- {/* Brand Colors */}
- <Grid item xs={12} md={3}>
- <Paper sx={{ p: 2 }}>
- <Typography variant="h6" sx={{ mb: 2 }}>Brand Colors</Typography>
- <ColorPicker
- label="Primary"
- value={colors.brand?.primary || '#2d3e4f'}
- onChange={handleColorChange}
- category="brand"
- colorKey="primary"
- />
- <ColorPicker
- label="Secondary"
- value={colors.brand?.secondary || '#006064'}
- onChange={handleColorChange}
- category="brand"
- colorKey="secondary"
- />
- <ColorPicker
- label="Tertiary"
- value={colors.brand?.tertiary || '#219f3d'}
- onChange={handleColorChange}
- category="brand"
- colorKey="tertiary"
- />
- <ColorPicker
- label="Alternate"
- value={colors.brand?.alternate || '#48a3fe'}
- onChange={handleColorChange}
- category="brand"
- colorKey="alternate"
- />
- </Paper>
- </Grid>
- {/* Utility Colors */}
- <Grid item xs={12} md={3}>
- <Paper sx={{ p: 2 }}>
- <Typography variant="h6" sx={{ mb: 2 }}>Utility Colors</Typography>
- <ColorPicker
- label="Primary Text"
- value={colors.utility?.primaryText || '#363636'}
- onChange={handleColorChange}
- category="utility"
- colorKey="primaryText"
- />
- <ColorPicker
- label="Secondary Text"
- value={colors.utility?.secondaryText || '#6f6f6f'}
- onChange={handleColorChange}
- category="utility"
- colorKey="secondaryText"
- />
- <ColorPicker
- label="Primary Background"
- value={colors.utility?.primaryBackground || '#f8f8f8'}
- onChange={handleColorChange}
- category="utility"
- colorKey="primaryBackground"
- />
- <ColorPicker
- label="Secondary Background"
- value={colors.utility?.secondaryBackground || '#a4a4a4'}
- onChange={handleColorChange}
- category="utility"
- colorKey="secondaryBackground"
- />
- </Paper>
- </Grid>
- {/* Accent Colors */}
- <Grid item xs={12} md={3}>
- <Paper sx={{ p: 2 }}>
- <Typography variant="h6" sx={{ mb: 2 }}>Accent Colors</Typography>
- <ColorPicker
- label="Accent 1 (Success)"
- value={colors.accent?.accent1 || '#2e7d32'}
- onChange={handleColorChange}
- category="accent"
- colorKey="accent1"
- />
- <ColorPicker
- label="Accent 2 (Portfolio)"
- value={colors.accent?.accent2 || '#420e60'}
- onChange={handleColorChange}
- category="accent"
- colorKey="accent2"
- />
- <ColorPicker
- label="Accent 3 (Charts)"
- value={colors.accent?.accent3 || '#00bcd4'}
- onChange={handleColorChange}
- category="accent"
- colorKey="accent3"
- />
- <ColorPicker
- label="Accent 4 (Indicators)"
- value={colors.accent?.accent4 || '#795548'}
- onChange={handleColorChange}
- category="accent"
- colorKey="accent4"
- />
- </Paper>
- </Grid>
- {/* Semantic Colors */}
- <Grid item xs={12} md={3}>
- <Paper sx={{ p: 2 }}>
- <Typography variant="h6" sx={{ mb: 2 }}>Semantic Colors</Typography>
- <ColorPicker
- label="Success"
- value={colors.semantic?.success || '#8bc34a'}
- onChange={handleColorChange}
- category="semantic"
- colorKey="success"
- />
- <ColorPicker
- label="Error"
- value={colors.semantic?.error || '#f44336'}
- onChange={handleColorChange}
- category="semantic"
- colorKey="error"
- />
- <ColorPicker
- label="Warning"
- value={colors.semantic?.warning || '#ffeb3b'}
- onChange={handleColorChange}
- category="semantic"
- colorKey="warning"
- />
- <ColorPicker
- label="Info"
- value={colors.semantic?.info || '#219f3d'}
- onChange={handleColorChange}
- category="semantic"
- colorKey="info"
- />
- </Paper>
- </Grid>
- </Grid>
- <Box sx={{ mt: 3, display: 'flex', gap: 2 }}>
- <Button variant="contained" onClick={handleSave}>
- Save Colors
- </Button>
- <Button variant="outlined" onClick={handleReset}>
- Reset to Default
- </Button>
- </Box>
- </Box>
- );
- };
- ```
- ### Database Operations
- #### Auto-loading Colors on Login
- Colors are automatically loaded when the user logs in through the existing authentication flow:
- ```javascript
- // frontend-react/src/context/AuthContext.jsx - MODIFICATION NEEDED
- // Add color loading to the login success handler
- const handleLoginSuccess = async (user) => {
- // ... existing login logic ...
- // Load user colors after successful login
- await loadUserColors(); // This will be called by ColorProvider
- };
- ```
- #### Persistence & Synchronization
- - **Real-time Updates**: Colors are applied immediately via CSS custom properties
- - **Database Sync**: Color changes are persisted to `user_profiles.user_colors` JSONB column
- - **Session Management**: Colors persist across browser sessions and device changes
- - **Fallback Strategy**: If no custom colors exist, system uses default FlutterFlow-inspired palette
- ## Implementation Priority
- ### Phase 1: Core System Setup
- 1. Create CSS custom properties file (`frontend-react/src/styles/colors.css`)
- 2. Create React ColorContext (`frontend-react/src/context/ColorContext.jsx`)
- 3. Add FastAPI endpoints (`backend/auth/routes.py`)
- 4. Update theme provider integration
- ### Phase 2: Node Editor Colors
- 1. Replace hardcoded colors in node components
- 2. Update handle colors across all node types
- 3. Implement selection and hover state colors
- ### Phase 3: Chart Colors
- 1. Update Chart.jsx color system
- 2. Update MultiChart.jsx color system
- 3. Update backend chart configuration colors
- ### Phase 4: UI Components
- 1. Update Global Strategy Options colors
- 2. Update sidebar colors
- 3. Update utility component colors
- ### Phase 5: User Customization
- 1. Add color picker components
- 2. Implement color persistence
- 3. Add preset color themes
- ## Files Requiring Updates
- ### High Priority (Core Functionality)
- 1. `frontend-react/src/components/StrategyFlowEditor.jsx`
- 2. `frontend-react/src/components/Chart.jsx`
- 3. `frontend-react/src/components/MultiChart.jsx`
- 4. `backend/utils/graph_executor.py`
- ### Medium Priority (Node Components)
- 5. `frontend-react/src/components/nodes/portfolio/*.jsx` (6 files)
- 6. `frontend-react/src/components/nodes/operator/*.jsx` (6 files)
- 7. `frontend-react/src/components/nodes/indicator/*.jsx` (40+ files)
- ### Lower Priority (UI Components)
- 8. `frontend-react/src/components/sections/GlobalStrategyOptions.jsx`
- 9. `frontend-react/src/components/sections/ActionButtons.jsx`
- 10. `frontend-react/src/components/sidebar/SlidingSidebar.jsx`
- 11. `frontend-react/src/components/utils/EnhancedTooltip.jsx`
- 12. `frontend-react/src/components/utils/edgeTypes.jsx`
- ## Color Accessibility Considerations
- ### Contrast Ratios
- - Ensure all text colors meet WCAG AA standards (4.5:1 contrast ratio)
- - Provide high contrast mode option
- - Test colors with color blindness simulation
- ### Color Coding
- - Never rely solely on color to convey information
- - Provide alternative indicators (shapes, patterns, text labels)
- - Support colorblind-friendly palette options
- ## Enhanced Color System (48 Colors Total)
- With the addition of Node Editor and Results Charts color categories, subscribers now have **48 customizable colors** per theme mode:
- ### Light Mode: 48 Colors
- - **Brand Colors**: 4 colors (primary, secondary, tertiary, alternate)
- - **Utility Colors**: 4 colors (text and background variations)
- - **Accent Colors**: 4 colors (categorized functionality)
- - **Semantic Colors**: 4 colors (success, error, warning, info)
- - **Node Editor Colors**: 15 colors (canvas, nodes, handles, edges, states)
- - **Results Charts Colors**: 15 colors (price data, indicators, signals, UI elements)
- ### Dark Mode: 48 Colors
- - Same 48 color categories optimized for dark theme visibility
- ## Node Editor Color Categories
- ### Canvas & Layout Colors
- - **Canvas Background** (`canvasBackground`): Main editor background
- - **Grid Lines** (`gridLines`): Canvas grid overlay
- - **Selection Box** (`selectionBox`): Multi-node selection rectangle
- ### Node Type Colors
- - **Indicator Nodes** (`nodeIndicator`): Technical analysis indicators (EMA, RSI, etc.)
- - **Operator Nodes** (`nodeOperator`): Logic operators (AND, OR, Math, etc.)
- - **Portfolio Nodes** (`nodePortfolio`): Portfolio management nodes
- - **Action Nodes** (`nodeAction`): Buy/Sell/Wait action nodes
- - **Event Nodes** (`nodeEvent`): Market event nodes (earnings, splits)
- ### Node State Colors
- - **Selected State** (`nodeSelected`): Active/selected node border
- - **Hover State** (`nodeHover`): Mouse hover overlay effect
- ### Connection Colors
- - **Default Handle** (`handleDefault`): Unconnected node handles
- - **Connected Handle** (`handleConnected`): Connected node handles
- - **Default Edge** (`edgeDefault`): Standard connection lines
- - **Active Edge** (`edgeActive`): Selected/highlighted connections
- ## Results Charts Color Categories
- ### Price Data Colors
- - **Price Up** (`priceUp`): Bullish candles/price movements
- - **Price Down** (`priceDown`): Bearish candles/price movements
- - **Price Neutral** (`priceNeutral`): Neutral/unchanged price data
- ### Volume Colors
- - **Volume High** (`volumeHigh`): High volume bars
- - **Volume Low** (`volumeLow`): Low volume bars (with transparency)
- ### Indicator Colors
- - **Indicator Primary** (`indicatorPrimary`): Main indicator lines (EMA, SMA)
- - **Indicator Secondary** (`indicatorSecondary`): Secondary indicators (signals)
- - **Indicator Tertiary** (`indicatorTertiary`): Additional indicator elements
- ### Signal Colors
- - **Buy Signal** (`buySignal`): Buy action markers
- - **Sell Signal** (`sellSignal`): Sell action markers
- ### Chart UI Colors
- - **Chart Background** (`chartBackground`): Main chart area background
- - **Chart Grid** (`chartGrid`): Chart grid lines
- - **Chart Axis** (`chartAxis`): Axis labels and lines
- - **Tooltip Background** (`tooltipBackground`): Tooltip/popup background
- - **Tooltip Text** (`tooltipText`): Tooltip text color
- ## Color Usage Examples
- ### Node Editor Implementation
- ```css
- /* Node editor canvas colors */
- .react-flow__pane {
- background: var(--nodeEditor-canvasBackground);
- }
- .react-flow__grid {
- stroke: var(--nodeEditor-gridLines);
- }
- /* Node type colors */
- .node-indicator {
- background: var(--nodeEditor-nodeIndicator);
- }
- .node-portfolio {
- background: var(--nodeEditor-nodePortfolio);
- }
- /* Node states */
- .node.selected {
- border-color: var(--nodeEditor-nodeSelected);
- }
- .node:hover {
- background: var(--nodeEditor-nodeHover);
- }
- /* Handles and edges */
- .react-flow__handle {
- background: var(--nodeEditor-handleDefault);
- }
- .react-flow__handle.connected {
- background: var(--nodeEditor-handleConnected);
- }
- .react-flow__edge {
- stroke: var(--nodeEditor-edgeDefault);
- }
- .react-flow__edge.selected {
- stroke: var(--nodeEditor-edgeActive);
- }
- ```
- ### Charts Implementation
- ```css
- /* Chart colors */
- .echarts-container {
- background: var(--resultsCharts-chartBackground);
- }
- .candlestick-up {
- color: var(--resultsCharts-priceUp);
- }
- .candlestick-down {
- color: var(--resultsCharts-priceDown);
- }
- .buy-signal {
- color: var(--resultsCharts-buySignal);
- }
- .sell-signal {
- color: var(--resultsCharts-sellSignal);
- }
- .chart-tooltip {
- background: var(--resultsCharts-tooltipBackground);
- color: var(--resultsCharts-tooltipText);
- }
- ```
- ## Next Steps
- 1. Create CSS custom properties file with all 48 color variables
- 2. Set up React ColorContext system with expanded color categories
- 3. Begin Phase 1 implementation with core system setup
- 4. Test color system with existing components
- 5. Implement user customization interface with 6 color category panels
- 6. Add color persistence and presets
Advertisement
Add Comment
Please, Sign In to add comment