From 645119c9b783fd3c7c0529471cfd7f21fd89159f Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Tue, 31 Mar 2026 22:09:07 -0400 Subject: [PATCH] fix: theme-aware CSS with dark mode support Replace all hardcoded colours with CSS custom properties. Dark mode overrides via html.o_dark / body.o_dark / [color-scheme: dark] selectors matching Odoo 19's theme system. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../static/src/css/woo_styles.css | 230 +++++++++++++----- 1 file changed, 168 insertions(+), 62 deletions(-) diff --git a/fusion-woo-odoo/fusion_woocommerce/static/src/css/woo_styles.css b/fusion-woo-odoo/fusion_woocommerce/static/src/css/woo_styles.css index 454aba45..0b8e09aa 100644 --- a/fusion-woo-odoo/fusion_woocommerce/static/src/css/woo_styles.css +++ b/fusion-woo-odoo/fusion_woocommerce/static/src/css/woo_styles.css @@ -1,7 +1,91 @@ /* ============================================================ - Fusion WooCommerce — Custom Styles + Fusion WooCommerce — Theme-Aware Styles + Uses Odoo's CSS custom properties for dark/light mode support. + Odoo 19 sets color_scheme cookie to "dark" or "bright" and + applies .o_dark on the body or uses Bootstrap variables. ============================================================ */ +/* ---------------------------------------------------------- + CSS Custom Properties — light defaults, dark overrides + ---------------------------------------------------------- */ +:root { + --woo-bg-primary: #ffffff; + --woo-bg-secondary: #f9fafb; + --woo-bg-tertiary: #f3f4f6; + --woo-bg-hover: #f3f4f6; + --woo-bg-selected: #ede9fe; + --woo-border: #e5e7eb; + --woo-border-light: #f3f4f6; + --woo-text-primary: #111827; + --woo-text-secondary: #374151; + --woo-text-muted: #6b7280; + --woo-text-faint: #9ca3af; + --woo-accent: #7c3aed; + --woo-accent-hover: #6d28d9; + --woo-accent-glow: rgba(124, 58, 237, 0.15); + --woo-success: #059669; + --woo-success-bg: #d1fae5; + --woo-success-text: #065f46; + --woo-warning: #d97706; + --woo-warning-bg: #fef3c7; + --woo-warning-text: #92400e; + --woo-danger: #dc2626; + --woo-danger-bg: #fee2e2; + --woo-danger-text: #991b1b; + --woo-info-bg: #dbeafe; + --woo-info-text: #1e40af; + --woo-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.06); + --woo-card-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.1); + --woo-progress-bg: #e5e7eb; + --woo-spinner-track: #e5e7eb; + --woo-btn-secondary-bg: #ffffff; + --woo-btn-secondary-border: #d1d5db; + --woo-btn-secondary-hover: #f3f4f6; + --woo-input-bg: #ffffff; + --woo-input-border: #d1d5db; +} + +/* Dark mode — Odoo 19 applies .o_dark on html or body, + and also uses [style*="color-scheme: dark"] on html */ +html.o_dark, +html[style*="color-scheme: dark"], +body.o_dark { + --woo-bg-primary: #1e1e2e; + --woo-bg-secondary: #262637; + --woo-bg-tertiary: #2e2e42; + --woo-bg-hover: #33334a; + --woo-bg-selected: #3b2d6b; + --woo-border: #3c3c54; + --woo-border-light: #33334a; + --woo-text-primary: #e4e4e7; + --woo-text-secondary: #c4c4cc; + --woo-text-muted: #9ca3af; + --woo-text-faint: #6b7280; + --woo-accent: #a78bfa; + --woo-accent-hover: #8b5cf6; + --woo-accent-glow: rgba(167, 139, 250, 0.2); + --woo-success: #34d399; + --woo-success-bg: #064e3b; + --woo-success-text: #6ee7b7; + --woo-warning: #fbbf24; + --woo-warning-bg: #451a03; + --woo-warning-text: #fcd34d; + --woo-danger: #f87171; + --woo-danger-bg: #450a0a; + --woo-danger-text: #fca5a5; + --woo-info-bg: #1e3a5f; + --woo-info-text: #93c5fd; + --woo-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + --woo-card-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.4); + --woo-progress-bg: #3c3c54; + --woo-spinner-track: #3c3c54; + --woo-btn-secondary-bg: #2e2e42; + --woo-btn-secondary-border: #3c3c54; + --woo-btn-secondary-hover: #33334a; + --woo-input-bg: #2e2e42; + --woo-input-border: #3c3c54; +} + /* ---------------------------------------------------------- Status badges ---------------------------------------------------------- */ @@ -13,12 +97,22 @@ font-weight: 600; letter-spacing: 0.02em; } -.woo-badge-mapped { background: #d1fae5; color: #065f46; } -.woo-badge-unmapped { background: #f3f4f6; color: #4b5563; } -.woo-badge-conflict { background: #fef3c7; color: #92400e; } -.woo-badge-error { background: #fee2e2; color: #991b1b; } -.woo-badge-success { background: #d1fae5; color: #065f46; } -.woo-badge-failed { background: #fee2e2; color: #991b1b; } +.woo-badge-mapped, .woo-badge-success { + background: var(--woo-success-bg); + color: var(--woo-success-text); +} +.woo-badge-unmapped { + background: var(--woo-bg-tertiary); + color: var(--woo-text-muted); +} +.woo-badge-conflict { + background: var(--woo-warning-bg); + color: var(--woo-warning-text); +} +.woo-badge-error, .woo-badge-failed { + background: var(--woo-danger-bg); + color: var(--woo-danger-text); +} /* ---------------------------------------------------------- Tab navigation @@ -26,14 +120,14 @@ .woo-tabs { display: flex; gap: 4px; - border-bottom: 2px solid #e5e7eb; + border-bottom: 2px solid var(--woo-border); margin-bottom: 16px; } .woo-tab { padding: 8px 20px; cursor: pointer; font-weight: 500; - color: #6b7280; + color: var(--woo-text-muted); border-bottom: 2px solid transparent; margin-bottom: -2px; background: none; @@ -42,10 +136,10 @@ border-right: none; transition: color 0.15s, border-color 0.15s; } -.woo-tab:hover { color: #374151; } +.woo-tab:hover { color: var(--woo-text-secondary); } .woo-tab.active { - color: #7c3aed; - border-bottom-color: #7c3aed; + color: var(--woo-accent); + border-bottom-color: var(--woo-accent); } /* ---------------------------------------------------------- @@ -56,32 +150,34 @@ align-items: center; gap: 12px; padding: 12px 16px; - background: #f9fafb; - border-bottom: 1px solid #e5e7eb; + background: var(--woo-bg-secondary); + border-bottom: 1px solid var(--woo-border); flex-wrap: wrap; } .woo-topbar select, .woo-topbar input { - border: 1px solid #d1d5db; + border: 1px solid var(--woo-input-border); border-radius: 6px; padding: 6px 10px; font-size: 0.875rem; + background: var(--woo-input-bg); + color: var(--woo-text-primary); } .woo-stat { display: flex; flex-direction: column; align-items: center; padding: 4px 14px; - border-left: 1px solid #e5e7eb; + border-left: 1px solid var(--woo-border); } .woo-stat-value { font-size: 1.25rem; font-weight: 700; - color: #111827; + color: var(--woo-text-primary); } .woo-stat-label { font-size: 0.7rem; - color: #6b7280; + color: var(--woo-text-muted); text-transform: uppercase; letter-spacing: 0.04em; } @@ -97,22 +193,27 @@ .woo-search-wrap .woo-search-icon { position: absolute; left: 10px; - color: #9ca3af; + color: var(--woo-text-faint); font-size: 14px; pointer-events: none; } .woo-search-input { padding: 6px 10px 6px 32px; - border: 1px solid #d1d5db; + border: 1px solid var(--woo-input-border); border-radius: 6px; font-size: 0.875rem; width: 240px; + background: var(--woo-input-bg); + color: var(--woo-text-primary); transition: border-color 0.15s; } .woo-search-input:focus { outline: none; - border-color: #7c3aed; - box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.15); + border-color: var(--woo-accent); + box-shadow: 0 0 0 2px var(--woo-accent-glow); +} +.woo-search-input::placeholder { + color: var(--woo-text-faint); } /* ---------------------------------------------------------- @@ -127,22 +228,22 @@ font-size: 0.875rem; } .woo-table th { - background: #f3f4f6; + background: var(--woo-bg-tertiary); padding: 10px 12px; text-align: left; font-weight: 600; - color: #374151; - border-bottom: 2px solid #e5e7eb; + color: var(--woo-text-secondary); + border-bottom: 2px solid var(--woo-border); white-space: nowrap; } .woo-table td { padding: 9px 12px; - border-bottom: 1px solid #f3f4f6; - color: #374151; + border-bottom: 1px solid var(--woo-border-light); + color: var(--woo-text-secondary); vertical-align: middle; } -.woo-table tr:hover td { background: #f9fafb; } -.woo-table tr.selected td { background: #ede9fe; } +.woo-table tr:hover td { background: var(--woo-bg-hover); } +.woo-table tr.selected td { background: var(--woo-bg-selected); } /* ---------------------------------------------------------- Split view (unmatched tab) @@ -154,16 +255,17 @@ align-items: start; } .woo-split-panel { - border: 1px solid #e5e7eb; + border: 1px solid var(--woo-border); border-radius: 8px; overflow: hidden; + background: var(--woo-bg-primary); } .woo-split-panel-header { - background: #f3f4f6; + background: var(--woo-bg-tertiary); padding: 10px 14px; font-weight: 600; - color: #374151; - border-bottom: 1px solid #e5e7eb; + color: var(--woo-text-secondary); + border-bottom: 1px solid var(--woo-border); display: flex; justify-content: space-between; align-items: center; @@ -175,7 +277,7 @@ justify-content: center; padding-top: 60px; gap: 8px; - color: #9ca3af; + color: var(--woo-text-faint); font-size: 1.2rem; } .woo-split-list { @@ -185,13 +287,13 @@ .woo-split-item { padding: 10px 14px; cursor: pointer; - border-bottom: 1px solid #f3f4f6; + border-bottom: 1px solid var(--woo-border-light); transition: background 0.1s; } -.woo-split-item:hover { background: #f9fafb; } -.woo-split-item.selected { background: #ede9fe; } -.woo-split-item-name { font-weight: 500; color: #111827; } -.woo-split-item-sub { font-size: 0.75rem; color: #6b7280; margin-top: 1px; } +.woo-split-item:hover { background: var(--woo-bg-hover); } +.woo-split-item.selected { background: var(--woo-bg-selected); } +.woo-split-item-name { font-weight: 500; color: var(--woo-text-primary); } +.woo-split-item-sub { font-size: 0.75rem; color: var(--woo-text-muted); margin-top: 1px; } /* ---------------------------------------------------------- Map actions bar @@ -215,16 +317,20 @@ border: 1px solid transparent; transition: background 0.15s, border-color 0.15s; } -.woo-btn-primary { background: #7c3aed; color: #fff; border-color: #7c3aed; } -.woo-btn-primary:hover { background: #6d28d9; } -.woo-btn-success { background: #059669; color: #fff; border-color: #059669; } +.woo-btn-primary { background: var(--woo-accent); color: #fff; border-color: var(--woo-accent); } +.woo-btn-primary:hover { background: var(--woo-accent-hover); } +.woo-btn-success { background: var(--woo-success); color: #fff; border-color: var(--woo-success); } .woo-btn-success:hover { background: #047857; } -.woo-btn-warning { background: #d97706; color: #fff; border-color: #d97706; } +.woo-btn-warning { background: var(--woo-warning); color: #fff; border-color: var(--woo-warning); } .woo-btn-warning:hover { background: #b45309; } -.woo-btn-danger { background: #dc2626; color: #fff; border-color: #dc2626; } +.woo-btn-danger { background: var(--woo-danger); color: #fff; border-color: var(--woo-danger); } .woo-btn-danger:hover { background: #b91c1c; } -.woo-btn-secondary { background: #fff; color: #374151; border-color: #d1d5db; } -.woo-btn-secondary:hover { background: #f3f4f6; } +.woo-btn-secondary { + background: var(--woo-btn-secondary-bg); + color: var(--woo-text-secondary); + border-color: var(--woo-btn-secondary-border); +} +.woo-btn-secondary:hover { background: var(--woo-btn-secondary-hover); } .woo-btn-sm { padding: 3px 10px; font-size: 0.8rem; } .woo-btn:disabled { opacity: 0.5; cursor: not-allowed; } @@ -237,12 +343,12 @@ .woo-dashboard-title { font-size: 1.4rem; font-weight: 700; - color: #111827; + color: var(--woo-text-primary); margin-bottom: 4px; } .woo-dashboard-subtitle { font-size: 0.875rem; - color: #6b7280; + color: var(--woo-text-muted); margin-bottom: 24px; } .woo-cards { @@ -252,17 +358,17 @@ margin-bottom: 24px; } .woo-card { - background: #fff; - border: 1px solid #e5e7eb; + background: var(--woo-bg-primary); + border: 1px solid var(--woo-border); border-radius: 10px; padding: 20px; display: flex; flex-direction: column; gap: 6px; - box-shadow: 0 1px 3px rgba(0,0,0,0.06); + box-shadow: var(--woo-card-shadow); transition: box-shadow 0.15s; } -.woo-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); } +.woo-card:hover { box-shadow: var(--woo-card-shadow-hover); } .woo-card-clickable { cursor: pointer; } .woo-card-icon { font-size: 1.6rem; @@ -271,18 +377,18 @@ .woo-card-value { font-size: 2rem; font-weight: 700; - color: #111827; + color: var(--woo-text-primary); line-height: 1; } .woo-card-label { font-size: 0.8rem; - color: #6b7280; + color: var(--woo-text-muted); text-transform: uppercase; letter-spacing: 0.04em; } .woo-card-sub { font-size: 0.78rem; - color: #9ca3af; + color: var(--woo-text-faint); margin-top: 2px; } .woo-card-pending { border-left: 4px solid #f59e0b; } @@ -294,7 +400,7 @@ Progress bar ---------------------------------------------------------- */ .woo-progress-wrap { - background: #e5e7eb; + background: var(--woo-progress-bg); border-radius: 6px; height: 8px; overflow: hidden; @@ -315,15 +421,15 @@ align-items: center; justify-content: center; padding: 40px; - color: #6b7280; + color: var(--woo-text-muted); gap: 10px; font-size: 0.9rem; } .woo-spinner { width: 20px; height: 20px; - border: 2px solid #e5e7eb; - border-top-color: #7c3aed; + border: 2px solid var(--woo-spinner-track); + border-top-color: var(--woo-accent); border-radius: 50%; animation: woo-spin 0.7s linear infinite; } @@ -335,7 +441,7 @@ .woo-empty { text-align: center; padding: 48px 20px; - color: #9ca3af; + color: var(--woo-text-faint); } .woo-empty-icon { font-size: 2.5rem; margin-bottom: 10px; } .woo-empty-text { font-size: 0.9rem; } @@ -356,10 +462,10 @@ .woo-section-title { font-size: 1rem; font-weight: 600; - color: #374151; + color: var(--woo-text-secondary); margin-bottom: 12px; padding-bottom: 8px; - border-bottom: 1px solid #f3f4f6; + border-bottom: 1px solid var(--woo-border-light); } /* ----------------------------------------------------------