From ca3e6525250e4384f3b83ec5f0b6dbc738ef70ba Mon Sep 17 00:00:00 2001
From: "gitea-actions[bot]"
Date: Sat, 18 Apr 2026 22:41:16 +0000
Subject: [PATCH 01/10] chore: update stable SHA-256 for 03.10.07 [skip ci]
---
updates.xml | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/updates.xml b/updates.xml
index 5ea39c5..1a2899b 100644
--- a/updates.xml
+++ b/updates.xml
@@ -19,7 +19,7 @@
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
- 78aebde056dcba369945c851fe1914d5bede9f2cbabb26e87b8d6379d155502d
+ 0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
development
Moko Consulting
https://mokoconsulting.tech
@@ -40,7 +40,7 @@
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
- 78aebde056dcba369945c851fe1914d5bede9f2cbabb26e87b8d6379d155502d
+ 0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
alpha
Moko Consulting
https://mokoconsulting.tech
@@ -61,7 +61,7 @@
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
- 78aebde056dcba369945c851fe1914d5bede9f2cbabb26e87b8d6379d155502d
+ 0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
beta
Moko Consulting
https://mokoconsulting.tech
@@ -83,7 +83,7 @@
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
- 78aebde056dcba369945c851fe1914d5bede9f2cbabb26e87b8d6379d155502d
+ 0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
rc
Moko Consulting
https://mokoconsulting.tech
@@ -105,7 +105,7 @@
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
- 78aebde056dcba369945c851fe1914d5bede9f2cbabb26e87b8d6379d155502d
+ 0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
stable
Moko Consulting
https://mokoconsulting.tech
From 7089761488dee2833faec944e97c7fd763dec9b2 Mon Sep 17 00:00:00 2001
From: Jonathan Miller
Date: Sat, 18 Apr 2026 17:51:44 -0500
Subject: [PATCH 02/10] Fix: updates.xml regex only matches target stability
block, restore correct SHAs
The Python regex now uses negative lookahead (?:(?!).)*? to
prevent matching across multiple blocks. All channels restored
with correct SHA (0f1cf23a...) matching the v03 stable ZIP.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.github/workflows/release.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 0b0d51d..381a8d9 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -314,9 +314,9 @@ jobs:
with open("updates.xml", "r") as f:
content = f.read()
- # Build regex to find the block containing this stability tag
- # Match from to that contains xml_tag
- block_pattern = r"(.*?" + re.escape(xml_tag) + r".*?)"
+ # Build regex to find the specific block for this stability tag
+ # Use negative lookahead to avoid matching across multiple blocks
+ block_pattern = r"((?:(?!).)*?" + re.escape(xml_tag) + r".*?)"
match = re.search(block_pattern, content, re.DOTALL)
if not match:
From 2c2a826dcb4f06cc45c19ba964606aadf3c0adf3 Mon Sep 17 00:00:00 2001
From: Jonathan Miller
Date: Sun, 19 Apr 2026 00:48:23 -0500
Subject: [PATCH 03/10] Remove update.xml (stale), gitignore it. Bump 03.10.08
Only updates.xml is used by the Joomla update server.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.gitignore | 1 +
README.md | 4 ++--
src/joomla.asset.json | 2 +-
src/templateDetails.xml | 4 ++--
update.xml | 39 ---------------------------------------
updates.xml | 26 +++++++++++++-------------
6 files changed, 19 insertions(+), 57 deletions(-)
delete mode 100644 update.xml
diff --git a/.gitignore b/.gitignore
index 6580c5c..e227a3a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -203,3 +203,4 @@ src/media/css/theme/*.custom.css
src/media/css/theme/*.custom.min.css
src/templates/*.custom.css
templates/*.custom.css
+update.xml
diff --git a/README.md b/README.md
index 751566d..cb2eba5 100644
--- a/README.md
+++ b/README.md
@@ -9,13 +9,13 @@
INGROUP: MokoCassiopeia.Documentation
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia
FILE: ./README.md
- VERSION: 03.10.07
+ VERSION: 03.10.08
BRIEF: Documentation for MokoCassiopeia template
-->
# MokoCassiopeia → MokoOnyx
-> **This template is being renamed to MokoOnyx.** Version 03.10.07 is the bridge release that automatically migrates your settings. After updating, MokoOnyx will be your active template and MokoCassiopeia can be safely uninstalled.
+> **This template is being renamed to MokoOnyx.** Version 03.10.08 is the bridge release that automatically migrates your settings. After updating, MokoOnyx will be your active template and MokoCassiopeia can be safely uninstalled.
**A Modern, Lightweight Joomla Template Based on Cassiopeia**
diff --git a/src/joomla.asset.json b/src/joomla.asset.json
index ce39749..d6c434c 100644
--- a/src/joomla.asset.json
+++ b/src/joomla.asset.json
@@ -17,7 +17,7 @@
"defgroup": "Joomla.Template.Site",
"ingroup": "MokoCassiopeia.Template.Assets",
"path": "./media/templates/site/mokocassiopeia/joomla.asset.json",
- "version": "03.10.07",
+ "version": "03.10.08",
"brief": "Joomla asset registry for MokoCassiopeia"
}
},
diff --git a/src/templateDetails.xml b/src/templateDetails.xml
index 0854a12..40918ec 100644
--- a/src/templateDetails.xml
+++ b/src/templateDetails.xml
@@ -39,13 +39,13 @@
MokoCassiopeia
- 03.10.07
+ 03.10.08
script.php
2026-04-15
Jonathan Miller || Moko Consulting
hello@mokoconsulting.tech
(C)GNU General Public License Version 3 - 2026 Moko Consulting
-

MokoCassiopeia Template Description
MokoCassiopeia continues Joomla's tradition of space-themed default templates— building on the legacy of Solarflare (Joomla 1.0), Milkyway (Joomla 1.5), and Protostar (Joomla 3.0).
This template is a customized fork of the Cassiopeia template introduced in Joomla 4, preserving its modern, accessible, and mobile-first foundation while introducing new stylistic enhancements and structural refinements specifically tailored for use by Moko Consulting.
Custom Colour Themes
Starter palette files are included with the template. To create a custom colour scheme, copy templates/mokocassiopeia/templates/light.custom.css to media/templates/site/mokocassiopeia/css/theme/light.custom.css, or templates/mokocassiopeia/templates/dark.custom.css to media/templates/site/mokocassiopeia/css/theme/dark.custom.css. Customise the CSS variables to match your brand, then activate your palette in System → Site Templates → MokoCassiopeia → Theme tab by selecting "Custom" for the Light or Dark Mode Palette. A full variable reference is available in the CSS Variables tab in template options.
Custom CSS & JavaScript
For site-specific styles and scripts that should survive template updates, create the following files:
media/templates/site/mokocassiopeia/css/user.css — loaded on every page for custom CSS overrides. media/templates/site/mokocassiopeia/js/user.js — loaded on every page for custom JavaScript.
These files are gitignored and will not be overwritten by template updates.
Code Attribution
This template is based on the original Cassiopeia template developed by the Joomla! Project and released under the GNU General Public License.
Modifications and enhancements have been made by Moko Consulting in accordance with open-source licensing standards.
It includes integration with Bootstrap TOC, an open-source table of contents generator by A. Feld, licensed under the MIT License.
All third-party libraries and assets remain the property of their respective authors and are credited within their source files where applicable.
]]>
+
MokoCassiopeia Template Description
MokoCassiopeia continues Joomla's tradition of space-themed default templates— building on the legacy of Solarflare (Joomla 1.0), Milkyway (Joomla 1.5), and Protostar (Joomla 3.0).
This template is a customized fork of the Cassiopeia template introduced in Joomla 4, preserving its modern, accessible, and mobile-first foundation while introducing new stylistic enhancements and structural refinements specifically tailored for use by Moko Consulting.
Custom Colour Themes
Starter palette files are included with the template. To create a custom colour scheme, copy templates/mokocassiopeia/templates/light.custom.css to media/templates/site/mokocassiopeia/css/theme/light.custom.css, or templates/mokocassiopeia/templates/dark.custom.css to media/templates/site/mokocassiopeia/css/theme/dark.custom.css. Customise the CSS variables to match your brand, then activate your palette in System → Site Templates → MokoCassiopeia → Theme tab by selecting "Custom" for the Light or Dark Mode Palette. A full variable reference is available in the CSS Variables tab in template options.
Custom CSS & JavaScript
For site-specific styles and scripts that should survive template updates, create the following files:
media/templates/site/mokocassiopeia/css/user.css — loaded on every page for custom CSS overrides. media/templates/site/mokocassiopeia/js/user.js — loaded on every page for custom JavaScript.
These files are gitignored and will not be overwritten by template updates.
Code Attribution
This template is based on the original Cassiopeia template developed by the Joomla! Project and released under the GNU General Public License.
Modifications and enhancements have been made by Moko Consulting in accordance with open-source licensing standards.
It includes integration with Bootstrap TOC, an open-source table of contents generator by A. Feld, licensed under the MIT License.
All third-party libraries and assets remain the property of their respective authors and are credited within their source files where applicable.
]]>
1
component.php
diff --git a/update.xml b/update.xml
deleted file mode 100644
index 1d28ab5..0000000
--- a/update.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- {{EXTENSION_NAME}}
- MokoCassiopeia — Moko Consulting Joomla extension
- {{EXTENSION_ELEMENT}}
- {{EXTENSION_TYPE}}
- {{VERSION}}
-
-
- https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCassiopeia/releases/download/v{{VERSION}}/{{EXTENSION_ELEMENT}}.zip
-
-
- https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v{{VERSION}}/{{EXTENSION_ELEMENT}}.zip
-
-
-
- 8.1
-
-
\ No newline at end of file
diff --git a/updates.xml b/updates.xml
index 1a2899b..936b0ee 100644
--- a/updates.xml
+++ b/updates.xml
@@ -1,7 +1,7 @@
@@ -13,11 +13,11 @@
mokocassiopeia
template
site
- 03.10.07
+ 03.10.08
2026-04-18
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/development
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
+ https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
development
@@ -34,11 +34,11 @@
mokocassiopeia
template
site
- 03.10.07
+ 03.10.08
2026-04-18
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/alpha
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
+ https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
alpha
@@ -55,11 +55,11 @@
mokocassiopeia
template
site
- 03.10.07
+ 03.10.08
2026-04-18
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/beta
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
+ https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
beta
@@ -76,12 +76,12 @@
mokocassiopeia
template
site
- 03.10.07
+ 03.10.08
2026-04-18
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/release-candidate
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
- https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
+ https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
+ https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
rc
@@ -98,12 +98,12 @@
mokocassiopeia
template
site
- 03.10.07
+ 03.10.08
2026-04-18
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/v03
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
- https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.07.zip
+ https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
+ https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
stable
From 032468edf3b92135736264d736c23e89ea7452db Mon Sep 17 00:00:00 2001
From: "gitea-actions[bot]"
Date: Sun, 19 Apr 2026 05:49:05 +0000
Subject: [PATCH 04/10] chore: update stable SHA-256 for 03.10.08 [skip ci]
---
updates.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/updates.xml b/updates.xml
index 936b0ee..5d31db5 100644
--- a/updates.xml
+++ b/updates.xml
@@ -99,13 +99,13 @@
template
site
03.10.08
- 2026-04-18
+ 2026-04-19
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/v03
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
- 0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
+ 8fb029bc6918cbe0372cd9ee8717c9bfa3db10283e9b61b8b05f5fec34fbaae0
stable
Moko Consulting
https://mokoconsulting.tech
From b6bce894c2b6d857817cb0fba0befa8bc679a1be Mon Sep 17 00:00:00 2001
From: Jonathan Miller
Date: Sun, 19 Apr 2026 00:49:15 -0500
Subject: [PATCH 05/10] Remove .moko-standards from tracking, gitignore it
---
.gitignore | 1 +
.moko-standards | 20 --------------------
2 files changed, 1 insertion(+), 20 deletions(-)
delete mode 100644 .moko-standards
diff --git a/.gitignore b/.gitignore
index e227a3a..bfdf546 100644
--- a/.gitignore
+++ b/.gitignore
@@ -204,3 +204,4 @@ src/media/css/theme/*.custom.min.css
src/templates/*.custom.css
templates/*.custom.css
update.xml
+.moko-standards
diff --git a/.moko-standards b/.moko-standards
deleted file mode 100644
index bcac6b4..0000000
--- a/.moko-standards
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2026 Moko Consulting
-# SPDX-License-Identifier: GPL-3.0-or-later
-# FILE INFORMATION
-# DEFGROUP: MokoStandards.Templates.Config
-# INGROUP: MokoStandards.Templates
-# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
-# PATH: /templates/configs/moko-standards.yml
-# VERSION: 04.01.00
-# BRIEF: Governance attachment template — synced to .moko-standards in every governed repository
-# NOTE: Tokens replaced at sync time: mokoconsulting-tech, MokoCassiopeia, waas-component, 04.00.04
-#
-# This file is managed automatically by MokoStandards bulk sync.
-# Do not edit manually — changes will be overwritten on the next sync.
-# To update governance settings, open a PR in MokoStandards instead:
-# https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
-
-standards_source: "https://git.mokoconsulting.tech/MokoConsulting/MokoStandards"
-standards_version: "04.00.04"
-platform: "waas-component"
-governed_repo: "MokoConsulting/MokoCassiopeia"
From 481200dc0228adbd94c201238171ebd399250916 Mon Sep 17 00:00:00 2001
From: Jonathan Miller
Date: Sun, 19 Apr 2026 00:51:49 -0500
Subject: [PATCH 06/10] Fix SHA to match 03.10.08 ZIP
---
updates.xml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/updates.xml b/updates.xml
index 5d31db5..c03a313 100644
--- a/updates.xml
+++ b/updates.xml
@@ -19,7 +19,7 @@
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
- 0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
+ 8fb029bc6918cbe0372cd9ee8717c9bfa3db10283e9b61b8b05f5fec34fbaae0
development
Moko Consulting
https://mokoconsulting.tech
@@ -40,7 +40,7 @@
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
- 0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
+ 8fb029bc6918cbe0372cd9ee8717c9bfa3db10283e9b61b8b05f5fec34fbaae0
alpha
Moko Consulting
https://mokoconsulting.tech
@@ -61,7 +61,7 @@
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
- 0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
+ 8fb029bc6918cbe0372cd9ee8717c9bfa3db10283e9b61b8b05f5fec34fbaae0
beta
Moko Consulting
https://mokoconsulting.tech
@@ -83,7 +83,7 @@
https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
- 0f1cf23a3b26f06506a7e282cacf3d56803165002bdd909fe0c4373f3ae87b06
+ 8fb029bc6918cbe0372cd9ee8717c9bfa3db10283e9b61b8b05f5fec34fbaae0
rc
Moko Consulting
https://mokoconsulting.tech
From 5dfc5ea158cae5adfdc51b0f65d29072b6c0acad Mon Sep 17 00:00:00 2001
From: Jonathan Miller
Date: Sun, 19 Apr 2026 00:53:51 -0500
Subject: [PATCH 07/10] Fix: release workflow SHA sync to main with error
logging
- Remove duplicate TOKEN line
- API PUT: log HTTP response code and body on failure
- Log warning if file SHA lookup fails
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.github/workflows/release.yml | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 381a8d9..618405f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -378,7 +378,6 @@ jobs:
VERSION="${{ steps.meta.outputs.version }}"
CURRENT_BRANCH="${{ github.ref_name }}"
TOKEN="${{ secrets.GA_TOKEN }}"
- TOKEN="${{ secrets.GA_TOKEN }}"
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]"
@@ -402,10 +401,10 @@ jobs:
"${API}/contents/updates.xml?ref=main" | jq -r '.sha // empty')
if [ -n "$FILE_SHA" ]; then
- # Base64-encode the updates.xml content
+ # Base64-encode the updates.xml content from working tree (has updated SHA)
CONTENT=$(base64 -w0 updates.xml)
- curl -sf -X PUT -H "Authorization: token ${GA_TOKEN}" \
+ RESPONSE=$(curl -s -w "\n%{http_code}" -X PUT -H "Authorization: token ${GA_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/contents/updates.xml" \
-d "$(jq -n \
@@ -414,7 +413,16 @@ jobs:
--arg msg "chore: update ${STABILITY} channel to ${VERSION} on main [skip ci]" \
--arg branch "main" \
'{content: $content, sha: $sha, message: $msg, branch: $branch}'
- )" > /dev/null && echo "updates.xml synced to main via API" || echo "WARNING: failed to sync updates.xml to main"
+ )")
+ HTTP_CODE=$(echo "$RESPONSE" | tail -1)
+ if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "201" ]; then
+ echo "updates.xml synced to main via API (HTTP ${HTTP_CODE})"
+ else
+ echo "WARNING: failed to sync updates.xml to main (HTTP ${HTTP_CODE})"
+ echo "$RESPONSE" | head -5
+ fi
+ else
+ echo "WARNING: could not get file SHA for updates.xml on main"
fi
fi
From 6491c97a5065d07e48c6ccb8c44cfaf1cc7456de Mon Sep 17 00:00:00 2001
From: Jonathan Miller
Date: Sun, 19 Apr 2026 05:54:09 +0000
Subject: [PATCH 08/10] chore: update updates.xml from MokoStandards
---
updates.xml | 151 +++++++++++++---------------------------------------
1 file changed, 37 insertions(+), 114 deletions(-)
diff --git a/updates.xml b/updates.xml
index c03a313..f69d346 100644
--- a/updates.xml
+++ b/updates.xml
@@ -1,116 +1,39 @@
-
-
+
-
-
-
- MokoCassiopeia
- MokoCassiopeia development build — unstable.
- mokocassiopeia
- template
- site
- 03.10.08
- 2026-04-18
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/development
-
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
-
- 8fb029bc6918cbe0372cd9ee8717c9bfa3db10283e9b61b8b05f5fec34fbaae0
- development
- Moko Consulting
- https://mokoconsulting.tech
-
- 8.1
-
-
-
-
- MokoCassiopeia
- MokoCassiopeia alpha build — early testing.
- mokocassiopeia
- template
- site
- 03.10.08
- 2026-04-18
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/alpha
-
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
-
- 8fb029bc6918cbe0372cd9ee8717c9bfa3db10283e9b61b8b05f5fec34fbaae0
- alpha
- Moko Consulting
- https://mokoconsulting.tech
-
- 8.1
-
-
-
-
- MokoCassiopeia
- MokoCassiopeia beta build — feature complete, stability testing.
- mokocassiopeia
- template
- site
- 03.10.08
- 2026-04-18
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/beta
-
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
-
- 8fb029bc6918cbe0372cd9ee8717c9bfa3db10283e9b61b8b05f5fec34fbaae0
- beta
- Moko Consulting
- https://mokoconsulting.tech
-
- 8.1
-
-
-
-
- MokoCassiopeia
- MokoCassiopeia release candidate — testing only.
- mokocassiopeia
- template
- site
- 03.10.08
- 2026-04-18
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/release-candidate
-
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
- https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
-
- 8fb029bc6918cbe0372cd9ee8717c9bfa3db10283e9b61b8b05f5fec34fbaae0
- rc
- Moko Consulting
- https://mokoconsulting.tech
-
- 8.1
-
-
-
-
- MokoCassiopeia
- Moko Consulting's site template based on Cassiopeia.
- mokocassiopeia
- template
- site
- 03.10.08
- 2026-04-19
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/v03
-
- https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
- https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.10.08.zip
-
- 8fb029bc6918cbe0372cd9ee8717c9bfa3db10283e9b61b8b05f5fec34fbaae0
- stable
- Moko Consulting
- https://mokoconsulting.tech
-
- 8.1
-
-
-
+
+ {{EXTENSION_NAME}}
+ MokoCassiopeia — Moko Consulting Joomla extension
+ {{EXTENSION_ELEMENT}}
+ {{EXTENSION_TYPE}}
+ {{VERSION}}
+
+
+ https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCassiopeia/releases/download/v{{VERSION}}/{{EXTENSION_ELEMENT}}.zip
+
+
+ https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v{{VERSION}}/{{EXTENSION_ELEMENT}}.zip
+
+
+
+ 8.1
+
+
\ No newline at end of file
From 203eb96b6cc350ec5ecc8b5ac6493760c94ab53c Mon Sep 17 00:00:00 2001
From: Jonathan Miller
Date: Sun, 19 Apr 2026 13:12:46 -0500
Subject: [PATCH 09/10] Recreate custom palette starters from standard themes
src/templates/*.custom.css are starter templates users copy to create
custom palettes. Removed from gitignore (they ARE shipped files).
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.gitignore | 2 +-
src/templates/dark.custom.css | 1210 +++++++++++++++++++++++++++++++
src/templates/light.custom.css | 1219 ++++++++++++++++++++++++++++++++
3 files changed, 2430 insertions(+), 1 deletion(-)
create mode 100644 src/templates/dark.custom.css
create mode 100644 src/templates/light.custom.css
diff --git a/.gitignore b/.gitignore
index bfdf546..f62ed2d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -199,9 +199,9 @@ venv/
hypothesis/
# Custom theme palettes (site-specific, not version controlled)
+# Note: src/templates/*.custom.css are STARTER templates (tracked)
src/media/css/theme/*.custom.css
src/media/css/theme/*.custom.min.css
-src/templates/*.custom.css
templates/*.custom.css
update.xml
.moko-standards
diff --git a/src/templates/dark.custom.css b/src/templates/dark.custom.css
new file mode 100644
index 0000000..6c731b9
--- /dev/null
+++ b/src/templates/dark.custom.css
@@ -0,0 +1,1210 @@
+@charset "UTF-8";
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+/* -----------------------------------------------
+ * DARK THEME (CUSTOM)
+ * --------------------------------------------- */
+
+:root[data-bs-theme='dark']{
+color-scheme: dark;
+
+
+/* ===== BRAND & THEME COLORS ===== */
+--color-primary: #112855;
+--accent-color-primary: #3f8ff0;
+--accent-color-secondary: #6fb3ff;
+
+
+/* ===== TYPOGRAPHY & BODY ===== */
+--font-sans-serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+--body-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--body-font-size: 1rem;
+--body-font-weight: 400;
+--body-line-height: 1.5;
+--body-color: #e6ebf1;
+--body-color-rgb: 230, 235, 241;
+--body-bg: #0e1318;
+--body-bg-rgb: 14, 19, 24;
+--heading-color: #f1f5f9;
+--emphasis-color: #fff;
+--emphasis-color-rgb: 255, 255, 255;
+--secondary-color: #e6ebf1bf;
+--secondary-color-rgb: 230, 235, 241;
+--tertiary-color: #e6ebf180;
+--tertiary-color-rgb: 230, 235, 241;
+--muted-color: #6d757e;
+--code-color: black;
+--code-color-ink: var(--code-color, #e93f8e);
+--code-bg-color: lightgreen;
+--highlight-color: #111;
+--highlight-bg: #ffe28a1a;
+
+
+/* ===== STANDARD COLORS ===== */
+--blue: #91a4ff;
+--indigo: #b19cff;
+--purple: #c0a5ff;
+--pink: #ff8fc0;
+--red: #ff7a73;
+--orange: #ff9c4d;
+--yellow: #ffd166;
+--green: #78d694;
+--teal: #76e3ff;
+--cyan: #6fb7ff;
+--black: #000;
+--white: #fff;
+
+
+/* ===== GRAY SCALE ===== */
+--gray-100: #161a20;
+--gray-200: #1b2027;
+--gray-300: #222831;
+--gray-400: #2b323b;
+--gray-500: #36404a;
+--gray-600: #48525d;
+--gray-700: #5b6672;
+--gray-800: #cfd6de;
+--gray-900: #e6ebf1;
+--white-rgb: 255, 255, 255;
+--black-rgb: 0, 0, 0;
+
+
+/* ===== OPACITY UTILITIES ===== */
+--opacity-0: 0;
+--opacity-5: 0.05;
+--opacity-10: 0.1;
+--opacity-15: 0.15;
+--opacity-20: 0.2;
+--opacity-25: 0.25;
+--opacity-30: 0.3;
+--opacity-50: 0.5;
+--opacity-75: 0.75;
+--opacity-100: 1;
+
+
+/* ===== LAYOUT & SPACING ===== */
+--padding-x: 0.15rem;
+--padding-y: 0.15rem;
+--bg-opacity: 1;
+--nav-toggle-size: 3rem;
+--gradient: linear-gradient(180deg, #ffffff26, #fff0);
+--secondary-bg: #151b22;
+--secondary-bg-rgb: 21, 27, 34;
+--tertiary-bg: #10151b;
+--tertiary-bg-rgb: 16, 21, 27;
+--hr-color: var(--border-color, #dfe3e7);
+--border-color-soft: var(--border-color, #dfe3e7);
+--kbd-bg: var(--secondary-bg, #eaedf0);
+--kbd-ink: var(--body-bg, #fff);
+--toc-bg: var(--secondary-bg, #eaedf0);
+--toc-ink: var(--color-primary, #112855);
+--selection-bg: var(--highlight-bg, #fbeea8);
+--selection-ink: var(--body-color, #22262a);
+--border: 5px;
+
+
+/* ===== BREAKPOINTS ===== */
+--bp-xs: 0;
+--bp-sm: 576px;
+--bp-md: 768px;
+--bp-lg: 992px;
+--bp-xl: 1200px;
+
+
+/* ===== BORDERS ===== */
+--border-width: 1px;
+--border-style: solid;
+--border-color: #2b323b;
+--border-color-translucent: #ffffff26;
+--border-radius: .25rem;
+--border-radius-sm: .2rem;
+--border-radius-lg: .3rem;
+--border-radius-xl: .3rem;
+--border-radius-xxl: 2rem;
+--border-radius-2xl: var(--border-radius-xxl);
+--border-radius-pill: 50rem;
+
+
+/* ===== SHADOWS ===== */
+--box-shadow: 0 .5rem 1rem #00000066;
+--box-shadow-sm: 0 .125rem .25rem #00000040;
+--box-shadow-lg: 0 1rem 3rem #00000080;
+--box-shadow-inset: inset 0 1px 2px #00000040;
+
+
+/* ===== COMMON SHADOW COLORS ===== */
+--shadow-color-light: rgba(var(--black-rgb), var(--opacity-30));
+--shadow-color-medium: rgba(var(--black-rgb), var(--opacity-50));
+--shadow-color-dark: rgba(var(--black-rgb), var(--opacity-75));
+--border-color-translucent: rgba(var(--white-rgb), var(--opacity-10));
+--highlight-translucent: rgba(var(--white-rgb), var(--opacity-5));
+
+
+/* ===== NAVIGATION ===== */
+--mainmenu-nav-link-color: #fff;
+--nav-text-color: gray;
+--nav-bg-color: var(--color-primary);
+
+
+/* ===== NAVBAR ===== */
+--navbar-padding-x: 1rem;
+--navbar-padding-y: 0.5rem;
+--navbar-color: var(--nav-text-color);
+--navbar-active-color: var(--mainmenu-nav-link-color);
+--navbar-disabled-color: #6c757d;
+--navbar-brand-padding-y: 0.3125rem;
+--navbar-brand-margin-end: 1rem;
+--navbar-brand-font-size: 1.25rem;
+--navbar-brand-color: var(--nav-text-color);
+--navbar-brand-active-color: var(--mainmenu-nav-link-color);
+--navbar-nav-link-padding-x: 0.5rem;
+--navbar-toggler-padding-y: 0.25rem;
+--navbar-toggler-padding-x: 0.75rem;
+--navbar-toggler-font-size: 1.25rem;
+--navbar-toggler-border-color: rgba(255, 255, 255, 0.1);
+--navbar-toggler-border-radius: 0.25rem;
+--navbar-toggler-focus-width: 0.25rem;
+--navbar-toggler-transition: box-shadow 0.15s ease-in-out;
+--nav-link-padding-x: 1rem;
+--nav-link-padding-y: 0.5rem;
+--nav-link-font-weight: 400;
+--nav-link-color: var(--nav-text-color);
+--nav-link-active-color: var(--mainmenu-nav-link-color);
+--nav-link-disabled-color: #6c757d;
+
+
+/* ===== LINKS ===== */
+--color-link: white;
+--color-hover: gray;
+--color-active: var(--mainmenu-nav-link-color);
+--link-color: #8ab4f8;
+--link-color-rgb: 138, 180, 248;
+--link-decoration: underline;
+--link-hover-color: #c3d6ff;
+--link-hover-color-rgb: 195, 214, 255;
+--link-active-color: var(--link-color);
+
+
+/* ===== LINK UTILITY COLORS ===== */
+--link-primary-color: hsl(240, 98%, 50%);
+--link-primary-hover-color: hsl(240, 98%, 45%);
+--link-secondary-color: hsl(210, 15%, 70%);
+--link-secondary-hover-color: hsl(210, 15%, 65%);
+--link-success-color: hsl(120, 40%, 60%);
+--link-success-hover-color: hsl(120, 40%, 55%);
+--link-info-color: hsl(207, 60%, 65%);
+--link-info-hover-color: hsl(207, 60%, 60%);
+--link-warning-color: hsl(38, 100%, 65%);
+--link-warning-hover-color: hsl(38, 100%, 60%);
+--link-danger-color: hsl(3, 85%, 65%);
+--link-danger-hover-color: hsl(3, 85%, 60%);
+--link-light-color: hsl(210, 20%, 90%);
+--link-light-hover-color: hsl(210, 20%, 85%);
+--link-dark-color: hsl(210, 10%, 35%);
+--link-dark-hover-color: hsl(210, 10%, 30%);
+
+
+/* ===== HEADER BACKGROUND ===== */
+--header-background-image: url('../../../../../../media/templates/site/mokocassiopeia/images/bg.svg');
+--header-background-attachment: fixed;
+--header-background-repeat: repeat;
+--header-background-size: auto;
+
+
+/* ===== CONTAINER BACKGROUNDS ===== */
+/* Below Topbar Container */
+--container-below-topbar-bg-image: none;
+--container-below-topbar-bg-color: transparent;
+--container-below-topbar-bg-position: center;
+--container-below-topbar-bg-attachment: fixed;
+--container-below-topbar-bg-repeat: no-repeat;
+--container-below-topbar-bg-size: cover;
+--container-below-topbar-border: none;
+--container-below-topbar-border-radius: 0;
+
+/* Top A Container */
+--container-top-a-bg-image: none;
+--container-top-a-bg-color: transparent;
+--container-top-a-bg-position: center;
+--container-top-a-bg-attachment: fixed;
+--container-top-a-bg-repeat: no-repeat;
+--container-top-a-bg-size: cover;
+--container-top-a-border: none;
+--container-top-a-border-radius: 0;
+
+/* Top B Container */
+--container-top-b-bg-image: none;
+--container-top-b-bg-color: transparent;
+--container-top-b-bg-position: center;
+--container-top-b-bg-attachment: fixed;
+--container-top-b-bg-repeat: no-repeat;
+--container-top-b-bg-size: cover;
+--container-top-b-border: none;
+--container-top-b-border-radius: 0;
+
+/* TOC Container */
+--container-toc-bg: var(--secondary-bg);
+--container-toc-color: #dbe3ff;
+
+/* Sidebar Container */
+--container-sidebar-bg-image: none;
+--container-sidebar-bg-color: transparent;
+--container-sidebar-bg-position: center;
+--container-sidebar-bg-attachment: scroll;
+--container-sidebar-bg-repeat: repeat;
+--container-sidebar-bg-size: auto;
+--container-sidebar-border: none;
+--container-sidebar-border-radius: 0;
+
+/* Bottom A Container */
+--container-bottom-a-bg-image: none;
+--container-bottom-a-bg-color: transparent;
+--container-bottom-a-bg-position: center;
+--container-bottom-a-bg-attachment: fixed;
+--container-bottom-a-bg-repeat: no-repeat;
+--container-bottom-a-bg-size: cover;
+--container-bottom-a-border: none;
+--container-bottom-a-border-radius: 5px;
+
+/* Bottom B Container */
+--container-bottom-b-bg-image: none;
+--container-bottom-b-bg-color: transparent;
+--container-bottom-b-bg-position: center;
+--container-bottom-b-bg-attachment: fixed;
+--container-bottom-b-bg-repeat: no-repeat;
+--container-bottom-b-bg-size: cover;
+--container-bottom-b-border: none;
+--container-bottom-b-border-radius: 0;
+
+
+/* ===== FOCUS & FORMS ===== */
+--focus-ring-width: .25rem;
+--focus-ring-opacity: .6;
+--focus-ring-color: #5472ff66;
+--input-color: #e6ebf1;
+--input-bg: #1a2332;
+--input-border-color: #3a4250;
+--input-focus-border-color: #5472ff;
+--input-focus-box-shadow: 0 0 0 0.25rem rgba(84, 114, 255, 0.25);
+--input-placeholder-color: #8894aa;
+--input-disabled-bg: #0f1318;
+--input-disabled-border-color: #2b323b;
+--input-file-button-active-bg: #2b3441;
+--form-range-thumb-active-bg: #4a5766;
+--form-valid-color: #78d694;
+--form-valid-border-color: #78d694;
+--form-invalid-color: #ff8e86;
+--form-invalid-border-color: #ff8e86;
+
+
+/* ===== BUTTONS ===== */
+--btn-border-radius: var(--border-radius);
+--btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 1px 1px rgba(0, 0, 0, 0.3);
+
+
+/* ===== ACCORDION ===== */
+--accordion-color: var(--body-color);
+--accordion-bg: var(--body-bg);
+--accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;
+--accordion-border-color: var(--border-color);
+--accordion-border-width: 1px;
+--accordion-border-radius: 0.25rem;
+--accordion-inner-border-radius: calc(0.25rem - 1px);
+--accordion-btn-padding-x: 1.25rem;
+--accordion-btn-padding-y: 1rem;
+--accordion-btn-color: var(--body-color);
+--accordion-btn-bg: var(--accordion-bg);
+--accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23e6ebf1'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-icon-width: 1.25rem;
+--accordion-btn-icon-transform: rotate(-180deg);
+--accordion-btn-icon-transition: transform 0.2s ease-in-out;
+--accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%238ab4f8'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-focus-border-color: var(--input-focus-border-color);
+--accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(84, 114, 255, 0.25);
+--accordion-body-padding-x: 1.25rem;
+--accordion-body-padding-y: 1rem;
+--accordion-active-color: var(--link-color);
+--accordion-active-bg: var(--secondary-bg);
+
+
+/* ===== ALERT ===== */
+--alert-bg: transparent;
+--alert-padding-x: 1rem;
+--alert-padding-y: 1rem;
+--alert-margin-bottom: 1rem;
+--alert-color: #000;
+--alert-border-color: transparent;
+--alert-border: 1px solid var(--alert-border-color);
+--alert-border-radius: 0.25rem;
+
+
+/* ===== ALERT LINK COLORS ===== */
+--alert-primary-link-color: #b3c1ff;
+--alert-secondary-link-color: #9fa6ad;
+--alert-success-link-color: #a0e5b3;
+--alert-info-link-color: #8eccf2;
+--alert-warning-link-color: #ffe4a0;
+--alert-danger-link-color: #ffa8a3;
+--alert-light-link-color: #f0f4f8;
+--alert-dark-link-color: #9fa6ad;
+
+
+/* ===== BACKDROP ===== */
+--backdrop-zindex: 1040;
+--backdrop-bg: hsl(0, 0%, 0%);
+--backdrop-opacity: 0.5;
+
+
+/* ===== BADGE ===== */
+--badge-padding-x: 0.65em;
+--badge-padding-y: 0.35em;
+--badge-font-size: 0.75em;
+--badge-font-weight: 700;
+--badge-color: var(--body-color);
+--badge-border-radius: 0.25rem;
+
+
+/* ===== BREADCRUMB ===== */
+--breadcrumb-padding-x: 0;
+--breadcrumb-padding-y: 0;
+--breadcrumb-margin-bottom: 1rem;
+--breadcrumb-bg: ;
+--breadcrumb-border-radius: ;
+--breadcrumb-divider-color: var(--gray-600);
+--breadcrumb-item-padding-x: 0.5rem;
+--breadcrumb-item-active-color: var(--link-color);
+
+
+/* ===== CARDS ===== */
+--card-spacer-y: 1rem;
+--card-spacer-x: 1rem;
+--card-title-spacer-y: 0.5rem;
+--card-border-width: 1px;
+--card-border-color: var(--border-color);
+--card-border-radius: var(--border-radius);
+--card-box-shadow: none;
+--card-inner-border-radius: calc(var(--border-radius) - 1px);
+--card-cap-padding-y: 0.5rem;
+--card-cap-padding-x: 1rem;
+--card-cap-bg: rgba(255, 255, 255, 0.03);
+--card-cap-color: var(--body-color);
+--card-height: auto;
+--card-color: var(--body-color);
+--card-bg: var(--secondary-bg);
+--card-img-overlay-padding: 1rem;
+--card-group-margin: 0.75rem;
+
+
+/* ===== DROPDOWN ===== */
+--dropdown-zindex: 1000;
+--dropdown-min-width: 10rem;
+--dropdown-padding-x: 0;
+--dropdown-padding-y: 0.5rem;
+--dropdown-spacer: 0.125rem;
+--dropdown-font-size: 1rem;
+--dropdown-color: var(--body-color);
+--dropdown-bg: var(--secondary-bg);
+--dropdown-border-color: var(--border-color-translucent);
+--dropdown-border-radius: 0.25rem;
+--dropdown-border-width: 1px;
+--dropdown-inner-border-radius: calc(0.25rem - 1px);
+--dropdown-divider-bg: var(--border-color-translucent);
+--dropdown-divider-margin-y: 0.5rem;
+--dropdown-box-shadow: 0 0.5rem 1rem var(--shadow-color-medium);
+--dropdown-link-color: var(--body-color);
+--dropdown-link-active-color: var(--body-color);
+--dropdown-link-active-bg: hsl(240, 98%, 17%);
+--dropdown-link-disabled-color: var(--gray-600);
+--dropdown-item-padding-x: 1rem;
+--dropdown-item-padding-y: 0.25rem;
+--dropdown-header-color: var(--gray-600);
+--dropdown-header-padding-x: 1rem;
+--dropdown-header-padding-y: 0.5rem;
+
+
+/* ===== LIST GROUP ===== */
+--list-group-color: var(--body-color);
+--list-group-bg: var(--secondary-bg);
+--list-group-border-color: rgba(var(--white-rgb), 0.125);
+--list-group-border-width: 1px;
+--list-group-border-radius: 0.25rem;
+--list-group-item-padding-x: 1rem;
+--list-group-item-padding-y: 0.5rem;
+--list-group-action-color: var(--gray-800);
+--list-group-action-active-color: var(--body-color);
+--list-group-action-active-bg: var(--tertiary-bg);
+--list-group-disabled-color: var(--gray-600);
+--list-group-disabled-bg: var(--secondary-bg);
+--list-group-active-color: var(--body-color);
+--list-group-active-bg: hsl(240, 98%, 17%);
+--list-group-active-border-color: hsl(240, 98%, 17%);
+
+
+/* ===== LIST GROUP ITEM COLORS ===== */
+--list-group-item-primary-color: #8ca3ff;
+--list-group-item-primary-bg: #1a2550;
+--list-group-item-primary-active-bg: #223066;
+--list-group-item-secondary-color: #9fa6ad;
+--list-group-item-secondary-bg: #2b323b;
+--list-group-item-secondary-active-bg: #363d47;
+--list-group-item-success-color: #a0e5b3;
+--list-group-item-success-bg: #1e3d2d;
+--list-group-item-success-active-bg: #275538;
+--list-group-item-info-color: #8eccf2;
+--list-group-item-info-bg: #1a3448;
+--list-group-item-info-active-bg: #234459;
+--list-group-item-warning-color: #ffe4a0;
+--list-group-item-warning-bg: #4a3410;
+--list-group-item-warning-active-bg: #5c4216;
+--list-group-item-danger-color: #ffa8a3;
+--list-group-item-danger-bg: #4a1e1c;
+--list-group-item-danger-active-bg: #5c2823;
+--list-group-item-light-color: #e9ecef;
+--list-group-item-light-bg: #1e2430;
+--list-group-item-light-active-bg: #282f3d;
+--list-group-item-dark-color: #48525d;
+--list-group-item-dark-bg: #0e1318;
+--list-group-item-dark-active-bg: #161b22;
+
+
+/* ===== MODAL ===== */
+--modal-zindex: 1050;
+--modal-width: 500px;
+--modal-padding: 1rem;
+--modal-margin: 0.5rem;
+--modal-color: ;
+--modal-bg: var(--secondary-bg);
+--modal-border-color: var(--border-color-translucent);
+--modal-border-width: 1px;
+--modal-border-radius: 0.3rem;
+--modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.3);
+--modal-inner-border-radius: calc(0.3rem - 1px);
+--modal-header-padding-x: 1rem;
+--modal-header-padding-y: 1rem;
+--modal-header-padding: 1rem 1rem;
+--modal-header-border-color: var(--border-color);
+--modal-header-border-width: 1px;
+--modal-title-line-height: 1.5;
+--modal-footer-gap: 0.5rem;
+--modal-footer-bg: ;
+--modal-footer-border-color: var(--border-color);
+--modal-footer-border-width: 1px;
+
+
+/* ===== NAV TABS ===== */
+--nav-tabs-border-width: 1px;
+--nav-tabs-border-color: var(--border-color);
+--nav-tabs-border-radius: 0.25rem;
+--nav-tabs-link-active-color: var(--body-color);
+--nav-tabs-link-active-bg: var(--secondary-bg);
+--nav-tabs-link-active-border-color: var(--border-color) var(--border-color) var(--secondary-bg);
+
+
+/* ===== NAV PILLS ===== */
+--nav-pills-border-radius: 0.25rem;
+--nav-pills-link-active-color: var(--body-color);
+--nav-pills-link-active-bg: hsl(240, 98%, 17%);
+
+
+/* ===== OFFCANVAS ===== */
+--offcanvas-zindex: 1045;
+--offcanvas-width: 400px;
+--offcanvas-height: 30vh;
+--offcanvas-padding-x: 1rem;
+--offcanvas-padding-y: 1rem;
+--offcanvas-color: var(--body-color);
+--offcanvas-bg: var(--body-bg);
+--offcanvas-border-width: 1px;
+--offcanvas-border-color: var(--border-color-translucent);
+--offcanvas-box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.3);
+
+
+/* ===== PAGINATION ===== */
+--pagination-padding-x: 0.75rem;
+--pagination-padding-y: 0.375rem;
+--pagination-font-size: 1rem;
+--pagination-color: var(--link-color);
+--pagination-bg: var(--secondary-bg);
+--pagination-border-width: 1px;
+--pagination-border-color: var(--border-color);
+--pagination-border-radius: 0.25rem;
+--pagination-focus-color: var(--link-active-color);
+--pagination-focus-bg: var(--tertiary-bg);
+--pagination-focus-box-shadow: 0 0 0 0.25rem rgba(84, 114, 255, 0.25);
+--pagination-active-color: var(--body-color);
+--pagination-active-bg: hsl(240, 98%, 17%);
+--pagination-active-border-color: hsl(240, 98%, 17%);
+--pagination-disabled-color: var(--gray-600);
+--pagination-disabled-bg: var(--secondary-bg);
+--pagination-disabled-border-color: var(--border-color);
+
+
+/* ===== POPOVER ===== */
+--popover-zindex: 1060;
+--popover-max-width: 276px;
+--popover-font-size: 0.875rem;
+--popover-bg: var(--secondary-bg);
+--popover-border-width: 1px;
+--popover-border-color: var(--border-color-translucent);
+--popover-border-radius: 0.3rem;
+--popover-inner-border-radius: calc(0.3rem - 1px);
+--popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.4);
+--popover-header-padding-x: 1rem;
+--popover-header-padding-y: 0.5rem;
+--popover-header-font-size: 1rem;
+--popover-header-color: ;
+--popover-header-bg: var(--tertiary-bg);
+--popover-body-padding-x: 1rem;
+--popover-body-padding-y: 1rem;
+--popover-body-color: var(--body-color);
+--popover-arrow-width: 1rem;
+--popover-arrow-height: 0.5rem;
+--popover-arrow-border: var(--popover-border-color);
+
+
+/* ===== PROGRESS ===== */
+--progress-height: 1rem;
+--progress-font-size: 0.75rem;
+--progress-bg: var(--secondary-bg);
+--progress-border-radius: 0.25rem;
+--progress-box-shadow: inset 0 1px 2px rgba(var(--black-rgb), 0.3);
+--progress-bar-color: var(--body-color);
+--progress-bar-bg: hsl(240, 98%, 40%);
+--progress-bar-transition: width 0.6s ease;
+
+
+/* ===== SPINNER ===== */
+--spinner-width: 2rem;
+--spinner-height: 2rem;
+--spinner-vertical-align: -0.125em;
+--spinner-border-width: 0.25em;
+--spinner-animation-speed: 0.75s;
+
+
+/* ===== TABLE ===== */
+--table-color: var(--body-color);
+--table-bg: transparent;
+--table-border-color: var(--border-color);
+--table-accent-bg: transparent;
+--table-striped-color: var(--body-color);
+--table-striped-bg: rgba(var(--white-rgb), var(--opacity-5));
+--table-active-color: var(--body-color);
+--table-active-bg: rgba(var(--white-rgb), 0.1);
+
+
+/* ===== TOAST ===== */
+--toast-zindex: 1090;
+--toast-padding-x: 0.75rem;
+--toast-padding-y: 0.5rem;
+--toast-spacing: 1em;
+--toast-max-width: 350px;
+--toast-font-size: 0.875rem;
+--toast-color: ;
+--toast-bg: rgba(21, 27, 34, 0.9);
+--toast-border-width: 1px;
+--toast-border-color: var(--border-color-translucent);
+--toast-border-radius: 0.25rem;
+--toast-box-shadow: 0 0.5rem 1rem var(--shadow-color-medium);
+--toast-header-color: var(--gray-600);
+--toast-header-bg: rgba(21, 27, 34, 0.85);
+--toast-header-border-color: rgba(var(--white-rgb), var(--opacity-10));
+
+
+/* ===== TOOLTIP ===== */
+--tooltip-zindex: 1070;
+--tooltip-max-width: 200px;
+--tooltip-padding-x: 0.5rem;
+--tooltip-padding-y: 0.25rem;
+--tooltip-margin: ;
+--tooltip-font-size: 0.875rem;
+--tooltip-color: var(--body-color);
+--tooltip-bg: hsl(0, 0%, 0%);
+--tooltip-border-radius: 0.25rem;
+--tooltip-opacity: 0.9;
+--tooltip-arrow-width: 0.8rem;
+--tooltip-arrow-height: 0.4rem;
+
+
+/* ===== BOOTSTRAP PALETTE ===== */
+--primary: #010156;
+--secondary: #48525d;
+--success: #4aa664;
+--info: #4f7aa0;
+--warning: #c77a00;
+--danger: #c23a31;
+--light: #1b2027;
+--dark: #0f1318;
+--primary-rgb: 1,1,86;
+--secondary-rgb: 72,82,93;
+--success-rgb: 74,166,100;
+--info-rgb: 79,122,160;
+--warning-rgb: 199,122,0;
+--danger-rgb: 194,58,49;
+--light-rgb: 27,32,39;
+--dark-rgb: 15,19,24;
+--primary-text-emphasis: #c7ccff;
+--secondary-text-emphasis: #cfd6de;
+--success-text-emphasis: #bde8c9;
+--info-text-emphasis: #bcd6ee;
+--warning-text-emphasis: #ffd9a6;
+--danger-text-emphasis: #ffb7b2;
+--light-text-emphasis: #d2d8df;
+--dark-text-emphasis: #d2d8df;
+--primary-bg-subtle: #0b1030;
+--secondary-bg-subtle: #1e2430;
+--success-bg-subtle: #0f2a1b;
+--info-bg-subtle: #0d2232;
+--warning-bg-subtle: #2a1e06;
+--danger-bg-subtle: #2d1110;
+--light-bg-subtle: #12161d;
+--dark-bg-subtle: #1e2430;
+--primary-border-subtle: #2b3a7a;
+--secondary-border-subtle: #2b323b;
+--success-border-subtle: #2b5b40;
+--info-border-subtle: #254861;
+--warning-border-subtle: #5a3c0e;
+--danger-border-subtle: #5c2723;
+--light-border-subtle: #222831;
+--dark-border-subtle: #2b323b;
+
+
+/* ===== HERO / BANNER OVERLAY ===== */
+--hero-height: 70vh;
+--hero-color: var(--body-color);
+--hero-bg-repeat: no-repeat;
+--hero-bg-attachment: fixed;
+--hero-bg-position: top center;
+--hero-bg-size: cover;
+--hero-border-bottom: solid var(--accent-color-secondary);
+--hero-overlay-bg: hsla(0, 0%, 0%, 0.3);
+--hero-overlay-bg-position: center;
+--hero-overlay-bg-size: cover;
+--hero-overlay-padding: 1em;
+--hero-overlay-text-align: center;
+--hero-overlay-text-color: var(--body-color);
+
+
+/* ===== HERO VARIANTS ===== */
+/* Primary — deep navy, dark overlay */
+--hero-primary-bg-color: #0d1e3a;
+--hero-primary-overlay: linear-gradient(rgba(13, 30, 58, .65), rgba(13, 30, 58, .65));
+--hero-primary-color: #f1f5f9;
+
+/* Secondary — darker navy, heavier overlay */
+--hero-secondary-bg-color: #080f1e;
+--hero-secondary-overlay: linear-gradient(rgba(8, 15, 30, .80), rgba(8, 15, 30, .80));
+--hero-secondary-color: #f1f5f9;
+
+
+/* ===== HERO CARD (inner .hero element) ===== */
+/* Default card — uses primary variant values */
+--hero-card-bg: var(--hero-primary-bg-color);
+--hero-card-color: white;
+--hero-card-overlay: var(--hero-primary-overlay);
+--hero-card-border-radius: .5rem;
+--hero-card-padding-x: 2rem;
+--hero-card-padding-y: 3rem;
+--hero-card-max-width: 800px;
+
+/* Alternative card — uses secondary variant values */
+--hero-alt-card-bg: var(--hero-secondary-bg-color);
+--hero-alt-card-color: var(--hero-secondary-color);
+--hero-alt-card-overlay: var(--hero-secondary-overlay);
+--hero-alt-card-border-radius: .5rem;
+--hero-alt-card-padding-x: 2rem;
+--hero-alt-card-padding-y: 3rem;
+--hero-alt-card-max-width: 600px;
+
+
+/* ===== BLOCK COLORS (top-a / top-b / bottom-a / bottom-b) ===== */
+--block-color-1: var(--secondary-bg);
+--block-text-1: var(--body-color);
+
+--block-color-2: var(--accent-color-primary);
+--block-text-2: #fff;
+
+--block-color-3: rgba(238, 194, 52, .15);
+--block-text-3: var(--body-color);
+
+--block-color-4: rgba(74, 166, 100, .15);
+--block-text-4: var(--body-color);
+
+
+/* ===== BLOCK COLOR OVERRIDES ===== */
+--block-highlight-bg: var(--accent-color-primary);
+--block-highlight-text: #fff;
+
+--block-cta-bg: var(--color-primary);
+--block-cta-text: #f1f5f9;
+
+--block-alert-bg: var(--danger, #c23a31);
+--block-alert-text: #fff;
+
+
+/* ===== FOOTER ===== */
+--footer-padding-top: 1rem;
+--footer-padding-bottom: 80px;
+--footer-grid-padding-y: 2.5rem;
+--footer-grid-padding-x: 0.5em;
+
+
+/* ===== THEME FAB ===== */
+--theme-fab-bg: #e6ebf1;
+--theme-fab-color: #0e1318;
+--theme-fab-btn-bg: transparent;
+--theme-fab-border: rgba(0, 0, 0, 0.15);
+
+
+/* ===== OFFLINE PAGE ===== */
+--offline-card-bg: rgba(0, 0, 0, 0.6);
+
+
+/* ===== COMPONENT-SPECIFIC COLORS ===== */
+--mod-finder-link-hover: #5a6470;
+--form-legend-color: #9fa6ad;
+--border-gray: #3a4250;
+--subhead-color: #9fa6ad;
+--box-shadow-gray: #1a2027;
+--btn-active-text-gray: #7a8490;
+--indicator-success-bg: var(--success);
+--item-list-color: #2a2f34;
+--notification-badge-bg: var(--danger);
+--content-bg-gray: #2b323b;
+--taba-btn-green: #5a9c2f;
+--taba-btn-blue: #3d75a8;
+--taba-btn-red: #c43620;
+--taba-btn-gray: #6a7080;
+--taba-msg-bg: #1e2430;
+--toc-link-color: #9fa6ad;
+--toc-link-active-color: #91a4ff;
+--choices-disabled-bg: #2b323b;
+--choices-input-bg: var(--body-bg);
+--choices-border-light: #48525d;
+--choices-arrow-color: #9fa6ad;
+--choices-inner-bg: #1a2027;
+--choices-focused-border: #5472ff;
+--choices-dropdown-bg: var(--body-bg);
+--choices-item-bg: #1a5f75;
+--choices-item-border: #1a748f;
+--choices-item-hover-bg: #1a748f;
+--choices-item-hover-border: #1a8aa8;
+--choices-item-disabled-bg: #48525d;
+--choices-item-disabled-border: #36404a;
+--choices-item-highlighted: #2b323b;
+--choices-input-inner-bg: #1a2027;
+
+
+/* ===== VIRTUEMART (VM) ===== */
+/* VM Surfaces */
+--vm-surface: var(--secondary-bg);
+--vm-surface-2: var(--tertiary-bg);
+--vm-text: var(--body-color);
+--vm-text-strong: #ffffff;
+--vm-text-muted: var(--gray-700);
+--vm-border: var(--border-color);
+--vm-price-color: var(--success);
+
+/* VM Layout and Density */
+--vm-container-max-width: 1200px;
+--vm-section-gap: 2rem;
+--vm-block-radius: var(--border-radius);
+--vm-block-shadow: var(--box-shadow-sm);
+
+/* VM Typography */
+--vm-category-title-size: 2rem;
+--vm-subcategory-title-size: 1.5rem;
+--vm-page-title-size: 1.75rem;
+--vm-products-type-title-size: 1.25rem;
+--vm-product-title-size: 1.125rem;
+--vm-product-title-weight: 500;
+--vm-products-type-title-weight: 600;
+--vm-price-size: 1.5rem;
+--vm-price-detail-size: 1.125rem;
+--vm-price-desc-size: 0.875rem;
+
+/* VM Controls */
+--vm-input-radius: var(--border-radius);
+--vm-input-shadow: var(--box-shadow-sm);
+--vm-qty-width: 80px;
+--vm-cart-dropdown-min-width: 300px;
+
+/* VM Alerts */
+--vm-alert-radius: var(--border-radius);
+--vm-alert-shadow: var(--box-shadow-sm);
+--vm-availability-bg: var(--success-bg-subtle);
+--vm-availability-text: var(--success);
+
+/* VM Buttons */
+--vm-btn-padding-x: 1rem;
+--vm-btn-padding-y: 0.5rem;
+--vm-btn-radius: var(--border-radius);
+--vm-btn-shadow: var(--box-shadow-sm);
+--vm-btn-primary-bg: var(--primary);
+--vm-btn-primary-text: #ffffff;
+--vm-btn-primary-border: var(--primary);
+--vm-btn-secondary-bg: var(--secondary);
+--vm-btn-secondary-text: #ffffff;
+--vm-btn-secondary-border: var(--secondary);
+
+/* VM Image Overlay Controls */
+--vm-image-overlay-gap-x: 0.5rem;
+--vm-image-overlay-gap-y: 0.5rem;
+--vm-image-overlay-raise: 0.25rem;
+--vm-image-overlay-btn-size: 2.5rem;
+--vm-image-overlay-btn-radius: 50%;
+--vm-image-overlay-btn-bg: rgba(0, 0, 0, 0.7);
+--vm-image-overlay-btn-bg-hover: rgba(0, 0, 0, 0.85);
+--vm-image-overlay-btn-border-color: rgba(255, 255, 255, 0.2);
+--vm-image-overlay-btn-border-width: 1px;
+--vm-image-overlay-btn-color: var(--body-color);
+--vm-image-overlay-btn-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
+
+/* VM Vendor Menu */
+--vm-vendor-menu-bg: var(--secondary-bg);
+--vm-vendor-menu-border: var(--border-color);
+--vm-vendor-menu-radius: var(--border-radius);
+--vm-vendor-menu-shadow: var(--box-shadow-sm);
+--vm-vendor-menu-item-gap: 0.25rem;
+--vm-vendor-menu-item-padding-x: 1rem;
+--vm-vendor-menu-item-padding-y: 0.5rem;
+--vm-vendor-menu-pill-radius: 50rem;
+--vm-vendor-menu-link: var(--link-color);
+--vm-vendor-menu-link-hover: var(--link-hover-color);
+--vm-vendor-menu-link-active: var(--primary);
+--vm-vendor-menu-hover-bg: var(--tertiary-bg);
+
+
+/* ===== GABLE ===== */
+--gab-blue: #4d9fff;
+--gab-green: #5cb85c;
+--gab-red: #ff6b6b;
+--gab-orange: #ff9f5a;
+--gab-gray1: #868e96;
+--gab-gray2: #adb5bd;
+--gab-gray3: #ced4da;
+
+}
+
+.btn {
+ --btn-padding-x: 1rem;
+ --btn-padding-y: 0.6rem;
+ --btn-font-family: inherit;
+ --btn-font-size: 1rem;
+ --btn-font-weight: 400;
+ --btn-line-height: 1.5;
+ --btn-color: var(--white);
+ --btn-bg: var(--body-bg);
+ --btn-border-width: 1px;
+ --btn-border-color: transparent;
+ --btn-border-radius: 0.25rem;
+ --btn-active-border-color: transparent;
+ --btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+ --btn-disabled-opacity: 0.65;
+ --btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5);
+ display: inline-block;
+ padding: var(--btn-padding-y) var(--btn-padding-x);
+ font-family: var(--btn-font-family);
+ font-size: var(--btn-font-size);
+ font-weight: var(--btn-font-weight);
+ line-height: var(--btn-line-height);
+ color: var(--btn-color);
+ text-align: center;
+ text-decoration: none;
+ vertical-align: middle;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ border: var(--btn-border-width) solid var(--btn-border-color);
+ border-radius: var(--btn-border-radius);
+ background-color: var(--btn-bg);
+ -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ -o-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+}
+
+/* Buttons — inherit brand hues; ensure strong contrast on dark bg */
+.btn-primary {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(240, 98%, 17%);
+ --btn-border-color: hsl(240, 98%, 17%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #010149;
+ --btn-hover-border-color: #010145;
+ --btn-focus-shadow-rgb: 84, 114, 255;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #010145;
+ --btn-active-border-color: #010141;
+}
+
+.btn-secondary {
+ --btn-color: var(--nav-text-color);
+ --btn-bg: var(--nav-bg-color);
+ --btn-border-color: #3a4250;
+ --btn-hover-color: #fff;
+ --btn-hover-bg: #1b2a55;
+ --btn-hover-border-color: #162448;
+ --btn-focus-shadow-rgb: 84, 114, 255;
+ --btn-active-color: #fff;
+ --btn-active-bg: #162448;
+ --btn-active-border-color: #12203f;
+}
+
+.btn-success {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(120, 35%, 45%);
+ --btn-border-color: hsl(120, 35%, 45%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(120, 35%, 40%);
+ --btn-hover-border-color: hsl(120, 35%, 38%);
+ --btn-focus-shadow-rgb: 96, 180, 96;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(120, 35%, 38%);
+ --btn-active-border-color: hsl(120, 35%, 36%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(120, 35%, 45%);
+ --btn-disabled-border-color: hsl(120, 35%, 45%);
+}
+
+.btn-info {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(207, 55%, 55%);
+ --btn-border-color: hsl(207, 55%, 55%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(207, 55%, 50%);
+ --btn-hover-border-color: hsl(207, 55%, 48%);
+ --btn-focus-shadow-rgb: 100, 160, 210);
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(207, 55%, 48%);
+ --btn-active-border-color: hsl(207, 55%, 46%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(207, 55%, 55%);
+ --btn-disabled-border-color: hsl(207, 55%, 55%);
+}
+
+.btn-warning {
+ --btn-color: hsl(0, 0%, 0%);
+ --btn-bg: hsl(38, 100%, 50%);
+ --btn-border-color: hsl(38, 100%, 50%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(38, 100%, 45%);
+ --btn-hover-border-color: hsl(38, 100%, 43%);
+ --btn-focus-shadow-rgb: 220, 170, 40;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(38, 100%, 43%);
+ --btn-active-border-color: hsl(38, 100%, 41%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 0%);
+ --btn-disabled-bg: hsl(38, 100%, 50%);
+ --btn-disabled-border-color: hsl(38, 100%, 50%);
+}
+
+.btn-danger {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(3, 82%, 50%);
+ --btn-border-color: hsl(3, 82%, 50%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(3, 82%, 45%);
+ --btn-hover-border-color: hsl(3, 82%, 43%);
+ --btn-focus-shadow-rgb: 220, 80, 80;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(3, 82%, 43%);
+ --btn-active-border-color: hsl(3, 82%, 41%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(3, 82%, 50%);
+ --btn-disabled-border-color: hsl(3, 82%, 50%);
+}
+
+.btn-light {
+ --btn-color: hsl(0, 0%, 0%);
+ --btn-bg: hsl(210, 17%, 85%);
+ --btn-border-color: hsl(210, 17%, 85%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(210, 17%, 80%);
+ --btn-hover-border-color: hsl(210, 17%, 78%);
+ --btn-focus-shadow-rgb: 200, 205, 210;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(210, 17%, 78%);
+ --btn-active-border-color: hsl(210, 17%, 76%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 0%);
+ --btn-disabled-bg: hsl(210, 17%, 85%);
+ --btn-disabled-border-color: hsl(210, 17%, 85%);
+}
+
+.btn-dark {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(210, 10%, 20%);
+ --btn-border-color: hsl(210, 10%, 20%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(210, 10%, 18%);
+ --btn-hover-border-color: hsl(210, 10%, 16%);
+ --btn-focus-shadow-rgb: 60, 65, 70;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(210, 10%, 16%);
+ --btn-active-border-color: hsl(210, 10%, 14%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(210, 10%, 20%);
+ --btn-disabled-border-color: hsl(210, 10%, 20%);
+}
+
+.btn-outline-primary {
+ --btn-color: hsl(240, 98%, 40%);
+ --btn-border-color: hsl(240, 98%, 40%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(240, 98%, 40%);
+ --btn-hover-border-color: hsl(240, 98%, 40%);
+ --btn-focus-shadow-rgb: 80, 80, 180;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(240, 98%, 40%);
+ --btn-active-border-color: hsl(240, 98%, 40%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(240, 98%, 40%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(240, 98%, 40%);
+ --gradient: none;
+}
+
+.btn-outline-secondary {
+ --btn-color: hsl(210, 20%, 60%);
+ --btn-border-color: hsl(210, 20%, 60%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(210, 20%, 60%);
+ --btn-hover-border-color: hsl(210, 20%, 60%);
+ --btn-focus-shadow-rgb: 120, 140, 160;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(210, 20%, 60%);
+ --btn-active-border-color: hsl(210, 20%, 60%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 20%, 60%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 20%, 60%);
+ --gradient: none;
+}
+
+.btn-outline-success {
+ --btn-color: hsl(120, 35%, 55%);
+ --btn-border-color: hsl(120, 35%, 55%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(120, 35%, 55%);
+ --btn-hover-border-color: hsl(120, 35%, 55%);
+ --btn-focus-shadow-rgb: 100, 190, 100;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(120, 35%, 55%);
+ --btn-active-border-color: hsl(120, 35%, 55%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(120, 35%, 55%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(120, 35%, 55%);
+ --gradient: none;
+}
+
+.btn-outline-info {
+ --btn-color: hsl(207, 55%, 65%);
+ --btn-border-color: hsl(207, 55%, 65%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(207, 55%, 65%);
+ --btn-hover-border-color: hsl(207, 55%, 65%);
+ --btn-focus-shadow-rgb: 110, 170, 220;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(207, 55%, 65%);
+ --btn-active-border-color: hsl(207, 55%, 65%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(207, 55%, 65%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(207, 55%, 65%);
+ --gradient: none;
+}
+
+.btn-outline-warning {
+ --btn-color: hsl(38, 100%, 60%);
+ --btn-border-color: hsl(38, 100%, 60%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(38, 100%, 60%);
+ --btn-hover-border-color: hsl(38, 100%, 60%);
+ --btn-focus-shadow-rgb: 240, 190, 70;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(38, 100%, 60%);
+ --btn-active-border-color: hsl(38, 100%, 60%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(38, 100%, 60%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(38, 100%, 60%);
+ --gradient: none;
+}
+
+.btn-outline-danger {
+ --btn-color: hsl(3, 82%, 60%);
+ --btn-border-color: hsl(3, 82%, 60%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(3, 82%, 60%);
+ --btn-hover-border-color: hsl(3, 82%, 60%);
+ --btn-focus-shadow-rgb: 240, 100, 100;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(3, 82%, 60%);
+ --btn-active-border-color: hsl(3, 82%, 60%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(3, 82%, 60%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(3, 82%, 60%);
+ --gradient: none;
+}
+
+/* Outline buttons on dark: keep readable borders */
+.btn-outline-light {
+ --btn-color: #e6ebf1;
+ --btn-border-color: #e6ebf1;
+ --btn-hover-color: #111;
+ --btn-hover-bg: #e6ebf1;
+ --btn-hover-border-color: #e6ebf1;
+ --btn-active-color: #111;
+ --btn-active-bg: #d7dce2;
+ --btn-active-border-color: #d7dce2;
+ --gradient: none;
+}
+
+.btn-outline-dark {
+ --btn-color: hsl(210, 10%, 30%);
+ --btn-border-color: hsl(210, 10%, 30%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(210, 10%, 30%);
+ --btn-hover-border-color: hsl(210, 10%, 30%);
+ --btn-focus-shadow-rgb: 70, 75, 80;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(210, 10%, 30%);
+ --btn-active-border-color: hsl(210, 10%, 30%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 10%, 30%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 10%, 30%);
+ --gradient: none;
+}
+
+/* Links as buttons */
+.btn-link {
+ --btn-font-weight: 400;
+ --btn-color: var(--color-link);
+ --btn-bg: transparent;
+ --btn-border-color: transparent;
+ --btn-hover-color: var(--link-hover-color);
+ --btn-hover-border-color: transparent;
+ --btn-active-color: var(--link-hover-color);
+ --btn-active-border-color: transparent;
+ --btn-disabled-color: #6d7781;
+ --btn-disabled-border-color: transparent;
+ --btn-box-shadow: none;
+ --btn-focus-shadow-rgb: 84, 114, 255;
+ text-decoration: underline;
+}
diff --git a/src/templates/light.custom.css b/src/templates/light.custom.css
new file mode 100644
index 0000000..fa67e82
--- /dev/null
+++ b/src/templates/light.custom.css
@@ -0,0 +1,1219 @@
+@charset "UTF-8";
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+/* -----------------------------------------------
+ * LIGHT THEME (CUSTOM)
+ * --------------------------------------------- */
+
+:root[data-bs-theme="light"] {
+color-scheme: light;
+
+
+/* ===== BRAND & THEME COLORS ===== */
+--color-primary: #112855;
+--accent-color-primary: #3f8ff0;
+--accent-color-secondary: #6fb3ff;
+
+
+/* ===== TYPOGRAPHY & BODY ===== */
+--font-sans-serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+--body-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--body-font-size: 1rem;
+--body-font-weight: 400;
+--body-line-height: 1.5;
+--body-color: #22262a;
+--body-color-rgb: 34, 38, 42;
+--body-bg: #fff;
+--body-bg-rgb: 255, 255, 255;
+--heading-color: inherit;
+--emphasis-color: #000;
+--emphasis-color-rgb: 0, 0, 0;
+--secondary-color: #22262abf;
+--secondary-color-rgb: 34, 38, 42;
+--tertiary-color: #22262a80;
+--tertiary-color-rgb: 34, 38, 42;
+--muted-color: #6d757e;
+--code-color: black;
+--code-color-ink: var(--code-color, #e93f8e);
+--code-bg-color: lightgreen;
+--highlight-color: #22262a;
+--highlight-bg: #fbeea8;
+
+
+/* ===== STANDARD COLORS ===== */
+--blue: #010156;
+--indigo: #6812f3;
+--purple: #6f42c2;
+--pink: #e93f8e;
+--red: #a51f18;
+--orange: #fd7e17;
+--yellow: #ad6200;
+--green: #448344;
+--teal: #5abfdd;
+--cyan: #30638d;
+--black: #000;
+--white: #fff;
+
+
+/* ===== GRAY SCALE ===== */
+--gray-100: #f9fafb;
+--gray-200: #eaedf0;
+--gray-300: #dfe3e7;
+--gray-400: #ced4da;
+--gray-500: #adb5bd;
+--gray-600: #6d757e;
+--gray-700: #484f56;
+--gray-800: #353b41;
+--gray-900: #22262a;
+--white-rgb: 255, 255, 255;
+--black-rgb: 0, 0, 0;
+
+
+/* ===== OPACITY UTILITIES ===== */
+--opacity-0: 0;
+--opacity-5: 0.05;
+--opacity-10: 0.1;
+--opacity-15: 0.15;
+--opacity-20: 0.2;
+--opacity-25: 0.25;
+--opacity-30: 0.3;
+--opacity-50: 0.5;
+--opacity-75: 0.75;
+--opacity-100: 1;
+
+
+/* ===== LAYOUT & SPACING ===== */
+--padding-x: 0.15rem;
+--padding-y: 0.15rem;
+--bg-opacity: 1;
+--nav-toggle-size: 3rem;
+--gradient: linear-gradient(180deg, #ffffff26, #fff0);
+--secondary-bg: #eaedf0;
+--secondary-bg-rgb: 234, 237, 240;
+--tertiary-bg: #f9fafb;
+--tertiary-bg-rgb: 249, 250, 251;
+--hr-color: var(--border-color, #dfe3e7);
+--border-color-soft: var(--border-color, #dfe3e7);
+--kbd-bg: var(--secondary-bg, #eaedf0);
+--kbd-ink: var(--body-bg, #fff);
+--toc-bg: var(--secondary-bg, #eaedf0);
+--toc-ink: var(--color-primary, #112855);
+--selection-bg: var(--highlight-bg, #fbeea8);
+--selection-ink: var(--body-color, #22262a);
+--border: 5px;
+
+
+/* ===== BREAKPOINTS ===== */
+--bp-xs: 0;
+--bp-sm: 576px;
+--bp-md: 768px;
+--bp-lg: 992px;
+--bp-xl: 1200px;
+
+
+/* ===== BORDERS ===== */
+--border-width: 1px;
+--border-style: solid;
+--border-color: #dfe3e7;
+--border-color-translucent: #0000002d;
+--border-radius: .25rem;
+--border-radius-sm: .2rem;
+--border-radius-lg: .3rem;
+--border-radius-xl: .3rem;
+--border-radius-xxl: 2rem;
+--border-radius-2xl: var(--border-radius-xxl)*2;
+--border-radius-pill: 50rem;
+
+
+/* ===== SHADOWS ===== */
+--box-shadow: 0 .5rem 1rem #00000026;
+--box-shadow-sm: 0 .125rem .25rem #00000013;
+--box-shadow-lg: 0 1rem 3rem #0000002d;
+--box-shadow-inset: inset 0 1px 2px #00000013;
+
+
+/* ===== COMMON SHADOW COLORS ===== */
+--shadow-color-light: rgba(var(--black-rgb), var(--opacity-15));
+--shadow-color-medium: rgba(var(--black-rgb), var(--opacity-25));
+--shadow-color-dark: rgba(var(--black-rgb), var(--opacity-30));
+--border-color-translucent: rgba(var(--black-rgb), var(--opacity-10));
+--highlight-translucent: rgba(var(--white-rgb), var(--opacity-15));
+
+
+/* ===== NAVIGATION ===== */
+--mainmenu-nav-link-color: white;
+--nav-text-color: white;
+--nav-bg-color: var(--color-link);
+
+
+/* ===== NAVBAR ===== */
+--navbar-padding-x: 1rem;
+--navbar-padding-y: 0.5rem;
+--navbar-color: var(--nav-text-color);
+--navbar-active-color: var(--mainmenu-nav-link-color);
+--navbar-disabled-color: #6c757d;
+--navbar-brand-padding-y: 0.3125rem;
+--navbar-brand-margin-end: 1rem;
+--navbar-brand-font-size: 1.25rem;
+--navbar-brand-color: var(--nav-text-color);
+--navbar-brand-active-color: var(--mainmenu-nav-link-color);
+--navbar-nav-link-padding-x: 0.5rem;
+--navbar-toggler-padding-y: 0.25rem;
+--navbar-toggler-padding-x: 0.75rem;
+--navbar-toggler-font-size: 1.25rem;
+--navbar-toggler-border-color: rgba(0, 0, 0, 0.1);
+--navbar-toggler-border-radius: 0.25rem;
+--navbar-toggler-focus-width: 0.25rem;
+--navbar-toggler-transition: box-shadow 0.15s ease-in-out;
+--nav-link-padding-x: 1rem;
+--nav-link-padding-y: 0.5rem;
+--nav-link-font-weight: 400;
+--nav-link-color: var(--nav-text-color);
+--nav-link-active-color: var(--mainmenu-nav-link-color);
+--nav-link-disabled-color: #6c757d;
+
+
+/* ===== LINKS ===== */
+--color-link: #224FAA;
+--color-hover: var(--accent-color-primary);
+--link-color: #224faa;
+--link-color-rgb: 34, 79, 170;
+--link-decoration: underline;
+--link-hover-color: #424077;
+--link-hover-color-rgb: 66, 64, 119;
+--link-active-color: var(--link-color);
+
+
+/* ===== LINK UTILITY COLORS ===== */
+--link-primary-color: hsl(240, 98%, 17%);
+--link-primary-hover-color: #010145;
+--link-secondary-color: hsl(210, 7%, 46%);
+--link-secondary-hover-color: #575e65;
+--link-success-color: hsl(120, 32%, 39%);
+--link-success-hover-color: #366936;
+--link-info-color: hsl(207, 49%, 37%);
+--link-info-hover-color: #264f71;
+--link-warning-color: hsl(34, 100%, 34%);
+--link-warning-hover-color: #8a4e00;
+--link-danger-color: hsl(3, 75%, 37%);
+--link-danger-hover-color: #841913;
+--link-light-color: hsl(210, 17%, 98%);
+--link-light-hover-color: #fafbfc;
+--link-dark-color: hsl(210, 10%, 23%);
+--link-dark-hover-color: #2a2f34;
+
+
+/* ===== HEADER BACKGROUND ===== */
+--header-background-image: url('../../../../../../media/templates/site/mokocassiopeia/images/bg.svg');
+--header-background-attachment: fixed;
+--header-background-repeat: repeat;
+--header-background-size: auto;
+
+
+/* ===== CONTAINER BACKGROUNDS ===== */
+/* Below Topbar Container */
+--container-below-topbar-bg-image: none;
+--container-below-topbar-bg-color: transparent;
+--container-below-topbar-bg-position: auto;
+--container-below-topbar-bg-attachment: fixed;
+--container-below-topbar-bg-repeat: repeat;
+--container-below-topbar-bg-size: auto;
+--container-below-topbar-border: none;
+--container-below-topbar-border-radius: 0;
+
+/* Top A Container */
+--container-top-a-bg-image: none;
+--container-top-a-bg-color: transparent;
+--container-top-a-bg-position: auto;
+--container-top-a-bg-attachment: fixed;
+--container-top-a-bg-repeat: repeat;
+--container-top-a-bg-size: auto;
+--container-top-a-border: none;
+--container-top-a-border-radius: 0;
+
+/* Top B Container */
+--container-top-b-bg-image: none;
+--container-top-b-bg-color: transparent;
+--container-top-b-bg-position: auto;
+--container-top-b-bg-attachment: fixed;
+--container-top-b-bg-repeat: repeat;
+--container-top-b-bg-size: auto;
+--container-top-b-border: none;
+--container-top-b-border-radius: 0;
+
+/* TOC Container */
+--container-toc-bg: var(--mainmenu-nav-link-color);
+--container-toc-color: var(--color-primary);
+
+/* Sidebar Container */
+--container-sidebar-bg-image: none;
+--container-sidebar-bg-color: transparent;
+--container-sidebar-bg-position: auto;
+--container-sidebar-bg-attachment: scroll;
+--container-sidebar-bg-repeat: repeat;
+--container-sidebar-bg-size: auto;
+--container-sidebar-border: none;
+--container-sidebar-border-radius: 0;
+
+/* Bottom A Container */
+--container-bottom-a-bg-image: none;
+--container-bottom-a-bg-color: transparent;
+--container-bottom-a-bg-position: auto;
+--container-bottom-a-bg-attachment: fixed;
+--container-bottom-a-bg-repeat: repeat;
+--container-bottom-a-bg-size: auto;
+--container-bottom-a-border: none;
+--container-bottom-a-border-radius: 0;
+
+/* Bottom B Container */
+--container-bottom-b-bg-image: none;
+--container-bottom-b-bg-color: transparent;
+--container-bottom-b-bg-position: auto;
+--container-bottom-b-bg-attachment: fixed;
+--container-bottom-b-bg-repeat: repeat;
+--container-bottom-b-bg-size: auto;
+--container-bottom-b-border: none;
+--container-bottom-b-border-radius: 0;
+
+
+/* ===== FOCUS & FORMS ===== */
+--focus-ring-width: .25rem;
+--focus-ring-opacity: .25;
+--focus-ring-color: #01015640;
+--input-color: hsl(210, 11%, 15%);
+--input-bg: hsl(210, 20%, 98%);
+--input-border-color: hsl(210, 14%, 83%);
+--input-focus-border-color: #8894aa;
+--input-focus-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+--input-placeholder-color: hsl(210, 7%, 46%);
+--input-disabled-bg: hsl(210, 16%, 93%);
+--input-disabled-border-color: hsl(210, 14%, 83%);
+--input-file-button-active-bg: #dee1e4;
+--form-range-thumb-active-bg: #b8bfcc;
+--form-valid-color: #448344;
+--form-valid-border-color: #448344;
+--form-invalid-color: #a51f18;
+--form-invalid-border-color: #a51f18;
+
+
+/* ===== BUTTONS ===== */
+--btn-border-radius: var(--border-radius);
+--btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+
+
+/* ===== ACCORDION ===== */
+--accordion-color: hsl(210, 11%, 15%);
+--accordion-bg: var(--body-bg);
+--accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;
+--accordion-border-color: var(--border-color);
+--accordion-border-width: 1px;
+--accordion-border-radius: 0.25rem;
+--accordion-inner-border-radius: calc(0.25rem - 1px);
+--accordion-btn-padding-x: 1.25rem;
+--accordion-btn-padding-y: 1rem;
+--accordion-btn-color: hsl(210, 11%, 15%);
+--accordion-btn-bg: var(--accordion-bg);
+--accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='hsl%28210, 11%25, 15%25%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-icon-width: 1.25rem;
+--accordion-btn-icon-transform: rotate(-180deg);
+--accordion-btn-icon-transition: transform 0.2s ease-in-out;
+--accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230f244d'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-focus-border-color: var(--input-focus-border-color);
+--accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+--accordion-body-padding-x: 1.25rem;
+--accordion-body-padding-y: 1rem;
+--accordion-active-color: #0f244d;
+--accordion-active-bg: #e7eaee;
+
+
+/* ===== ALERT ===== */
+--alert-bg: transparent;
+--alert-padding-x: 1rem;
+--alert-padding-y: 1rem;
+--alert-margin-bottom: 1rem;
+--alert-color: #000;
+--alert-border-color: transparent;
+--alert-border: 1px solid var(--alert-border-color);
+--alert-border-radius: 0.25rem;
+
+
+/* ===== ALERT LINK COLORS ===== */
+--alert-primary-link-color: #01012a;
+--alert-secondary-link-color: #34383d;
+--alert-success-link-color: #213f21;
+--alert-info-link-color: #172f44;
+--alert-warning-link-color: #532f00;
+--alert-danger-link-color: #4f0f0b;
+--alert-light-link-color: #505050;
+--alert-dark-link-color: #1a1c1f;
+
+
+/* ===== BACKDROP ===== */
+--backdrop-zindex: 1040;
+--backdrop-bg: hsl(0, 0%, 0%);
+--backdrop-opacity: 0.5;
+
+
+/* ===== BADGE ===== */
+--badge-padding-x: 0.65em;
+--badge-padding-y: 0.35em;
+--badge-font-size: 0.75em;
+--badge-font-weight: 700;
+--badge-color: var(--body-bg);
+--badge-border-radius: 0.25rem;
+
+
+/* ===== BREADCRUMB ===== */
+--breadcrumb-padding-x: 0;
+--breadcrumb-padding-y: 0;
+--breadcrumb-margin-bottom: 1rem;
+--breadcrumb-bg: ;
+--breadcrumb-border-radius: ;
+--breadcrumb-divider-color: hsl(210, 7%, 46%);
+--breadcrumb-item-padding-x: 0.5rem;
+--breadcrumb-item-active-color: var(--link-color);
+
+
+/* ===== CARDS ===== */
+--card-spacer-y: 1rem;
+--card-spacer-x: 1rem;
+--card-title-spacer-y: 0.5rem;
+--card-border-width: 1px;
+--card-border-color: var(--border-color);
+--card-border-radius: var(--border-radius);
+--card-box-shadow: none;
+--card-inner-border-radius: calc(var(--border-radius) - 1px);
+--card-cap-padding-y: 0.5rem;
+--card-cap-padding-x: 1rem;
+--card-cap-bg: rgba(0, 0, 0, 0.03);
+--card-cap-color: var(--body-color);
+--card-height: auto;
+--card-color: var(--body-color);
+--card-bg: var(--body-bg);
+--card-img-overlay-padding: 1rem;
+--card-group-margin: 0.75rem;
+
+
+/* ===== DROPDOWN ===== */
+--dropdown-zindex: 1000;
+--dropdown-min-width: 10rem;
+--dropdown-padding-x: 0;
+--dropdown-padding-y: 0.5rem;
+--dropdown-spacer: 0.125rem;
+--dropdown-font-size: 1rem;
+--dropdown-color: hsl(210, 11%, 15%);
+--dropdown-bg: var(--body-bg);
+--dropdown-border-color: var(--border-color-translucent);
+--dropdown-border-radius: 0.25rem;
+--dropdown-border-width: 1px;
+--dropdown-inner-border-radius: calc(0.25rem - 1px);
+--dropdown-divider-bg: var(--border-color-translucent);
+--dropdown-divider-margin-y: 0.5rem;
+--dropdown-box-shadow: 0 0.5rem 1rem var(--shadow-color-light);
+--dropdown-link-color: hsl(210, 11%, 15%);
+--dropdown-link-active-color: var(--body-bg);
+--dropdown-link-active-bg: hsl(240, 98%, 17%);
+--dropdown-link-disabled-color: hsl(210, 11%, 71%);
+--dropdown-item-padding-x: 1rem;
+--dropdown-item-padding-y: 0.25rem;
+--dropdown-header-color: hsl(210, 7%, 46%);
+--dropdown-header-padding-x: 1rem;
+--dropdown-header-padding-y: 0.5rem;
+
+
+/* ===== LIST GROUP ===== */
+--list-group-color: hsl(210, 11%, 15%);
+--list-group-bg: var(--body-bg);
+--list-group-border-color: rgba(var(--black-rgb), 0.125);
+--list-group-border-width: 1px;
+--list-group-border-radius: 0.25rem;
+--list-group-item-padding-x: 1rem;
+--list-group-item-padding-y: 0.5rem;
+--list-group-action-color: hsl(210, 9%, 31%);
+--list-group-action-active-color: hsl(210, 11%, 15%);
+--list-group-action-active-bg: hsl(210, 16%, 93%);
+--list-group-disabled-color: hsl(210, 7%, 46%);
+--list-group-disabled-bg: var(--body-bg);
+--list-group-active-color: var(--body-bg);
+--list-group-active-bg: hsl(240, 98%, 17%);
+--list-group-active-border-color: hsl(240, 98%, 17%);
+
+
+/* ===== LIST GROUP ITEM COLORS ===== */
+--list-group-item-primary-color: #010134;
+--list-group-item-primary-bg: #ccccdd;
+--list-group-item-primary-active-bg: #b8b8c7;
+--list-group-item-secondary-color: #41464c;
+--list-group-item-secondary-bg: #e2e3e5;
+--list-group-item-secondary-active-bg: #cbccce;
+--list-group-item-success-color: #294f29;
+--list-group-item-success-bg: #dae6da;
+--list-group-item-success-active-bg: #c4cfc4;
+--list-group-item-info-color: #1d3b55;
+--list-group-item-info-bg: #d6e0e8;
+--list-group-item-info-active-bg: #c1cad1;
+--list-group-item-warning-color: #683b00;
+--list-group-item-warning-bg: #efe0cc;
+--list-group-item-warning-active-bg: #d7cab8;
+--list-group-item-danger-color: #63130e;
+--list-group-item-danger-bg: #edd2d1;
+--list-group-item-danger-active-bg: #d5bdbc;
+--list-group-item-light-color: #646464;
+--list-group-item-light-bg: #fefefe;
+--list-group-item-light-active-bg: #e5e5e5;
+--list-group-item-dark-color: #202327;
+--list-group-item-dark-bg: #d7d8d9;
+--list-group-item-dark-active-bg: #c2c2c3;
+
+
+/* ===== MODAL ===== */
+--modal-zindex: 1050;
+--modal-width: 500px;
+--modal-padding: 1rem;
+--modal-margin: 0.5rem;
+--modal-color: ;
+--modal-bg: var(--body-bg);
+--modal-border-color: var(--border-color-translucent);
+--modal-border-width: 1px;
+--modal-border-radius: 0.3rem;
+--modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
+--modal-inner-border-radius: calc(0.3rem - 1px);
+--modal-header-padding-x: 1rem;
+--modal-header-padding-y: 1rem;
+--modal-header-padding: 1rem 1rem;
+--modal-header-border-color: var(--border-color);
+--modal-header-border-width: 1px;
+--modal-title-line-height: 1.5;
+--modal-footer-gap: 0.5rem;
+--modal-footer-bg: ;
+--modal-footer-border-color: var(--border-color);
+--modal-footer-border-width: 1px;
+
+
+/* ===== NAV TABS ===== */
+--nav-tabs-border-width: 1px;
+--nav-tabs-border-color: hsl(210, 14%, 89%);
+--nav-tabs-border-radius: 0.25rem;
+--nav-tabs-link-active-color: hsl(210, 9%, 31%);
+--nav-tabs-link-active-bg: var(--body-bg);
+--nav-tabs-link-active-border-color: hsl(210, 14%, 89%) hsl(210, 14%, 89%) var(--body-bg);
+
+
+/* ===== NAV PILLS ===== */
+--nav-pills-border-radius: 0.25rem;
+--nav-pills-link-active-color: var(--body-bg);
+--nav-pills-link-active-bg: hsl(240, 98%, 17%);
+
+
+/* ===== OFFCANVAS ===== */
+--offcanvas-zindex: 1045;
+--offcanvas-width: 400px;
+--offcanvas-height: 30vh;
+--offcanvas-padding-x: 1rem;
+--offcanvas-padding-y: 1rem;
+--offcanvas-color: var(--body-color);
+--offcanvas-bg: var(--body-bg);
+--offcanvas-border-width: 1px;
+--offcanvas-border-color: var(--border-color-translucent);
+--offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
+
+
+/* ===== PAGINATION ===== */
+--pagination-padding-x: 0.75rem;
+--pagination-padding-y: 0.375rem;
+--pagination-font-size: 1rem;
+--pagination-color: var(--link-color);
+--pagination-bg: var(--body-bg);
+--pagination-border-width: 1px;
+--pagination-border-color: hsl(210, 14%, 89%);
+--pagination-border-radius: 0.25rem;
+--pagination-focus-color: var(--link-active-color);
+--pagination-focus-bg: hsl(210, 16%, 93%);
+--pagination-focus-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+--pagination-active-color: var(--body-bg);
+--pagination-active-bg: hsl(240, 98%, 17%);
+--pagination-active-border-color: hsl(240, 98%, 17%);
+--pagination-disabled-color: hsl(210, 7%, 46%);
+--pagination-disabled-bg: var(--body-bg);
+--pagination-disabled-border-color: hsl(210, 14%, 89%);
+
+
+/* ===== POPOVER ===== */
+--popover-zindex: 1060;
+--popover-max-width: 276px;
+--popover-font-size: 0.875rem;
+--popover-bg: var(--body-bg);
+--popover-border-width: 1px;
+--popover-border-color: var(--border-color-translucent);
+--popover-border-radius: 0.3rem;
+--popover-inner-border-radius: calc(0.3rem - 1px);
+--popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
+--popover-header-padding-x: 1rem;
+--popover-header-padding-y: 0.5rem;
+--popover-header-font-size: 1rem;
+--popover-header-color: ;
+--popover-header-bg: #f0f0f0;
+--popover-body-padding-x: 1rem;
+--popover-body-padding-y: 1rem;
+--popover-body-color: hsl(210, 11%, 15%);
+--popover-arrow-width: 1rem;
+--popover-arrow-height: 0.5rem;
+--popover-arrow-border: var(--popover-border-color);
+
+
+/* ===== PROGRESS ===== */
+--progress-height: 1rem;
+--progress-font-size: 0.75rem;
+--progress-bg: hsl(210, 16%, 93%);
+--progress-border-radius: 0.25rem;
+--progress-box-shadow: inset 0 1px 2px rgba(var(--black-rgb), 0.075);
+--progress-bar-color: var(--body-bg);
+--progress-bar-bg: hsl(240, 98%, 17%);
+--progress-bar-transition: width 0.6s ease;
+
+
+/* ===== SPINNER ===== */
+--spinner-width: 2rem;
+--spinner-height: 2rem;
+--spinner-vertical-align: -0.125em;
+--spinner-border-width: 0.25em;
+--spinner-animation-speed: 0.75s;
+
+
+/* ===== TABLE ===== */
+--table-color: var(--body-color);
+--table-bg: transparent;
+--table-border-color: var(--border-color);
+--table-accent-bg: transparent;
+--table-striped-color: var(--body-color);
+--table-striped-bg: rgba(var(--black-rgb), var(--opacity-5));
+--table-active-color: var(--body-color);
+--table-active-bg: rgba(var(--black-rgb), 0.075);
+
+
+/* ===== TOAST ===== */
+--toast-zindex: 1090;
+--toast-padding-x: 0.75rem;
+--toast-padding-y: 0.5rem;
+--toast-spacing: 1em;
+--toast-max-width: 350px;
+--toast-font-size: 0.875rem;
+--toast-color: ;
+--toast-bg: rgba(255, 255, 255, 0.85);
+--toast-border-width: 1px;
+--toast-border-color: var(--border-color-translucent);
+--toast-border-radius: 0.25rem;
+--toast-box-shadow: 0 0.5rem 1rem var(--shadow-color-light);
+--toast-header-color: hsl(210, 7%, 46%);
+--toast-header-bg: rgba(var(--white-rgb), 0.85);
+--toast-header-border-color: rgba(var(--black-rgb), var(--opacity-5));
+
+
+/* ===== TOOLTIP ===== */
+--tooltip-zindex: 1070;
+--tooltip-max-width: 200px;
+--tooltip-padding-x: 0.5rem;
+--tooltip-padding-y: 0.25rem;
+--tooltip-margin: ;
+--tooltip-font-size: 0.875rem;
+--tooltip-color: var(--body-bg);
+--tooltip-bg: hsl(0, 0%, 0%);
+--tooltip-border-radius: 0.25rem;
+--tooltip-opacity: 0.9;
+--tooltip-arrow-width: 0.8rem;
+--tooltip-arrow-height: 0.4rem;
+
+
+/* ===== BOOTSTRAP PALETTE ===== */
+--primary: #010156;
+--secondary: #6d757e;
+--success: #448344;
+--info: #30638d;
+--warning: #ad6200;
+--danger: #a51f18;
+--light: #f9fafb;
+--dark: #353b41;
+--primary-rgb: 1, 1, 86;
+--secondary-rgb: 109, 117, 126;
+--success-rgb: 68, 131, 68;
+--info-rgb: 48, 99, 141;
+--warning-rgb: 173, 98, 0;
+--danger-rgb: 165, 31, 24;
+--light-rgb: 249, 250, 251;
+--dark-rgb: 53, 59, 65;
+--primary-text-emphasis: #002;
+--secondary-text-emphasis: #2c2f32;
+--success-text-emphasis: #1b351b;
+--info-text-emphasis: #132838;
+--warning-text-emphasis: #452700;
+--danger-text-emphasis: #420c09;
+--light-text-emphasis: #484f56;
+--dark-text-emphasis: #484f56;
+--primary-bg-subtle: #ccd;
+--secondary-bg-subtle: #e2e3e5;
+--success-bg-subtle: #dae6da;
+--info-bg-subtle: #d6e0e8;
+--warning-bg-subtle: #efe0cc;
+--danger-bg-subtle: #edd2d1;
+--light-bg-subtle: #fcfcfd;
+--dark-bg-subtle: #ced4da;
+--primary-border-subtle: #99b;
+--secondary-border-subtle: #c5c8cb;
+--success-border-subtle: #b4ceb4;
+--info-border-subtle: #acc1d1;
+--warning-border-subtle: #dec099;
+--danger-border-subtle: #dba5a2;
+--light-border-subtle: #eaedf0;
+--dark-border-subtle: #adb5bd;
+
+
+/* ===== HERO / BANNER OVERLAY ===== */
+--hero-height: 70vh;
+--hero-color: var(--body-color);
+--hero-bg-repeat: no-repeat;
+--hero-bg-attachment: fixed;
+--hero-bg-position: top center;
+--hero-bg-size: cover;
+--hero-border-bottom: solid var(--accent-color-secondary);
+--hero-overlay-bg: hsla(0, 0%, 0%, 0.1);
+--hero-overlay-bg-position: center;
+--hero-overlay-bg-size: cover;
+--hero-overlay-padding: 1em;
+--hero-overlay-text-align: center;
+--hero-overlay-text-color: var(--body-color);
+
+
+/* ===== HERO VARIANTS ===== */
+/* Primary — sky blue, light overlay */
+--hero-primary-bg-color: var(--color-primary);
+--hero-primary-overlay: linear-gradient(rgba(163, 205, 226, .45), rgba(163, 205, 226, .45));
+--hero-primary-color: var(--color-primary);
+
+/* Secondary — navy, stronger overlay */
+--hero-secondary-bg-color: var(--color-primary);
+--hero-secondary-overlay: linear-gradient(rgba(17, 40, 85, .75), rgba(17, 40, 85, .75));
+--hero-secondary-color: #f1f5f9;
+
+
+/* ===== HERO CARD (inner .hero element) ===== */
+/* Default card — uses primary variant values */
+--hero-card-bg: var(--hero-primary-bg-color);
+--hero-card-color: white;
+--hero-card-overlay: var(--hero-primary-overlay);
+--hero-card-border-radius: .5rem;
+--hero-card-padding-x: 2rem;
+--hero-card-padding-y: 3rem;
+--hero-card-max-width: 800px;
+
+/* Alternative card — uses secondary variant values */
+--hero-alt-card-bg: var(--hero-secondary-bg-color);
+--hero-alt-card-color: var(--hero-secondary-color);
+--hero-alt-card-overlay: var(--hero-secondary-overlay);
+--hero-alt-card-border-radius: .5rem;
+--hero-alt-card-padding-x: 2rem;
+--hero-alt-card-padding-y: 3rem;
+--hero-alt-card-max-width: 600px;
+
+
+/* ===== BLOCK COLORS (top-a / top-b / bottom-a / bottom-b) ===== */
+--block-color-1: var(--color-primary);
+--block-text-1: var(--body-color);
+
+--block-color-2: var(--accent-color-primary);
+--block-text-2: #fff;
+
+--block-color-3: var(--warning, #eec234);
+--block-text-3: var(--body-color);
+
+--block-color-4: var(--success-bg-subtle, #eef7f0);
+--block-text-4: var(--body-color);
+
+
+/* ===== BLOCK COLOR OVERRIDES ===== */
+--block-highlight-bg: var(--accent-color-primary);
+--block-highlight-text: #fff;
+
+--block-cta-bg: var(--color-primary);
+--block-cta-text: #fff;
+
+--block-alert-bg: var(--danger, #a51f18);
+--block-alert-text: #fff;
+
+
+/* ===== FOOTER ===== */
+--footer-padding-top: 1rem;
+--footer-padding-bottom: 80px;
+--footer-grid-padding-y: 2.5rem;
+--footer-grid-padding-x: 0.5em;
+
+
+/* ===== THEME FAB ===== */
+--theme-fab-bg: var(--color-primary, #112855);
+--theme-fab-color: #fff;
+--theme-fab-btn-bg: rgba(255,255,255,.15);
+--theme-fab-border: rgba(255, 255, 255, 0.3);
+
+
+/* ===== OFFLINE PAGE ===== */
+--offline-card-bg: rgba(0, 0, 0, 0.55);
+
+
+/* ===== COMPONENT-SPECIFIC COLORS ===== */
+--mod-finder-link-hover: #e6e6e6;
+--form-legend-color: #495057;
+--border-gray: #b2bfcd;
+--subhead-color: #495057;
+--box-shadow-gray: #ddd;
+--btn-active-text-gray: #A0A0A0;
+--indicator-success-bg: var(--success);
+--item-list-color: #F5F5F5;
+--notification-badge-bg: var(--danger);
+--content-bg-gray: #DDD;
+--taba-btn-green: #7ac143;
+--taba-btn-blue: #5091cd;
+--taba-btn-red: #f44321;
+--taba-btn-gray: #AAA;
+--taba-msg-bg: #f5f5f5;
+--toc-link-color: #767676;
+--toc-link-active-color: #563d7c;
+--choices-disabled-bg: #eaeaea;
+--choices-input-bg: var(--white);
+--choices-border-light: #ddd;
+--choices-arrow-color: #333;
+--choices-inner-bg: #f9f9f9;
+--choices-focused-border: #b7b7b7;
+--choices-dropdown-bg: var(--white);
+--choices-item-bg: #00bcd4;
+--choices-item-border: #00a5bb;
+--choices-item-hover-bg: #00a5bb;
+--choices-item-hover-border: #008fa1;
+--choices-item-disabled-bg: #aaaaaa;
+--choices-item-disabled-border: #919191;
+--choices-item-highlighted: #f2f2f2;
+--choices-input-inner-bg: #f9f9f9;
+
+
+/* ===== VIRTUEMART (VM) ===== */
+/* VM Surfaces */
+--vm-surface: #ffffff;
+--vm-surface-2: #f8f9fa;
+--vm-text: var(--body-color);
+--vm-text-strong: #000000;
+--vm-text-muted: #6c757d;
+--vm-border: var(--border-color);
+--vm-price-color: var(--success);
+
+/* VM Layout and Density */
+--vm-container-max-width: 1200px;
+--vm-section-gap: 2rem;
+--vm-block-radius: var(--border-radius);
+--vm-block-shadow: var(--box-shadow-sm);
+
+/* VM Typography */
+--vm-category-title-size: 2rem;
+--vm-subcategory-title-size: 1.5rem;
+--vm-page-title-size: 1.75rem;
+--vm-products-type-title-size: 1.25rem;
+--vm-product-title-size: 1.125rem;
+--vm-product-title-weight: 500;
+--vm-products-type-title-weight: 600;
+--vm-price-size: 1.5rem;
+--vm-price-detail-size: 1.125rem;
+--vm-price-desc-size: 0.875rem;
+
+/* VM Controls */
+--vm-input-radius: var(--border-radius);
+--vm-input-shadow: var(--box-shadow-sm);
+--vm-qty-width: 80px;
+--vm-cart-dropdown-min-width: 300px;
+
+/* VM Alerts */
+--vm-alert-radius: var(--border-radius);
+--vm-alert-shadow: var(--box-shadow-sm);
+--vm-availability-bg: var(--success-bg-subtle);
+--vm-availability-text: var(--success);
+
+/* VM Buttons */
+--vm-btn-padding-x: 1rem;
+--vm-btn-padding-y: 0.5rem;
+--vm-btn-radius: var(--border-radius);
+--vm-btn-shadow: var(--box-shadow-sm);
+--vm-btn-primary-bg: var(--primary);
+--vm-btn-primary-text: #ffffff;
+--vm-btn-primary-border: var(--primary);
+--vm-btn-secondary-bg: var(--secondary);
+--vm-btn-secondary-text: #ffffff;
+--vm-btn-secondary-border: var(--secondary);
+
+/* VM Image Overlay Controls */
+--vm-image-overlay-gap-x: 0.5rem;
+--vm-image-overlay-gap-y: 0.5rem;
+--vm-image-overlay-raise: 0.25rem;
+--vm-image-overlay-btn-size: 2.5rem;
+--vm-image-overlay-btn-radius: 50%;
+--vm-image-overlay-btn-bg: rgba(255, 255, 255, 0.9);
+--vm-image-overlay-btn-bg-hover: rgba(255, 255, 255, 1);
+--vm-image-overlay-btn-border-color: rgba(0, 0, 0, 0.1);
+--vm-image-overlay-btn-border-width: 1px;
+--vm-image-overlay-btn-color: var(--body-color);
+--vm-image-overlay-btn-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+
+/* VM Vendor Menu */
+--vm-vendor-menu-bg: var(--body-bg);
+--vm-vendor-menu-border: var(--border-color);
+--vm-vendor-menu-radius: var(--border-radius);
+--vm-vendor-menu-shadow: var(--box-shadow-sm);
+--vm-vendor-menu-item-gap: 0.25rem;
+--vm-vendor-menu-item-padding-x: 1rem;
+--vm-vendor-menu-item-padding-y: 0.5rem;
+--vm-vendor-menu-pill-radius: 50rem;
+--vm-vendor-menu-link: var(--link-color);
+--vm-vendor-menu-link-hover: var(--link-hover-color);
+--vm-vendor-menu-link-active: var(--primary);
+--vm-vendor-menu-hover-bg: var(--secondary-bg);
+
+
+/* ===== GABLE ===== */
+--gab-blue: #0066cc;
+--gab-green: #28a745;
+--gab-red: #dc3545;
+--gab-orange: #fd7e14;
+--gab-gray1: #495057;
+--gab-gray2: #6c757d;
+--gab-gray3: #adb5bd;
+
+}
+
+.btn {
+--btn-padding-x: 1rem;
+--btn-padding-y: 0.6rem;
+--btn-font-family: inherit;
+--btn-font-size: 1rem;
+--btn-font-weight: 400;
+--btn-line-height: 1.5;
+--btn-color: hsl(210, 11%, 15%);
+--btn-bg: var(--body-bg);
+--btn-border-width: 1px;
+--btn-border-color: transparent;
+--btn-border-radius: 0.25rem;
+--btn-active-border-color: transparent;
+--btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+--btn-disabled-opacity: 0.65;
+--btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5);
+display: inline-block;
+padding: var(--btn-padding-y) var(--btn-padding-x);
+font-family: var(--btn-font-family);
+font-size: var(--btn-font-size);
+font-weight: var(--btn-font-weight);
+line-height: var(--btn-line-height);
+color: var(--btn-color);
+text-align: center;
+text-decoration: none;
+vertical-align: middle;
+cursor: pointer;
+-webkit-user-select: none;
+-moz-user-select: none;
+-ms-user-select: none;
+user-select: none;
+border: var(--btn-border-width) solid var(--btn-border-color);
+border-radius: var(--btn-border-radius);
+background-color: var(--btn-bg);
+-webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+-o-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+}
+
+.btn-primary {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(240, 98%, 17%);
+--btn-border-color: hsl(240, 98%, 17%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #010149;
+--btn-hover-border-color: #010145;
+--btn-focus-shadow-rgb: 39, 39, 111;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #010145;
+--btn-active-border-color: #010141;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(240, 98%, 17%);
+--btn-disabled-border-color: hsl(240, 98%, 17%);
+}
+
+.btn-secondary {
+--btn-color: var(--body-bg);
+--btn-bg: var(--nav-bg-color);
+--btn-border-color: hsl(210, 7%, 46%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #5d636b;
+--btn-hover-border-color: #575e65;
+--btn-focus-shadow-rgb: gray;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #575e65;
+--btn-active-border-color: #52585f;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(210, 7%, 46%);
+--btn-disabled-border-color: hsl(210, 7%, 46%);
+}
+
+.btn-success {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(120, 32%, 39%);
+--btn-border-color: hsl(120, 32%, 39%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #3a6f3a;
+--btn-hover-border-color: #366936;
+--btn-focus-shadow-rgb: 96, 150, 96;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #366936;
+--btn-active-border-color: #336233;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(120, 32%, 39%);
+--btn-disabled-border-color: hsl(120, 32%, 39%);
+}
+
+.btn-info {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(207, 49%, 37%);
+--btn-border-color: hsl(207, 49%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #295478;
+--btn-hover-border-color: #264f71;
+--btn-focus-shadow-rgb: 79, 122, 158;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #264f71;
+--btn-active-border-color: #244a6a;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(207, 49%, 37%);
+--btn-disabled-border-color: hsl(207, 49%, 37%);
+}
+
+.btn-warning {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(34, 100%, 34%);
+--btn-border-color: hsl(34, 100%, 34%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #935300;
+--btn-hover-border-color: #8a4e00;
+--btn-focus-shadow-rgb: 185, 122, 38;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #8a4e00;
+--btn-active-border-color: #824a00;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(34, 100%, 34%);
+--btn-disabled-border-color: hsl(34, 100%, 34%);
+}
+
+.btn-danger {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(3, 75%, 37%);
+--btn-border-color: hsl(3, 75%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #8c1a14;
+--btn-hover-border-color: #841913;
+--btn-focus-shadow-rgb: 179, 65, 59;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #841913;
+--btn-active-border-color: #7c1712;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(3, 75%, 37%);
+--btn-disabled-border-color: hsl(3, 75%, 37%);
+}
+
+.btn-light {
+--btn-color: hsl(0, 0%, 0%);
+--btn-bg: hsl(210, 17%, 98%);
+--btn-border-color: hsl(210, 17%, 98%);
+--btn-hover-color: hsl(0, 0%, 0%);
+--btn-hover-bg: #d4d5d5;
+--btn-hover-border-color: #c7c8c9;
+--btn-focus-shadow-rgb: 212, 213, 213;
+--btn-active-color: hsl(0, 0%, 0%);
+--btn-active-bg: #c7c8c9;
+--btn-active-border-color: #bbbcbc;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 0%);
+--btn-disabled-bg: hsl(210, 17%, 98%);
+--btn-disabled-border-color: hsl(210, 17%, 98%);
+}
+
+.btn-dark {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(210, 10%, 23%);
+--btn-border-color: hsl(210, 10%, 23%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #53585e;
+--btn-hover-border-color: #494f54;
+--btn-focus-shadow-rgb: 83, 88, 94;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #5d6267;
+--btn-active-border-color: #494f54;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(210, 10%, 23%);
+--btn-disabled-border-color: hsl(210, 10%, 23%);
+}
+
+.btn-outline-primary {
+--btn-color: hsl(240, 98%, 17%);
+--btn-border-color: hsl(240, 98%, 17%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(240, 98%, 17%);
+--btn-hover-border-color: hsl(240, 98%, 17%);
+--btn-focus-shadow-rgb: 1, 1, 86;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(240, 98%, 17%);
+--btn-active-border-color: hsl(240, 98%, 17%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(240, 98%, 17%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(240, 98%, 17%);
+--gradient: none;
+}
+
+.btn-outline-secondary {
+--btn-color: hsl(210, 7%, 46%);
+--btn-border-color: hsl(210, 7%, 46%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(210, 7%, 46%);
+--btn-hover-border-color: hsl(210, 7%, 46%);
+--btn-focus-shadow-rgb: 109, 117, 126;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(210, 7%, 46%);
+--btn-active-border-color: hsl(210, 7%, 46%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(210, 7%, 46%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(210, 7%, 46%);
+--gradient: none;
+}
+
+.btn-outline-success {
+--btn-color: hsl(120, 32%, 39%);
+--btn-border-color: hsl(120, 32%, 39%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(120, 32%, 39%);
+--btn-hover-border-color: hsl(120, 32%, 39%);
+--btn-focus-shadow-rgb: 68, 131, 68;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(120, 32%, 39%);
+--btn-active-border-color: hsl(120, 32%, 39%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(120, 32%, 39%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(120, 32%, 39%);
+--gradient: none;
+}
+
+.btn-outline-info {
+--btn-color: hsl(207, 49%, 37%);
+--btn-border-color: hsl(207, 49%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(207, 49%, 37%);
+--btn-hover-border-color: hsl(207, 49%, 37%);
+--btn-focus-shadow-rgb: 48, 99, 141;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(207, 49%, 37%);
+--btn-active-border-color: hsl(207, 49%, 37%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(207, 49%, 37%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(207, 49%, 37%);
+--gradient: none;
+}
+
+.btn-outline-warning {
+--btn-color: hsl(34, 100%, 34%);
+--btn-border-color: hsl(34, 100%, 34%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(34, 100%, 34%);
+--btn-hover-border-color: hsl(34, 100%, 34%);
+--btn-focus-shadow-rgb: 173, 98, 0;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(34, 100%, 34%);
+--btn-active-border-color: hsl(34, 100%, 34%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(34, 100%, 34%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(34, 100%, 34%);
+--gradient: none;
+}
+
+.btn-outline-danger {
+--btn-color: hsl(3, 75%, 37%);
+--btn-border-color: hsl(3, 75%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(3, 75%, 37%);
+--btn-hover-border-color: hsl(3, 75%, 37%);
+--btn-focus-shadow-rgb: 165, 31, 24;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(3, 75%, 37%);
+--btn-active-border-color: hsl(3, 75%, 37%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(3, 75%, 37%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(3, 75%, 37%);
+--gradient: none;
+}
+
+.btn-outline-light {
+--btn-color: hsl(210, 17%, 98%);
+--btn-border-color: hsl(210, 17%, 98%);
+--btn-hover-color: hsl(0, 0%, 0%);
+--btn-hover-bg: hsl(210, 17%, 98%);
+--btn-hover-border-color: hsl(210, 17%, 98%);
+--btn-focus-shadow-rgb: 249, 250, 251;
+--btn-active-color: hsl(0, 0%, 0%);
+--btn-active-bg: hsl(210, 17%, 98%);
+--btn-active-border-color: hsl(210, 17%, 98%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(210, 17%, 98%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(210, 17%, 98%);
+--gradient: none;
+}
+
+.btn-outline-dark {
+--btn-color: hsl(210, 10%, 23%);
+--btn-border-color: hsl(210, 10%, 23%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(210, 10%, 23%);
+--btn-hover-border-color: hsl(210, 10%, 23%);
+--btn-focus-shadow-rgb: 53, 59, 65;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(210, 10%, 23%);
+--btn-active-border-color: hsl(210, 10%, 23%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(210, 10%, 23%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(210, 10%, 23%);
+--gradient: none;
+}
+
+.btn-link {
+--btn-font-weight: 400;
+--btn-color: var(--link-color);
+--btn-bg: transparent;
+--btn-border-color: transparent;
+--btn-hover-color: var(--link-hover-color);
+--btn-hover-border-color: transparent;
+--btn-active-color: var(--link-hover-color);
+--btn-active-border-color: transparent;
+--btn-disabled-color: hsl(210, 7%, 46%);
+--btn-disabled-border-color: transparent;
+--btn-box-shadow: none;
+--btn-focus-shadow-rgb: 39, 39, 111;
+text-decoration: underline;
+}
From c97af7c1c84dd96dc0a53560f675648fee464739 Mon Sep 17 00:00:00 2001
From: Jonathan Miller
Date: Sun, 19 Apr 2026 13:16:30 -0500
Subject: [PATCH 10/10] =?UTF-8?q?Bump=20version=2003.10.08=20=E2=86=92=200?=
=?UTF-8?q?3.10.09?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 4 ++--
src/joomla.asset.json | 2 +-
src/templateDetails.xml | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index cb2eba5..d03e10c 100644
--- a/README.md
+++ b/README.md
@@ -9,13 +9,13 @@
INGROUP: MokoCassiopeia.Documentation
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia
FILE: ./README.md
- VERSION: 03.10.08
+ VERSION: 03.10.09
BRIEF: Documentation for MokoCassiopeia template
-->
# MokoCassiopeia → MokoOnyx
-> **This template is being renamed to MokoOnyx.** Version 03.10.08 is the bridge release that automatically migrates your settings. After updating, MokoOnyx will be your active template and MokoCassiopeia can be safely uninstalled.
+> **This template is being renamed to MokoOnyx.** Version 03.10.09 is the bridge release that automatically migrates your settings. After updating, MokoOnyx will be your active template and MokoCassiopeia can be safely uninstalled.
**A Modern, Lightweight Joomla Template Based on Cassiopeia**
diff --git a/src/joomla.asset.json b/src/joomla.asset.json
index d6c434c..a6a6548 100644
--- a/src/joomla.asset.json
+++ b/src/joomla.asset.json
@@ -17,7 +17,7 @@
"defgroup": "Joomla.Template.Site",
"ingroup": "MokoCassiopeia.Template.Assets",
"path": "./media/templates/site/mokocassiopeia/joomla.asset.json",
- "version": "03.10.08",
+ "version": "03.10.09",
"brief": "Joomla asset registry for MokoCassiopeia"
}
},
diff --git a/src/templateDetails.xml b/src/templateDetails.xml
index 40918ec..33fd39b 100644
--- a/src/templateDetails.xml
+++ b/src/templateDetails.xml
@@ -39,13 +39,13 @@
MokoCassiopeia
- 03.10.08
+ 03.10.09
script.php
2026-04-15
Jonathan Miller || Moko Consulting
hello@mokoconsulting.tech
(C)GNU General Public License Version 3 - 2026 Moko Consulting
-
MokoCassiopeia Template Description
MokoCassiopeia continues Joomla's tradition of space-themed default templates— building on the legacy of Solarflare (Joomla 1.0), Milkyway (Joomla 1.5), and Protostar (Joomla 3.0).
This template is a customized fork of the Cassiopeia template introduced in Joomla 4, preserving its modern, accessible, and mobile-first foundation while introducing new stylistic enhancements and structural refinements specifically tailored for use by Moko Consulting.
Custom Colour Themes
Starter palette files are included with the template. To create a custom colour scheme, copy templates/mokocassiopeia/templates/light.custom.css to media/templates/site/mokocassiopeia/css/theme/light.custom.css, or templates/mokocassiopeia/templates/dark.custom.css to media/templates/site/mokocassiopeia/css/theme/dark.custom.css. Customise the CSS variables to match your brand, then activate your palette in System → Site Templates → MokoCassiopeia → Theme tab by selecting "Custom" for the Light or Dark Mode Palette. A full variable reference is available in the CSS Variables tab in template options.
Custom CSS & JavaScript
For site-specific styles and scripts that should survive template updates, create the following files:
media/templates/site/mokocassiopeia/css/user.css — loaded on every page for custom CSS overrides. media/templates/site/mokocassiopeia/js/user.js — loaded on every page for custom JavaScript.
These files are gitignored and will not be overwritten by template updates.
Code Attribution
This template is based on the original Cassiopeia template developed by the Joomla! Project and released under the GNU General Public License.
Modifications and enhancements have been made by Moko Consulting in accordance with open-source licensing standards.
It includes integration with Bootstrap TOC, an open-source table of contents generator by A. Feld, licensed under the MIT License.
All third-party libraries and assets remain the property of their respective authors and are credited within their source files where applicable.
]]>
+
MokoCassiopeia Template Description
MokoCassiopeia continues Joomla's tradition of space-themed default templates— building on the legacy of Solarflare (Joomla 1.0), Milkyway (Joomla 1.5), and Protostar (Joomla 3.0).
This template is a customized fork of the Cassiopeia template introduced in Joomla 4, preserving its modern, accessible, and mobile-first foundation while introducing new stylistic enhancements and structural refinements specifically tailored for use by Moko Consulting.
Custom Colour Themes
Starter palette files are included with the template. To create a custom colour scheme, copy templates/mokocassiopeia/templates/light.custom.css to media/templates/site/mokocassiopeia/css/theme/light.custom.css, or templates/mokocassiopeia/templates/dark.custom.css to media/templates/site/mokocassiopeia/css/theme/dark.custom.css. Customise the CSS variables to match your brand, then activate your palette in System → Site Templates → MokoCassiopeia → Theme tab by selecting "Custom" for the Light or Dark Mode Palette. A full variable reference is available in the CSS Variables tab in template options.
Custom CSS & JavaScript
For site-specific styles and scripts that should survive template updates, create the following files:
media/templates/site/mokocassiopeia/css/user.css — loaded on every page for custom CSS overrides. media/templates/site/mokocassiopeia/js/user.js — loaded on every page for custom JavaScript.
These files are gitignored and will not be overwritten by template updates.
Code Attribution
This template is based on the original Cassiopeia template developed by the Joomla! Project and released under the GNU General Public License.
Modifications and enhancements have been made by Moko Consulting in accordance with open-source licensing standards.
It includes integration with Bootstrap TOC, an open-source table of contents generator by A. Feld, licensed under the MIT License.
All third-party libraries and assets remain the property of their respective authors and are credited within their source files where applicable.
]]>
1
component.php