Skip to content

Theme Configuration Investigation

Date: 2026-01-07 Issue: Test user unable to set theme colors in app

Summary

Theme/branding configuration UI exists and API works, but CSS uses hardcoded colors instead of the dynamic variables from the template. Changes saved in Settings don't visually affect the app.

Current Architecture

Data Flow (Working)

Settings UI → API → Database → Template Context → CSS Variables
     ✓          ✓        ✓            ✓               ✗ (broken)

The Problem

  1. layout.html correctly injects dynamic CSS variables:

    <style>
        :root {
            --primary-color: {{ theme.primary }};    /* From database */
            --secondary-color: {{ theme.secondary }};
            --accent-color: {{ theme.accent }};
            --text-color: {{ theme.text }};
            --sidebar-color: {{ theme.sidebar }};
        }
    </style>
    

  2. styles.css defines its own hardcoded variables:

    :root {
        --color-navy-primary: #1E3A5F;  /* HARDCODED */
        --color-navy-dark: #152942;
        --color-red-primary: #8B2332;
        --primary: var(--color-navy-primary);  /* Points to hardcoded */
    }
    

  3. Components use hardcoded variables:

    .btn-primary {
        background-color: var(--color-navy-primary);  /* IGNORES theme */
    }
    

What's Working

Component Status Location
Settings UI - Appearance Tab /settings → Appearance tab
Color pickers (5 colors) Primary, Secondary, Accent, Text, Sidebar
Logo upload (5 slots) Full, Name, Cropped, Icon, Mobile
API endpoints GET/PUT /api/branding/
Database storage integration_setting table
Template injection --primary-color etc in layout.html

What's Broken

Issue Impact
CSS uses --color-navy-primary Theme colors don't apply to buttons
CSS uses --color-red-primary Secondary/accent colors don't apply
No mapping from --primary-color → components Visual customization broken

Files Involved

Configuration

  • src/api/config.py - Default color values
  • src/app/main.py - get_theme() function, template context

API

  • src/api/routes/branding.py - GET/PUT/POST/DELETE endpoints
  • src/api/models/branding.py - BrandingSettings, BrandingUpdate models

Frontend

  • src/app/templates/layout.html - Injects CSS variables (lines 25-31)
  • src/app/templates/settings/index.html - Appearance tab UI (line 510+)
  • src/app/static/css/styles.css - Uses hardcoded colors (line 3+)

Database

-- integration_setting table
-- integration='branding', setting_key='primary_color', setting_value='#0e173e'

Fix Required

Replace in styles.css:

/* FROM */
.btn-primary { background-color: var(--color-navy-primary); }

/* TO */
.btn-primary { background-color: var(--primary-color); }

Option B: Override hardcoded variables in layout.html

Add to layout.html's <style> block:

:root {
    --color-navy-primary: var(--primary-color);
    --color-red-primary: var(--secondary-color);
}

Affected CSS Selectors (14 occurrences)

Line Selector Property
65 a color: var(--color-navy-primary)
218 .btn-primary background-color: var(--color-navy-primary)
228 .btn-outline-primary color: var(--color-navy-primary)
296 .form-input:focus border-color: var(--color-navy-primary)
305 .form-select:focus color: var(--color-navy-primary)
371 .sidebar-nav-item.active color: var(--color-navy-primary)
525-526 .stat-card border-left, color
768 .gradient-header background: linear-gradient(...)
802 .text-primary color: var(--color-navy-primary)
829 .hover:text-primary:hover color
920 .pagination .active color

Environment Variables (Defaults)

THEME_PRIMARY_COLOR=#0e173e
THEME_SECONDARY_COLOR=#f1c613
THEME_ACCENT_COLOR=#f1c613
THEME_TEXT_COLOR=#374151
THEME_SIDEBAR_COLOR=#f8fafc

Migration Path from cbtenant

The functionality was moved from ../cbtenant/ to this app. The backend/API implementation is complete. Only the CSS variable wiring is broken.

Recommendation

  1. Quick fix: Add CSS variable overrides in layout.html to map hardcoded vars to dynamic ones
  2. Proper fix: Update styles.css to use --primary-color etc directly
  3. Test: Verify changes in Settings → Appearance reflect in UI

Active Routes (Registered in cbtenant/api/main.py)

Route File Description Status
api/routes/theme.py AI theme analysis (Claude Vision) ACTIVE
api/routes/branding.py Logo upload for tenants ACTIVE

Theme Routes in cbtenant

  • POST /{tenant_id}/theme/analyze - Start AI analysis of website
  • GET /{tenant_id}/theme/analysis/{id} - Poll analysis status
  • POST /{tenant_id}/theme/apply - Apply suggested theme
  • PUT /{tenant_id}/theme - Manual theme update
  • GET /{tenant_id}/theme/suggestions - Get AI suggestions

Supporting Files

  • api/tasks/analyze_theme.py - Background task using Claude Vision
  • api/models/theme_schemas.py - Pydantic models
  • db/models.py - AIAnalysis, ThemeSuggestion, TenantTheme tables
  • agents/ - WebsiteAnalyzer for screenshots + Claude analysis

Frontend (cbtenant/frontend/main.py)

  • Theme tab in tenant settings (lines 322-347)
  • API proxy handlers for analyze/status/apply (lines 527-571)

Cleanup Needed

The cbtenant theme/branding functionality should be: 1. Disabled or removed from registration in api/main.py 2. Frontend theme tab hidden or removed 3. AI analysis could potentially be migrated to cbapp as future enhancement

The AI-directed feature extracts colors from campaign website screenshots using Claude Vision and generates theme suggestions. This was never migrated to cbapp.