From c13ed61d4e8591a96e9debf96a0b0c0e62ba7395 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 17:18:36 -0500 Subject: [PATCH 01/13] Fix footer color variable and remove unused page-link styles Use --body-color instead of --body-bg for footer text color, and remove redundant .page-link / .page-link:active rules. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/media/css/template.css | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/media/css/template.css b/src/media/css/template.css index 2251e3f..3d1854f 100644 --- a/src/media/css/template.css +++ b/src/media/css/template.css @@ -13780,14 +13780,6 @@ meter { margin-left: auto; } -.page-link { - color: var(--color-link, white); -} - -.page-link:active { - color: var(--color-link, white); -} - .pager .pagination { -webkit-box-pack: center; -ms-flex-pack: center; @@ -13988,7 +13980,7 @@ meter { .footer { padding-top: 1rem; - color: var(--body-bg, #e6ebf1); + color: var(--body-color, #e6ebf1); background-color: var(--nav-bg-color); padding-bottom: 80px; } From a6bd0662d5532f7d1c050ab3017fffb2947f47cb Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 17:24:19 -0500 Subject: [PATCH 02/13] Update footer text color to use nav link color variable Co-Authored-By: Claude Opus 4.6 (1M context) --- src/media/css/template.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/media/css/template.css b/src/media/css/template.css index 3d1854f..792b60c 100644 --- a/src/media/css/template.css +++ b/src/media/css/template.css @@ -13980,7 +13980,7 @@ meter { .footer { padding-top: 1rem; - color: var(--body-color, #e6ebf1); + color: var(--mainmenu-nav-link-color, #fff); background-color: var(--nav-bg-color); padding-bottom: 80px; } From 4d96b0c7ac856341afe17c03c0d86bc9017aeb23 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 17:35:16 -0500 Subject: [PATCH 03/13] Update footer grid-child padding to use navbar CSS variables Co-Authored-By: Claude Opus 4.6 (1M context) --- src/media/css/template.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/media/css/template.css b/src/media/css/template.css index 792b60c..48f7bb5 100644 --- a/src/media/css/template.css +++ b/src/media/css/template.css @@ -15773,7 +15773,7 @@ body.wrapper-fluid header>.grid-child { } footer .grid-child>div { - padding: 1rem 0 0; + padding: var(--navbar-padding-y, 1rem) var(--navbar-padding-x, 1rem) 0; } header .grid-child .navbar-brand { From befd1380612fdf31537704035dc32650651b9c48 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 17:53:44 -0500 Subject: [PATCH 04/13] =?UTF-8?q?chore(version):=20bump=2003.09.13=20?= =?UTF-8?q?=E2=86=92=2003.09.14,=20CSS=20padding=20variables,=20Gitea=20UR?= =?UTF-8?q?Ls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace hardcoded padding with CSS variables in footer and header - Bump version to 03.09.14 across all manifest files - Switch update server and download URLs from GitHub to Gitea Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 +- src/joomla.asset.json | 2 +- src/media/css/template.css | 10 ++++----- src/templateDetails.xml | 8 ++++---- updates.xml | 42 +++++++++++++++++++------------------- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index f120c8e..4b0816d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ INGROUP: MokoCassiopeia.Documentation REPO: https://github.com/mokoconsulting-tech/MokoCassiopeia FILE: ./README.md - VERSION: 03.09.13 + VERSION: 03.09.14 BRIEF: Documentation for MokoCassiopeia template --> diff --git a/src/joomla.asset.json b/src/joomla.asset.json index ff60ae1..56ff7a1 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.09.02", + "version": "03.09.14", "brief": "Joomla asset registry for MokoCassiopeia" } }, diff --git a/src/media/css/template.css b/src/media/css/template.css index 48f7bb5..737af8e 100644 --- a/src/media/css/template.css +++ b/src/media/css/template.css @@ -13979,10 +13979,10 @@ meter { } .footer { - padding-top: 1rem; + padding-top: var(--footer-padding-top, 1rem); color: var(--mainmenu-nav-link-color, #fff); background-color: var(--nav-bg-color); - padding-bottom: 80px; + padding-bottom: var(--footer-padding-bottom, 80px); } .footer .grid-child { @@ -13994,7 +13994,7 @@ meter { -ms-flex-direction: column; flex-direction: column; width: 100%; - padding: 2.5rem 0.5em; + padding: var(--footer-grid-padding-y, 2.5rem) var(--footer-grid-padding-x, 0.5em); } .footer a { @@ -14240,8 +14240,8 @@ fieldset>* { .container-header .navbar-brand { position: relative; display: inline-block; - padding-top: 0.3125rem; - padding-bottom: 0.3125rem; + padding-top: var(--navbar-brand-padding-y, 0.3125rem); + padding-bottom: var(--navbar-brand-padding-y, 0.3125rem); font-size: 2rem; color: var(--nav-text-color, gray); -webkit-margin-end: auto; diff --git a/src/templateDetails.xml b/src/templateDetails.xml index fd87629..d4af938 100644 --- a/src/templateDetails.xml +++ b/src/templateDetails.xml @@ -32,17 +32,17 @@ - https://raw.githubusercontent.com/mokoconsulting-tech/MokoCassiopeia/main/updates.xml + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/raw/branch/main/updates.xml MokoCassiopeia - 03.09.12 + 03.09.14 script.php - 2026-03-26 + 2026-04-14 Jonathan Miller || Moko Consulting hello@mokoconsulting.tech (C)GNU General Public License Version 3 - 2026 Moko Consulting - Version 03.09.12 License Joomla PHP

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.

]]>
+ Version 03.09.14 License Joomla PHP

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/updates.xml b/updates.xml index f5eb54d..33f5688 100644 --- a/updates.xml +++ b/updates.xml @@ -1,7 +1,7 @@ @@ -13,11 +13,11 @@ mokocassiopeia template site - 03.09.12 - 2026-04-08 - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/development + 03.09.14 + 2026-04-14 + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/development - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/development/mokocassiopeia-03.09.12-dev.zip + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/development/mokocassiopeia-03.09.14-dev.zip c2660acdf7389244462485f7ab4c286e9f851366a148acc16739a184576f7932 development @@ -33,11 +33,11 @@ mokocassiopeia template site - 03.09.12 - 2026-04-08 - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/alpha + 03.09.14 + 2026-04-14 + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/alpha - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/alpha/mokocassiopeia-03.09.12-alpha.zip + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/alpha/mokocassiopeia-03.09.14-alpha.zip c2660acdf7389244462485f7ab4c286e9f851366a148acc16739a184576f7932 alpha @@ -53,11 +53,11 @@ mokocassiopeia template site - 03.09.12 - 2026-04-08 - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/beta + 03.09.14 + 2026-04-14 + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/beta - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/beta/mokocassiopeia-03.09.12-beta.zip + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/beta/mokocassiopeia-03.09.14-beta.zip c2660acdf7389244462485f7ab4c286e9f851366a148acc16739a184576f7932 beta @@ -73,11 +73,11 @@ mokocassiopeia template site - 03.09.12 - 2026-04-08 - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/release-candidate + 03.09.14 + 2026-04-14 + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/release-candidate - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/release-candidate/mokocassiopeia-03.09.12-rc.zip + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/release-candidate/mokocassiopeia-03.09.14-rc.zip c2660acdf7389244462485f7ab4c286e9f851366a148acc16739a184576f7932 rc @@ -93,11 +93,11 @@ mokocassiopeia template site - 03.09.12 - 2026-04-08 - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03 + 03.09.14 + 2026-04-14 + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/v03 - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.09.12.zip + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.09.14.zip c2660acdf7389244462485f7ab4c286e9f851366a148acc16739a184576f7932 stable From 15a43fcdcac4ff7c538e6848e9cfe8e2ebfcb9bc Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 17:55:26 -0500 Subject: [PATCH 05/13] Add GitHub fallback update server, update beta SHA-256 - Add secondary update server pointing to GitHub as fallback - Update beta release SHA-256 hash to match actual build Co-Authored-By: Claude Opus 4.6 (1M context) --- src/templateDetails.xml | 5 ++++- updates.xml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/templateDetails.xml b/src/templateDetails.xml index d4af938..d4cc404 100644 --- a/src/templateDetails.xml +++ b/src/templateDetails.xml @@ -31,9 +31,12 @@ --> - + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/raw/branch/main/updates.xml + + https://raw.githubusercontent.com/mokoconsulting-tech/MokoCassiopeia/main/updates.xml + MokoCassiopeia 03.09.14 diff --git a/updates.xml b/updates.xml index 33f5688..705da7a 100644 --- a/updates.xml +++ b/updates.xml @@ -59,7 +59,7 @@ https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/beta/mokocassiopeia-03.09.14-beta.zip - c2660acdf7389244462485f7ab4c286e9f851366a148acc16739a184576f7932 + d2654fe1f0c2c83e4901aad775937dea07211096e0df886cff2a2b465d0e0840 beta Moko Consulting https://mokoconsulting.tech From 652307b7746f49851845546fb1fb260d749d4624 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 18:02:26 -0500 Subject: [PATCH 06/13] Integrate MokoStandards API for build and validation - Add mokoconsulting-tech/enterprise as Composer dev dependency - Replace generic Makefile with MokoStandards CLI-powered targets - Validation: check:syntax, check:joomla, check:version, check:xml, check:headers, check:secrets, health - Build: reads version from README.md, packages src/ into installable ZIP - Cross-platform ZIP support (zip, pwsh, powershell) Co-Authored-By: Claude Opus 4.6 (1M context) --- Makefile | 390 +++++++++++++++++--------------------------------- composer.json | 30 +++- 2 files changed, 157 insertions(+), 263 deletions(-) diff --git a/Makefile b/Makefile index ec94cc9..dc8ca18 100644 --- a/Makefile +++ b/Makefile @@ -1,58 +1,32 @@ -# Makefile for Joomla Extensions +# Makefile for MokoCassiopeia Joomla Template # Copyright (C) 2026 Moko Consulting # SPDX-License-Identifier: GPL-3.0-or-later # -# This is a reference Makefile for building Joomla extensions. -# Copy this to your repository root as "Makefile" and customize as needed. -# -# Supports: Modules, Plugins, Components, Packages, Templates +# Build and validation powered by MokoStandards Enterprise API +# Install: composer install # ============================================================================== -# CONFIGURATION - Customize these for your extension +# CONFIGURATION # ============================================================================== -# Extension Configuration -EXTENSION_NAME := mokoexample -EXTENSION_TYPE := module -# Options: module, plugin, component, package, template -EXTENSION_VERSION := 1.0.0 +EXTENSION_NAME := mokocassiopeia +EXTENSION_TYPE := template +EXTENSION_VERSION := $(shell grep -oP 'VERSION:\s*\K[0-9.]+' README.md 2>/dev/null || echo "0.0.0") -# Module Configuration (for modules only) -MODULE_TYPE := site -# Options: site, admin - -# Plugin Configuration (for plugins only) -PLUGIN_GROUP := system -# Options: system, content, user, authentication, etc. - -# Directories -SRC_DIR := . +SRC_DIR := src BUILD_DIR := build -DIST_DIR := dist -DOCS_DIR := docs +DIST_DIR := dist -# Joomla Installation (for local testing - customize paths) -JOOMLA_ROOT := /var/www/html/joomla -JOOMLA_VERSION := 4 - -# Tools -PHP := php +PHP := php COMPOSER := composer -NPM := npm -PHPCS := vendor/bin/phpcs -PHPCBF := vendor/bin/phpcbf -PHPUNIT := vendor/bin/phpunit -ZIP := zip +MOKO := vendor/bin/moko -# Coding Standards -PHPCS_STANDARD := Joomla - -# Colors for output -COLOR_RESET := \033[0m -COLOR_GREEN := \033[32m +# Colors +COLOR_RESET := \033[0m +COLOR_GREEN := \033[32m COLOR_YELLOW := \033[33m -COLOR_BLUE := \033[34m -COLOR_RED := \033[31m +COLOR_BLUE := \033[34m +COLOR_RED := \033[31m # ============================================================================== # TARGETS @@ -61,92 +35,85 @@ COLOR_RED := \033[31m .PHONY: help help: ## Show this help message @echo "$(COLOR_BLUE)╔════════════════════════════════════════════════════════════╗$(COLOR_RESET)" - @echo "$(COLOR_BLUE)║ Joomla Extension Makefile ║$(COLOR_RESET)" + @echo "$(COLOR_BLUE)║ MokoCassiopeia Template Build ║$(COLOR_RESET)" @echo "$(COLOR_BLUE)╚════════════════════════════════════════════════════════════╝$(COLOR_RESET)" @echo "" @echo "Extension: $(EXTENSION_NAME) ($(EXTENSION_TYPE)) v$(EXTENSION_VERSION)" + @echo "Powered by: MokoStandards Enterprise API" @echo "" @echo "$(COLOR_GREEN)Available targets:$(COLOR_RESET)" @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " $(COLOR_BLUE)%-20s$(COLOR_RESET) %s\n", $$1, $$2}' @echo "" - @echo "$(COLOR_YELLOW)Quick Start:$(COLOR_RESET)" - @echo " 1. make install-deps # Install dependencies" - @echo " 2. make build # Build extension package" - @echo " 3. make test # Run tests" - @echo "" + +# ── Dependencies ────────────────────────────────────────────────────────────── .PHONY: install-deps -install-deps: ## Install all dependencies (Composer + npm) +install-deps: ## Install Composer dependencies (includes MokoStandards API) @echo "$(COLOR_BLUE)Installing dependencies...$(COLOR_RESET)" - @if [ -f "composer.json" ]; then \ - $(COMPOSER) install; \ - echo "$(COLOR_GREEN)✓ Composer dependencies installed$(COLOR_RESET)"; \ - fi - @if [ -f "package.json" ]; then \ - $(NPM) install; \ - echo "$(COLOR_GREEN)✓ npm dependencies installed$(COLOR_RESET)"; \ - fi + @$(COMPOSER) install + @echo "$(COLOR_GREEN)✓ Dependencies installed$(COLOR_RESET)" .PHONY: update-deps -update-deps: ## Update all dependencies +update-deps: ## Update Composer dependencies @echo "$(COLOR_BLUE)Updating dependencies...$(COLOR_RESET)" - @if [ -f "composer.json" ]; then \ - $(COMPOSER) update; \ - echo "$(COLOR_GREEN)✓ Composer dependencies updated$(COLOR_RESET)"; \ - fi - @if [ -f "package.json" ]; then \ - $(NPM) update; \ - echo "$(COLOR_GREEN)✓ npm dependencies updated$(COLOR_RESET)"; \ + @$(COMPOSER) update + @echo "$(COLOR_GREEN)✓ Dependencies updated$(COLOR_RESET)" + +# ── Validation (MokoStandards API) ──────────────────────────────────────────── + +.PHONY: check-moko +check-moko: + @if [ ! -f "$(MOKO)" ]; then \ + echo "$(COLOR_RED)✗ MokoStandards CLI not found. Run: make install-deps$(COLOR_RESET)"; \ + exit 1; \ fi .PHONY: lint -lint: ## Run PHP linter (syntax check) - @echo "$(COLOR_BLUE)Running PHP linter...$(COLOR_RESET)" - @find . -name "*.php" ! -path "./vendor/*" ! -path "./node_modules/*" ! -path "./$(BUILD_DIR)/*" \ - -exec $(PHP) -l {} \; | grep -v "No syntax errors" || true - @echo "$(COLOR_GREEN)✓ PHP linting complete$(COLOR_RESET)" +lint: check-moko ## PHP syntax check via MokoStandards + @echo "$(COLOR_BLUE)Running PHP syntax check...$(COLOR_RESET)" + @$(PHP) $(MOKO) check:syntax -- --path . + @echo "$(COLOR_GREEN)✓ PHP syntax OK$(COLOR_RESET)" -.PHONY: phpcs -phpcs: ## Run PHP CodeSniffer (Joomla standards) - @echo "$(COLOR_BLUE)Running PHP CodeSniffer...$(COLOR_RESET)" - @if [ -f "$(PHPCS)" ]; then \ - $(PHPCS) --standard=$(PHPCS_STANDARD) --extensions=php --ignore=vendor,node_modules,$(BUILD_DIR) .; \ - else \ - echo "$(COLOR_YELLOW)⚠ PHP CodeSniffer not installed. Run: make install-deps$(COLOR_RESET)"; \ - fi +.PHONY: check-joomla +check-joomla: check-moko ## Validate Joomla manifest via MokoStandards + @echo "$(COLOR_BLUE)Validating Joomla manifest...$(COLOR_RESET)" + @$(PHP) $(MOKO) check:joomla -- --path . + @echo "$(COLOR_GREEN)✓ Joomla manifest valid$(COLOR_RESET)" -.PHONY: phpcbf -phpcbf: ## Fix coding standards automatically - @echo "$(COLOR_BLUE)Running PHP Code Beautifier...$(COLOR_RESET)" - @if [ -f "$(PHPCBF)" ]; then \ - $(PHPCBF) --standard=$(PHPCS_STANDARD) --extensions=php --ignore=vendor,node_modules,$(BUILD_DIR) .; \ - echo "$(COLOR_GREEN)✓ Code formatting applied$(COLOR_RESET)"; \ - else \ - echo "$(COLOR_YELLOW)⚠ PHP Code Beautifier not installed. Run: make install-deps$(COLOR_RESET)"; \ - fi +.PHONY: check-version +check-version: check-moko ## Verify version consistency across files + @echo "$(COLOR_BLUE)Checking version consistency...$(COLOR_RESET)" + @$(PHP) $(MOKO) check:version -- --path . + @echo "$(COLOR_GREEN)✓ Versions consistent$(COLOR_RESET)" + +.PHONY: check-headers +check-headers: check-moko ## Check license headers on source files + @echo "$(COLOR_BLUE)Checking license headers...$(COLOR_RESET)" + @$(PHP) $(MOKO) check:headers -- --path . + @echo "$(COLOR_GREEN)✓ Headers OK$(COLOR_RESET)" + +.PHONY: check-secrets +check-secrets: check-moko ## Scan for leaked credentials + @echo "$(COLOR_BLUE)Scanning for secrets...$(COLOR_RESET)" + @$(PHP) $(MOKO) check:secrets -- --path . + @echo "$(COLOR_GREEN)✓ No secrets found$(COLOR_RESET)" + +.PHONY: check-xml +check-xml: check-moko ## Validate XML files are well-formed + @echo "$(COLOR_BLUE)Checking XML files...$(COLOR_RESET)" + @$(PHP) $(MOKO) check:xml -- --path . + @echo "$(COLOR_GREEN)✓ XML well-formed$(COLOR_RESET)" .PHONY: validate -validate: lint phpcs ## Run all validation checks +validate: lint check-joomla check-version check-xml check-headers check-secrets ## Run all MokoStandards validation checks @echo "$(COLOR_GREEN)✓ All validation checks passed$(COLOR_RESET)" -.PHONY: test -test: ## Run PHPUnit tests - @echo "$(COLOR_BLUE)Running tests...$(COLOR_RESET)" - @if [ -f "$(PHPUNIT)" ] && [ -f "phpunit.xml" ]; then \ - $(PHPUNIT); \ - else \ - echo "$(COLOR_YELLOW)⚠ PHPUnit not configured$(COLOR_RESET)"; \ - fi +.PHONY: health +health: check-moko ## Full repository health check via MokoStandards + @echo "$(COLOR_BLUE)Running full health check...$(COLOR_RESET)" + @$(PHP) $(MOKO) health -- --path . -.PHONY: test-coverage -test-coverage: ## Run tests with coverage report - @echo "$(COLOR_BLUE)Running tests with coverage...$(COLOR_RESET)" - @if [ -f "$(PHPUNIT)" ] && [ -f "phpunit.xml" ]; then \ - $(PHPUNIT) --coverage-html $(BUILD_DIR)/coverage; \ - echo "$(COLOR_GREEN)✓ Coverage report: $(BUILD_DIR)/coverage/index.html$(COLOR_RESET)"; \ - else \ - echo "$(COLOR_YELLOW)⚠ PHPUnit not configured$(COLOR_RESET)"; \ - fi +# ── Build ───────────────────────────────────────────────────────────────────── .PHONY: clean clean: ## Clean build artifacts @@ -155,179 +122,78 @@ clean: ## Clean build artifacts @echo "$(COLOR_GREEN)✓ Build artifacts cleaned$(COLOR_RESET)" .PHONY: build -build: clean validate ## Build extension package - @echo "$(COLOR_BLUE)Building Joomla extension package...$(COLOR_RESET)" - @mkdir -p $(DIST_DIR) $(BUILD_DIR) - - # Determine package prefix based on extension type - @case "$(EXTENSION_TYPE)" in \ - module) \ - PACKAGE_PREFIX="mod_$(EXTENSION_NAME)"; \ - BUILD_TARGET="$(BUILD_DIR)/$$PACKAGE_PREFIX"; \ - ;; \ - plugin) \ - PACKAGE_PREFIX="plg_$(PLUGIN_GROUP)_$(EXTENSION_NAME)"; \ - BUILD_TARGET="$(BUILD_DIR)/$$PACKAGE_PREFIX"; \ - ;; \ - component) \ - PACKAGE_PREFIX="com_$(EXTENSION_NAME)"; \ - BUILD_TARGET="$(BUILD_DIR)/$$PACKAGE_PREFIX"; \ - ;; \ - package) \ - PACKAGE_PREFIX="pkg_$(EXTENSION_NAME)"; \ - BUILD_TARGET="$(BUILD_DIR)/$$PACKAGE_PREFIX"; \ - ;; \ - template) \ - PACKAGE_PREFIX="tpl_$(EXTENSION_NAME)"; \ - BUILD_TARGET="$(BUILD_DIR)/$$PACKAGE_PREFIX"; \ - ;; \ - *) \ - echo "$(COLOR_RED)✗ Unknown extension type: $(EXTENSION_TYPE)$(COLOR_RESET)"; \ +build: clean ## Build template installable ZIP from src/ + @echo "$(COLOR_BLUE)Building $(EXTENSION_NAME) v$(EXTENSION_VERSION)...$(COLOR_RESET)" + @mkdir -p $(BUILD_DIR)/package $(DIST_DIR) + @cp -r $(SRC_DIR)/* $(BUILD_DIR)/package/ + @cd $(BUILD_DIR)/package && \ + if command -v zip >/dev/null 2>&1; then \ + zip -r "../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION).zip" .; \ + elif command -v pwsh >/dev/null 2>&1; then \ + pwsh -Command "Compress-Archive -Path '*' -DestinationPath '../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION).zip' -Force"; \ + elif command -v powershell >/dev/null 2>&1; then \ + powershell -Command "Compress-Archive -Path '*' -DestinationPath '../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION).zip' -Force"; \ + else \ + echo "$(COLOR_RED)✗ No zip tool found (zip, pwsh, powershell)$(COLOR_RESET)"; \ exit 1; \ - ;; \ - esac; \ - \ - mkdir -p "$$BUILD_TARGET"; \ - \ - echo "Building $$PACKAGE_PREFIX..."; \ - \ - rsync -av --progress \ - --exclude='$(BUILD_DIR)' \ - --exclude='$(DIST_DIR)' \ - --exclude='.git*' \ - --exclude='vendor/' \ - --exclude='node_modules/' \ - --exclude='tests/' \ - --exclude='Makefile' \ - --exclude='composer.json' \ - --exclude='composer.lock' \ - --exclude='package.json' \ - --exclude='package-lock.json' \ - --exclude='phpunit.xml' \ - --exclude='*.md' \ - --exclude='.editorconfig' \ - . "$$BUILD_TARGET/"; \ - \ - cd $(BUILD_DIR) && $(ZIP) -r "../$(DIST_DIR)/$${PACKAGE_PREFIX}-$(EXTENSION_VERSION).zip" "$${PACKAGE_PREFIX}"; \ - \ - echo "$(COLOR_GREEN)✓ Package created: $(DIST_DIR)/$${PACKAGE_PREFIX}-$(EXTENSION_VERSION).zip$(COLOR_RESET)" + fi + @echo "$(COLOR_GREEN)✓ Package: $(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION).zip$(COLOR_RESET)" -.PHONY: package -package: build ## Alias for build - @echo "$(COLOR_GREEN)✓ Package ready for distribution$(COLOR_RESET)" - -.PHONY: install-local -install-local: build ## Install to local Joomla (upload via admin) - @echo "$(COLOR_BLUE)Package ready for installation$(COLOR_RESET)" - @case "$(EXTENSION_TYPE)" in \ - module) PACKAGE="mod_$(EXTENSION_NAME)";; \ - plugin) PACKAGE="plg_$(PLUGIN_GROUP)_$(EXTENSION_NAME)";; \ - component) PACKAGE="com_$(EXTENSION_NAME)";; \ - package) PACKAGE="pkg_$(EXTENSION_NAME)";; \ - template) PACKAGE="tpl_$(EXTENSION_NAME)";; \ - esac; \ - echo "$(COLOR_YELLOW)Upload $(DIST_DIR)/$${PACKAGE}-$(EXTENSION_VERSION).zip via Joomla Administrator$(COLOR_RESET)"; \ - echo "Admin URL: $(JOOMLA_ROOT) → Extensions → Install" - -.PHONY: dev-install -dev-install: ## Create symlink for development (Joomla 4+) - @echo "$(COLOR_BLUE)Creating development symlink...$(COLOR_RESET)" - @if [ ! -d "$(JOOMLA_ROOT)" ]; then \ - echo "$(COLOR_RED)✗ Joomla root not found at $(JOOMLA_ROOT)$(COLOR_RESET)"; \ - echo "Update JOOMLA_ROOT in Makefile"; \ - exit 1; \ - fi - - @case "$(EXTENSION_TYPE)" in \ - module) \ - if [ "$(MODULE_TYPE)" = "admin" ]; then \ - TARGET="$(JOOMLA_ROOT)/administrator/modules/mod_$(EXTENSION_NAME)"; \ - else \ - TARGET="$(JOOMLA_ROOT)/modules/mod_$(EXTENSION_NAME)"; \ - fi; \ - ;; \ - plugin) \ - TARGET="$(JOOMLA_ROOT)/plugins/$(PLUGIN_GROUP)/$(EXTENSION_NAME)"; \ - ;; \ - component) \ - echo "$(COLOR_YELLOW)⚠ Components require complex symlink setup$(COLOR_RESET)"; \ - echo "Manual setup recommended for component development"; \ +.PHONY: build-beta +build-beta: clean ## Build beta release ZIP + @echo "$(COLOR_BLUE)Building $(EXTENSION_NAME) v$(EXTENSION_VERSION)-beta...$(COLOR_RESET)" + @mkdir -p $(BUILD_DIR)/package $(DIST_DIR) + @cp -r $(SRC_DIR)/* $(BUILD_DIR)/package/ + @cd $(BUILD_DIR)/package && \ + if command -v zip >/dev/null 2>&1; then \ + zip -r "../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION)-beta.zip" .; \ + elif command -v pwsh >/dev/null 2>&1; then \ + pwsh -Command "Compress-Archive -Path '*' -DestinationPath '../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION)-beta.zip' -Force"; \ + elif command -v powershell >/dev/null 2>&1; then \ + powershell -Command "Compress-Archive -Path '*' -DestinationPath '../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION)-beta.zip' -Force"; \ + else \ + echo "$(COLOR_RED)✗ No zip tool found$(COLOR_RESET)"; \ exit 1; \ - ;; \ - *) \ - echo "$(COLOR_RED)✗ dev-install not supported for $(EXTENSION_TYPE)$(COLOR_RESET)"; \ - exit 1; \ - ;; \ - esac; \ - \ - rm -rf "$$TARGET"; \ - ln -s "$(PWD)" "$$TARGET"; \ - echo "$(COLOR_GREEN)✓ Development symlink created at $$TARGET$(COLOR_RESET)" + fi + @echo "$(COLOR_GREEN)✓ Package: $(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION)-beta.zip$(COLOR_RESET)" -.PHONY: watch -watch: ## Watch for changes and rebuild - @echo "$(COLOR_BLUE)Watching for changes...$(COLOR_RESET)" - @echo "$(COLOR_YELLOW)Press Ctrl+C to stop$(COLOR_RESET)" - @while true; do \ - inotifywait -r -e modify,create,delete --exclude '($(BUILD_DIR)|$(DIST_DIR)|vendor|node_modules)' . 2>/dev/null || \ - (echo "$(COLOR_YELLOW)⚠ inotifywait not installed. Install: apt-get install inotify-tools$(COLOR_RESET)" && sleep 5); \ - make build; \ +.PHONY: checksum +checksum: ## Generate SHA-256 checksums for dist packages + @echo "$(COLOR_BLUE)Generating checksums...$(COLOR_RESET)" + @for f in $(DIST_DIR)/*.zip; do \ + sha256sum "$$f" | tee "$${f}.sha256"; \ done + @echo "$(COLOR_GREEN)✓ Checksums generated$(COLOR_RESET)" + +# ── Release ─────────────────────────────────────────────────────────────────── + +.PHONY: release +release: validate build checksum ## Full release pipeline (validate + build + checksum) + @echo "$(COLOR_GREEN)✓ Release package ready$(COLOR_RESET)" + @echo "" + @echo "$(COLOR_BLUE)Next steps:$(COLOR_RESET)" + @echo " 1. Tag: git tag $(EXTENSION_VERSION)" + @echo " 2. Push: git push origin --tags" + @echo " 3. Create Gitea release and attach $(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION).zip" + @echo "" + +# ── Info ────────────────────────────────────────────────────────────────────── .PHONY: version -version: ## Display version information +version: ## Display version and extension info @echo "$(COLOR_BLUE)Extension Information:$(COLOR_RESET)" @echo " Name: $(EXTENSION_NAME)" @echo " Type: $(EXTENSION_TYPE)" @echo " Version: $(EXTENSION_VERSION)" - @if [ "$(EXTENSION_TYPE)" = "module" ]; then \ - echo " Module: $(MODULE_TYPE)"; \ - fi - @if [ "$(EXTENSION_TYPE)" = "plugin" ]; then \ - echo " Group: $(PLUGIN_GROUP)"; \ - fi - -.PHONY: docs -docs: ## Generate documentation - @echo "$(COLOR_BLUE)Generating documentation...$(COLOR_RESET)" - @mkdir -p $(DOCS_DIR) - @echo "$(COLOR_YELLOW)⚠ Documentation generation not configured$(COLOR_RESET)" - @echo "Consider adding phpDocumentor or similar" - -.PHONY: release -release: validate test build ## Create a release (validate + test + build) - @echo "$(COLOR_GREEN)✓ Release package ready$(COLOR_RESET)" - @echo "" - @echo "$(COLOR_BLUE)Release Checklist:$(COLOR_RESET)" - @echo " [ ] Update CHANGELOG.md" - @echo " [ ] Update version in XML manifest" - @echo " [ ] Test installation in clean Joomla" - @echo " [ ] Tag release in git: git tag v$(EXTENSION_VERSION)" - @echo " [ ] Push tags: git push --tags" - @echo " [ ] Create GitHub release" - @echo "" - @case "$(EXTENSION_TYPE)" in \ - module) PACKAGE="mod_$(EXTENSION_NAME)";; \ - plugin) PACKAGE="plg_$(PLUGIN_GROUP)_$(EXTENSION_NAME)";; \ - component) PACKAGE="com_$(EXTENSION_NAME)";; \ - package) PACKAGE="pkg_$(EXTENSION_NAME)";; \ - template) PACKAGE="tpl_$(EXTENSION_NAME)";; \ - esac; \ - echo "$(COLOR_GREEN)Package: $(DIST_DIR)/$${PACKAGE}-$(EXTENSION_VERSION).zip$(COLOR_RESET)" .PHONY: security-check -security-check: ## Run security checks on dependencies +security-check: ## Run Composer security audit @echo "$(COLOR_BLUE)Running security checks...$(COLOR_RESET)" - @if [ -f "composer.json" ]; then \ - $(COMPOSER) audit || echo "$(COLOR_YELLOW)⚠ Vulnerabilities found$(COLOR_RESET)"; \ - fi - @if [ -f "package.json" ]; then \ - $(NPM) audit || echo "$(COLOR_YELLOW)⚠ Vulnerabilities found$(COLOR_RESET)"; \ - fi + @$(COMPOSER) audit + @echo "$(COLOR_GREEN)✓ Security check complete$(COLOR_RESET)" .PHONY: all -all: install-deps validate test build ## Run complete build pipeline +all: install-deps validate build checksum ## Full pipeline: deps → validate → build → checksum @echo "$(COLOR_GREEN)✓ Complete build pipeline finished$(COLOR_RESET)" -# Default target .DEFAULT_GOAL := help diff --git a/composer.json b/composer.json index 8b13789..5f32b61 100644 --- a/composer.json +++ b/composer.json @@ -1 +1,29 @@ - +{ + "name": "mokoconsulting/mokocassiopeia", + "description": "MokoCassiopeia — Joomla site template based on Cassiopeia", + "type": "joomla-template", + "license": "GPL-3.0-or-later", + "authors": [ + { + "name": "Jonathan Miller", + "email": "hello@mokoconsulting.tech" + } + ], + "require": { + "php": ">=8.1" + }, + "require-dev": { + "mokoconsulting-tech/enterprise": "^4.0" + }, + "config": { + "sort-packages": true, + "optimize-autoloader": true, + "preferred-install": "dist" + }, + "repositories": [ + { + "type": "composer", + "url": "https://git.mokoconsulting.tech/api/packages/MokoConsulting/composer" + } + ] +} From d8796638313797f0383bd7d47e3baaf3422ee185 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 18:08:38 -0500 Subject: [PATCH 07/13] Place a11y button inline with theme switch, add Auto on/off toggle - A11y toggle button now sits side-by-side with theme switch inside the FAB bar, separated by a divider - A11y button height matches the theme switch - Auto button replaced with a proper on/off toggle switch that clearly indicates system-follow state - Manual theme switch turns off Auto automatically - A11y panel floats from its inline position when opened - Falls back to standalone toolbar when theme FAB is disabled Co-Authored-By: Claude Opus 4.6 (1M context) --- src/media/css/template.css | 109 ++++++++++++++++++++++++++++++-- src/media/js/template.js | 123 ++++++++++++++++++++++++++++--------- 2 files changed, 197 insertions(+), 35 deletions(-) diff --git a/src/media/css/template.css b/src/media/css/template.css index 737af8e..0ff490b 100644 --- a/src/media/css/template.css +++ b/src/media/css/template.css @@ -13979,7 +13979,6 @@ meter { } .footer { - padding-top: var(--footer-padding-top, 1rem); color: var(--mainmenu-nav-link-color, #fff); background-color: var(--nav-bg-color); padding-bottom: var(--footer-padding-bottom, 80px); @@ -13994,7 +13993,6 @@ meter { -ms-flex-direction: column; flex-direction: column; width: 100%; - padding: var(--footer-grid-padding-y, 2.5rem) var(--footer-grid-padding-x, 0.5em); } .footer a { @@ -17141,6 +17139,107 @@ button#mokoThemeSwitch { color: var(--body-bg, #0e1318); } +/* Auto toggle switch (on/off style) */ +.auto-toggle-wrap { + display: flex; + align-items: center; + gap: .35rem; +} + +.auto-label { + font-size: .75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: .04em; + opacity: .7; + user-select: none; +} + +.auto-switch { + position: relative; + display: inline-flex; + align-items: center; + width: 32px; + height: 18px; + border: none; + border-radius: 999px; + background: var(--secondary-color, #6c757d); + cursor: pointer; + padding: 0; + transition: background .2s; +} + +.auto-switch.on { + background: var(--link-color, #3565e5); +} + +.auto-track { + position: relative; + width: 100%; + height: 100%; +} + +.auto-knob { + position: absolute; + top: 2px; + left: 2px; + width: 14px; + height: 14px; + border-radius: 50%; + background: #fff; + box-shadow: 0 1px 3px rgba(0,0,0,.3); + transition: transform .2s ease; +} + +.auto-switch.on .auto-knob { + transform: translateX(14px); +} + +/* FAB divider between theme controls and a11y */ +.fab-divider { + display: block; + width: 1px; + height: 24px; + background: currentColor; + opacity: .25; + margin: 0 .15rem; +} + +/* Inline a11y toggle inside theme FAB */ +.a11y-toggle-inline { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border-radius: 50%; + border: 1.5px solid currentColor; + background: transparent; + color: inherit; + font-size: 1rem; + cursor: pointer; + padding: 0; + transition: background .2s, color .2s; + opacity: .8; +} + +.a11y-toggle-inline:hover, +.a11y-toggle-inline:focus-visible { + opacity: 1; + background: rgba(255,255,255,.15); +} + +.a11y-toggle-inline.active { + opacity: 1; + background: rgba(255,255,255,.25); +} + +/* Floating a11y panel when inline */ +.a11y-toolbar-floating { + position: fixed; + z-index: 1202; +} + body.site.error-page { margin: 0; padding: 0; @@ -17364,11 +17463,9 @@ html.a11y-pause-animations *::after { right: 2.5rem; } -/* When theme FAB is present, sit a11y toolbar to its left */ +/* When theme FAB is present, a11y toggle is inline — hide standalone toolbar positioning */ body[data-theme-fab-enabled="1"] #mokoA11yToolbar { - right: auto; - left: 2.5rem; - bottom: 1rem; + position: static; } /* Toggle button */ diff --git a/src/media/js/template.js b/src/media/js/template.js index b1d85d1..5345f42 100644 --- a/src/media/js/template.js +++ b/src/media/js/template.js @@ -87,13 +87,40 @@ lblD.className = 'label'; lblD.textContent = 'Dark'; - // Auto button + // Auto toggle (on/off switch style) + var autoWrap = doc.createElement('div'); + autoWrap.className = 'auto-toggle-wrap'; + + var autoLabel = doc.createElement('span'); + autoLabel.className = 'auto-label'; + autoLabel.textContent = 'Auto'; + var auto = doc.createElement('button'); auto.id = 'mokoThemeAuto'; auto.type = 'button'; - auto.className = 'btn btn-sm btn-link text-decoration-none px-2'; - auto.setAttribute('aria-label', 'Follow system theme'); - auto.textContent = 'Auto'; + auto.className = 'auto-switch'; + auto.setAttribute('role', 'switch'); + auto.setAttribute('aria-label', 'Automatic theme (follow system)'); + auto.setAttribute('aria-checked', getStored() ? 'false' : 'true'); + + var autoTrack = doc.createElement('span'); + autoTrack.className = 'auto-track'; + var autoKnob = doc.createElement('span'); + autoKnob.className = 'auto-knob'; + autoTrack.appendChild(autoKnob); + auto.appendChild(autoTrack); + if (!getStored()) auto.classList.add('on'); + + autoWrap.appendChild(autoLabel); + autoWrap.appendChild(auto); + + // Divider before a11y slot + var divider = doc.createElement('span'); + divider.className = 'fab-divider'; + + // A11y slot — buildA11yToolbar will inject its toggle here + var a11ySlot = doc.createElement('span'); + a11ySlot.id = 'mokoA11ySlot'; // Behavior switchWrap.addEventListener('click', function () { @@ -101,6 +128,9 @@ var next = current === 'dark' ? 'light' : 'dark'; applyTheme(next); switchWrap.setAttribute('aria-checked', next === 'dark' ? 'true' : 'false'); + // Turn off auto when manually switching + auto.classList.remove('on'); + auto.setAttribute('aria-checked', 'false'); // Update meta theme color var meta = doc.querySelector('meta[name="theme-color"]'); if (meta) { @@ -109,10 +139,14 @@ }); auto.addEventListener('click', function () { - clearStored(); - var sys = systemTheme(); - applyTheme(sys); - switchWrap.setAttribute('aria-checked', sys === 'dark' ? 'true' : 'false'); + var isAuto = auto.classList.toggle('on'); + auto.setAttribute('aria-checked', isAuto ? 'true' : 'false'); + if (isAuto) { + clearStored(); + var sys = systemTheme(); + applyTheme(sys); + switchWrap.setAttribute('aria-checked', sys === 'dark' ? 'true' : 'false'); + } }); // Respond to OS changes only when not user-forced @@ -134,7 +168,9 @@ wrap.appendChild(lblL); wrap.appendChild(switchWrap); wrap.appendChild(lblD); - wrap.appendChild(auto); + wrap.appendChild(autoWrap); + wrap.appendChild(divider); + wrap.appendChild(a11ySlot); doc.body.appendChild(wrap); // Debug helper @@ -359,23 +395,6 @@ addSwitchOption(showFont, "font", "fa-solid fa-font", "Readable font", applyFont); addSwitchOption(showAnimations, "paused", "fa-solid fa-pause", "Pause animations", applyPaused); - // Toggle panel open/close - toggle.addEventListener("click", function () { - var isOpen = !panel.hidden; - panel.hidden = isOpen; - toggle.setAttribute("aria-expanded", isOpen ? "false" : "true"); - toggle.classList.toggle("active", !isOpen); - }); - - // Close on outside click - doc.addEventListener("click", function (e) { - if (!toolbar.contains(e.target) && !panel.hidden) { - panel.hidden = true; - toggle.setAttribute("aria-expanded", "false"); - toggle.classList.remove("active"); - } - }); - // Apply saved preferences on load if (prefs.fontStep !== defaultStep) applyFontSize(prefs.fontStep); if (prefs.inverted) applyInversion(true); @@ -384,9 +403,55 @@ if (prefs.font) applyFont(true); if (prefs.paused) applyPaused(true); - toolbar.appendChild(toggle); - toolbar.appendChild(panel); - body.appendChild(toolbar); + // If theme FAB is present, mount a11y toggle inside it; otherwise standalone + var fabSlot = doc.getElementById("mokoA11ySlot"); + if (fabSlot) { + toggle.className = "a11y-toggle a11y-toggle-inline"; + fabSlot.appendChild(toggle); + toolbar.className = "a11y-toolbar-floating"; + toolbar.appendChild(panel); + body.appendChild(toolbar); + // Position panel near the FAB + toggle.addEventListener("click", function () { + var isOpen = !panel.hidden; + panel.hidden = isOpen; + toggle.setAttribute("aria-expanded", isOpen ? "false" : "true"); + toggle.classList.toggle("active", !isOpen); + if (!isOpen) { + var rect = toggle.getBoundingClientRect(); + toolbar.style.position = "fixed"; + toolbar.style.bottom = (win.innerHeight - rect.top + 8) + "px"; + toolbar.style.right = (win.innerWidth - rect.right) + "px"; + toolbar.style.zIndex = "1202"; + } + }); + // Close on outside click for inline mode + doc.addEventListener("click", function (e) { + if (!toggle.contains(e.target) && !toolbar.contains(e.target) && !panel.hidden) { + panel.hidden = true; + toggle.setAttribute("aria-expanded", "false"); + toggle.classList.remove("active"); + } + }); + } else { + // Standalone mode — toggle and close handlers + toggle.addEventListener("click", function () { + var isOpen = !panel.hidden; + panel.hidden = isOpen; + toggle.setAttribute("aria-expanded", isOpen ? "false" : "true"); + toggle.classList.toggle("active", !isOpen); + }); + doc.addEventListener("click", function (e) { + if (!toolbar.contains(e.target) && !panel.hidden) { + panel.hidden = true; + toggle.setAttribute("aria-expanded", "false"); + toggle.classList.remove("active"); + } + }); + toolbar.appendChild(toggle); + toolbar.appendChild(panel); + body.appendChild(toolbar); + } } // ======================================================================== From e43a1a445bd91240fd2ffbd778fdf9bd2f653a0a Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 18:27:29 -0500 Subject: [PATCH 08/13] Fix updateservers format to match Joomla manifest standard Co-Authored-By: Claude Opus 4.6 (1M context) --- src/templateDetails.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/templateDetails.xml b/src/templateDetails.xml index d4cc404..2df2708 100644 --- a/src/templateDetails.xml +++ b/src/templateDetails.xml @@ -31,12 +31,12 @@ --> - - https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/raw/branch/main/updates.xml - - - https://raw.githubusercontent.com/mokoconsulting-tech/MokoCassiopeia/main/updates.xml - + + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/raw/branch/main/updates.xml + + + https://raw.githubusercontent.com/mokoconsulting-tech/MokoCassiopeia/main/updates.xml + MokoCassiopeia 03.09.14 From 2b8c60ccbe80ed6554da633c1d74a7c4ffbadcab Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 18:28:20 -0500 Subject: [PATCH 09/13] Add platform labels to update server names (Gitea/GitHub) Co-Authored-By: Claude Opus 4.6 (1M context) --- src/templateDetails.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/templateDetails.xml b/src/templateDetails.xml index 2df2708..f928b11 100644 --- a/src/templateDetails.xml +++ b/src/templateDetails.xml @@ -31,10 +31,10 @@ --> - + https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/raw/branch/main/updates.xml - + https://raw.githubusercontent.com/mokoconsulting-tech/MokoCassiopeia/main/updates.xml From f47feaa2b1f16ff3e51eda2a0bec605790b78c01 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 20:03:09 -0500 Subject: [PATCH 10/13] Add dual download URLs (Gitea primary, GitHub fallback) to updates.xml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each release channel now lists both Gitea and GitHub download URLs. Joomla tries them in order — Gitea first, GitHub as fallback. Also updated dev/beta SHA-256 hashes to match actual builds. Co-Authored-By: Claude Opus 4.6 (1M context) --- updates.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/updates.xml b/updates.xml index 705da7a..d872bdb 100644 --- a/updates.xml +++ b/updates.xml @@ -18,8 +18,9 @@ https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/development https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/development/mokocassiopeia-03.09.14-dev.zip + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/development/mokocassiopeia-03.09.14-dev.zip - c2660acdf7389244462485f7ab4c286e9f851366a148acc16739a184576f7932 + 4cbe4fc379182ef17580396e7d12ce4ce95a90017ef364b922bdc2d04b0b3d97 development Moko Consulting https://mokoconsulting.tech @@ -38,6 +39,7 @@ https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/alpha https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/alpha/mokocassiopeia-03.09.14-alpha.zip + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/alpha/mokocassiopeia-03.09.14-alpha.zip c2660acdf7389244462485f7ab4c286e9f851366a148acc16739a184576f7932 alpha @@ -58,8 +60,9 @@ https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/beta https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/beta/mokocassiopeia-03.09.14-beta.zip + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/beta/mokocassiopeia-03.09.14-beta.zip - d2654fe1f0c2c83e4901aad775937dea07211096e0df886cff2a2b465d0e0840 + 4cbe4fc379182ef17580396e7d12ce4ce95a90017ef364b922bdc2d04b0b3d97 beta Moko Consulting https://mokoconsulting.tech @@ -78,6 +81,7 @@ https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/release-candidate https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/release-candidate/mokocassiopeia-03.09.14-rc.zip + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/release-candidate/mokocassiopeia-03.09.14-rc.zip c2660acdf7389244462485f7ab4c286e9f851366a148acc16739a184576f7932 rc @@ -98,6 +102,7 @@ https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/tag/v03 https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.09.14.zip + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.09.14.zip c2660acdf7389244462485f7ab4c286e9f851366a148acc16739a184576f7932 stable From a27e82b7d6d9c3c8e5786d6f9a3dce7cf9b7bcc8 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 20:03:40 -0500 Subject: [PATCH 11/13] Align updates.xml with Joomla standard format - Add php_minimum 8.1 to all update entries - Simplify targetplatform version to '5.*' Co-Authored-By: Claude Opus 4.6 (1M context) --- updates.xml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/updates.xml b/updates.xml index d872bdb..194285f 100644 --- a/updates.xml +++ b/updates.xml @@ -24,7 +24,8 @@ development Moko Consulting https://mokoconsulting.tech - + + 8.1 @@ -45,7 +46,8 @@ alpha Moko Consulting https://mokoconsulting.tech - + + 8.1 @@ -66,7 +68,8 @@ beta Moko Consulting https://mokoconsulting.tech - + + 8.1 @@ -87,7 +90,8 @@ rc Moko Consulting https://mokoconsulting.tech - + + 8.1 @@ -108,7 +112,8 @@ stable Moko Consulting https://mokoconsulting.tech - + + 8.1 From cc58b75b0d18c931a1a6dab838e846f8ea32b32d Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 20:06:57 -0500 Subject: [PATCH 12/13] Target Joomla 5 and 6 in updates.xml Co-Authored-By: Claude Opus 4.6 (1M context) --- updates.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/updates.xml b/updates.xml index 194285f..2609b3b 100644 --- a/updates.xml +++ b/updates.xml @@ -24,7 +24,7 @@ development Moko Consulting https://mokoconsulting.tech - + 8.1 @@ -46,7 +46,7 @@ alpha Moko Consulting https://mokoconsulting.tech - + 8.1 @@ -68,7 +68,7 @@ beta Moko Consulting https://mokoconsulting.tech - + 8.1 @@ -90,7 +90,7 @@ rc Moko Consulting https://mokoconsulting.tech - + 8.1 @@ -112,7 +112,7 @@ stable Moko Consulting https://mokoconsulting.tech - + 8.1 From ddf365550100672ea932ec885bd46e548a5faed4 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 14 Apr 2026 20:25:15 -0500 Subject: [PATCH 13/13] Fix a11y icon, FAB label colors, add high-contrast stylesheet, sync theme vars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix faIcon() to use elements (FA7 compatibility) - Fix #mokoThemeFab .label and button colors to white (visible on both light and dark themes) - Fix font-weight typo (600px → 600) - Add --footer-padding-* variables to all 6 theme files - Create a11y-high-contrast.css with WCAG AAA contrast ratios for both light and dark modes - Register high-contrast stylesheet in joomla.asset.json - Lazy-load high-contrast CSS when a11y contrast toggle is activated Co-Authored-By: Claude Opus 4.6 (1M context) --- src/joomla.asset.json | 6 + src/media/css/a11y-high-contrast.css | 227 +++++++++++++++++++++++++ src/media/css/template.css | 7 +- src/media/css/theme/dark.custom.css | 6 + src/media/css/theme/dark.standard.css | 6 + src/media/css/theme/light.custom.css | 6 + src/media/css/theme/light.standard.css | 6 + src/media/js/template.js | 20 ++- src/templates/dark.custom.css | 6 + src/templates/light.custom.css | 6 + 10 files changed, 289 insertions(+), 7 deletions(-) create mode 100644 src/media/css/a11y-high-contrast.css diff --git a/src/joomla.asset.json b/src/joomla.asset.json index 56ff7a1..737a35c 100644 --- a/src/joomla.asset.json +++ b/src/joomla.asset.json @@ -124,6 +124,12 @@ "uri": "media/templates/site/mokocassiopeia/css/theme/dark.custom.min.css", "attributes": {"media": "all"} }, + { + "name": "template.a11y-high-contrast", + "type": "style", + "uri": "media/templates/site/mokocassiopeia/css/a11y-high-contrast.css", + "attributes": {"media": "all"} + }, { "name": "template.js", "type": "script", diff --git a/src/media/css/a11y-high-contrast.css b/src/media/css/a11y-high-contrast.css new file mode 100644 index 0000000..10606fa --- /dev/null +++ b/src/media/css/a11y-high-contrast.css @@ -0,0 +1,227 @@ +@charset "UTF-8"; +/* Copyright (C) 2026 Moko Consulting + * + * This file is part of a Moko Consulting project. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + * FILE INFORMATION + * DEFGROUP: Joomla.Template.Site + * INGROUP: MokoCassiopeia.Accessibility + * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCassiopeia + * PATH: ./media/css/a11y-high-contrast.css + * VERSION: 03.09.14 + * BRIEF: High-contrast stylesheet for accessibility toolbar + */ + +/* =================================================================== + * HIGH CONTRAST MODE + * Applied when .a11y-high-contrast is on . + * Overrides theme variables to maximise contrast ratios (WCAG AAA). + * =================================================================== */ + +/* ── Light mode high contrast ─────────────────────────────────────── */ +:root[data-bs-theme="light"].a11y-high-contrast { + --body-color: #000; + --body-color-rgb: 0, 0, 0; + --body-bg: #fff; + --body-bg-rgb: 255, 255, 255; + --heading-color: #000; + --emphasis-color: #000; + --secondary-color: #000000bf; + --tertiary-color: #00000080; + --muted-color: #333; + + /* Links — strong blue on white */ + --color-link: #0000ee; + --link-color: #0000ee; + --link-color-rgb: 0, 0, 238; + --color-hover: #cc0000; + --link-hover-color: #cc0000; + --link-hover-color-rgb: 204, 0, 0; + + /* Borders — visible on all backgrounds */ + --border-color: #000; + --border-color-soft: #333; + + /* Backgrounds */ + --secondary-bg: #e0e0e0; + --secondary-bg-rgb: 224, 224, 224; + --tertiary-bg: #f0f0f0; + --tertiary-bg-rgb: 240, 240, 240; + + /* Navigation */ + --nav-bg-color: #000; + --nav-text-color: #fff; + --mainmenu-nav-link-color: #fff; + + /* Buttons */ + --btn-color: #fff; + --btn-bg: #000; + --btn-border-color: #000; + --btn-hover-color: #000; + --btn-hover-bg: #ffff00; + --btn-hover-border-color: #000; + --btn-active-color: #000; + --btn-active-bg: #ffff00; + --btn-active-border-color: #000; + + /* Forms */ + --input-color: #000; + --input-bg: #fff; + --input-border-color: #000; + --input-focus-color: #000; + --input-focus-bg: #ffffcc; + --input-focus-border-color: #0000ee; + --input-placeholder-color: #555; + + /* Cards */ + --card-border-color: #000; + --card-bg: #fff; + --card-cap-bg: #e0e0e0; + + /* Tables */ + --table-color: #000; + --table-bg: #fff; + --table-border-color: #000; + --table-striped-bg: #f0f0f0; + --table-hover-bg: #ffff99; + + /* Alerts */ + --alert-border-width: 2px; + + /* Code */ + --code-color: #000; + --code-bg-color: #ffffcc; + + /* Selection */ + --selection-bg: #0000ee; + --selection-ink: #fff; + + /* Focus indicator — always visible */ + --focus-ring-color: #0000ee; + --focus-ring-width: 3px; +} + +/* ── Dark mode high contrast ──────────────────────────────────────── */ +:root[data-bs-theme="dark"].a11y-high-contrast { + --body-color: #fff; + --body-color-rgb: 255, 255, 255; + --body-bg: #000; + --body-bg-rgb: 0, 0, 0; + --heading-color: #fff; + --emphasis-color: #fff; + --secondary-color: #ffffffbf; + --tertiary-color: #ffffff80; + --muted-color: #ccc; + + /* Links — bright yellow on black */ + --color-link: #ffff00; + --link-color: #ffff00; + --link-color-rgb: 255, 255, 0; + --color-hover: #00ffff; + --link-hover-color: #00ffff; + --link-hover-color-rgb: 0, 255, 255; + + /* Borders */ + --border-color: #fff; + --border-color-soft: #ccc; + + /* Backgrounds */ + --secondary-bg: #1a1a1a; + --secondary-bg-rgb: 26, 26, 26; + --tertiary-bg: #111; + --tertiary-bg-rgb: 17, 17, 17; + + /* Navigation */ + --nav-bg-color: #000; + --nav-text-color: #fff; + --mainmenu-nav-link-color: #ffff00; + + /* Buttons */ + --btn-color: #000; + --btn-bg: #ffff00; + --btn-border-color: #ffff00; + --btn-hover-color: #000; + --btn-hover-bg: #00ffff; + --btn-hover-border-color: #00ffff; + --btn-active-color: #000; + --btn-active-bg: #00ffff; + --btn-active-border-color: #00ffff; + + /* Forms */ + --input-color: #fff; + --input-bg: #000; + --input-border-color: #fff; + --input-focus-color: #fff; + --input-focus-bg: #1a1a1a; + --input-focus-border-color: #ffff00; + --input-placeholder-color: #aaa; + + /* Cards */ + --card-border-color: #fff; + --card-bg: #000; + --card-cap-bg: #1a1a1a; + + /* Tables */ + --table-color: #fff; + --table-bg: #000; + --table-border-color: #fff; + --table-striped-bg: #111; + --table-hover-bg: #333; + + /* Alerts */ + --alert-border-width: 2px; + + /* Code */ + --code-color: #00ff00; + --code-bg-color: #1a1a1a; + + /* Selection */ + --selection-bg: #ffff00; + --selection-ink: #000; + + /* Focus indicator */ + --focus-ring-color: #ffff00; + --focus-ring-width: 3px; +} + +/* ── Shared high-contrast overrides (both modes) ──────────────────── */ +.a11y-high-contrast * { + border-color: var(--border-color) !important; +} + +.a11y-high-contrast *:focus-visible { + outline: var(--focus-ring-width, 3px) solid var(--focus-ring-color, #0000ee) !important; + outline-offset: 2px !important; +} + +.a11y-high-contrast img { + outline: 2px solid var(--border-color); +} + +.a11y-high-contrast a { + text-decoration: underline !important; + text-decoration-thickness: 2px !important; +} + +.a11y-high-contrast button, +.a11y-high-contrast .btn, +.a11y-high-contrast input, +.a11y-high-contrast select, +.a11y-high-contrast textarea { + border-width: 2px !important; + border-style: solid !important; +} + +.a11y-high-contrast .badge, +.a11y-high-contrast .alert { + border: 2px solid var(--border-color) !important; +} + +/* Ensure disabled states are still distinguishable */ +.a11y-high-contrast [disabled], +.a11y-high-contrast .disabled { + opacity: .5 !important; + text-decoration: line-through !important; +} diff --git a/src/media/css/template.css b/src/media/css/template.css index 0ff490b..5b82fc3 100644 --- a/src/media/css/template.css +++ b/src/media/css/template.css @@ -17070,8 +17070,8 @@ form .form-select { background: var(--muted-color, #6d757e); box-shadow: var(--box-shadow, 0 .5rem 1rem #00000066); font: inherit; - color: var(--body-bg, #0e1318); - font-weight: 600px; + color: #fff; + font-weight: 600; } #mokoThemeFab.pos-br { @@ -17133,10 +17133,11 @@ button#mokoThemeSwitch { #mokoThemeFab .label { user-select: none; font-size: .875rem; + color: #fff; } #mokoThemeFab button { - color: var(--body-bg, #0e1318); + color: #fff; } /* Auto toggle switch (on/off style) */ diff --git a/src/media/css/theme/dark.custom.css b/src/media/css/theme/dark.custom.css index 50f9782..b04fd7e 100644 --- a/src/media/css/theme/dark.custom.css +++ b/src/media/css/theme/dark.custom.css @@ -817,6 +817,12 @@ color-scheme: dark; --table-active-color: var(--body-color); --table-active-bg: rgba(var(--white-rgb), 0.1); +/* ===== FOOTER ===== */ +--footer-padding-top: 1rem; +--footer-padding-bottom: 80px; +--footer-grid-padding-y: 2.5rem; +--footer-grid-padding-x: 0.5em; + /* ===== BACKDROP ===== */ --backdrop-zindex: 1040; --backdrop-bg: hsl(0, 0%, 0%); diff --git a/src/media/css/theme/dark.standard.css b/src/media/css/theme/dark.standard.css index 97515a7..8f2a82d 100644 --- a/src/media/css/theme/dark.standard.css +++ b/src/media/css/theme/dark.standard.css @@ -817,6 +817,12 @@ color-scheme: dark; --table-active-color: var(--body-color); --table-active-bg: rgba(var(--white-rgb), 0.1); +/* ===== FOOTER ===== */ +--footer-padding-top: 1rem; +--footer-padding-bottom: 80px; +--footer-grid-padding-y: 2.5rem; +--footer-grid-padding-x: 0.5em; + /* ===== BACKDROP ===== */ --backdrop-zindex: 1040; --backdrop-bg: hsl(0, 0%, 0%); diff --git a/src/media/css/theme/light.custom.css b/src/media/css/theme/light.custom.css index 53dc8c4..a99b9db 100644 --- a/src/media/css/theme/light.custom.css +++ b/src/media/css/theme/light.custom.css @@ -816,6 +816,12 @@ color-scheme: light; --table-active-color: var(--body-color); --table-active-bg: rgba(var(--black-rgb), 0.075); +/* ===== FOOTER ===== */ +--footer-padding-top: 1rem; +--footer-padding-bottom: 80px; +--footer-grid-padding-y: 2.5rem; +--footer-grid-padding-x: 0.5em; + /* ===== BACKDROP ===== */ --backdrop-zindex: 1040; --backdrop-bg: hsl(0, 0%, 0%); diff --git a/src/media/css/theme/light.standard.css b/src/media/css/theme/light.standard.css index 3ca6e62..07a74c2 100644 --- a/src/media/css/theme/light.standard.css +++ b/src/media/css/theme/light.standard.css @@ -816,6 +816,12 @@ color-scheme: light; --table-active-color: var(--body-color); --table-active-bg: rgba(var(--black-rgb), 0.075); +/* ===== FOOTER ===== */ +--footer-padding-top: 1rem; +--footer-padding-bottom: 80px; +--footer-grid-padding-y: 2.5rem; +--footer-grid-padding-x: 0.5em; + /* ===== BACKDROP ===== */ --backdrop-zindex: 1040; --backdrop-bg: hsl(0, 0%, 0%); diff --git a/src/media/js/template.js b/src/media/js/template.js index 5345f42..f1fb442 100644 --- a/src/media/js/template.js +++ b/src/media/js/template.js @@ -229,6 +229,18 @@ function applyContrast(on) { root.classList.toggle("a11y-high-contrast", on); + // Lazy-load the high-contrast stylesheet + var hcId = "mokoA11yHcSheet"; + var existing = doc.getElementById(hcId); + if (on && !existing) { + var link = doc.createElement("link"); + link.id = hcId; + link.rel = "stylesheet"; + link.href = (doc.querySelector('link[href*="mokocassiopeia/css/template"]') || {}).href + ? (doc.querySelector('link[href*="mokocassiopeia/css/template"]').href.replace(/\/css\/template[^/]*$/, "/css/a11y-high-contrast.css")) + : "media/templates/site/mokocassiopeia/css/a11y-high-contrast.css"; + doc.head.appendChild(link); + } } function applyLinks(on) { @@ -245,10 +257,10 @@ /** Create a Font Awesome icon element (safe DOM, no innerHTML). */ function faIcon(classes) { - var span = doc.createElement("span"); - span.className = classes; - span.setAttribute("aria-hidden", "true"); - return span; + var i = doc.createElement("i"); + i.className = classes; + i.setAttribute("aria-hidden", "true"); + return i; } function buildA11yToolbar() { diff --git a/src/templates/dark.custom.css b/src/templates/dark.custom.css index f3fdbf3..689bfda 100644 --- a/src/templates/dark.custom.css +++ b/src/templates/dark.custom.css @@ -813,6 +813,12 @@ color-scheme: dark; --table-active-color: var(--body-color); --table-active-bg: rgba(var(--white-rgb), 0.1); +/* ===== FOOTER ===== */ +--footer-padding-top: 1rem; +--footer-padding-bottom: 80px; +--footer-grid-padding-y: 2.5rem; +--footer-grid-padding-x: 0.5em; + /* ===== BACKDROP ===== */ --backdrop-zindex: 1040; --backdrop-bg: hsl(0, 0%, 0%); diff --git a/src/templates/light.custom.css b/src/templates/light.custom.css index 9170f61..d4b6d60 100644 --- a/src/templates/light.custom.css +++ b/src/templates/light.custom.css @@ -812,6 +812,12 @@ color-scheme: light; --table-active-color: var(--body-color); --table-active-bg: rgba(var(--black-rgb), 0.075); +/* ===== FOOTER ===== */ +--footer-padding-top: 1rem; +--footer-padding-bottom: 80px; +--footer-grid-padding-y: 2.5rem; +--footer-grid-padding-x: 0.5em; + /* ===== BACKDROP ===== */ --backdrop-zindex: 1040; --backdrop-bg: hsl(0, 0%, 0%);