Add RGB CSS variables for theme colors
Introduce --primary-rgb, --accent-rgb, --success-rgb and --warning-rgb and replace hardcoded rgba(...) usages in CSS with rgba(var(--*-rgb), alpha) to allow dynamic alpha blending from theme colors. Add a hexToRgb helper in setup.js and populate these RGB variables in applyThemeToSetupPage (handles 3- and 6-digit hex and validates input), so runtime theme changes can drive translucent shadows, backgrounds and highlights.
This commit is contained in:
+13
-9
@@ -12,14 +12,18 @@
|
|||||||
--dark-blue: #0B1C2B;
|
--dark-blue: #0B1C2B;
|
||||||
--dark-purple: #1B1035;
|
--dark-purple: #1B1035;
|
||||||
--primary: #7B2EFF;
|
--primary: #7B2EFF;
|
||||||
|
--primary-rgb: 123, 46, 255;
|
||||||
--accent: #00C6FF;
|
--accent: #00C6FF;
|
||||||
|
--accent-rgb: 0, 198, 255;
|
||||||
--text: #E0E0E0;
|
--text: #E0E0E0;
|
||||||
--text-secondary: #A0A0A0;
|
--text-secondary: #A0A0A0;
|
||||||
--card-bg: rgba(255, 255, 255, 0.05);
|
--card-bg: rgba(255, 255, 255, 0.05);
|
||||||
--card-hover: rgba(255, 255, 255, 0.08);
|
--card-hover: rgba(255, 255, 255, 0.08);
|
||||||
--border: rgba(255, 255, 255, 0.1);
|
--border: rgba(255, 255, 255, 0.1);
|
||||||
--success: #4CAF50;
|
--success: #4CAF50;
|
||||||
|
--success-rgb: 76, 175, 80;
|
||||||
--warning: #FF9800;
|
--warning: #FF9800;
|
||||||
|
--warning-rgb: 255, 152, 0;
|
||||||
--gradient-primary: linear-gradient(135deg, var(--accent), var(--primary));
|
--gradient-primary: linear-gradient(135deg, var(--accent), var(--primary));
|
||||||
--gradient-bg: linear-gradient(145deg, var(--bg) 0%, var(--dark-purple) 100%);
|
--gradient-bg: linear-gradient(145deg, var(--bg) 0%, var(--dark-purple) 100%);
|
||||||
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.2);
|
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||||
@@ -98,7 +102,7 @@ body, html {
|
|||||||
.progress-step.active .step-circle {
|
.progress-step.active .step-circle {
|
||||||
background: var(--primary);
|
background: var(--primary);
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
box-shadow: 0 4px 12px rgba(123, 46, 255, 0.4);
|
box-shadow: 0 4px 12px rgba(var(--primary-rgb), 0.4);
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +194,7 @@ body, html {
|
|||||||
.setup-logo {
|
.setup-logo {
|
||||||
width: 120px;
|
width: 120px;
|
||||||
height: 120px;
|
height: 120px;
|
||||||
filter: drop-shadow(0 8px 24px rgba(123, 46, 255, 0.3));
|
filter: drop-shadow(0 8px 24px rgba(var(--primary-rgb), 0.3));
|
||||||
animation: float 3s ease-in-out infinite;
|
animation: float 3s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,7 +277,7 @@ body, html {
|
|||||||
.theme-card.selected {
|
.theme-card.selected {
|
||||||
border-color: var(--primary);
|
border-color: var(--primary);
|
||||||
background: var(--card-hover);
|
background: var(--card-hover);
|
||||||
box-shadow: 0 0 0 3px rgba(123, 46, 255, 0.2);
|
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-card.selected::after {
|
.theme-card.selected::after {
|
||||||
@@ -383,7 +387,7 @@ body, html {
|
|||||||
|
|
||||||
.default-browser-status.is-default {
|
.default-browser-status.is-default {
|
||||||
border-color: var(--success);
|
border-color: var(--success);
|
||||||
background: rgba(76, 175, 80, 0.1);
|
background: rgba(var(--success-rgb), 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.default-browser-status.is-default .status-icon {
|
.default-browser-status.is-default .status-icon {
|
||||||
@@ -396,7 +400,7 @@ body, html {
|
|||||||
|
|
||||||
.default-browser-status.not-default {
|
.default-browser-status.not-default {
|
||||||
border-color: var(--warning);
|
border-color: var(--warning);
|
||||||
background: rgba(255, 152, 0, 0.1);
|
background: rgba(var(--warning-rgb), 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
@@ -430,7 +434,7 @@ body, html {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 4rem;
|
font-size: 4rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
box-shadow: 0 8px 32px rgba(123, 46, 255, 0.4);
|
box-shadow: 0 8px 32px rgba(var(--primary-rgb), 0.4);
|
||||||
animation: scaleIn 0.5s ease;
|
animation: scaleIn 0.5s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,7 +496,7 @@ body, html {
|
|||||||
|
|
||||||
/* Future Feature Teaser */
|
/* Future Feature Teaser */
|
||||||
.future-feature-teaser {
|
.future-feature-teaser {
|
||||||
background: linear-gradient(135deg, rgba(123, 46, 255, 0.1), rgba(0, 198, 255, 0.1));
|
background: linear-gradient(135deg, rgba(var(--primary-rgb), 0.1), rgba(var(--accent-rgb), 0.1));
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
@@ -554,12 +558,12 @@ body, html {
|
|||||||
.btn-primary {
|
.btn-primary {
|
||||||
background: var(--primary);
|
background: var(--primary);
|
||||||
color: white;
|
color: white;
|
||||||
box-shadow: 0 4px 12px rgba(123, 46, 255, 0.3);
|
box-shadow: 0 4px 12px rgba(var(--primary-rgb), 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary:hover {
|
.btn-primary:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 6px 20px rgba(123, 46, 255, 0.4);
|
box-shadow: 0 6px 20px rgba(var(--primary-rgb), 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary:active {
|
.btn-primary:active {
|
||||||
|
|||||||
@@ -121,6 +121,22 @@ function getThemeById(themeId) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hexToRgb(hex) {
|
||||||
|
if (!hex || typeof hex !== 'string') return null;
|
||||||
|
let normalized = hex.trim().replace(/^#/, '');
|
||||||
|
if (normalized.length === 3) {
|
||||||
|
normalized = normalized.split('').map(char => char + char).join('');
|
||||||
|
}
|
||||||
|
if (!/^[a-fA-F\d]{6}$/.test(normalized)) return null;
|
||||||
|
|
||||||
|
const intValue = parseInt(normalized, 16);
|
||||||
|
return {
|
||||||
|
r: (intValue >> 16) & 255,
|
||||||
|
g: (intValue >> 8) & 255,
|
||||||
|
b: intValue & 255
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply theme to the setup page UI and persist selection
|
* Apply theme to the setup page UI and persist selection
|
||||||
*/
|
*/
|
||||||
@@ -140,6 +156,25 @@ function applyThemeToSetupPage(theme, themeId = null) {
|
|||||||
setVar('--primary', colors.primary, '#7B2EFF');
|
setVar('--primary', colors.primary, '#7B2EFF');
|
||||||
setVar('--accent', colors.accent, '#00C6FF');
|
setVar('--accent', colors.accent, '#00C6FF');
|
||||||
setVar('--text', colors.text, '#E0E0E0');
|
setVar('--text', colors.text, '#E0E0E0');
|
||||||
|
setVar('--success', colors.accent, '#4CAF50');
|
||||||
|
setVar('--warning', colors.primary, '#FF9800');
|
||||||
|
|
||||||
|
const primaryRgb = hexToRgb(colors.primary || '#7B2EFF');
|
||||||
|
const accentRgb = hexToRgb(colors.accent || '#00C6FF');
|
||||||
|
const successRgb = hexToRgb(colors.accent || '#4CAF50');
|
||||||
|
const warningRgb = hexToRgb(colors.primary || '#FF9800');
|
||||||
|
if (primaryRgb) {
|
||||||
|
setVar('--primary-rgb', `${primaryRgb.r}, ${primaryRgb.g}, ${primaryRgb.b}`);
|
||||||
|
}
|
||||||
|
if (accentRgb) {
|
||||||
|
setVar('--accent-rgb', `${accentRgb.r}, ${accentRgb.g}, ${accentRgb.b}`);
|
||||||
|
}
|
||||||
|
if (successRgb) {
|
||||||
|
setVar('--success-rgb', `${successRgb.r}, ${successRgb.g}, ${successRgb.b}`);
|
||||||
|
}
|
||||||
|
if (warningRgb) {
|
||||||
|
setVar('--warning-rgb', `${warningRgb.r}, ${warningRgb.g}, ${warningRgb.b}`);
|
||||||
|
}
|
||||||
|
|
||||||
if (theme.gradient) {
|
if (theme.gradient) {
|
||||||
document.body.style.background = theme.gradient;
|
document.body.style.background = theme.gradient;
|
||||||
|
|||||||
Reference in New Issue
Block a user