From 1324370ed183a8a200af39f78855486d685bb85e Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Feb 2026 10:40:17 +0000
Subject: [PATCH 1/6] Initial plan
--
2.49.1
From 2d588afa3fef4d5edbfc828c3ff0dc64d4607360 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Feb 2026 10:43:19 +0000
Subject: [PATCH 2/6] Add custom color parameters to template backend
Co-authored-by: jmiller-moko <230051081+jmiller-moko@users.noreply.github.com>
---
src/language/en-GB/tpl_mokocassiopeia.ini | 45 ++++++++++++++++++
src/language/en-US/tpl_mokocassiopeia.ini | 45 ++++++++++++++++++
src/templates/index.php | 58 +++++++++++++++++++++++
src/templates/templateDetails.xml | 45 ++++++++++++++++++
4 files changed, 193 insertions(+)
diff --git a/src/language/en-GB/tpl_mokocassiopeia.ini b/src/language/en-GB/tpl_mokocassiopeia.ini
index 0eb9c00..a323293 100644
--- a/src/language/en-GB/tpl_mokocassiopeia.ini
+++ b/src/language/en-GB/tpl_mokocassiopeia.ini
@@ -111,6 +111,51 @@ TPL_MOKO_THEME_FAB_ENABLED_DESC="Display a persistent, accessible theme toggle."
TPL_MOKO_THEME_FAB_POS="Floating switch position"
TPL_MOKO_THEME_FAB_POS_DESC="Screen corner for the toggle."
+; ===== Custom colour parameters =====
+TPL_MOKOCASSIOPEIA_CUSTOM_COLORS_LIGHT_LABEL="Custom Colours - Light Mode"
+TPL_MOKOCASSIOPEIA_CUSTOM_COLORS_DARK_LABEL="Custom Colours - Dark Mode"
+TPL_MOKOCASSIOPEIA_CUSTOM_COLORS_DESC="Override CSS colour variables with custom values below. Leave blank to use theme defaults. These settings override values from colour palette files. Changes apply immediately when you save the template."
+
+; Light mode colour fields
+TPL_MOKOCASSIOPEIA_LIGHT_COLOR_PRIMARY_LABEL="Brand Primary Colour"
+TPL_MOKOCASSIOPEIA_LIGHT_COLOR_PRIMARY_DESC="Main brand colour used throughout the template (CSS variable: --color-primary)"
+TPL_MOKOCASSIOPEIA_LIGHT_ACCENT_PRIMARY_LABEL="Accent Primary Colour"
+TPL_MOKOCASSIOPEIA_LIGHT_ACCENT_PRIMARY_DESC="Primary accent colour for highlights and interactive elements (CSS variable: --accent-color-primary)"
+TPL_MOKOCASSIOPEIA_LIGHT_NAV_BG_LABEL="Navigation Background"
+TPL_MOKOCASSIOPEIA_LIGHT_NAV_BG_DESC="Background colour for the main navigation menu (CSS variable: --nav-bg-color)"
+TPL_MOKOCASSIOPEIA_LIGHT_NAV_LINK_LABEL="Navigation Link Colour"
+TPL_MOKOCASSIOPEIA_LIGHT_NAV_LINK_DESC="Text colour for navigation links (CSS variable: --mainmenu-nav-link-color)"
+TPL_MOKOCASSIOPEIA_LIGHT_BODY_BG_LABEL="Body Background"
+TPL_MOKOCASSIOPEIA_LIGHT_BODY_BG_DESC="Main page background colour (CSS variable: --body-bg)"
+TPL_MOKOCASSIOPEIA_LIGHT_BODY_COLOR_LABEL="Body Text Colour"
+TPL_MOKOCASSIOPEIA_LIGHT_BODY_COLOR_DESC="Default text colour for body content (CSS variable: --body-color)"
+TPL_MOKOCASSIOPEIA_LIGHT_LINK_COLOR_LABEL="Link Colour"
+TPL_MOKOCASSIOPEIA_LIGHT_LINK_COLOR_DESC="Colour for regular hyperlinks (CSS variable: --link-color)"
+TPL_MOKOCASSIOPEIA_LIGHT_LINK_HOVER_LABEL="Link Hover Colour"
+TPL_MOKOCASSIOPEIA_LIGHT_LINK_HOVER_DESC="Colour for hyperlinks on hover (CSS variable: --link-hover-color)"
+TPL_MOKOCASSIOPEIA_LIGHT_BS_PRIMARY_LABEL="Bootstrap Primary Colour"
+TPL_MOKOCASSIOPEIA_LIGHT_BS_PRIMARY_DESC="Bootstrap primary colour for buttons, alerts, and components (CSS variable: --primary)"
+
+; Dark mode colour fields
+TPL_MOKOCASSIOPEIA_DARK_COLOR_PRIMARY_LABEL="Brand Primary Colour"
+TPL_MOKOCASSIOPEIA_DARK_COLOR_PRIMARY_DESC="Main brand colour used throughout the template (CSS variable: --color-primary)"
+TPL_MOKOCASSIOPEIA_DARK_ACCENT_PRIMARY_LABEL="Accent Primary Colour"
+TPL_MOKOCASSIOPEIA_DARK_ACCENT_PRIMARY_DESC="Primary accent colour for highlights and interactive elements (CSS variable: --accent-color-primary)"
+TPL_MOKOCASSIOPEIA_DARK_NAV_BG_LABEL="Navigation Background"
+TPL_MOKOCASSIOPEIA_DARK_NAV_BG_DESC="Background colour for the main navigation menu (CSS variable: --nav-bg-color)"
+TPL_MOKOCASSIOPEIA_DARK_NAV_LINK_LABEL="Navigation Link Colour"
+TPL_MOKOCASSIOPEIA_DARK_NAV_LINK_DESC="Text colour for navigation links (CSS variable: --mainmenu-nav-link-color)"
+TPL_MOKOCASSIOPEIA_DARK_BODY_BG_LABEL="Body Background"
+TPL_MOKOCASSIOPEIA_DARK_BODY_BG_DESC="Main page background colour (CSS variable: --body-bg)"
+TPL_MOKOCASSIOPEIA_DARK_BODY_COLOR_LABEL="Body Text Colour"
+TPL_MOKOCASSIOPEIA_DARK_BODY_COLOR_DESC="Default text colour for body content (CSS variable: --body-color)"
+TPL_MOKOCASSIOPEIA_DARK_LINK_COLOR_LABEL="Link Colour"
+TPL_MOKOCASSIOPEIA_DARK_LINK_COLOR_DESC="Colour for regular hyperlinks (CSS variable: --link-color)"
+TPL_MOKOCASSIOPEIA_DARK_LINK_HOVER_LABEL="Link Hover Colour"
+TPL_MOKOCASSIOPEIA_DARK_LINK_HOVER_DESC="Colour for hyperlinks on hover (CSS variable: --link-hover-color)"
+TPL_MOKOCASSIOPEIA_DARK_BS_PRIMARY_LABEL="Bootstrap Primary Colour"
+TPL_MOKOCASSIOPEIA_DARK_BS_PRIMARY_DESC="Bootstrap primary colour for buttons, alerts, and components (CSS variable: --primary)"
+
; ===== Misc =====
MOD_BREADCRUMBS_HERE="YOU ARE HERE:"
diff --git a/src/language/en-US/tpl_mokocassiopeia.ini b/src/language/en-US/tpl_mokocassiopeia.ini
index 4c12993..01a3bdb 100644
--- a/src/language/en-US/tpl_mokocassiopeia.ini
+++ b/src/language/en-US/tpl_mokocassiopeia.ini
@@ -111,6 +111,51 @@ TPL_MOKO_THEME_FAB_ENABLED_DESC="Display a persistent, accessible theme toggle."
TPL_MOKO_THEME_FAB_POS="Floating switch position"
TPL_MOKO_THEME_FAB_POS_DESC="Screen corner for the toggle."
+; ===== Custom color parameters =====
+TPL_MOKOCASSIOPEIA_CUSTOM_COLORS_LIGHT_LABEL="Custom Colors - Light Mode"
+TPL_MOKOCASSIOPEIA_CUSTOM_COLORS_DARK_LABEL="Custom Colors - Dark Mode"
+TPL_MOKOCASSIOPEIA_CUSTOM_COLORS_DESC="Override CSS color variables with custom values below. Leave blank to use theme defaults. These settings override values from color palette files. Changes apply immediately when you save the template."
+
+; Light mode color fields
+TPL_MOKOCASSIOPEIA_LIGHT_COLOR_PRIMARY_LABEL="Brand Primary Color"
+TPL_MOKOCASSIOPEIA_LIGHT_COLOR_PRIMARY_DESC="Main brand color used throughout the template (CSS variable: --color-primary)"
+TPL_MOKOCASSIOPEIA_LIGHT_ACCENT_PRIMARY_LABEL="Accent Primary Color"
+TPL_MOKOCASSIOPEIA_LIGHT_ACCENT_PRIMARY_DESC="Primary accent color for highlights and interactive elements (CSS variable: --accent-color-primary)"
+TPL_MOKOCASSIOPEIA_LIGHT_NAV_BG_LABEL="Navigation Background"
+TPL_MOKOCASSIOPEIA_LIGHT_NAV_BG_DESC="Background color for the main navigation menu (CSS variable: --nav-bg-color)"
+TPL_MOKOCASSIOPEIA_LIGHT_NAV_LINK_LABEL="Navigation Link Color"
+TPL_MOKOCASSIOPEIA_LIGHT_NAV_LINK_DESC="Text color for navigation links (CSS variable: --mainmenu-nav-link-color)"
+TPL_MOKOCASSIOPEIA_LIGHT_BODY_BG_LABEL="Body Background"
+TPL_MOKOCASSIOPEIA_LIGHT_BODY_BG_DESC="Main page background color (CSS variable: --body-bg)"
+TPL_MOKOCASSIOPEIA_LIGHT_BODY_COLOR_LABEL="Body Text Color"
+TPL_MOKOCASSIOPEIA_LIGHT_BODY_COLOR_DESC="Default text color for body content (CSS variable: --body-color)"
+TPL_MOKOCASSIOPEIA_LIGHT_LINK_COLOR_LABEL="Link Color"
+TPL_MOKOCASSIOPEIA_LIGHT_LINK_COLOR_DESC="Color for regular hyperlinks (CSS variable: --link-color)"
+TPL_MOKOCASSIOPEIA_LIGHT_LINK_HOVER_LABEL="Link Hover Color"
+TPL_MOKOCASSIOPEIA_LIGHT_LINK_HOVER_DESC="Color for hyperlinks on hover (CSS variable: --link-hover-color)"
+TPL_MOKOCASSIOPEIA_LIGHT_BS_PRIMARY_LABEL="Bootstrap Primary Color"
+TPL_MOKOCASSIOPEIA_LIGHT_BS_PRIMARY_DESC="Bootstrap primary color for buttons, alerts, and components (CSS variable: --primary)"
+
+; Dark mode color fields
+TPL_MOKOCASSIOPEIA_DARK_COLOR_PRIMARY_LABEL="Brand Primary Color"
+TPL_MOKOCASSIOPEIA_DARK_COLOR_PRIMARY_DESC="Main brand color used throughout the template (CSS variable: --color-primary)"
+TPL_MOKOCASSIOPEIA_DARK_ACCENT_PRIMARY_LABEL="Accent Primary Color"
+TPL_MOKOCASSIOPEIA_DARK_ACCENT_PRIMARY_DESC="Primary accent color for highlights and interactive elements (CSS variable: --accent-color-primary)"
+TPL_MOKOCASSIOPEIA_DARK_NAV_BG_LABEL="Navigation Background"
+TPL_MOKOCASSIOPEIA_DARK_NAV_BG_DESC="Background color for the main navigation menu (CSS variable: --nav-bg-color)"
+TPL_MOKOCASSIOPEIA_DARK_NAV_LINK_LABEL="Navigation Link Color"
+TPL_MOKOCASSIOPEIA_DARK_NAV_LINK_DESC="Text color for navigation links (CSS variable: --mainmenu-nav-link-color)"
+TPL_MOKOCASSIOPEIA_DARK_BODY_BG_LABEL="Body Background"
+TPL_MOKOCASSIOPEIA_DARK_BODY_BG_DESC="Main page background color (CSS variable: --body-bg)"
+TPL_MOKOCASSIOPEIA_DARK_BODY_COLOR_LABEL="Body Text Color"
+TPL_MOKOCASSIOPEIA_DARK_BODY_COLOR_DESC="Default text color for body content (CSS variable: --body-color)"
+TPL_MOKOCASSIOPEIA_DARK_LINK_COLOR_LABEL="Link Color"
+TPL_MOKOCASSIOPEIA_DARK_LINK_COLOR_DESC="Color for regular hyperlinks (CSS variable: --link-color)"
+TPL_MOKOCASSIOPEIA_DARK_LINK_HOVER_LABEL="Link Hover Color"
+TPL_MOKOCASSIOPEIA_DARK_LINK_HOVER_DESC="Color for hyperlinks on hover (CSS variable: --link-hover-color)"
+TPL_MOKOCASSIOPEIA_DARK_BS_PRIMARY_LABEL="Bootstrap Primary Color"
+TPL_MOKOCASSIOPEIA_DARK_BS_PRIMARY_DESC="Bootstrap primary color for buttons, alerts, and components (CSS variable: --primary)"
+
; ===== Misc =====
MOD_BREADCRUMBS_HERE="YOU ARE HERE:"
diff --git a/src/templates/index.php b/src/templates/index.php
index 795669a..0d68290 100644
--- a/src/templates/index.php
+++ b/src/templates/index.php
@@ -118,6 +118,64 @@ try {
$wa->registerAndUseStyle('template.dark.dynamic', $templatePath . '/css/colors/dark/' . $colorDarkKey . '.css');
}
+// Custom color parameters - generate inline CSS for color overrides
+$customColorCSS = '';
+
+// Light mode custom colors
+$lightColors = [
+ 'light_color_primary' => '--color-primary',
+ 'light_accent_primary' => '--accent-color-primary',
+ 'light_nav_bg' => '--nav-bg-color',
+ 'light_nav_link' => '--mainmenu-nav-link-color',
+ 'light_body_bg' => '--body-bg',
+ 'light_body_color' => '--body-color',
+ 'light_link_color' => '--link-color',
+ 'light_link_hover' => '--link-hover-color',
+ 'light_bootstrap_primary' => '--primary',
+];
+
+$lightOverrides = [];
+foreach ($lightColors as $param => $cssVar) {
+ $value = $this->params->get($param, '');
+ if (!empty($value)) {
+ $lightOverrides[] = $cssVar . ': ' . $value . ';';
+ }
+}
+
+if (!empty($lightOverrides)) {
+ $customColorCSS .= ":root[data-bs-theme='light'] {\n" . implode("\n", $lightOverrides) . "\n}\n";
+}
+
+// Dark mode custom colors
+$darkColors = [
+ 'dark_color_primary' => '--color-primary',
+ 'dark_accent_primary' => '--accent-color-primary',
+ 'dark_nav_bg' => '--nav-bg-color',
+ 'dark_nav_link' => '--mainmenu-nav-link-color',
+ 'dark_body_bg' => '--body-bg',
+ 'dark_body_color' => '--body-color',
+ 'dark_link_color' => '--link-color',
+ 'dark_link_hover' => '--link-hover-color',
+ 'dark_bootstrap_primary' => '--primary',
+];
+
+$darkOverrides = [];
+foreach ($darkColors as $param => $cssVar) {
+ $value = $this->params->get($param, '');
+ if (!empty($value)) {
+ $darkOverrides[] = $cssVar . ': ' . $value . ';';
+ }
+}
+
+if (!empty($darkOverrides)) {
+ $customColorCSS .= ":root[data-bs-theme='dark'] {\n" . implode("\n", $darkOverrides) . "\n}\n";
+}
+
+// Add custom color CSS to document if any overrides are defined
+if (!empty($customColorCSS)) {
+ $wa->addInlineStyle($customColorCSS);
+}
+
// Scripts
$wa->useScript('template.js');
diff --git a/src/templates/templateDetails.xml b/src/templates/templateDetails.xml
index 646857b..27ebbbf 100644
--- a/src/templates/templateDetails.xml
+++ b/src/templates/templateDetails.xml
@@ -198,6 +198,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--
2.49.1
From f4dcd69c923d7a01e4374fa848d7a9c239848e0f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Feb 2026 10:45:06 +0000
Subject: [PATCH 3/6] Add documentation for parameter-based color customization
Co-authored-by: jmiller-moko <230051081+jmiller-moko@users.noreply.github.com>
---
README.md | 18 +++++++++++++
docs/CLIENT_FORK_WORKFLOW.md | 52 ++++++++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+)
diff --git a/README.md b/README.md
index f7ae954..ffe99ac 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,7 @@ MokoCassiopeia is a modern, lightweight enhancement layer built on top of Joomla
- **Dark Mode Support**: Built-in light/dark mode toggle with system preference detection
- **Color Palettes**: Standard, Alternative, and Custom color schemes
+- **Parameter-Based Colors**: Edit key brand colors directly in template settings (no CSS files required)
- **Theme Persistence**: User preferences saved via localStorage
- **Theme Control Options**: Switch, radio buttons, or hidden controls
- **Auto Dark Mode**: Optional automatic dark mode based on time/system settings
@@ -69,6 +70,7 @@ MokoCassiopeia is a modern, lightweight enhancement layer built on top of Joomla
- **Font Options**: Local and web fonts (Roboto, Fira Sans, Noto Sans)
- **Sticky Header**: Optional sticky navigation
- **Back to Top**: Floating back-to-top button
+- **400+ CSS Variables**: Complete control over colors, spacing, and styling
### Analytics & Tracking
@@ -164,6 +166,22 @@ Access template configuration via **System → Site Templates → MokoCassiopeia
- **Light Mode Palette**: Standard, Alternative, or Custom
- **Dark Mode Palette**: Standard, Alternative, or Custom
+**Custom Colors - Light Mode:**
+- **Brand Primary Color**: Main brand color throughout the template
+- **Accent Primary Color**: Accent color for highlights and interactive elements
+- **Navigation Background**: Background color for the main navigation menu
+- **Navigation Link Color**: Text color for navigation links
+- **Body Background**: Main page background color
+- **Body Text Color**: Default text color for body content
+- **Link Color**: Color for regular hyperlinks
+- **Link Hover Color**: Color for hyperlinks on hover
+- **Bootstrap Primary Color**: Bootstrap primary color for buttons, alerts, and components
+
+**Custom Colors - Dark Mode:**
+- Same 9 color options as Light Mode, but optimized for dark backgrounds
+
+> **Note**: Custom color parameters override values from color palette CSS files. Leave fields blank to use palette defaults. Changes apply immediately when you save the template.
+
**Typography:**
- **Font Scheme**: Local (Roboto) or Web fonts (Fira Sans, Roboto+Noto Sans)
diff --git a/docs/CLIENT_FORK_WORKFLOW.md b/docs/CLIENT_FORK_WORKFLOW.md
index 131ceaf..beba3d3 100644
--- a/docs/CLIENT_FORK_WORKFLOW.md
+++ b/docs/CLIENT_FORK_WORKFLOW.md
@@ -195,6 +195,58 @@ After running the workflow or script, you should:
---
+## Color Customization Methods
+
+You now have **two ways** to customize colors for your client fork:
+
+### Method 1: Parameter-Based Customization (Recommended for Simple Branding)
+
+**Best for**: Quick brand color changes without editing CSS files
+
+1. Log into Joomla admin
+2. Navigate to System → Site Templates → MokoCassiopeia
+3. Click on the template name to edit
+4. Go to the "Theme" tab
+5. Scroll to "Custom Colours - Light Mode" and "Custom Colours - Dark Mode" sections
+6. Use the color pickers to set:
+ - Brand Primary Color
+ - Accent Primary Color
+ - Navigation Background & Link Color
+ - Body Background & Text Color
+ - Link & Link Hover Colors
+ - Bootstrap Primary Color
+7. Save the template
+
+**Advantages**:
+- ✅ No CSS files to edit
+- ✅ Visual color picker interface
+- ✅ Changes apply immediately
+- ✅ Easy to revert by clearing the fields
+- ✅ No file management required
+
+**Limitations**:
+- Only 9 essential colors per theme can be customized
+- For advanced customization, use Method 2
+
+### Method 2: CSS File Customization (Advanced)
+
+**Best for**: Complete control over all 400+ CSS variables
+
+1. Edit `src/media/css/colors/light/colors_custom.css`
+2. Edit `src/media/css/colors/dark/colors_custom.css`
+3. Update any of the 400+ CSS variables
+4. Commit and deploy the changes
+
+**Advantages**:
+- ✅ Complete control over all variables
+- ✅ Can customize spacing, borders, shadows, etc.
+- ✅ Supports complex color schemes
+- ✅ Version controlled with your fork
+
+**Note**: Parameter-based colors (Method 1) will override CSS file colors (Method 2) if both are set.
+
+---
+
## Troubleshooting
### Workflow Fails with "CONFIRM" Error
--
2.49.1
From b182beb66ddf6150e3312f481b1dbb174a23700e Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Feb 2026 10:46:43 +0000
Subject: [PATCH 4/6] Add color sanitization and refactor CSS generation
Co-authored-by: jmiller-moko <230051081+jmiller-moko@users.noreply.github.com>
---
src/templates/index.php | 89 +++++++++++++++++++++++++++++------------
1 file changed, 64 insertions(+), 25 deletions(-)
diff --git a/src/templates/index.php b/src/templates/index.php
index 0d68290..d270ae5 100644
--- a/src/templates/index.php
+++ b/src/templates/index.php
@@ -121,7 +121,67 @@ try {
// Custom color parameters - generate inline CSS for color overrides
$customColorCSS = '';
-// Light mode custom colors
+/**
+ * Helper function to sanitize color values for CSS
+ * Accepts hex, rgb, rgba, hsl, hsla, and named colors
+ * @param string $color The color value to sanitize
+ * @return string|null Sanitized color or null if invalid
+ */
+$sanitizeColor = function($color) {
+ $color = trim($color);
+ if (empty($color)) {
+ return null;
+ }
+
+ // Allow hex colors (#fff, #ffffff, #ffffffff)
+ if (preg_match('/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/', $color)) {
+ return strtolower($color);
+ }
+
+ // Allow rgb/rgba
+ if (preg_match('/^rgba?\s*\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}(\s*,\s*[\d.]+)?\s*\)$/i', $color)) {
+ return strtolower($color);
+ }
+
+ // Allow hsl/hsla
+ if (preg_match('/^hsla?\s*\(\s*\d{1,3}\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%(\s*,\s*[\d.]+)?\s*\)$/i', $color)) {
+ return strtolower($color);
+ }
+
+ // Allow named colors (common CSS color names)
+ $namedColors = ['transparent', 'black', 'white', 'red', 'green', 'blue', 'yellow', 'cyan', 'magenta',
+ 'gray', 'grey', 'silver', 'navy', 'teal', 'aqua', 'lime', 'olive', 'maroon', 'purple', 'fuchsia'];
+ if (in_array(strtolower($color), $namedColors, true)) {
+ return strtolower($color);
+ }
+
+ return null;
+};
+
+/**
+ * Helper function to generate CSS overrides for a theme
+ * @param array $colorMap Array mapping parameter names to CSS variables
+ * @param string $theme Theme name ('light' or 'dark')
+ * @return string CSS rules or empty string
+ */
+$generateThemeCSS = function($colorMap, $theme) use ($sanitizeColor) {
+ $overrides = [];
+ foreach ($colorMap as $param => $cssVar) {
+ $value = $this->params->get($param, '');
+ $sanitized = $sanitizeColor($value);
+ if ($sanitized !== null) {
+ $overrides[] = $cssVar . ': ' . $sanitized . ';';
+ }
+ }
+
+ if (!empty($overrides)) {
+ return ":root[data-bs-theme='" . $theme . "'] {\n" . implode("\n", $overrides) . "\n}\n";
+ }
+
+ return '';
+};
+
+// Define color mappings for light and dark modes
$lightColors = [
'light_color_primary' => '--color-primary',
'light_accent_primary' => '--accent-color-primary',
@@ -134,19 +194,6 @@ $lightColors = [
'light_bootstrap_primary' => '--primary',
];
-$lightOverrides = [];
-foreach ($lightColors as $param => $cssVar) {
- $value = $this->params->get($param, '');
- if (!empty($value)) {
- $lightOverrides[] = $cssVar . ': ' . $value . ';';
- }
-}
-
-if (!empty($lightOverrides)) {
- $customColorCSS .= ":root[data-bs-theme='light'] {\n" . implode("\n", $lightOverrides) . "\n}\n";
-}
-
-// Dark mode custom colors
$darkColors = [
'dark_color_primary' => '--color-primary',
'dark_accent_primary' => '--accent-color-primary',
@@ -159,17 +206,9 @@ $darkColors = [
'dark_bootstrap_primary' => '--primary',
];
-$darkOverrides = [];
-foreach ($darkColors as $param => $cssVar) {
- $value = $this->params->get($param, '');
- if (!empty($value)) {
- $darkOverrides[] = $cssVar . ': ' . $value . ';';
- }
-}
-
-if (!empty($darkOverrides)) {
- $customColorCSS .= ":root[data-bs-theme='dark'] {\n" . implode("\n", $darkOverrides) . "\n}\n";
-}
+// Generate CSS for both themes
+$customColorCSS .= $generateThemeCSS($lightColors, 'light');
+$customColorCSS .= $generateThemeCSS($darkColors, 'dark');
// Add custom color CSS to document if any overrides are defined
if (!empty($customColorCSS)) {
--
2.49.1
From d653134a5a7c98ebbda637c17d3be775090c456a Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Feb 2026 10:47:49 +0000
Subject: [PATCH 5/6] Improve CSS formatting with proper indentation
Co-authored-by: jmiller-moko <230051081+jmiller-moko@users.noreply.github.com>
---
src/templates/index.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/templates/index.php b/src/templates/index.php
index d270ae5..b655a9c 100644
--- a/src/templates/index.php
+++ b/src/templates/index.php
@@ -170,7 +170,7 @@ $generateThemeCSS = function($colorMap, $theme) use ($sanitizeColor) {
$value = $this->params->get($param, '');
$sanitized = $sanitizeColor($value);
if ($sanitized !== null) {
- $overrides[] = $cssVar . ': ' . $sanitized . ';';
+ $overrides[] = "\t" . $cssVar . ': ' . $sanitized . ';';
}
}
--
2.49.1
From 3b52647d01f182b57c8a0981d387d01632365c5d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Feb 2026 10:48:52 +0000
Subject: [PATCH 6/6] Expand named colors list and add documentation
Co-authored-by: jmiller-moko <230051081+jmiller-moko@users.noreply.github.com>
---
src/templates/index.php | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/templates/index.php b/src/templates/index.php
index b655a9c..a4152b8 100644
--- a/src/templates/index.php
+++ b/src/templates/index.php
@@ -124,8 +124,13 @@ $customColorCSS = '';
/**
* Helper function to sanitize color values for CSS
* Accepts hex, rgb, rgba, hsl, hsla, and named colors
+ *
+ * Note: This function validates format but not value ranges (e.g., RGB 0-255).
+ * CSS will automatically clamp out-of-range values, so strict range validation
+ * is not necessary for security purposes.
+ *
* @param string $color The color value to sanitize
- * @return string|null Sanitized color or null if invalid
+ * @return string|null Sanitized color or null if invalid format
*/
$sanitizeColor = function($color) {
$color = trim($color);
@@ -149,8 +154,12 @@ $sanitizeColor = function($color) {
}
// Allow named colors (common CSS color names)
- $namedColors = ['transparent', 'black', 'white', 'red', 'green', 'blue', 'yellow', 'cyan', 'magenta',
- 'gray', 'grey', 'silver', 'navy', 'teal', 'aqua', 'lime', 'olive', 'maroon', 'purple', 'fuchsia'];
+ $namedColors = [
+ 'transparent', 'black', 'white', 'red', 'green', 'blue', 'yellow', 'cyan', 'magenta',
+ 'gray', 'grey', 'silver', 'navy', 'teal', 'aqua', 'lime', 'olive', 'maroon', 'purple', 'fuchsia',
+ 'orange', 'pink', 'brown', 'gold', 'coral', 'crimson', 'indigo', 'violet', 'tan', 'khaki',
+ 'salmon', 'tomato', 'orchid', 'plum', 'lavender', 'ivory', 'beige', 'wheat', 'azure', 'snow'
+ ];
if (in_array(strtolower($color), $namedColors, true)) {
return strtolower($color);
}
--
2.49.1