diff --git a/.gitignore b/.gitignore
index 0b0d472..7bfe2cf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,65 +1,72 @@
-@ -0,0 +1,47 @@
-# Logs and databases
-/logs/
-/tmp/
-/documents/
-/administrator/logs/
-/packages/*
-
-#Dev related
-build/
-dev/
-scripts/
-
-#Configuration files
-/configuration.php
-/htdocs/conf/*
-
-# Joomla-generated files
-installation/
-/cache/
-/media/com_joomlaupdate/
-
-# Backup files
-*.bak
-*.backup
-/backups/
-/htdocs/solo/
-
-# Environment-specific files
+# ============================================================
.env
.env.local
.env.*.local
+*.local.php
+*.secret.php
-# Node.js dependencies (if using npm for template development)
-node_modules/
-npm-debug.log*
+# ============================================================
+# Logs, dumps & databases
+# ============================================================
+*.log
+*.pid
+*.seed
+*.sql
+*.sql.gz
+*.sqlite
+*.sqlite3
+*.db
+*.db-journal
-# Build files
-/dist/
-/build/
+# ============================================================
+# OS / Editor / IDE cruft
+# ============================================================
+.DS_Store
+Thumbs.db
+desktop.ini
+# Windows artifacts
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+$RECYCLE.BIN/
+System Volume Information/
+*.lnk
+Icon?
+.idea/
+.vscode/
+*.code-workspace
+*.sublime-project
+*.sublime-workspace
+.project
+.settings/
+.buildpath
-# Compiled assets
+# ============================================================
+# Dev scripts & scratch
+# ============================================================
+$1TODO
+todo
+
+# ============================================================
+# Maps & compiled asset helpers
+# ============================================================
*.css.map
*.js.map
-# System files
-desktop.ini
-.DS_Store
-Thumbs.db
-.idea/
-*.sublime*
+# ============================================================
+# SFTP / sync tools
+# ============================================================
sftp-config*.json
-*.ffs*
+sync.ffs_db
+*.ffs_gui
-# Editor and IDE files
-.vscode/
-*.swp
+# ============================================================
+# Replit / cloud IDE
+# ============================================================
+.replit
+replit.md
-# Other
-*.lock
-upgrade.unlock
-*conf*.php
-*.back*
-*.bak*
-*.old
+# ============================================================
+# Keep-empty folders helper
+# ============================================================
+!.gitkeep
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..916da36
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,85 @@
+
+
+Changelog — Moko-Cassiopeia
+
+# Version 2.0 (2025-08-30)
+
+**Major Release** — introduces the long-awaited **Dark Mode Toggle**, streamlining accessibility and usability enhancements.
+
+## Added
+
+* **Dark Mode Toggle**
+
+ * Frontend toggle switch included in template.
+ * JavaScript handles switching between light/dark modes.
+ * Dark mode CSS rules applied across template styles.
+ * Automatic persistence of user choice (via localStorage).
+
+* **Header Parameters Update**
+
+ * Added **logo parameter support** in template settings.
+ * Updated metadata & copyright header.
+
+* **Expanded TOC (Table of Contents)**
+
+ * Automatic TOC injection when enabled.
+ * User selects placement via article > options > layout (`toc-left` or `toc-right`).
+
+## Improved
+
+* Cleaned up `index.php` by removing **skip-to-content** duplicate calls.
+* Consolidated JavaScript asset loading (ensuring dark-mode script is loaded correctly from external JS file).
+* Streamlined CSS for **toggle switch**, ensuring it inherits Bootstrap/Cassiopeia defaults.
+* General accessibility refinements in typography and color contrast.
+
+## Fixed
+
+* Fixed missing **logo param** in header output.
+* Corrected stylesheet inconsistencies between Bootstrap 5 helpers and template overrides.
+* Patched redundant calls in script includes.
+
+---
+
+#Previous Versions
+
+## 1.0
+
+* **Initial Public Release** with:
+
+ * Font Awesome 6
+ * Bootstrap 5 helpers
+ * Automatic Table of Contents (TOC) utility
+ * Moko Expansions: Google Tag Manager / GA4 hooks
+
+---
+
+For the full development roadmap, visit:
+[Moko-Cassiopeia Roadmap](https://mokoconsulting.tech/support/joomla-cms/moko-cassiopeia-roadmap)
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index b1f5a16..07caafc 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,22 +1,31 @@
# Code of Conduct
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2f560f1..93f134d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,3 +1,33 @@
+
+
# Contributing Guidelines
Thank you for considering contributing to this project! We welcome contributions from the community and are grateful for your support.
@@ -6,27 +36,27 @@ Thank you for considering contributing to this project! We welcome contributions
1. **Fork the repository**
- - Click the "Fork" button at the top of the repository page.
+ - Click the "Fork" button at the top of the repository page.
2. **Create a branch**
- ```bash
- git checkout -b feature/your-feature-name
- ```
+ ```bash
+ git checkout -b feature/your-feature-name
+ ```
3. **Make your changes**
- - Follow the existing code style.
- - Write clear commit messages.
+ - Follow the existing code style.
+ - Write clear commit messages.
4. **Test your changes**
- - Ensure all tests pass and new code is covered.
+ - Ensure all tests pass and new code is covered.
5. **Submit a pull request (PR)**
- - Push your branch to your fork.
- - Open a PR against the `main` branch.
+ - Push your branch to your fork.
+ - Open a PR against the `main` branch.
---
diff --git a/README.md b/README.md
index bad909c..f0142b9 100644
--- a/README.md
+++ b/README.md
@@ -1,254 +1,304 @@
-# Moko-Cassiopeia
+
+
+
+# Moko-Cassiopeia v02.00 — README
+
+> Joomla! site template by **Moko Consulting**
+> License: **GPL-3.0-or-later**
+> Compatibility: **Joomla 4.4+ / 5.x** (PHP 8.1+)
---
-## Table of Contents
+## Overview
-- [Features](#features)
-- [Requirements](#requirements)
-- [Quick Start](#quick-start)
-- [Installation](#installation)
-- [Configuration](#configuration)
- - [Global Params](#global-params)
- - [Font Awesome 6](#font-awesome-6)
- - [Bootstrap 5 Helpers](#bootstrap-5-helpers)
- - [TOC Function](#toc-function)
- - [Moko Expansions](#moko-expansions)
- - [Google Tag Manager](#google-tag-manager)
- - [Google Analytics (GA4)](#google-analytics-ga4)
-- [CSS Variables](#css-variables)
-- [Usage Examples](#usage-examples)
-- [Best Practices](#best-practices)
-- [Development](#development)
-- [Changelog](#changelog)
-- [License](#license)
+Moko-Cassiopeia is a streamlined, Bootstrap-friendly Joomla template with a tokenized color system, Google Tag Manager / Analytics hooks, and performance-minded assets.
+
+* **v02.00 (2025-08-30)** introduces **Dark Mode** with OS auto-detection **and** an optional **Dark Mode Toggle** (ID **25**) so users can manually switch themes; their preference persists.
+* **v01.00** was the initial public release (FA6, BS5, TOC, GTM/GA hooks).
+
+Public roadmap: **[https://mokoconsulting.tech/support/joomla-cms/moko-cassiopeia-roadmap](https://mokoconsulting.tech/support/joomla-cms/moko-cassiopeia-roadmap)**
+
+---
+
+## What’s New in v02.00
+
+* **Dark Mode** with `prefers-color-scheme` auto-detect.
+* **Dark Mode Toggle** (Template param **ID 25**) with positions **Header / Navbar / Footer**.
+
+ * Persists choice to `localStorage` (key: `moko.theme`).
+ * Keyboard- and screen-reader-friendly; focus ring uses theme tokens.
+ * Admin option **“Show Theme Toggle”** (`On/Off`).
+* CSS refactor to **variables**: light tokens in `:root`, dark overrides in `[data-theme="dark"]`.
+* Lowered CSS specificity, `rem` units for scalable typography/spacing.
+* Stabilized WebAsset registrations (LTR/RTL presets).
---
## Features
-- **Font Awesome 6**: Solid, Regular, Brands (locally enqueued or CDN with Subresource Integrity).
-- **Bootstrap 5**: Utility classes, grid, and components available to your layouts and modules.
-- **Auto TOC**: Generate an in‑page Table of Contents from headings with a single data attribute.
-- **Moko Expansions**:
- - **GTM**: Drop‑in dataLayer and container injection with a template param.
- - **GA4**: Native GA4 Measurement ID support (with or without GTM).
-- **Production‑safe**: Assets loaded conditionally; no duplicate library loads if another extension already enqueues them.
-- **Accessible by default**: TOC anchors and focus styles follow a11y guidelines.
+* **Dark Mode + Toggle**
+ Auto-detect plus manual switch; persistent per user.
+
+* **Bootstrap-friendly CSS**
+ Low specificity, variable-driven utilities for buttons, alerts, typography, spacing.
+
+* **GTM / GA Hooks**
+ Clean injection points for Google Tag Manager and optional direct GA4 tag.
+
+* **LTR / RTL Presets**
+ Stable asset registration pattern for palette and template styles.
+
+* **A11y & Performance**
+ Clear focus styling and balanced contrast; minified bundles in production.
+
+---
## Requirements
-- Joomla 4.4+ or Joomla 5+
-- PHP 8.1+
-- Cassiopeia as the active base template (Moko-Cassiopeia may be installed as a child/override set)
+* Joomla **4.4+** / **5.x**
+* PHP **8.1+**
+* Modern evergreen browsers (graceful fallback if `prefers-color-scheme` isn’t available)
-## Quick Start
-
-1. Install the template package via Joomla Extension Manager.
-2. In the Template Style settings, enable the features you want (FA6, BS5, TOC, GTM/GA).
-3. (Optional) Add a TOC container to any article or module using the data attribute shown below.
+---
## Installation
-1. Go to 'System' → 'Install' → 'Extensions'.
-2. Upload 'Moko-Cassiopeia.zip'.
-3. After installation, go to 'System' → 'Site Templates' → 'Styles' and open 'Moko-Cassiopeia'.
-4. Choose 'Default' to make it your active style (or assign per menu item).
+1. **Install** via *Extensions → Manage → Install* (upload the template `.zip`).
+2. **Set as default** in *System → Templates → Site Templates*.
+3. **Clear caches**: *System → Clear Cache* and hard-reload your browser.
-## Configuration
+---
-Configuration lives in the Template Style parameters. Common params are listed below. Names may vary slightly depending on release.
+## Template Options (high-level)
-### Global Params
+**Theme**
-- 'load\_bootstrap5' (bool): Enqueue Bootstrap 5 core CSS/JS if not provided by Joomla context.
-- 'load\_fontawesome6' (bool): Enqueue Font Awesome 6 (solid, regular, brands).
-- 'use\_cdn' (bool): Use CDN with SRI instead of local assets.
-- 'minified' (bool): Prefer '.min' assets.
-- 'defer\_js' (bool): Add 'defer' to template‑injected scripts where safe.
+* **Force Theme**: `Auto` (default) | `Light` | `Dark`
+* **Show Theme Toggle** (ID **25**): `On` | `Off`
+* **Toggle Position**: `Header` | `Navbar` | `Footer`
+* **Default Theme** (when not using Auto): `Light`
-### Font Awesome 6
+**GTM / Analytics**
-When enabled, the template registers FA6 and exposes the standard icon syntax:
+* **GTM Container ID** (e.g., `GTM-XXXXXXX`)
+* **Analytics Tag ID** (optional GA4 if not using GTM)
-```html
-
-Success
-```
+**Performance**
-**Notes**
+* **Development Mode**
-- Icons are decorative unless paired with text or 'aria-label'.
-- Prefer the 'fa-solid', 'fa-regular', or 'fa-brands' families explicitly.
+ * `Off` → `.min.css` / `.min.js` bundles
+ * `On` → unminified sources for debugging
-### Bootstrap 5 Helpers
+---
-If 'load\_bootstrap5' is enabled, grid and utilities are available:
+## Dark Mode — Tokens & Toggle
-```html
-
-
-
Left
-
Right
-
-
-```
-
-You can also use helpers like 'ratio', 'visually-hidden', 'd-flex', and spacing utilities (e.g., 'mt-3', 'px-4').
-
-### TOC Function
-
-Moko-Cassiopeia ships a tiny script that scans within a container for headings (h2–h6) and builds a nested TOC with anchor links.
-
-**Enable**: Turn on 'auto\_toc' in Template Style.
-
-**Place a TOC container**:
-
-```html
-
-```
-
-**Mark your content region**:
-
-```html
-
-
Section A
-
...
-
Subsection A.1
-
...
-
-```
-
-**Options via data attributes**
-
-- 'data-moko-toc-target': CSS selector for the content area (default: 'main').
-- 'data-moko-toc-levels': CSV or range string like '2-4' (default: '2-4').
-- 'data-moko-toc-collapsible': 'true'|'false' to make nested lists collapsible.
-
-**Styling**
-
-A minimal stylesheet is included. Customize using the CSS variables below or add your own overrides.
-
-### Moko Expansions
-
-#### Google Tag Manager
-
-Enable GTM by entering your container ID (e.g., 'GTM-XXXXXXX') in Template Style under 'Moko Expansions'. The template will inject the standard script and 'noscript' iframe per Google guidance.
-
-**Data Layer**
-
-You can push events from modules or overrides like so:
-
-```html
-
-```
-
-#### Google Analytics (GA4)
-
-Two options:
-
-1. **Direct GA4**: Provide 'G-' Measurement ID (e.g., 'G-ABC123XYZ'). The template injects the GA4 base script.
-
-2. **Via GTM**: Leave GA4 field empty and configure GA4 inside your GTM container.
-
-```html
-
-```
-
-> Tip: When both GTM and direct GA4 are set, the template prefers GTM to avoid duplicate pageviews.
-
-## CSS Variables
-
-Moko-Cassiopeia exposes custom properties for theme tuning. Example set:
+**Color tokens**
```css
:root {
- --moko-cassiopeia-color-primary: #0b4008;
- --moko-cassiopeia-color-link: #0b4008;
- --moko-cassiopeia-color-hover: #000000;
+ --color-bg: #ffffff;
+ --color-surface: #f8f9fa;
+ --color-text: #1d2125;
+ --color-text-muted: #6c757d;
+ --color-border: #dee2e6;
- --moko-cassiopeia-header-background-image: linear-gradient(30deg, #fefcf9, var(--accent-color-primary));
- --moko-cassiopeia-header-background-position: auto;
- --moko-cassiopeia-header-background-attachment: fixed;
- --moko-cassiopeia-header-background-repeat: repeat;
- --moko-cassiopeia-header-background-size: auto;
+ --color-primary: #0d6efd;
+ --color-primary-contrast: #ffffff;
+
+ --color-link: var(--color-primary);
+ --color-link-hover: #0b5ed7;
+
+ --focus-ring: 0 0 0 .2rem rgba(13,110,253,.25);
+}
+
+[data-theme="dark"] {
+ --color-bg: #0e1116;
+ --color-surface: #151922;
+ --color-text: #e7eaf0;
+ --color-text-muted: #a4acb9;
+ --color-border: #2a3240;
+
+ --color-primary: #66b2ff;
+ --color-primary-contrast: #0d1117;
+
+ --color-link: var(--color-primary);
+ --color-link-hover: #99ccff;
+
+ --focus-ring: 0 0 0 .2rem rgba(102,178,255,.35);
}
```
-> Apply these in a custom stylesheet or template options if provided. Use semantic variables where possible to maintain consistency.
+**Programmatic switch (optional)**
-## Usage Examples
-
-### 1) FA6 Icon Buttons
-
-```html
-
-
- Action
-
+```js
+// Apply and persist a choice
+document.documentElement.dataset.theme = 'dark'; // or 'light'
+localStorage.setItem('moko.theme', 'dark'); // namespaced key
```
-### 2) Sticky Sidebar TOC
+---
-```html
-
+## CSS Architecture
+
+* **`template.css`** = structure/layout and component scaffolding
+* **No hard-coded hex** in core selectors; all colors reference tokens
+* **Units**: `rem` (replacing `em`) for scalable typography/spacing
+* **Low specificity** to play nicely with Bootstrap and content plugins
+
+---
+
+## GTM / Analytics Integration
+
+* Enter **GTM Container ID** in Template Options to inject the GTM snippet.
+* Optionally add a **GA4 Measurement ID** if not routing GA via GTM.
+* Output uses Joomla rendering events to avoid duplication.
+
+> Verify tags with DevTools / Tag Assistant.
+
+---
+
+## RTL / LTR Assets (WebAsset JSON)
+
+Minimal pattern:
+
+```json
+{
+ "$schema": "https://developer.joomla.org/schemas/json/schema_web_assets.json",
+ "name": "template.moko-cassiopeia",
+ "assets": [
+ { "name": "template.moko-cassiopeia.styles", "type": "style", "uri": "templates/moko-cassiopeia/css/template.min.css" },
+ { "name": "template.moko-cassiopeia.palette", "type": "style", "uri": "templates/moko-cassiopeia/css/colors_standard.min.css" },
+ { "name": "template.moko-cassiopeia", "type": "preset", "dependencies": ["template.moko-cassiopeia.styles","template.moko-cassiopeia.palette"] }
+ ]
+}
```
-### 3) Module‑driven GA Event
+In `index.php`:
```php
-
-
+/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
+$wa = $this->getWebAssetManager();
+$wa->usePreset('template.moko-cassiopeia');
```
-> Note: We use single quotes in HTML where possible to keep consistency with PHP string style preferences.
+---
-## Best Practices
+## Upgrade Notes
-- **One source of truth** for analytics injection (prefer GTM, or direct GA4—not both).
-- **Defer non‑critical JS** using the 'defer\_js' param when feasible.
-- **Avoid duplicate libraries** if another extension already loads FA6/BS5.
-- **Respect a11y**: Provide visible focus, 'visually-hidden' labels, and heading order for the TOC.
-- **Cache smartly**: After enabling new features, clear Joomla cache and any CDN cache to propagate assets.
+**1.0 → 2.0**
-## Development
+* Clear Joomla + browser caches.
+* Convert any hard-coded colors in overrides to **tokens** (e.g., `var(--color-text-muted)`).
+* Review spacing/typography where `rem` replaces `em`.
+* Verify asset names if you referenced WebAsset handles directly.
+* If you previously added a custom dark-mode toggle, remove it and enable **Show Theme Toggle** (ID **25**).
-- Source structure follows Joomla template conventions:
- - '/css', '/js', '/images', '/html' (overrides), 'templateDetails.xml'
-- Scripts are enqueued via the template's 'index.php' with conditional params.
-- Build/compile steps (if using bundlers) are noted in 'package.json' (when applicable).
+---
-**Local overrides**
+## Accessibility
-- Place site‑specific CSS in '/css/custom.css'.
-- Use '/html' for component/module layout overrides as needed.
+* Improved contrast targets across light/dark.
+* Visible, consistent focus indicators.
+* Toggle is keyboard-navigable and labeled for assistive tech.
-## Changelog
+---
-- 1.15: Added CSS theme seletor (dark/light)
-- 1.00: Initial public release with FA6, BS5, TOC, GTM/GA hooks.
+## Troubleshooting
-## License
+* **Toggle not visible** → Ensure “Show Theme Toggle” is on and placed in a visible position.
+* **Preference not persisting** → Check `localStorage` availability and console for JS errors.
+* **Asset dependency warnings** → Confirm preset/asset names match your `joomla.asset.json`.
-Distributed under the GNU General Public License v3. See 'LICENSE' for details.
+---
+## Feature Rundown & Comparison
+
+### Moko-Cassiopeia v01.00 — Initial public release
+
+* **Font Awesome 6** integrated; **Bootstrap 5** helpers.
+* **TOC utility** hooks for article table of contents.
+* **GTM/GA hooks** with safe injection points.
+* Minimal, upgrade-friendly overrides; variable-ready CSS.
+
+### Moko-Cassiopeia v02.00 — Dark Mode + Toggle (ID 25)
+
+* **Dark Mode** with OS auto-detect.
+* **Optional Dark Mode Toggle** (ID 25) in Header / Navbar / Footer; persisted per user.
+* **Tokenized palette** (`:root` + `[data-theme="dark"]`).
+* **CSS refactor**: low specificity; `rem` units; Bootstrap-friendly utilities.
+* Stabilized **Web Asset** registrations (LTR/RTL presets).
+
+### Baseline: Cassiopeia (Joomla 4.4 / 5.x)
+
+* Responsive, accessible core site template with Bootstrap-friendly markup.
+* Template options for color preset, layout width, sticky header, and module menu layouts.
+* Web Asset Manager integration (`joomla.asset.json`, `$this->getWebAssetManager()`).
+
+---
+
+## Roadmap
+
+Public roadmap: **[https://mokoconsulting.tech/support/joomla-cms/moko-cassiopeia-roadmap](https://mokoconsulting.tech/support/joomla-cms/moko-cassiopeia-roadmap)**
+
+---
+
+## Changelog (1.0 → 2.0)
+
+### 02.00 — 2025-08-30 — “Dark Mode”
+
+**Added**
+
+* Dark Mode with OS auto-detection (`prefers-color-scheme`).
+* **Dark Mode Toggle** (param **ID 25**) with positions Header / Navbar / Footer; persists choice via `localStorage` (`moko.theme`); accessible markup and focus styling.
+* Tokenized CSS palette with `[data-theme="dark"]` overrides.
+* Admin override to force Light/Dark/Auto.
+* Bootstrap-friendly utility hooks mapped to tokens.
+
+**Changed**
+
+* `template.css` now structure/layout only; colors via tokens.
+* `em` → `rem`; reduced specificity; standardized focus indicators.
+
+**Fixed**
+
+* WebAsset registrations (LTR/RTL/preset deps) and dark-theme link/muted contrast.
+
+**Removed / Deprecated**
+
+* Hard-coded color declarations and legacy hex-based helper classes.
+
+---
+
+### 01.00 — Initial public release
+
+* **FA6**, **BS5**, **TOC**, **GTM/GA** hooks.
diff --git a/language/en-GB/tpl_moko-cassiopeia.ini b/language/en-GB/tpl_moko-cassiopeia.ini
index a9662f2..183d520 100644
--- a/language/en-GB/tpl_moko-cassiopeia.ini
+++ b/language/en-GB/tpl_moko-cassiopeia.ini
@@ -1,13 +1,30 @@
-;---------------------------------------------------
-; Template: moko-cassiopeia
-; File: en-GB.tpl_moko-cassiopeia.ini
-; Version: 02.00
-; Author: Jonathan Miller
-; Copyright: (C) 2025 Moko Consulting. All rights reserved.
-; License: GNU General Public License v3 or later; see LICENSE.txt
-; Description: Language strings for the frontend template.
-; Note: All ini files must be saved as UTF-8 without BOM.
-;---------------------------------------------------
+# =========================================================================
+# Copyright (C) 2025 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see https://www.gnu.org/licenses/ .
+# =========================================================================
+# FILE INFORMATION
+# DEFGROUP: Joomla
+# INGROUP: Moko-Cassiopeia
+# PATH: language/en-GB/tpl_moko-cassiopeia.ini
+# VERSION: 02.00
+# BRIEF: English (GB) language strings for the Moko-Cassiopeia Joomla template
+# =========================================================================
; ===== Template meta =====
MOKO-CASSIOPEIA="MOKO-CASSIOPEIA Site template"
diff --git a/language/en-GB/tpl_moko-cassiopeia.sys.ini b/language/en-GB/tpl_moko-cassiopeia.sys.ini
index ea2a9df..809fb14 100644
--- a/language/en-GB/tpl_moko-cassiopeia.sys.ini
+++ b/language/en-GB/tpl_moko-cassiopeia.sys.ini
@@ -1,13 +1,30 @@
-;---------------------------------------------------
-; Template: moko-cassiopeia
-; File: en-GB.tpl_moko-cassiopeia.sys.ini
-; Version: 02.00
-; Author: Jonathan Miller
-; Copyright: (C) 2025 Moko Consulting. All rights reserved.
-; License: GNU General Public License v3 or later; see LICENSE.txt
-; Description: Language strings for the frontend template.
-; Note: All ini files must be saved as UTF-8 without BOM.
-;---------------------------------------------------
+# =========================================================================
+# Copyright (C) 2025 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see https://www.gnu.org/licenses/ .
+# =========================================================================
+# FILE INFORMATION
+# DEFGROUP: Joomla
+# INGROUP: Moko-Cassiopeia
+# PATH: language/en-GB/tpl_moko-cassiopeia.sys.ini
+# VERSION: 02.00
+# BRIEF: English (GB) system language strings for template metadata and installer
+# =========================================================================
TPL_MOKO-CASSIOPEIA="Moko-Cassiopeia Site template"
TPL_MOKO-CASSIOPEIA_MOD_MENU_LAYOUT_COLLAPSE-METISMENU="Collapsible Dropdown"
@@ -30,11 +47,12 @@ TPL_MOKO-CASSIOPEIA_POSITION_TOP-B="Top-b"
TPL_MOKO-CASSIOPEIA_POSITION_TOPBAR="Top Bar"
TPL_MOKO-CASSIOPEIA_POSITION_DRAWER-LEFT="Drawer-Left"
TPL_MOKO-CASSIOPEIA_POSITION_DRAWER-RIGHT="Drawer-Right"
-TPL_MOKO-CASSIOPEIA_XML_DESCRIPTION="
- MOKO-CASSIOPEIA continues Joomla’s tradition of space-themed default templates—
- building on the legacy of Solarflare from Joomla 1.0, Milkyway from Joomla 1.5,
- and Protostar from Joomla 3.0.
+ MOKO-CASSIOPEIA 2.0 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,
@@ -42,41 +60,40 @@ TPL_MOKO-CASSIOPEIA_XML_DESCRIPTION="
MOKO-CASSIOPEIA Template Description
- MOKO-CASSIOPEIA is designed to serve as a versatile, production-ready base for
- contemporary Joomla websites, emphasizing speed, clarity, and open-source philosophy.
+ Version 2.0 introduces significant new functionality including a Dark Mode toggle,
+ Google Tag Manager (GTM) and Google Analytics 4 (GA4) hooks, and expanded template configuration
+ options — all while keeping overrides minimal and upgrade-friendly.
Features
Fully responsive and mobile-first layout
Based on Joomla 4+ template architecture
-
Enhanced SCSS and CSS overrides for custom styling
-
Built-in support for Bootstrap 5
-
- Integrated dynamic Table of Contents via
- Bootstrap TOC
-
+
Enhanced SCSS and CSS overrides for streamlined custom styling
+
Built-in support for Bootstrap 5
+
Font Awesome 6 integration for modern iconography
+
Automatic Table of Contents (TOC) — selectable per article via toc-left or toc-right layouts
+
Dark Mode toggle (new in v2.0) with user switch and admin override
+
Optional GTM + GA4 hooks (new in v2.0) for analytics and marketing integration
Optimized template structure for performance and maintainability
Custom module positions and layout presets
-
Accessible, lightweight, and extensible
+
Accessible, lightweight, and extensible for long-term use
Ideal for professional services, portfolios, and informational websites
Code Attribution
This template is based on the original Cassiopeia template developed by the
- Joomla! Project and released under the GNU General Public License.
+ 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.
-
a
+
It includes integration with
- Bootstrap TOC,
+ 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.
"
-
-JGLOBAL_OFFLINE="Offline"
diff --git a/language/en-US/tpl_moko-cassiopeia.ini b/language/en-US/tpl_moko-cassiopeia.ini
index a9662f2..f183188 100644
--- a/language/en-US/tpl_moko-cassiopeia.ini
+++ b/language/en-US/tpl_moko-cassiopeia.ini
@@ -1,13 +1,30 @@
-;---------------------------------------------------
-; Template: moko-cassiopeia
-; File: en-GB.tpl_moko-cassiopeia.ini
-; Version: 02.00
-; Author: Jonathan Miller
-; Copyright: (C) 2025 Moko Consulting. All rights reserved.
-; License: GNU General Public License v3 or later; see LICENSE.txt
-; Description: Language strings for the frontend template.
-; Note: All ini files must be saved as UTF-8 without BOM.
-;---------------------------------------------------
+# =========================================================================
+# Copyright (C) 2025 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see https://www.gnu.org/licenses/ .
+# =========================================================================
+# FILE INFORMATION
+# DEFGROUP: Joomla
+# INGROUP: Moko-Cassiopeia
+# PATH: language/en-US/tpl_moko-cassiopeia.ini
+# VERSION: 02.00
+# BRIEF: English (US) language strings for the Moko-Cassiopeia Joomla template
+# =========================================================================
; ===== Template meta =====
MOKO-CASSIOPEIA="MOKO-CASSIOPEIA Site template"
diff --git a/language/en-US/tpl_moko-cassiopeia.sys.ini b/language/en-US/tpl_moko-cassiopeia.sys.ini
index 3c3a2e5..774ca82 100644
--- a/language/en-US/tpl_moko-cassiopeia.sys.ini
+++ b/language/en-US/tpl_moko-cassiopeia.sys.ini
@@ -1,13 +1,30 @@
-;---------------------------------------------------
-; Template: moko-cassiopeia
-; File: en-US.tpl_moko-cassiopeia.sys.ini
-; Version: 02.00
-; Author: Jonathan Miller
-; Copyright: (C) 2025 Moko Consulting. All rights reserved.
-; License: GNU General Public License v3 or later; see LICENSE.txt
-; Description: Language strings for the frontend template.
-; Note: All ini files must be saved as UTF-8 without BOM.
-;---------------------------------------------------
+# =========================================================================
+# Copyright (C) 2025 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see https://www.gnu.org/licenses/ .
+# =========================================================================
+# FILE INFORMATION
+# DEFGROUP: Joomla
+# INGROUP: Moko-Cassiopeia
+# PATH: language/en-US/tpl_moko-cassiopeia.sys.ini
+# VERSION: 02.00
+# BRIEF: English (US) system language strings for template metadata and installer
+# =========================================================================
TPL_MOKO-CASSIOPEIA="Moko-Cassiopeia Site template"
TPL_MOKO-CASSIOPEIA_MOD_MENU_LAYOUT_COLLAPSE-METISMENU="Collapsible Dropdown"
@@ -31,11 +48,11 @@ TPL_MOKO-CASSIOPEIA_POSITION_TOPBAR="Top Bar"
TPL_MOKO-CASSIOPEIA_POSITION_DRAWER-LEFT="Drawer-Left"
TPL_MOKO-CASSIOPEIA_POSITION_DRAWER-RIGHT="Drawer-Right"
TPL_MOKO-CASSIOPEIA_XML_DESCRIPTION=
-TPL_MOKO-CASSIOPEIA_XML_DESCRIPTION="
MOKO-CASSIOPEIA Template Description
+TPL_MOKO-CASSIOPEIA_XML_DESCRIPTION="
MOKO-CASSIOPEIA Template Description (v2.0)
- MOKO-CASSIOPEIA continues Joomla’s tradition of space-themed default templates—
- building on the legacy of Solarflare from Joomla 1.0, Milkyway from Joomla 1.5,
- and Protostar from Joomla 3.0.
+ MOKO-CASSIOPEIA 2.0 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,
@@ -43,41 +60,40 @@ TPL_MOKO-CASSIOPEIA_XML_DESCRIPTION="
MOKO-CASSIOPEIA Template Description
- MOKO-CASSIOPEIA is designed to serve as a versatile, production-ready base for
- contemporary Joomla websites, emphasizing speed, clarity, and open-source philosophy.
+ Version 2.0 introduces significant new functionality including a Dark Mode toggle,
+ Google Tag Manager (GTM) and Google Analytics 4 (GA4) hooks, and expanded template configuration
+ options — all while keeping overrides minimal and upgrade-friendly.
Features
Fully responsive and mobile-first layout
Based on Joomla 4+ template architecture
-
Enhanced SCSS and CSS overrides for custom styling
-
Built-in support for Bootstrap 5
-
- Integrated dynamic Table of Contents via
- Bootstrap TOC
-
+
Enhanced SCSS and CSS overrides for streamlined custom styling
+
Built-in support for Bootstrap 5
+
Font Awesome 6 integration for modern iconography
+
Automatic Table of Contents (TOC) — selectable per article via toc-left or toc-right layouts
+
Dark Mode toggle (new in v2.0) with user switch and admin override
+
Optional GTM + GA4 hooks (new in v2.0) for analytics and marketing integration
Optimized template structure for performance and maintainability
Custom module positions and layout presets
-
Accessible, lightweight, and extensible
+
Accessible, lightweight, and extensible for long-term use
Ideal for professional services, portfolios, and informational websites
Code Attribution
This template is based on the original Cassiopeia template developed by the
- Joomla! Project and released under the GNU General Public License.
+ 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.
-
a
+
It includes integration with
- Bootstrap TOC,
+ 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.
"
-
-JGLOBAL_OFFLINE="Offline"
diff --git a/media/templates/site/moko-cassiopeia/css/editor.css b/media/templates/site/moko-cassiopeia/css/editor.css
index bd2032d..f5c8d7d 100644
--- a/media/templates/site/moko-cassiopeia/css/editor.css
+++ b/media/templates/site/moko-cassiopeia/css/editor.css
@@ -1,3 +1,33 @@
+@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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/editor.css
+ * VERSION: 02.00
+ * BRIEF: Stylesheet for Joomla editor content within Moko-Cassiopeia template
+ * =========================================================================
+ */
+
/* STYLES FOR JOOMLA! EDITOR */
body {
font-size: 1rem;
diff --git a/media/templates/site/moko-cassiopeia/css/gable.css b/media/templates/site/moko-cassiopeia/css/gable.css
index d5a281c..1e653df 100644
--- a/media/templates/site/moko-cassiopeia/css/gable.css
+++ b/media/templates/site/moko-cassiopeia/css/gable.css
@@ -1,3 +1,33 @@
+@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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/gable.css
+ * VERSION: 02.00
+ * BRIEF: Stylesheet providing gable-specific layout and design rules for Moko-Cassiopeia
+ * =========================================================================
+ */
+
:root {
--gab-blue: transparent;
--gab-green: #7ac143;
diff --git a/media/templates/site/moko-cassiopeia/css/global/dark/colors_alternative.css b/media/templates/site/moko-cassiopeia/css/global/dark/colors_alternative.css
new file mode 100644
index 0000000..5130cea
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/css/global/dark/colors_alternative.css
@@ -0,0 +1,368 @@
+@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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/global/dark/colors_alternative.css
+ * VERSION: 02.00
+ * BRIEF: Alternative dark mode color definitions for Moko-Cassiopeia template
+ * =========================================================================
+ */
+
+/* -----------------------------------------------
+ * DARK THEME
+ * --------------------------------------------- */
+
+:root[data-bs-theme='dark']{
+ /* System hint for native widgets */
+ color-scheme: dark;
+
+ /* Brand & links */
+ --color-primary: #112855;
+ --accent-color-primary: #3f8ff0;
+ --accent-color-secondary: #6fb3ff;
+
+ --mainmenu-nav-link-color: #fff;
+
+ --color-link: #224FAA;
+ --color-hover: #224FAA;
+
+ /* Header background (kept same image; works over dark bg) */
+ --header-background-image: url('../../../../../../media/templates/site/moko-cassiopeia/images/bg.svg'); --header-background-attachment: fixed;
+ --header-background-repeat: repeat;
+ --header-background-size: auto;
+
+ /* Section containers */
+ --container-below-topbar-bg-image: ;
+ --container-below-topbar-bg-color: ;
+ --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: ;
+ --container-below-topbar-border-radius: ;
+
+ --container-top-a-bg-image: ;
+ --container-top-a-bg-color: ;
+ --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: ;
+ --container-top-a-border-radius: ;
+
+ --container-top-b-bg-image: ;
+ --container-top-b-bg-color: ;
+ --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: ;
+ --container-top-b-border-radius: ;
+
+ --container-toc-bg: ;
+ --container-toc-color: #dbe3ff;
+
+ --container-sidebar-bg-image: ;
+ --container-sidebar-bg-color: ;
+ --container-sidebar-bg-position: center;
+ --container-sidebar-bg-attachment: scroll;
+ --container-sidebar-bg-repeat: repeat;
+ --container-sidebar-bg-size: auto;
+ --container-sidebar-border: ;
+ --container-sidebar-border-radius: ;
+
+ --container-bottom-a-bg-image: ;
+ --container-bottom-a-bg-color: ;
+ --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: ;
+ --container-bottom-a-border-radius: 5px;
+
+ --container-bottom-b-bg-image: ;
+ --container-bottom-b-bg-color: ;
+ --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: ;
+ --container-bottom-b-border-radius: ;
+
+ /* Nav & accents */
+ --nav-text-color: var(--mainmenu-nav-link-color);
+ --nav-bg-color: var(--color-link);
+ --border: 5px;
+
+ --muted-color: #6d757e;
+ --hr-color: var(--border-color, #dfe3e7);
+ --link-active-color: var(--link-color);
+ --code-color-ink: var(--code-color, #e93f8e);
+ --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);
+
+ /* Palette */
+ --blue: #91a4ff;
+ --black: #000;
+ --indigo: #b19cff;
+ --purple: #c0a5ff;
+ --pink: #ff8fc0;
+ --red: #ff7a73;
+ --orange: #ff9c4d;
+ --yellow: #ffd166;
+ --green: #78d694;
+ --teal: #76e3ff;
+ --cyan: #6fb7ff;
+ --white: #fff;
+
+ /* Grays tuned for dark */
+ --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;
+
+ /* Contextuals (keep brand hues) */
+ --primary: #010156;
+ --secondary: #48525d;
+ --success: #4aa664;
+ --info: #4f7aa0;
+ --warning: #c77a00;
+ --danger: #c23a31;
+ --light: #1b2027;
+ --dark: #0f1318;
+
+ /* RGB helpers */
+ --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;
+
+ /* Emphasis & subtle variants */
+ --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;
+
+ /* Typography & layout */
+ --body-font-family: var(--optain-cassiopeia-font-family-body, -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;
+
+ --emphasis-color: #fff;
+ --emphasis-color-rgb: 255, 255, 255;
+
+ --secondary-color: #e6ebf1bf;
+ --secondary-color-rgb: 230, 235, 241;
+
+ --secondary-bg: #151b22;
+ --secondary-bg-rgb: 21, 27, 34;
+
+ --tertiary-color: #e6ebf180;
+ --tertiary-color-rgb: 230, 235, 241;
+ --tertiary-bg: #10151b;
+ --tertiary-bg-rgb: 16, 21, 27;
+
+ --heading-color: #f1f5f9;
+
+ --link-color: #8ab4f8;
+ --link-color-rgb: 138, 180, 248;
+ --link-decoration: underline;
+ --link-hover-color: #c3d6ff;
+ --link-hover-color-rgb: 195, 214, 255;
+
+ --code-color: #ff7abd;
+ --highlight-color: #111;
+ --highlight-bg: #ffe28a1a;
+
+ --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;
+
+ --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;
+
+ --focus-ring-width: .25rem;
+ --focus-ring-opacity: .6;
+ --focus-ring-color: #5472ff66;
+
+ --form-valid-color: #78d694;
+ --form-valid-border-color: #78d694;
+ --form-invalid-color: #ff8e86;
+ --form-invalid-border-color: #ff8e86;
+}
+
+.btn {
+ --btn-padding-x: 1rem;
+ --btn-padding-y: 0.6rem;
+ --btn-font-family: ;
+ --btn-font-size: 1rem;
+ --btn-font-weight: 400;
+ --btn-line-height: 1.5;
+ --btn-color: var(--white);
+ --btn-bg: transparent;
+ --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;
+}
+
+/* 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;
+}
+
+/* Links as buttons */
+.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: #6d7781;
+ --btn-disabled-border-color: transparent;
+ --btn-box-shadow: none;
+ --btn-focus-shadow-rgb: 84, 114, 255;
+ text-decoration: underline;
+}
+
+.btn-secondary {
+ --btn-color: var(--nav-text-color);
+ --btn-bg: var(--nav-bg-color);
+}
diff --git a/media/templates/site/moko-cassiopeia/css/global/dark/colors_standard.css b/media/templates/site/moko-cassiopeia/css/global/dark/colors_standard.css
new file mode 100644
index 0000000..9da4f20
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/css/global/dark/colors_standard.css
@@ -0,0 +1,368 @@
+@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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/global/dark/colors_standard.css
+ * VERSION: 02.00
+ * BRIEF: Standard dark mode color definitions for Moko-Cassiopeia template
+ * =========================================================================
+ */
+
+/* -----------------------------------------------
+ * DARK THEME
+ * --------------------------------------------- */
+
+:root[data-bs-theme='dark']{
+ /* System hint for native widgets */
+ color-scheme: dark;
+
+ /* Brand & links */
+ --color-primary: #112855;
+ --accent-color-primary: #3f8ff0;
+ --accent-color-secondary: #6fb3ff;
+
+ --mainmenu-nav-link-color: #fff;
+
+ --color-link: #224FAA;
+ --color-hover: #224FAA;
+
+ /* Header background (kept same image; works over dark bg) */
+ --header-background-image: url('../../../../../../media/templates/site/moko-cassiopeia/images/bg.svg'); --header-background-attachment: fixed;
+ --header-background-repeat: repeat;
+ --header-background-size: auto;
+
+ /* Section containers */
+ --container-below-topbar-bg-image: ;
+ --container-below-topbar-bg-color: ;
+ --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: ;
+ --container-below-topbar-border-radius: ;
+
+ --container-top-a-bg-image: ;
+ --container-top-a-bg-color: ;
+ --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: ;
+ --container-top-a-border-radius: ;
+
+ --container-top-b-bg-image: ;
+ --container-top-b-bg-color: ;
+ --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: ;
+ --container-top-b-border-radius: ;
+
+ --container-toc-bg: ;
+ --container-toc-color: #dbe3ff;
+
+ --container-sidebar-bg-image: ;
+ --container-sidebar-bg-color: ;
+ --container-sidebar-bg-position: center;
+ --container-sidebar-bg-attachment: scroll;
+ --container-sidebar-bg-repeat: repeat;
+ --container-sidebar-bg-size: auto;
+ --container-sidebar-border: ;
+ --container-sidebar-border-radius: ;
+
+ --container-bottom-a-bg-image: ;
+ --container-bottom-a-bg-color: ;
+ --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: ;
+ --container-bottom-a-border-radius: 5px;
+
+ --container-bottom-b-bg-image: ;
+ --container-bottom-b-bg-color: ;
+ --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: ;
+ --container-bottom-b-border-radius: ;
+
+ /* Nav & accents */
+ --nav-text-color: var(--mainmenu-nav-link-color);
+ --nav-bg-color: var(--color-link);
+ --border: 5px;
+
+ --muted-color: #6d757e;
+ --hr-color: var(--border-color, #dfe3e7);
+ --link-active-color: var(--link-color);
+ --code-color-ink: var(--code-color, #e93f8e);
+ --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);
+
+ /* Palette */
+ --blue: #91a4ff;
+ --black: #000;
+ --indigo: #b19cff;
+ --purple: #c0a5ff;
+ --pink: #ff8fc0;
+ --red: #ff7a73;
+ --orange: #ff9c4d;
+ --yellow: #ffd166;
+ --green: #78d694;
+ --teal: #76e3ff;
+ --cyan: #6fb7ff;
+ --white: #fff;
+
+ /* Grays tuned for dark */
+ --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;
+
+ /* Contextuals (keep brand hues) */
+ --primary: #010156;
+ --secondary: #48525d;
+ --success: #4aa664;
+ --info: #4f7aa0;
+ --warning: #c77a00;
+ --danger: #c23a31;
+ --light: #1b2027;
+ --dark: #0f1318;
+
+ /* RGB helpers */
+ --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;
+
+ /* Emphasis & subtle variants */
+ --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;
+
+ /* Typography & layout */
+ --body-font-family: var(--optain-cassiopeia-font-family-body, -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;
+
+ --emphasis-color: #fff;
+ --emphasis-color-rgb: 255, 255, 255;
+
+ --secondary-color: #e6ebf1bf;
+ --secondary-color-rgb: 230, 235, 241;
+
+ --secondary-bg: #151b22;
+ --secondary-bg-rgb: 21, 27, 34;
+
+ --tertiary-color: #e6ebf180;
+ --tertiary-color-rgb: 230, 235, 241;
+ --tertiary-bg: #10151b;
+ --tertiary-bg-rgb: 16, 21, 27;
+
+ --heading-color: #f1f5f9;
+
+ --link-color: #8ab4f8;
+ --link-color-rgb: 138, 180, 248;
+ --link-decoration: underline;
+ --link-hover-color: #c3d6ff;
+ --link-hover-color-rgb: 195, 214, 255;
+
+ --code-color: #ff7abd;
+ --highlight-color: #111;
+ --highlight-bg: #ffe28a1a;
+
+ --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;
+
+ --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;
+
+ --focus-ring-width: .25rem;
+ --focus-ring-opacity: .6;
+ --focus-ring-color: #5472ff66;
+
+ --form-valid-color: #78d694;
+ --form-valid-border-color: #78d694;
+ --form-invalid-color: #ff8e86;
+ --form-invalid-border-color: #ff8e86;
+}
+
+.btn {
+ --btn-padding-x: 1rem;
+ --btn-padding-y: 0.6rem;
+ --btn-font-family: ;
+ --btn-font-size: 1rem;
+ --btn-font-weight: 400;
+ --btn-line-height: 1.5;
+ --btn-color: var(--white);
+ --btn-bg: transparent;
+ --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;
+}
+
+/* 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;
+}
+
+/* Links as buttons */
+.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: #6d7781;
+ --btn-disabled-border-color: transparent;
+ --btn-box-shadow: none;
+ --btn-focus-shadow-rgb: 84, 114, 255;
+ text-decoration: underline;
+}
+
+.btn-secondary {
+ --btn-color: var(--nav-text-color);
+ --btn-bg: var(--nav-bg-color);
+}
diff --git a/media/templates/site/moko-cassiopeia/js/mod_gabble/index.html b/media/templates/site/moko-cassiopeia/css/global/dark/index.html
similarity index 100%
rename from media/templates/site/moko-cassiopeia/js/mod_gabble/index.html
rename to media/templates/site/moko-cassiopeia/css/global/dark/index.html
diff --git a/media/templates/site/moko-cassiopeia/css/global/fonts-local_roboto.css b/media/templates/site/moko-cassiopeia/css/global/fonts-local_roboto.css
index 795e022..d38af2d 100644
--- a/media/templates/site/moko-cassiopeia/css/global/fonts-local_roboto.css
+++ b/media/templates/site/moko-cassiopeia/css/global/fonts-local_roboto.css
@@ -1,126 +1,156 @@
+@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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/global/fonts-local_roboto.css
+ * VERSION: 02.00
+ * BRIEF: Local Roboto font-face definitions for the Moko-Cassiopeia template
+ * =========================================================================
+ */
+
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Regular.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Regular.woff") format("woff");
- font-weight: 400;
- font-style: normal;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Regular.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Regular.woff") format("woff");
+ font-weight: 400;
+ font-style: normal;
}
@font-face {
- font-family: "Roboto-Regular";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Regular.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Regular.woff") format("woff");
+ font-family: "Roboto-Regular";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Regular.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Regular.woff") format("woff");
}
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff") format("woff");
- font-weight: 400;
- font-style: italic;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff") format("woff");
+ font-weight: 400;
+ font-style: italic;
}
@font-face {
- font-family: "Roboto-RegularItalic";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff") format("woff");
+ font-family: "Roboto-RegularItalic";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff") format("woff");
}
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Light.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Light.woff") format("woff");
- font-weight: 300;
- font-style: normal;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Light.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Light.woff") format("woff");
+ font-weight: 300;
+ font-style: normal;
}
@font-face {
- font-family: "Roboto-Light";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Light.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Light.woff") format("woff");
+ font-family: "Roboto-Light";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Light.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Light.woff") format("woff");
}
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff") format("woff");
- font-weight: 300;
- font-style: italic;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff") format("woff");
+ font-weight: 300;
+ font-style: italic;
}
@font-face {
- font-family: "Roboto-LightItalic";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff") format("woff");
+ font-family: "Roboto-LightItalic";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff") format("woff");
}
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Thin.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Thin.woff") format("woff");
- font-weight: 100;
- font-style: normal;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Thin.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Thin.woff") format("woff");
+ font-weight: 100;
+ font-style: normal;
}
@font-face {
- font-family: "Roboto-Thin";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Thin.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Thin.woff") format("woff");
+ font-family: "Roboto-Thin";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Thin.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Thin.woff") format("woff");
}
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff") format("woff");
- font-weight: 100;
- font-style: italic;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff") format("woff");
+ font-weight: 100;
+ font-style: italic;
}
@font-face {
- font-family: "Roboto-ThinItalic";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff") format("woff");
+ font-family: "Roboto-ThinItalic";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff") format("woff");
}
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Medium.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Medium.woff") format("woff");
- font-weight: 500;
- font-style: normal;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Medium.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Medium.woff") format("woff");
+ font-weight: 500;
+ font-style: normal;
}
@font-face {
- font-family: "Roboto-Medium";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Medium.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Medium.woff") format("woff");
+ font-family: "Roboto-Medium";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Medium.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Medium.woff") format("woff");
}
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff") format("woff");
- font-weight: 500;
- font-style: italic;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff") format("woff");
+ font-weight: 500;
+ font-style: italic;
}
@font-face {
- font-family: "Roboto-MediumItalic";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff") format("woff");
+ font-family: "Roboto-MediumItalic";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff") format("woff");
}
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Bold.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Bold.woff") format("woff");
- font-weight: 700;
- font-style: normal;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Bold.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Bold.woff") format("woff");
+ font-weight: 700;
+ font-style: normal;
}
@font-face {
- font-family: "Roboto-Bold";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Bold.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Bold.woff") format("woff");
+ font-family: "Roboto-Bold";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Bold.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Bold.woff") format("woff");
}
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff") format("woff");
- font-weight: 700;
- font-style: italic;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff") format("woff");
+ font-weight: 700;
+ font-style: italic;
}
@font-face {
- font-family: "Roboto-BoldItalic";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff") format("woff");
+ font-family: "Roboto-BoldItalic";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff") format("woff");
}
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Black.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Black.woff") format("woff");
- font-weight: 900;
- font-style: normal;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Black.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Black.woff") format("woff");
+ font-weight: 900;
+ font-style: normal;
}
@font-face {
- font-family: "Roboto-Black";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Black.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Black.woff") format("woff");
+ font-family: "Roboto-Black";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Black.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-Black.woff") format("woff");
}
@font-face {
- font-family: "Roboto";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff") format("woff");
- font-weight: 900;
- font-style: italic;
+ font-family: "Roboto";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff") format("woff");
+ font-weight: 900;
+ font-style: italic;
}
@font-face {
- font-family: "Roboto-BlackItalic";
- src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff") format("woff");
+ font-family: "Roboto-BlackItalic";
+ src: url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff2") format("woff2"), url("../../../../../vendor/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff") format("woff");
}
:root {
- --font-family-body: "Roboto", sans-serif;
- --font-family-headings: "Roboto", sans-serif;
- --font-weight-headings: 700;
- --font-weight-normal: 400;
-}
\ No newline at end of file
+ --font-family-body: "Roboto", sans-serif;
+ --font-family-headings: "Roboto", sans-serif;
+ --font-weight-headings: 700;
+ --font-weight-normal: 400;
+}
diff --git a/media/templates/site/moko-cassiopeia/css/global/colors/colors_alternative.css b/media/templates/site/moko-cassiopeia/css/global/light/colors_alternative.css
similarity index 92%
rename from media/templates/site/moko-cassiopeia/css/global/colors/colors_alternative.css
rename to media/templates/site/moko-cassiopeia/css/global/light/colors_alternative.css
index 85558f3..1668018 100644
--- a/media/templates/site/moko-cassiopeia/css/global/colors/colors_alternative.css
+++ b/media/templates/site/moko-cassiopeia/css/global/light/colors_alternative.css
@@ -1,14 +1,31 @@
-/*!
- * @package Joomla.Site
- * @subpackage Templates.moko-cassiopeia
- * @file /media/templates/sote/moko-cassiopeia/css/global/light/colors_alternative.css
+@charset "UTF-8";
+/* =========================================================================
+ * Copyright (C) 2025 Moko Consulting
*
- * @copyright 2025 Moko Consulting
- * @license GNU General Public License version 2 or later; see LICENSE.txt
+ * This file is part of a Moko Consulting project.
*
- * Website: https://mokoconsulting.tech
- * Email: hello@mokoconsulting.tech
- * Phone: +1 (931) 279-6313
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/global/light/colors_alternative.css
+ * VERSION: 02.00
+ * BRIEF: Alternative light mode color definitions for Moko-Cassiopeia template
+ * =========================================================================
*/
/* -----------------------------------------------
@@ -26,7 +43,7 @@
--color-link: #224FAA;
--color-hover: var(--accent-color-primary);
- --header-background-image: url('../../../../../../../media/templates/site/moko-cassiopeia/images/bg.svg');
+ --header-background-image: url('../../../../../../media/templates/site/moko-cassiopeia/images/bg.svg');
--header-background-attachment: fixed;
--header-background-repeat: repeat;
--header-background-size: auto;
diff --git a/media/templates/site/moko-cassiopeia/css/global/colors/colors_standard.css b/media/templates/site/moko-cassiopeia/css/global/light/colors_standard.css
similarity index 92%
rename from media/templates/site/moko-cassiopeia/css/global/colors/colors_standard.css
rename to media/templates/site/moko-cassiopeia/css/global/light/colors_standard.css
index 8d5e068..a2de92d 100644
--- a/media/templates/site/moko-cassiopeia/css/global/colors/colors_standard.css
+++ b/media/templates/site/moko-cassiopeia/css/global/light/colors_standard.css
@@ -1,14 +1,31 @@
-/*!
- * @package Joomla.Site
- * @subpackage Templates.moko-cassiopeia
- * @file /media/templates/sote/moko-cassiopeia/css/global/light/colors_standard.css
+@charset "UTF-8";
+/* =========================================================================
+ * Copyright (C) 2025 Moko Consulting
*
- * @copyright 2025 Moko Consulting
- * @license GNU General Public License version 2 or later; see LICENSE.txt
+ * This file is part of a Moko Consulting project.
*
- * Website: https://mokoconsulting.tech
- * Email: hello@mokoconsulting.tech
- * Phone: +1 (931) 279-6313
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/global/light/colors_standard.css
+ * VERSION: 02.00
+ * BRIEF: Standard light mode color definitions for Moko-Cassiopeia template
+ * =========================================================================
*/
/* -----------------------------------------------
@@ -26,7 +43,7 @@
--color-link: #224FAA;
--color-hover: var(--accent-color-primary);
- --header-background-image: url('../../../../../../../media/templates/site/moko-cassiopeia/images/bg.svg');
+ --header-background-image: url('../../../../../../media/templates/site/moko-cassiopeia/images/bg.svg');
--header-background-attachment: fixed;
--header-background-repeat: repeat;
--header-background-size: auto;
diff --git a/media/templates/site/moko-cassiopeia/css/global/light/index.html b/media/templates/site/moko-cassiopeia/css/global/light/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/css/global/light/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Redirecting to the site root… If you are not redirected, click here.
+
+
diff --git a/media/templates/site/moko-cassiopeia/css/global/social-media-demo.css b/media/templates/site/moko-cassiopeia/css/global/social-media-demo.css
index e42553c..4afedf8 100644
--- a/media/templates/site/moko-cassiopeia/css/global/social-media-demo.css
+++ b/media/templates/site/moko-cassiopeia/css/global/social-media-demo.css
@@ -1,16 +1,33 @@
-/*!
- * @package Joomla.Site
- * @subpackage Templates.moko-cassiopeia
- * @file /media/templates/sote/moko-cassiopeia/css/global/csocial-media-demos.css
+@charset "UTF-8";
+/* =========================================================================
+ * Copyright (C) 2025 Moko Consulting
*
- * @copyright 2025 Moko Consulting
- * @license GNU General Public License version 2 or later; see LICENSE.txt
+ * This file is part of a Moko Consulting project.
*
- * Website: https://mokoconsulting.tech
- * Email: hello@mokoconsulting.tech
- * Phone: +1 (931) 279-6313
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/global/social-media-demo.css
+ * VERSION: 02.00
+ * BRIEF: Demo styles for showcasing social media elements in Moko-Cassiopeia template
+ * =========================================================================
*/
- *
+
/*
======================================================================
Social Media Demo — FULL CSS (Joomla-safe, fully scoped)
@@ -19,10 +36,10 @@ Usage: Wrap your article markup in
...
Version: 2.0 (2025-08-23)
How it’s organized:
- 1) Container-level CSS variables (IMAGES ONLY). Colors are hard-coded per brand below.
- 2) Base/layout styles (sections, header shell, placeholders, buttons).
- 3) Platform brand colors (hard-coded) and cover height tweaks.
- 4) Image assignments (map classes like .fb-cover → variable --fb-cover-img).
+ 1) Container-level CSS variables (IMAGES ONLY). Colors are hard-coded per brand below.
+ 2) Base/layout styles (sections, header shell, placeholders, buttons).
+ 3) Platform brand colors (hard-coded) and cover height tweaks.
+ 4) Image assignments (map classes like .fb-cover → variable --fb-cover-img).
INSTRUCTIONS:
- Save the images in their requried sizes into the [SITEROOT]/images/social/ folder with the exact names.
@@ -32,77 +49,77 @@ INSTRUCTIONS:
REQUIRED IMAGE SIZES — Social Media Demo Wireframes
Facebook
- --fb-cover-img → Cover: 820×312 (desktop), 640×360 (mobile safe)
- --fb-avatar-img → Profile: 176×176 (shown as circle, but use square image)
+ --fb-cover-img → Cover: 820×312 (desktop), 640×360 (mobile safe)
+ --fb-avatar-img → Profile: 176×176 (shown as circle, but use square image)
Twitter / X
- --x-cover-img → Header: 1500×500
- --x-avatar-img → Profile: up to 400×400 (shown as circle, but use square image)
+ --x-cover-img → Header: 1500×500
+ --x-avatar-img → Profile: up to 400×400 (shown as circle, but use square image)
LinkedIn Company
- --li-cover-img → Banner: ~1128×191
- --li-logo-img → Logo: up to 300×300 (rounded square)
+ --li-cover-img → Banner: ~1128×191
+ --li-logo-img → Logo: up to 300×300 (rounded square)
Google Business Profile
- --gmb-cover-img → Banner: ~960×200 (mobile ~960×140)
- --gmb-logo-img → Logo: up to 300×300 (shown as circle, but use square image)
+ --gmb-cover-img → Banner: ~960×200 (mobile ~960×140)
+ --gmb-logo-img → Logo: up to 300×300 (shown as circle, but use square image)
Instagram Business
- --ig-cover-img → Not always visible, safe 1080×608 for highlight background
- --ig-avatar-img → Profile: 320×320 (shown as circle, but use square image)
+ --ig-cover-img → Not always visible, safe 1080×608 for highlight background
+ --ig-avatar-img → Profile: 320×320 (shown as circle, but use square image)
YouTube Channel
- --yt-cover-img → Channel art: 2560×1440 (safe area ~1546×423 center)
- --yt-avatar-img → Channel icon: 800×800 (shown as circle, but use square image)
+ --yt-cover-img → Channel art: 2560×1440 (safe area ~1546×423 center)
+ --yt-avatar-img → Channel icon: 800×800 (shown as circle, but use square image)
TikTok Business
- --tt-cover-img → Profile header: ~900×500 (safe area ~720×405)
- --tt-avatar-img → Profile: 200×200 (shown as circle, but use square image)
+ --tt-cover-img → Profile header: ~900×500 (safe area ~720×405)
+ --tt-avatar-img → Profile: 200×200 (shown as circle, but use square image)
Pinterest Business
- --pin-cover-img → Board/brand banner: ~800×450
- --pin-avatar-img → Profile: 165×165 (shown as circle, but use square image)
+ --pin-cover-img → Board/brand banner: ~800×450
+ --pin-avatar-img → Profile: 165×165 (shown as circle, but use square image)
Snapchat Public Profile
- --sc-cover-img → Banner: ~1080×1920 (stories/poster)
- --sc-avatar-img → Bitmoji/Profile: 320×320 (shown as circle, but use square image)
+ --sc-cover-img → Banner: ~1080×1920 (stories/poster)
+ --sc-avatar-img → Bitmoji/Profile: 320×320 (shown as circle, but use square image)
Reddit Community
- --rd-cover-img → Banner: 1920×384
- --rd-avatar-img → Community icon: 256×256 (shown as circle, but use square image)
+ --rd-cover-img → Banner: 1920×384
+ --rd-avatar-img → Community icon: 256×256 (shown as circle, but use square image)
====================================================================== */
/* Container variables — IMAGES ONLY (safe-scoped) */
.social-media-demo {
- --fb-cover-img: url('../../../../../image/social/fb-cover.jpg');
- --fb-avatar-img: url('../../../../../image/social/fb-avatar.jpg');
+ --fb-cover-img: url('../../../../../image/social/fb-cover.jpg');
+ --fb-avatar-img: url('../../../../../image/social/fb-avatar.jpg');
- --x-cover-img: url('../../../../../image/social/x-cover.jpg');
- --x-avatar-img: url('../../../../../image/social/x-avatar.jpg');
+ --x-cover-img: url('../../../../../image/social/x-cover.jpg');
+ --x-avatar-img: url('../../../../../image/social/x-avatar.jpg');
- --li-cover-img: url('../../../../../image/social/li-cover.jpg');
- --li-logo-img: url('../../../../../image/social/li-logo.jpg');
+ --li-cover-img: url('../../../../../image/social/li-cover.jpg');
+ --li-logo-img: url('../../../../../image/social/li-logo.jpg');
- --gmb-cover-img: url('../../../../../image/social/gmb-cover.jpg');
- --gmb-logo-img: url('../../../../../image/social/gmb-logo.jpg');
+ --gmb-cover-img: url('../../../../../image/social/gmb-cover.jpg');
+ --gmb-logo-img: url('../../../../../image/social/gmb-logo.jpg');
- --ig-cover-img: url('../../../../../image/social/ig-cover.jpg');
- --ig-avatar-img: url('../../../../../image/social/ig-avatar.jpg');
+ --ig-cover-img: url('../../../../../image/social/ig-cover.jpg');
+ --ig-avatar-img: url('../../../../../image/social/ig-avatar.jpg');
- --yt-cover-img: url('../../../../../image/social/yt-cover.jpg');
- --yt-avatar-img: url('../../../../../image/social/yt-avatar.jpg');
+ --yt-cover-img: url('../../../../../image/social/yt-cover.jpg');
+ --yt-avatar-img: url('../../../../../image/social/yt-avatar.jpg');
- --tt-cover-img: url('../../../../../image/social/tt-cover.jpg');
- --tt-avatar-img: url('../../../../../image/social/tt-avatar.jpg');
+ --tt-cover-img: url('../../../../../image/social/tt-cover.jpg');
+ --tt-avatar-img: url('../../../../../image/social/tt-avatar.jpg');
- --pin-cover-img: url('../../../../../image/social/pin-cover.jpg');
- --pin-avatar-img: url('../../../../../image/social/pin-avatar.jpg');
+ --pin-cover-img: url('../../../../../image/social/pin-cover.jpg');
+ --pin-avatar-img: url('../../../../../image/social/pin-avatar.jpg');
- --sc-cover-img: url('../../../../../image/social/sc-cover.jpg');
- --sc-avatar-img: url('../../../../../image/social/sc-avatar.jpg');
+ --sc-cover-img: url('../../../../../image/social/sc-cover.jpg');
+ --sc-avatar-img: url('../../../../../image/social/sc-avatar.jpg');
- --rd-cover-img: url('../../../../../image/social/rd-cover.jpg');
- --rd-avatar-img: url('../../../../../image/social/rd-avatar.jpg');
+ --rd-cover-img: url('../../../../../image/social/rd-cover.jpg');
+ --rd-avatar-img: url('../../../../../image/social/rd-avatar.jpg');
}
/* DO NOT TOUCH */
diff --git a/media/templates/site/moko-cassiopeia/css/system/searchtools/searchtools.css b/media/templates/site/moko-cassiopeia/css/system/searchtools/searchtools.css
index e203db0..b494b00 100644
--- a/media/templates/site/moko-cassiopeia/css/system/searchtools/searchtools.css
+++ b/media/templates/site/moko-cassiopeia/css/system/searchtools/searchtools.css
@@ -1,49 +1,79 @@
+@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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/system/searchtools/searchtools.css
+ * VERSION: 02.00
+ * BRIEF: Stylesheet for Joomla search tools integration in Moko-Cassiopeia template
+ * =========================================================================
+ */
+
.js-stools-container-bar {
- padding: 10px 20px;
+ padding: 10px 20px;
}
.js-stools-container-bar .btn-toolbar {
- -webkit-box-pack: end;
- -ms-flex-pack: end;
- justify-content: flex-end;
+ -webkit-box-pack: end;
+ -ms-flex-pack: end;
+ justify-content: flex-end;
}
.js-stools-container-bar .btn-toolbar > * {
- margin: 4px 0;
- -webkit-margin-end: 8px;
- margin-inline-end: 8px;
+ margin: 4px 0;
+ -webkit-margin-end: 8px;
+ margin-inline-end: 8px;
}
.js-stools-container-bar .btn-toolbar .js-stools-btn-clear {
- background-color: hsl(207, 49%, 37%);
- border: 0;
+ background-color: hsl(207, 49%, 37%);
+ border: 0;
}
.js-stools-container-bar .ordering-select {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
}
.js-stools-container-filters {
- display: none;
- padding: 0 20px;
- margin-bottom: 20px;
+ display: none;
+ padding: 0 20px;
+ margin-bottom: 20px;
}
.js-stools-container-filters-visible {
- display: grid;
- grid-gap: 8px;
- grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
- padding: 10px;
- background-color: hsl(0, 0%, 100%);
+ display: grid;
+ grid-gap: 8px;
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+ padding: 10px;
+ background-color: hsl(0, 0%, 100%);
}
.js-stools-container-filters > * {
- margin: 4px 0;
- -webkit-margin-end: 8px;
- margin-inline-end: 8px;
+ margin: 4px 0;
+ -webkit-margin-end: 8px;
+ margin-inline-end: 8px;
}
.js-stools-field-list + .js-stools-field-list {
- -webkit-margin-start: 8px;
- margin-inline-start: 8px;
+ -webkit-margin-start: 8px;
+ margin-inline-start: 8px;
}
.js-stools-field-selector .form-select {
- width: auto;
-}
\ No newline at end of file
+ width: auto;
+}
diff --git a/media/templates/site/moko-cassiopeia/css/template-rtl.css b/media/templates/site/moko-cassiopeia/css/template-rtl.css
index f9a3955..bee0293 100644
--- a/media/templates/site/moko-cassiopeia/css/template-rtl.css
+++ b/media/templates/site/moko-cassiopeia/css/template-rtl.css
@@ -1,15 +1,31 @@
@charset "UTF-8";
-/*!
- * @package Joomla.Site
- * @subpackage Templates.moko-cassiopeia
- * @file /media/templates/sote/moko-cassiopeia/css/template-rtl.css
+/* =========================================================================
+ * Copyright (C) 2025 Moko Consulting
*
- * @copyright 2025 Moko Consulting
- * @license GNU General Public License version 2 or later; see LICENSE.txt
+ * This file is part of a Moko Consulting project.
*
- * Website: https://mokoconsulting.tech
- * Email: hello@mokoconsulting.tech
- * Phone: +1 (931) 279-6313
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/template-rtl.css
+ * VERSION: 02.00
+ * BRIEF: Right-to-left (RTL) layout stylesheet for Moko-Cassiopeia template
+ * =========================================================================
*/
/*!
@@ -20,7 +36,6 @@
* sensitive rules are mirrored here to keep file size reasonable.
*/
-
[dir="rtl"] .table-of-contents-ck-wrap {
width: 30%;
diff --git a/media/templates/site/moko-cassiopeia/css/template.css b/media/templates/site/moko-cassiopeia/css/template.css
index 530d204..1ffa263 100644
--- a/media/templates/site/moko-cassiopeia/css/template.css
+++ b/media/templates/site/moko-cassiopeia/css/template.css
@@ -1,15 +1,31 @@
@charset "UTF-8";
-/*!
- * @package Joomla.Site
- * @subpackage Templates.moko-cassiopeia
- * @file /media/templates/sote/moko-cassiopeia/css/template.css
+/* =========================================================================
+ * Copyright (C) 2025 Moko Consulting
*
- * @copyright 2025 Moko Consulting
- * @license GNU General Public License version 2 or later; see LICENSE.txt
+ * This file is part of a Moko Consulting project.
*
- * Website: https://mokoconsulting.tech
- * Email: hello@mokoconsulting.tech
- * Phone: +1 (931) 279-6313
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/template.css
+ * VERSION: 02.00
+ * BRIEF: Main stylesheet providing layout, typography, and component styles for Moko-Cassiopeia
+ * =========================================================================
*/
*,
@@ -17206,5 +17222,41 @@ body.site.error-page {
text-decoration: none;
}
+ #mokoThemeFab .knob {
+ position: absolute;
+ top: 2px;
+ left: 2px;
+ width: 20px;
+ height: 20px;
+ border-radius: var(--border-radius-xxl);
+ background: var(--bs-body-bg, #fff);
+ box-shadow: var(--box-shadow);
+ transition: transform .2s ease;
+}
+
+#mokoThemeFab [role="switch"][aria-checked="true"] .knob {
+ transform: translateX(20px);
+}
+
+#mokoThemeFab [role="switch"][aria-checked="true"] .switch {
+ background: rgba(var(--secondary-color), .15);
+}
+
+button#mokoThemeSwitch {
+ border: unset;
+ background-color: unset;
+}
+
+#mokoThemeFab .label {
+ user-select: none;
+ font-size: .875rem;
+}
+
+#mokoThemeFab.debug-outline {
+ outline: 2px dashed var(--pink);
+ outline-offset: 2px;
+}
+
+
/* SOCIAL MEDIA DEMOS */
@import url("global/social-media-demos.css");
diff --git a/media/templates/site/moko-cassiopeia/css/vendor/choicesjs/choices.css b/media/templates/site/moko-cassiopeia/css/vendor/choicesjs/choices.css
index 586806f..0fce1e4 100644
--- a/media/templates/site/moko-cassiopeia/css/vendor/choicesjs/choices.css
+++ b/media/templates/site/moko-cassiopeia/css/vendor/choicesjs/choices.css
@@ -1,499 +1,528 @@
@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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/vendor/choicesjs/choices.css
+ * VERSION: 02.00
+ * BRIEF: Vendor stylesheet for Choices.js select and input enhancements in Moko-Cassiopeia
+ * =========================================================================
+ */
+
/* ===============================
= Choices =
=============================== */
.choices {
- position: relative;
- overflow: hidden;
- margin-bottom: 24px;
- font-size: 16px;
+ position: relative;
+ overflow: hidden;
+ margin-bottom: 24px;
+ font-size: 16px;
}
.choices:focus {
- outline: none;
+ outline: none;
}
.choices:last-child {
- margin-bottom: 0;
+ margin-bottom: 0;
}
.choices.is-open {
- overflow: initial;
+ overflow: initial;
}
.choices.is-disabled .choices__inner,
.choices.is-disabled .choices__input {
- background-color: #eaeaea;
- cursor: not-allowed;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
+ background-color: #eaeaea;
+ cursor: not-allowed;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
}
.choices.is-disabled .choices__item {
- cursor: not-allowed;
+ cursor: not-allowed;
}
.choices [hidden] {
- display: none !important;
+ display: none !important;
}
.choices[data-type*=select-one] {
- cursor: pointer;
+ cursor: pointer;
}
.choices[data-type*=select-one] .choices__inner {
- padding-bottom: 7.5px;
+ padding-bottom: 7.5px;
}
.choices[data-type*=select-one] .choices__input {
- display: block;
- width: 100%;
- padding: 10px;
- border-bottom: 1px solid #ddd;
- background-color: #fff;
- margin: 0;
+ display: block;
+ width: 100%;
+ padding: 10px;
+ border-bottom: 1px solid #ddd;
+ background-color: #fff;
+ margin: 0;
}
.choices[data-type*=select-one] .choices__button {
- background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");
- padding: 0;
- background-size: 8px;
- position: absolute;
- top: 50%;
- right: 0;
- margin-top: -10px;
- margin-right: 25px;
- height: 20px;
- width: 20px;
- border-radius: 10em;
- opacity: 0.25;
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");
+ padding: 0;
+ background-size: 8px;
+ position: absolute;
+ top: 50%;
+ right: 0;
+ margin-top: -10px;
+ margin-right: 25px;
+ height: 20px;
+ width: 20px;
+ border-radius: 10em;
+ opacity: 0.25;
}
.choices[data-type*=select-one] .choices__button:hover, .choices[data-type*=select-one] .choices__button:focus {
- opacity: 1;
+ opacity: 1;
}
.choices[data-type*=select-one] .choices__button:focus {
- -webkit-box-shadow: 0 0 0 2px #00bcd4;
- box-shadow: 0 0 0 2px #00bcd4;
+ -webkit-box-shadow: 0 0 0 2px #00bcd4;
+ box-shadow: 0 0 0 2px #00bcd4;
}
.choices[data-type*=select-one] .choices__item[data-value=""] .choices__button {
- display: none;
+ display: none;
}
.choices[data-type*=select-one]::after {
- content: "";
- height: 0;
- width: 0;
- border-style: solid;
- border-color: #333 transparent transparent transparent;
- border-width: 5px;
- position: absolute;
- right: 11.5px;
- top: 50%;
- margin-top: -2.5px;
- pointer-events: none;
+ content: "";
+ height: 0;
+ width: 0;
+ border-style: solid;
+ border-color: #333 transparent transparent transparent;
+ border-width: 5px;
+ position: absolute;
+ right: 11.5px;
+ top: 50%;
+ margin-top: -2.5px;
+ pointer-events: none;
}
.choices[data-type*=select-one].is-open::after {
- border-color: transparent transparent #333 transparent;
- margin-top: -7.5px;
+ border-color: transparent transparent #333 transparent;
+ margin-top: -7.5px;
}
.choices[data-type*=select-one][dir=rtl]::after {
- left: 11.5px;
- right: auto;
+ left: 11.5px;
+ right: auto;
}
.choices[data-type*=select-one][dir=rtl] .choices__button {
- right: auto;
- left: 0;
- margin-left: 25px;
- margin-right: 0;
+ right: auto;
+ left: 0;
+ margin-left: 25px;
+ margin-right: 0;
}
.choices[data-type*=select-multiple] .choices__inner,
.choices[data-type*=text] .choices__inner {
- cursor: text;
+ cursor: text;
}
.choices[data-type*=select-multiple] .choices__button,
.choices[data-type*=text] .choices__button {
- position: relative;
- display: inline-block;
- margin-top: 0;
- margin-right: -4px;
- margin-bottom: 0;
- margin-left: 8px;
- padding-left: 16px;
- border-left: 1px solid #008fa1;
- background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");
- background-size: 8px;
- width: 8px;
- line-height: 1;
- opacity: 0.75;
- border-radius: 0;
+ position: relative;
+ display: inline-block;
+ margin-top: 0;
+ margin-right: -4px;
+ margin-bottom: 0;
+ margin-left: 8px;
+ padding-left: 16px;
+ border-left: 1px solid #008fa1;
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");
+ background-size: 8px;
+ width: 8px;
+ line-height: 1;
+ opacity: 0.75;
+ border-radius: 0;
}
.choices[data-type*=select-multiple] .choices__button:hover, .choices[data-type*=select-multiple] .choices__button:focus,
.choices[data-type*=text] .choices__button:hover,
.choices[data-type*=text] .choices__button:focus {
- opacity: 1;
+ opacity: 1;
}
.choices__inner {
- display: inline-block;
- vertical-align: top;
- width: 100%;
- background-color: #f9f9f9;
- padding: 7.5px 7.5px 3.75px;
- border: 1px solid #ddd;
- border-radius: 2.5px;
- font-size: 14px;
- min-height: 44px;
- overflow: hidden;
+ display: inline-block;
+ vertical-align: top;
+ width: 100%;
+ background-color: #f9f9f9;
+ padding: 7.5px 7.5px 3.75px;
+ border: 1px solid #ddd;
+ border-radius: 2.5px;
+ font-size: 14px;
+ min-height: 44px;
+ overflow: hidden;
}
.is-focused .choices__inner, .is-open .choices__inner {
- border-color: #b7b7b7;
+ border-color: #b7b7b7;
}
.is-open .choices__inner {
- border-radius: 2.5px 2.5px 0 0;
+ border-radius: 2.5px 2.5px 0 0;
}
.is-flipped.is-open .choices__inner {
- border-radius: 0 0 2.5px 2.5px;
+ border-radius: 0 0 2.5px 2.5px;
}
.choices__list {
- margin: 0;
- padding-left: 0;
- list-style: none;
+ margin: 0;
+ padding-left: 0;
+ list-style: none;
}
.choices__list--single {
- display: inline-block;
- padding: 4px 16px 4px 4px;
- width: 100%;
+ display: inline-block;
+ padding: 4px 16px 4px 4px;
+ width: 100%;
}
[dir=rtl] .choices__list--single {
- padding-right: 4px;
- padding-left: 16px;
+ padding-right: 4px;
+ padding-left: 16px;
}
.choices__list--single .choices__item {
- width: 100%;
+ width: 100%;
}
.choices__list--multiple {
- display: inline;
+ display: inline;
}
.choices__list--multiple .choices__item {
- display: inline-block;
- vertical-align: middle;
- border-radius: 20px;
- padding: 4px 10px;
- font-size: 12px;
- font-weight: 500;
- margin-right: 3.75px;
- margin-bottom: 3.75px;
- background-color: #00bcd4;
- border: 1px solid #00a5bb;
- color: #fff;
- word-break: break-all;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
+ display: inline-block;
+ vertical-align: middle;
+ border-radius: 20px;
+ padding: 4px 10px;
+ font-size: 12px;
+ font-weight: 500;
+ margin-right: 3.75px;
+ margin-bottom: 3.75px;
+ background-color: #00bcd4;
+ border: 1px solid #00a5bb;
+ color: #fff;
+ word-break: break-all;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
}
.choices__list--multiple .choices__item[data-deletable] {
- padding-right: 5px;
+ padding-right: 5px;
}
[dir=rtl] .choices__list--multiple .choices__item {
- margin-right: 0;
- margin-left: 3.75px;
+ margin-right: 0;
+ margin-left: 3.75px;
}
.choices__list--multiple .choices__item.is-highlighted {
- background-color: #00a5bb;
- border: 1px solid #008fa1;
+ background-color: #00a5bb;
+ border: 1px solid #008fa1;
}
.is-disabled .choices__list--multiple .choices__item {
- background-color: #aaaaaa;
- border: 1px solid #919191;
+ background-color: #aaaaaa;
+ border: 1px solid #919191;
}
.choices__list--dropdown {
- visibility: hidden;
- z-index: 1;
- position: absolute;
- width: 100%;
- background-color: #fff;
- border: 1px solid #ddd;
- top: 100%;
- margin-top: -1px;
- border-bottom-left-radius: 2.5px;
- border-bottom-right-radius: 2.5px;
- overflow: hidden;
- word-break: break-all;
- will-change: visibility;
+ visibility: hidden;
+ z-index: 1;
+ position: absolute;
+ width: 100%;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ top: 100%;
+ margin-top: -1px;
+ border-bottom-left-radius: 2.5px;
+ border-bottom-right-radius: 2.5px;
+ overflow: hidden;
+ word-break: break-all;
+ will-change: visibility;
}
.choices__list--dropdown.is-active {
- visibility: visible;
+ visibility: visible;
}
.is-open .choices__list--dropdown {
- border-color: #b7b7b7;
+ border-color: #b7b7b7;
}
.is-flipped .choices__list--dropdown {
- top: auto;
- bottom: 100%;
- margin-top: 0;
- margin-bottom: -1px;
- border-radius: 0.25rem 0.25rem 0 0;
+ top: auto;
+ bottom: 100%;
+ margin-top: 0;
+ margin-bottom: -1px;
+ border-radius: 0.25rem 0.25rem 0 0;
}
.choices__list--dropdown .choices__list {
- position: relative;
- max-height: 300px;
- overflow: auto;
- -webkit-overflow-scrolling: touch;
- will-change: scroll-position;
+ position: relative;
+ max-height: 300px;
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
+ will-change: scroll-position;
}
.choices__list--dropdown .choices__item {
- position: relative;
- padding: 10px;
- font-size: 14px;
+ position: relative;
+ padding: 10px;
+ font-size: 14px;
}
[dir=rtl] .choices__list--dropdown .choices__item {
- text-align: right;
+ text-align: right;
}
@media (min-width: 640px) {
- .choices__list--dropdown .choices__item--selectable {
- padding-right: 100px;
- }
- .choices__list--dropdown .choices__item--selectable::after {
- content: attr(data-select-text);
- font-size: 12px;
- opacity: 0;
- position: absolute;
- right: 10px;
- top: 50%;
- -webkit-transform: translateY(-50%);
- transform: translateY(-50%);
- }
- [dir=rtl] .choices__list--dropdown .choices__item--selectable {
- text-align: right;
- padding-left: 100px;
- padding-right: 10px;
- }
- [dir=rtl] .choices__list--dropdown .choices__item--selectable::after {
- right: auto;
- left: 10px;
- }
+ .choices__list--dropdown .choices__item--selectable {
+ padding-right: 100px;
+ }
+ .choices__list--dropdown .choices__item--selectable::after {
+ content: attr(data-select-text);
+ font-size: 12px;
+ opacity: 0;
+ position: absolute;
+ right: 10px;
+ top: 50%;
+ -webkit-transform: translateY(-50%);
+ transform: translateY(-50%);
+ }
+ [dir=rtl] .choices__list--dropdown .choices__item--selectable {
+ text-align: right;
+ padding-left: 100px;
+ padding-right: 10px;
+ }
+ [dir=rtl] .choices__list--dropdown .choices__item--selectable::after {
+ right: auto;
+ left: 10px;
+ }
}
.choices__list--dropdown .choices__item--selectable.is-highlighted {
- background-color: #f2f2f2;
+ background-color: #f2f2f2;
}
.choices__list--dropdown .choices__item--selectable.is-highlighted::after {
- opacity: 0.5;
+ opacity: 0.5;
}
.choices__item {
- cursor: default;
+ cursor: default;
}
.choices__item--selectable {
- cursor: pointer;
+ cursor: pointer;
}
.choices__item--disabled {
- cursor: not-allowed;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- opacity: 0.5;
+ cursor: not-allowed;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ opacity: 0.5;
}
.choices__heading {
- font-weight: 600;
- font-size: 12px;
- padding: 10px;
- border-bottom: 1px solid #f7f7f7;
- color: gray;
+ font-weight: 600;
+ font-size: 12px;
+ padding: 10px;
+ border-bottom: 1px solid #f7f7f7;
+ color: gray;
}
.choices__button {
- text-indent: -9999px;
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
- border: 0;
- background-color: transparent;
- background-repeat: no-repeat;
- background-position: center;
- cursor: pointer;
+ text-indent: -9999px;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ border: 0;
+ background-color: transparent;
+ background-repeat: no-repeat;
+ background-position: center;
+ cursor: pointer;
}
.choices__button:focus {
- outline: none;
+ outline: none;
}
.choices__input {
- display: inline-block;
- vertical-align: baseline;
- background-color: #f9f9f9;
- font-size: 14px;
- margin-bottom: 5px;
- border: 0;
- border-radius: 0;
- max-width: 100%;
- padding: 4px 0 4px 2px;
+ display: inline-block;
+ vertical-align: baseline;
+ background-color: #f9f9f9;
+ font-size: 14px;
+ margin-bottom: 5px;
+ border: 0;
+ border-radius: 0;
+ max-width: 100%;
+ padding: 4px 0 4px 2px;
}
.choices__input:focus {
- outline: 0;
+ outline: 0;
}
[dir=rtl] .choices__input {
- padding-right: 2px;
- padding-left: 0;
+ padding-right: 2px;
+ padding-left: 0;
}
.choices__placeholder {
- opacity: 0.5;
+ opacity: 0.5;
}
/* ===== End of Choices ====== */
.choices {
- border: 1px solid hsl(210, 14%, 83%);
- border-radius: 0.25rem;
+ border: 1px solid hsl(210, 14%, 83%);
+ border-radius: 0.25rem;
}
.choices.is-focused {
- border-color: #8894aa;
- -webkit-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
- box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+ border-color: #8894aa;
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
}
.choices__inner {
- padding: 0.4rem 1rem;
- margin-bottom: 0;
- font-size: 1rem;
- border: none;
- border-radius: 0;
+ padding: 0.4rem 1rem;
+ margin-bottom: 0;
+ font-size: 1rem;
+ border: none;
+ border-radius: 0;
}
.choices__input {
- padding: 0;
- margin-bottom: 0;
- font-size: 1rem;
- background-color: transparent;
+ padding: 0;
+ margin-bottom: 0;
+ font-size: 1rem;
+ background-color: transparent;
}
.choices__input::-webkit-input-placeholder {
- color: hsl(210, 9%, 31%);
- opacity: 1;
+ color: hsl(210, 9%, 31%);
+ opacity: 1;
}
.choices__input::-moz-placeholder {
- color: hsl(210, 9%, 31%);
- opacity: 1;
+ color: hsl(210, 9%, 31%);
+ opacity: 1;
}
.choices__input:-ms-input-placeholder {
- color: hsl(210, 9%, 31%);
- opacity: 1;
+ color: hsl(210, 9%, 31%);
+ opacity: 1;
}
.choices__input::-ms-input-placeholder {
- color: hsl(210, 9%, 31%);
- opacity: 1;
+ color: hsl(210, 9%, 31%);
+ opacity: 1;
}
.choices__input::placeholder {
- color: hsl(210, 9%, 31%);
- opacity: 1;
+ color: hsl(210, 9%, 31%);
+ opacity: 1;
}
.choices__list--dropdown {
- z-index: 1060;
+ z-index: 1060;
}
.choices__list--multiple .choices__item {
- position: relative;
- margin: 2px;
- background-color: var(--color-primary);
- -webkit-margin-end: 2px;
- margin-inline-end: 2px;
- border: 0;
- border-radius: 0.25rem;
+ position: relative;
+ margin: 2px;
+ background-color: var(--color-primary);
+ -webkit-margin-end: 2px;
+ margin-inline-end: 2px;
+ border: 0;
+ border-radius: 0.25rem;
}
.choices__list--multiple .choices__item.is-highlighted {
- background-color: var(--color-primary);
- opacity: 0.9;
+ background-color: var(--color-primary);
+ opacity: 0.9;
}
.choices .choices__list--dropdown .choices__item {
- -webkit-padding-end: 10px;
- padding-inline-end: 10px;
+ -webkit-padding-end: 10px;
+ padding-inline-end: 10px;
}
.choices .choices__list--dropdown .choices__item--selectable::after {
- display: none;
+ display: none;
}
.choices__button_joomla {
- position: relative;
- padding: 0 10px;
- color: inherit;
- text-indent: -9999px;
- cursor: pointer;
- background: none;
- border: 0;
- opacity: 0.5;
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
+ position: relative;
+ padding: 0 10px;
+ color: inherit;
+ text-indent: -9999px;
+ cursor: pointer;
+ background: none;
+ border: 0;
+ opacity: 0.5;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
}
.choices__button_joomla::before {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- display: block;
- text-align: center;
- text-indent: 0;
- content: "×";
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ display: block;
+ text-align: center;
+ text-indent: 0;
+ content: "×";
}
.choices__button_joomla:hover, .choices__button_joomla:focus {
- opacity: 1;
+ opacity: 1;
}
.choices__button_joomla:focus {
- outline: none;
+ outline: none;
}
.choices[data-type*=select-one] .choices__inner,
.choices[data-type*=select-multiple] .choices__inner {
- -webkit-padding-end: 3rem;
- padding-inline-end: 3rem;
- cursor: pointer;
- background: url("../../../images/select-bg.svg") no-repeat 100%/116rem;
- background-color: hsl(210, 16%, 93%);
+ -webkit-padding-end: 3rem;
+ padding-inline-end: 3rem;
+ cursor: pointer;
+ background: url("../../../images/select-bg.svg") no-repeat 100%/116rem;
+ background-color: hsl(210, 16%, 93%);
}
[dir=rtl] .choices[data-type*=select-one] .choices__inner,
[dir=rtl] .choices[data-type*=select-multiple] .choices__inner {
- background: url("../../../images/select-bg-rtl.svg") no-repeat 0/116rem;
- background-color: hsl(210, 16%, 93%);
+ background: url("../../../images/select-bg-rtl.svg") no-repeat 0/116rem;
+ background-color: hsl(210, 16%, 93%);
}
.choices[data-type*=select-one] .choices__item {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-pack: justify;
- -ms-flex-pack: justify;
- justify-content: space-between;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
}
.choices[data-type*=select-one] .choices__button_joomla {
- position: absolute;
- top: 50%;
- inset-inline-end: 0;
- width: 20px;
- height: 20px;
- padding: 0;
- -webkit-margin-before: -10px;
- margin-block-start: -10px;
- -webkit-margin-end: 50px;
- margin-inline-end: 50px;
- border-radius: 10em;
- opacity: 0.5;
+ position: absolute;
+ top: 50%;
+ inset-inline-end: 0;
+ width: 20px;
+ height: 20px;
+ padding: 0;
+ -webkit-margin-before: -10px;
+ margin-block-start: -10px;
+ -webkit-margin-end: 50px;
+ margin-inline-end: 50px;
+ border-radius: 10em;
+ opacity: 0.5;
}
.choices[data-type*=select-one] .choices__button_joomla:hover, .choices[data-type*=select-one] .choices__button_joomla:focus {
- opacity: 1;
+ opacity: 1;
}
.choices[data-type*=select-one] .choices__button_joomla:focus {
- -webkit-box-shadow: 0 0 0 2px #00bcd4;
- box-shadow: 0 0 0 2px #00bcd4;
+ -webkit-box-shadow: 0 0 0 2px #00bcd4;
+ box-shadow: 0 0 0 2px #00bcd4;
}
.choices[data-type*=select-one]::after {
- display: none;
+ display: none;
}
.choices[data-type*=select-multiple] .choices__input,
.choices[data-type*=text] .choices__input {
- padding: 0.2rem 0;
+ padding: 0.2rem 0;
}
.choices__heading {
- font-size: 1.2rem;
-}
\ No newline at end of file
+ font-size: 1.2rem;
+}
diff --git a/media/templates/site/moko-cassiopeia/css/vendor/joomla-custom-elements/joomla-alert.css b/media/templates/site/moko-cassiopeia/css/vendor/joomla-custom-elements/joomla-alert.css
index 6acec10..7859987 100644
--- a/media/templates/site/moko-cassiopeia/css/vendor/joomla-custom-elements/joomla-alert.css
+++ b/media/templates/site/moko-cassiopeia/css/vendor/joomla-custom-elements/joomla-alert.css
@@ -1,146 +1,176 @@
+@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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/vendor/choicesjs/choices.css
+ * VERSION: 02.00
+ * BRIEF: Vendor stylesheet for Choices.js select and input enhancements in Moko-Cassiopeia
+ * =========================================================================
+ */
+
@import "../../../../../../vendor/joomla-custom-elements/css/joomla-alert.css";
#system-message-container:empty {
- display: none;
- margin-top: 0;
+ display: none;
+ margin-top: 0;
}
#system-message-container joomla-alert {
- position: relative;
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- width: 100%;
- min-width: 16rem;
- padding: 0;
- margin-bottom: 0;
- color: var(--gray-dark);
- background-color: hsl(0, 0%, 100%);
- border: 1px solid var(--alert-accent-color, transparent);
- border-radius: 0.25rem;
- -webkit-transition: opacity 0.15s linear;
- -o-transition: opacity 0.15s linear;
- transition: opacity 0.15s linear;
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ width: 100%;
+ min-width: 16rem;
+ padding: 0;
+ margin-bottom: 0;
+ color: var(--gray-dark);
+ background-color: hsl(0, 0%, 100%);
+ border: 1px solid var(--alert-accent-color, transparent);
+ border-radius: 0.25rem;
+ -webkit-transition: opacity 0.15s linear;
+ -o-transition: opacity 0.15s linear;
+ transition: opacity 0.15s linear;
}
#system-message-container joomla-alert + * {
- margin-top: 1rem;
+ margin-top: 1rem;
}
#system-message-container joomla-alert .alert-heading {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- justify-content: center;
- -ms-flex-line-pack: center;
- align-content: center;
- padding: 0.8rem;
- color: var(--alert-heading-text);
- background: var(--alert-accent-color, transparent);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -ms-flex-line-pack: center;
+ align-content: center;
+ padding: 0.8rem;
+ color: var(--alert-heading-text);
+ background: var(--alert-accent-color, transparent);
}
#system-message-container joomla-alert .alert-heading .message::before,
#system-message-container joomla-alert .alert-heading .success::before {
- display: inline-block;
- width: 1em;
- height: 1em;
- content: "";
- background-image: url('data:image/svg+xml;utf8,');
- background-size: 100%;
+ display: inline-block;
+ width: 1em;
+ height: 1em;
+ content: "";
+ background-image: url('data:image/svg+xml;utf8,');
+ background-size: 100%;
}
#system-message-container joomla-alert .alert-heading .notice::before,
#system-message-container joomla-alert .alert-heading .info::before {
- display: inline-block;
- width: 1em;
- height: 1em;
- content: "";
- background-image: url('data:image/svg+xml;utf8,');
- background-size: 100%;
+ display: inline-block;
+ width: 1em;
+ height: 1em;
+ content: "";
+ background-image: url('data:image/svg+xml;utf8,');
+ background-size: 100%;
}
#system-message-container joomla-alert .alert-heading .warning::before {
- display: inline-block;
- width: 1em;
- height: 1em;
- content: "";
- background-image: url('data:image/svg+xml;utf8,');
- background-size: 100%;
+ display: inline-block;
+ width: 1em;
+ height: 1em;
+ content: "";
+ background-image: url('data:image/svg+xml;utf8,');
+ background-size: 100%;
}
#system-message-container joomla-alert .alert-heading .error::before,
#system-message-container joomla-alert .alert-heading .danger::before {
- display: inline-block;
- width: 1em;
- height: 1em;
- content: "";
- background-image: url('data:image/svg+xml;utf8,');
- background-size: 100%;
+ display: inline-block;
+ width: 1em;
+ height: 1em;
+ content: "";
+ background-image: url('data:image/svg+xml;utf8,');
+ background-size: 100%;
}
#system-message-container joomla-alert .alert-wrapper {
- width: 100%;
+ width: 100%;
}
#system-message-container joomla-alert .alert-link {
- color: var(--success, inherit);
+ color: var(--success, inherit);
}
#system-message-container joomla-alert[type=success], #system-message-container joomla-alert[type=message] {
- --alert-accent-color: var(--success);
- --alert-heading-text: hsla(0, 0%, 100%, .95);
- --alert-close-button: var(--success);
- background-color: hsl(0, 0%, 100%);
+ --alert-accent-color: var(--success);
+ --alert-heading-text: hsla(0, 0%, 100%, .95);
+ --alert-close-button: var(--success);
+ background-color: hsl(0, 0%, 100%);
}
#system-message-container joomla-alert[type=info], #system-message-container joomla-alert[type=notice] {
- --alert-accent-color: var(--info);
- --alert-heading-text: hsla(0, 0%, 100%, .95);
- --alert-close-button: var(--info);
- background-color: hsl(0, 0%, 100%);
+ --alert-accent-color: var(--info);
+ --alert-heading-text: hsla(0, 0%, 100%, .95);
+ --alert-close-button: var(--info);
+ background-color: hsl(0, 0%, 100%);
}
#system-message-container joomla-alert[type=warning] {
- --alert-accent-color: var(--warning);
- --alert-heading-text: hsla(0, 0%, 100%, .95);
- --alert-close-button: var(--warning);
- background-color: hsl(0, 0%, 100%);
+ --alert-accent-color: var(--warning);
+ --alert-heading-text: hsla(0, 0%, 100%, .95);
+ --alert-close-button: var(--warning);
+ background-color: hsl(0, 0%, 100%);
}
#system-message-container joomla-alert[type=error], #system-message-container joomla-alert[type=danger] {
- --alert-accent-color: var(--danger);
- --alert-heading-text: hsla(0, 0%, 100%, .95);
- --alert-close-button: var(--danger);
- background-color: hsl(0, 0%, 100%);
+ --alert-accent-color: var(--danger);
+ --alert-heading-text: hsla(0, 0%, 100%, .95);
+ --alert-close-button: var(--danger);
+ background-color: hsl(0, 0%, 100%);
}
#system-message-container joomla-alert .joomla-alert--close,
#system-message-container joomla-alert .joomla-alert-button--close {
- position: absolute;
- top: 0;
- right: 0;
- padding: 0.2rem 0.8rem;
- font-size: 2rem;
- color: var(--alert-close-button);
- background: none;
- border: 0;
- opacity: 1;
+ position: absolute;
+ top: 0;
+ right: 0;
+ padding: 0.2rem 0.8rem;
+ font-size: 2rem;
+ color: var(--alert-close-button);
+ background: none;
+ border: 0;
+ opacity: 1;
}
#system-message-container joomla-alert .joomla-alert--close:hover, #system-message-container joomla-alert .joomla-alert--close:focus,
#system-message-container joomla-alert .joomla-alert-button--close:hover,
#system-message-container joomla-alert .joomla-alert-button--close:focus {
- text-decoration: none;
- cursor: pointer;
- opacity: 0.75;
+ text-decoration: none;
+ cursor: pointer;
+ opacity: 0.75;
}
[dir=rtl] #system-message-container joomla-alert .joomla-alert--close,
[dir=rtl] #system-message-container joomla-alert .joomla-alert-button--close {
- right: auto;
- left: 0;
- padding: 0.2rem 0.6rem;
+ right: auto;
+ left: 0;
+ padding: 0.2rem 0.6rem;
}
#system-message-container joomla-alert div {
- font-size: 1rem;
+ font-size: 1rem;
}
#system-message-container joomla-alert div .alert-message {
- padding: 0.3rem 2rem 0.3rem 0.3rem;
- margin: 0.5rem;
+ padding: 0.3rem 2rem 0.3rem 0.3rem;
+ margin: 0.5rem;
}
[dir=rtl] #system-message-container joomla-alert div .alert-message {
- padding: 0.3rem 0.3rem 0.3rem 2rem;
+ padding: 0.3rem 0.3rem 0.3rem 2rem;
}
#system-message-container joomla-alert div .alert-message:not(:first-of-type) {
- border-top: 1px solid var(--alert-accent-color);
-}
\ No newline at end of file
+ border-top: 1px solid var(--alert-accent-color);
+}
diff --git a/media/templates/site/moko-cassiopeia/css/vendor/vmbasic.css b/media/templates/site/moko-cassiopeia/css/vendor/vmbasic.css
index bedf29f..e3722a3 100644
--- a/media/templates/site/moko-cassiopeia/css/vendor/vmbasic.css
+++ b/media/templates/site/moko-cassiopeia/css/vendor/vmbasic.css
@@ -1,3 +1,33 @@
+@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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/css/vendor/vmbasic.css
+ * VERSION: 02.00
+ * BRIEF: Vendor stylesheet providing base styles for VM Basic in Moko-Cassiopeia
+ * =========================================================================
+ */
+
/* Bootstrap */
.dropdown-menu {
border-radius: 0;
diff --git a/media/templates/site/moko-cassiopeia/css/vmbasic.css b/media/templates/site/moko-cassiopeia/css/vmbasic.css
new file mode 100644
index 0000000..bedf29f
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/css/vmbasic.css
@@ -0,0 +1,617 @@
+/* Bootstrap */
+.dropdown-menu {
+ border-radius: 0;
+ --bs-dropdown-zindex: 1030;
+}
+
+.dropdown-toggle {
+ display: flex;
+ align-items: center;
+}
+
+.dropdown-toggle::after {
+ content: "";
+ border: none;
+ background-image: url('data:image/svg+xml,');
+ background-repeat: no-repeat;
+ width: 10px;
+ height: 10px
+}
+
+.btn {
+ border-radius: 0
+}
+
+.input-group .btn {
+ font-size: 14px;
+ border-radius: var(--bs-border-radius);
+}
+
+.btn-primary {
+ --bs-btn-bg: #333;
+ --bs-btn-border-color: #333;
+ --bs-btn-hover-bg: #555;
+ --bs-btn-hover-border-color: #555;
+ --bs-btn-focus-shadow-rgb: 49, 132, 253;
+ --bs-btn-active-bg: #555;
+ --bs-btn-active-border-color: #555;
+ --bs-btn-disabled-bg: #A0A0A0;
+ --bs-btn-disabled-border-color: #A0A0A0;
+}
+
+.btn-secondary {
+ --bs-btn-color: #333;
+ --bs-btn-bg: #EFEFEF;
+ --bs-btn-border-color: #EFEFEF;
+ --bs-btn-hover-bg: #333;
+ --bs-btn-hover-border-color: #333;
+ --bs-btn-active-bg: #333;
+ --bs-btn-active-border-color: #333;
+}
+
+.btn-check:checked + .btn, .btn.active, .btn.show, .btn:first-child:active, :not(.btn-check) + .btn:active {
+ color: #A0A0A0;
+}
+
+.text-secondary {
+ color: #A0A0A0 !important;
+}
+
+.form-control, .form-select {
+ font-size: 14px
+}
+
+form .form-control, form .form-select {
+ border-color: #C7C7C7
+}
+
+/* General styles */
+body {
+ font-size: 15px;
+ color: #333;
+}
+
+a, .btn-link {
+ color: #A0A0A0;
+ text-decoration: none
+}
+
+a:hover, .btn-link:hover {
+ color: #333;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+ aspect-ratio: attr(width) / attr(height);
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-weight: 600;
+ margin-bottom: 1em;
+ color: #333;
+}
+
+h1 {
+ font-size: 32px
+}
+
+h2 {
+ font-size: 28px
+}
+
+h3 {
+ font-size: 25px
+}
+
+h4 {
+ font-size: 22px
+}
+
+h5 {
+ font-size: 20px
+}
+
+h6 {
+ font-size: 18px
+}
+
+.toolbar {
+ font-size: 14px;
+ padding: 9px 0;
+ background-color: #EFEFEF
+}
+
+.toolbar a, .toolbar .btn-link {
+ color: inherit;
+}
+
+.toolbar .btn svg {
+ margin-right: 5px;
+}
+
+.toolbar svg {
+ line-height: 16px;
+ vertical-align: sub;
+}
+
+.top-bar {
+ font-weight: bold;
+}
+
+header p {
+ margin: 0
+}
+
+.toolbar .dropdown-menu {
+ font-size: 14px;
+ line-height: 14px;
+ min-width: 100%;
+ width: max-content;
+}
+
+.form-control-feedback {
+ display: block;
+ font-size: 14px;
+ color: red;
+}
+
+/* Main menu */
+.main-menu {
+ background-color: #555;
+ color: #fff;
+}
+
+.main-menu .nav-item {
+ position: relative;
+}
+
+.main-menu a, .main-menu span {
+ position: relative;
+ display: block;
+ padding: 14px 18px;
+ color: #fff;
+ background-color: #555;
+ transition: background-color linear 250ms
+}
+
+.main-menu .active > a, .main-menu .active > span, .main-menu a:hover, .main-menu span:hover {
+ background-color: #000;
+ transition: background-color linear 250ms
+}
+
+.main-menu .parent > a::after, .main-menu .parent > span::after {
+ content: "";
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ background-color: #fff;
+ margin-left: 5px;
+ -webkit-mask: url('data:image/svg+xml,');
+ mask: url('data:image/svg+xml,');
+}
+
+.main-menu .mod-menu__sub .parent > a::after, .main-menu .mod-menu__sub .parent > span::after {
+ position: absolute;
+ right: 9px;
+ top: 50%;
+ transform: translateY(-50%) rotate(-90deg);
+}
+
+.main-menu .mod-menu__sub {
+ position: absolute;
+ left: 0;
+ top: 100%;
+ z-index: 1022;
+ min-width: 200px;
+ opacity: 0;
+ visibility: hidden;
+ transition: all linear 250ms
+}
+
+.main-menu .parent:hover > .mod-menu__sub {
+ opacity: 1;
+ visibility: visible;
+ box-shadow: 0 5px 15px 0 rgba(0,0,0,0.3);
+ transition: all linear 250ms
+}
+
+.mod-menu__sub .mod-menu__sub {
+ left: 100%;
+ top: 0
+}
+
+/* Banners */
+.banner-section p {
+ margin: 0
+}
+
+/* Modules */
+.mod-breadcrumbs {
+ background-color: #EFEFEF;
+ font-size: 14px;
+ white-space: nowrap;
+ overflow: auto;
+ flex-wrap: nowrap;
+}
+
+.breadcrumb-item + .breadcrumb-item::before {
+ float: none;
+}
+
+.mod-breadcrumbs a, .manufacturer-details-view a:not(.btn) {
+ color: #71ABD6;
+}
+
+.breadcrumb-item.active {
+ color: #A0A0A0;
+}
+
+aside .module-title {
+ font-size: 24px;
+ font-weight: normal;
+ border-bottom: 1px solid #dee2e6;
+ padding-bottom: 15px;
+ margin-bottom: 15px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+/* Footer */
+footer {
+ padding: 50px 0;
+ background-color: #EFEFEF;
+}
+
+footer .module-title {
+ font-size: 18px;
+ margin-bottom: 20px;
+}
+
+footer .nav {
+ flex-direction: column;
+}
+
+footer ul {
+ list-style: none;
+ padding: 0;
+ margin: 0
+}
+
+footer .nav-item, footer li {
+ margin-bottom: 10px;
+}
+
+footer a {
+ color: #333;
+}
+
+footer a:hover {
+ color: #A0A0A0;
+}
+
+/* Forms */
+textarea {
+ min-height: 100px
+}
+
+.control-label {
+ margin-bottom: 5px;
+}
+
+/*********
+Virtuemart
+*********/
+
+/* VM Search module */
+.vmbasic-search input {
+ border-color: #A0A0A0;
+ border-radius: 0;
+ height: 40px;
+}
+
+.mod-vm-search .btn-svg {
+ padding: 0 10px;
+ position: absolute;
+ z-index: 5;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ height: 40px;
+}
+
+.vm-search-custom-search-input input, #vm-orderby-select {
+ border-radius: var(--bs-border-radius) !important;
+}
+
+/* VM cart module */
+.vmCartModule .btn-link {
+ color: #333;
+}
+
+/* Product page */
+.manufacturer a {
+ color: #71ABD6;
+}
+
+/* Account */
+.vm-add-edit-address > a, .vm-order-list a {
+ font-weight: 600;
+ color: #71ABD6
+}
+
+/* Checkout */
+.vm-coupon-container .btn {
+ border-radius: var(--bs-border-radius);
+}
+
+#checkoutForm .details {
+ font-weight: 600;
+ color: #71ABD6
+}
+
+
+/*********
+Joomla
+*********/
+
+/* com_content */
+.item-content .page-header h2 {
+ font-size: 20px;
+}
+
+.article-info {
+ display: flex;
+ flex-wrap: wrap;
+ font-size: 14px;
+ margin-bottom: 5px;
+}
+
+.item-image {
+ display: block;
+ margin: 0 auto 30px;
+}
+
+.article-info > * {
+ margin-right: 8px
+}
+
+.com-content-article__links {
+ list-style: none;
+ padding: 0;
+ margin: 30px 0;
+}
+
+.com-content-article__links a, .items-more a {
+ color: #71ABD6
+}
+
+.active > .page-link, .page-link.active {
+ background-color: #555555;
+ border-color: #555555;
+}
+
+.page-link, .page-link:hover {
+ color: #333;
+}
+
+.pagenavigation {
+ margin: 30px 0;
+}
+
+.pagenavigation .next {
+ margin-left: auto;
+}
+
+/* tags */
+.com-tags-tag-list__category, .com-tags-tag__category {
+ margin-top: 30px;
+}
+
+.tag-category .list-group-item h3 {
+ margin: 0;
+ font-size: 16px;
+}
+
+.tags .btn {
+ font-size: 12px;
+ padding: 0 5px;
+ color: #fff;
+}
+
+
+/* User */
+.com-users-login.login, .com-users-reset, .com-users-remind, .com-users-registration {
+ max-width: 400px;
+ margin: auto;
+ padding: 15px;
+ border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;
+}
+
+.control-group, .com-users-login__remember {
+ margin-bottom: 15px;
+}
+
+.com-users-reset legend, .com-users-remind legend {
+ font-size: 14px
+}
+
+/* Contact */
+#contact-form legend {
+ font-size: 16px;
+ font-weight: 600;
+}
+
+.com-contact-featured__table {
+ margin-top: 30px;
+}
+
+/* Modules */
+.sidebar-right ul, .sidebar-left ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.sidebar-right li, .sidebar-left li {
+ margin-bottom: 10px
+}
+
+
+.mod-login__userdata > div {
+ margin-bottom: 15px;
+}
+
+.awesomplete input {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.mod-login__userdata.userdata {
+ padding: 15px;
+ border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;
+}
+
+#Passkey {
+ width: 24px;
+}
+
+/* offcanvas*/
+.offcanvas-body .mod-menu {
+ flex-direction: column;
+}
+
+.offcanvas-body .mod-menu__sub {
+ display: none;
+ padding: 10px
+}
+
+.offcanvas-body .nav-item {
+ padding: 5px 0;
+ border-bottom: 1px solid var(--bs-border-color);
+ position: relative;
+}
+
+.offcanvas-body .nav-item:last-child {
+ border-bottom: none;
+}
+
+.offcanvas-body a {
+ font-size: 15px;
+ color: #333
+}
+
+.offcanvas-body .active > a {
+ font-weight: bold;
+}
+
+.offcanvas-body .subtoggle {
+ padding: 0;
+ background-color: transparent;
+ border: none;
+ width: 30px;
+ height: 30px;
+ position: absolute;
+ right: 0;
+ top: 1px;
+ z-index: 1
+}
+
+.offcanvas-body .subtoggle.open {
+ transform: rotate(-180deg);
+ transition: all linear 200ms
+}
+
+/* To top */
+.back-to-top-link {
+ display: none;
+ position: fixed;
+ right: 12px;
+ bottom: 12px;
+ z-index: 1020;
+}
+
+@media screen and (max-width: 1080px) {
+
+ body {
+ font-size: 14px
+ }
+
+}
+
+@media screen and (max-width: 991px) {
+
+ h1 {
+ font-size: 24px
+ }
+
+ h2 {
+ font-size: 22px
+ }
+
+ h3 {
+ font-size: 20px
+ }
+
+ h4 {
+ font-size: 18px
+ }
+
+ h5 {
+ font-size: 16px
+ }
+
+ h6 {
+ font-size: 15px
+ }
+
+ .main-search {
+ display: none;
+ }
+}
+
+@media screen and (max-width: 490px) {
+
+ .toolbar {
+ padding: 6px 0;
+ }
+
+ .toolbar .bg-alt {
+ background-color: #333;
+ color: #fff;
+ }
+
+ .top-bar {
+ background-color: #333;
+ color: #fff;
+ }
+
+ .top-bar a {
+ color: #fff;
+ }
+
+ .cart-module .bi-cart3 {
+ margin-top: 2px
+ }
+
+ .cart-module .total_products {
+ display: none;
+ }
+
+ .vmCartModule .dropdown-menu {
+ margin-right: -10px !important;
+ }
+
+ .cart-module .dropdown-toggle::after {
+ content: none;
+ }
+
+ .com-contact-featured__items, .com-contact-category__items {
+ overflow-x: auto;
+ }
+
+ footer {
+ padding-bottom: 30px;
+ }
+}
diff --git a/media/templates/site/moko-cassiopeia/images/bg.svg b/media/templates/site/moko-cassiopeia/images/bg.svg
new file mode 100644
index 0000000..6e73f8c
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/images/bg.svg
@@ -0,0 +1,107 @@
+
+
+
+
diff --git a/media/templates/site/moko-cassiopeia/images/logo.svg b/media/templates/site/moko-cassiopeia/images/logo.svg
new file mode 100644
index 0000000..c4b4647
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/images/logo.svg
@@ -0,0 +1,93 @@
+
+
+
+
diff --git a/media/templates/site/moko-cassiopeia/images/select-bg-active-rtl.svg b/media/templates/site/moko-cassiopeia/images/select-bg-active-rtl.svg
new file mode 100644
index 0000000..eae47aa
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/images/select-bg-active-rtl.svg
@@ -0,0 +1 @@
+
diff --git a/media/templates/site/moko-cassiopeia/images/select-bg-active.svg b/media/templates/site/moko-cassiopeia/images/select-bg-active.svg
new file mode 100644
index 0000000..19cd786
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/images/select-bg-active.svg
@@ -0,0 +1 @@
+
diff --git a/media/templates/site/moko-cassiopeia/images/select-bg-rtl.svg b/media/templates/site/moko-cassiopeia/images/select-bg-rtl.svg
new file mode 100644
index 0000000..a1ae9a3
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/images/select-bg-rtl.svg
@@ -0,0 +1 @@
+
diff --git a/media/templates/site/moko-cassiopeia/images/select-bg.svg b/media/templates/site/moko-cassiopeia/images/select-bg.svg
new file mode 100644
index 0000000..e2fefcc
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/images/select-bg.svg
@@ -0,0 +1 @@
+
diff --git a/media/templates/site/moko-cassiopeia/images/teaser_bg_sm.png b/media/templates/site/moko-cassiopeia/images/teaser_bg_sm.png
new file mode 100644
index 0000000..94d8fbe
Binary files /dev/null and b/media/templates/site/moko-cassiopeia/images/teaser_bg_sm.png differ
diff --git a/media/templates/site/moko-cassiopeia/images/template_preview.png b/media/templates/site/moko-cassiopeia/images/template_preview.png
new file mode 100644
index 0000000..a83ca41
Binary files /dev/null and b/media/templates/site/moko-cassiopeia/images/template_preview.png differ
diff --git a/media/templates/site/moko-cassiopeia/images/template_thumbnail.png b/media/templates/site/moko-cassiopeia/images/template_thumbnail.png
new file mode 100644
index 0000000..e237919
Binary files /dev/null and b/media/templates/site/moko-cassiopeia/images/template_thumbnail.png differ
diff --git a/media/templates/site/moko-cassiopeia/js/darkmode-toggle.js b/media/templates/site/moko-cassiopeia/js/darkmode-toggle.js
index cd2485d..921a18e 100644
--- a/media/templates/site/moko-cassiopeia/js/darkmode-toggle.js
+++ b/media/templates/site/moko-cassiopeia/js/darkmode-toggle.js
@@ -1,147 +1,170 @@
-/**
- * darkmode-toggle.js — Floating theme switch (class-based, CSP-proof)
- * @version 2.2.1
- * Storage key: "theme" -> "light" | "dark"
- * Corner from (default br)
+/* =========================================================================
+ * Copyright (C) 2025 Moko Consulting
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ * =========================================================================
+ * FILE INFORMATION
+ * DEFGROUP: Joomla
+ * INGROUP: Moko-Cassiopeia
+ * PATH: media/templates/site/moko-cassiopeia/js/darkmode-toggle.js
+ * VERSION: 02.00
+ * BRIEF: JavaScript logic for dark mode toggle functionality in Moko-Cassiopeia
+ * =========================================================================
*/
+
(function () {
- 'use strict';
+ 'use strict';
- var STORAGE_KEY = 'theme';
- var docEl = document.documentElement;
- var mql = window.matchMedia('(prefers-color-scheme: dark)');
+ var STORAGE_KEY = 'theme';
+ var docEl = document.documentElement;
+ var mql = window.matchMedia('(prefers-color-scheme: dark)');
- function getStored() { try { return localStorage.getItem(STORAGE_KEY); } catch (e) { return null; } }
- function setStored(v) { try { localStorage.setItem(STORAGE_KEY, v); } catch (e) {} }
- function clearStored() { try { localStorage.removeItem(STORAGE_KEY); } catch (e) {} }
- function systemTheme() { return mql.matches ? 'dark' : 'light'; }
+ function getStored() { try { return localStorage.getItem(STORAGE_KEY); } catch (e) { return null; } }
+ function setStored(v) { try { localStorage.setItem(STORAGE_KEY, v); } catch (e) {} }
+ function clearStored() { try { localStorage.removeItem(STORAGE_KEY); } catch (e) {} }
+ function systemTheme() { return mql.matches ? 'dark' : 'light'; }
- function applyTheme(theme) {
- docEl.setAttribute('data-bs-theme', theme);
- docEl.setAttribute('data-aria-theme', theme);
- var meta = document.querySelector('meta[name="theme-color"]');
- if (meta) {
- meta.setAttribute('content', theme === 'dark' ? '#0f1115' : '#ffffff');
- }
- var sw = document.getElementById('mokoThemeSwitch');
- if (sw) {
- sw.setAttribute('aria-checked', theme === 'dark' ? 'true' : 'false');
- }
- }
+ function applyTheme(theme) {
+ docEl.setAttribute('data-bs-theme', theme);
+ docEl.setAttribute('data-aria-theme', theme);
+ var meta = document.querySelector('meta[name="theme-color"]');
+ if (meta) {
+ meta.setAttribute('content', theme === 'dark' ? '#0f1115' : '#ffffff');
+ }
+ var sw = document.getElementById('mokoThemeSwitch');
+ if (sw) {
+ sw.setAttribute('aria-checked', theme === 'dark' ? 'true' : 'false');
+ }
+ }
- function initTheme() {
- var stored = getStored();
- applyTheme(stored ? stored : systemTheme());
- }
+ function initTheme() {
+ var stored = getStored();
+ applyTheme(stored ? stored : systemTheme());
+ }
- function posClassFromBody() {
- var pos = (document.body.getAttribute('data-theme-fab-pos') || 'br').toLowerCase();
- if (!/^(br|bl|tr|tl)$/.test(pos)) pos = 'br';
- return 'pos-' + pos;
- }
+ function posClassFromBody() {
+ var pos = (document.body.getAttribute('data-theme-fab-pos') || 'br').toLowerCase();
+ if (!/^(br|bl|tr|tl)$/.test(pos)) pos = 'br';
+ return 'pos-' + pos;
+ }
- function buildToggle() {
- if (document.getElementById('mokoThemeFab')) return;
+ function buildToggle() {
+ if (document.getElementById('mokoThemeFab')) return;
- var wrap = document.createElement('div');
- wrap.id = 'mokoThemeFab';
- wrap.className = posClassFromBody();
+ var wrap = document.createElement('div');
+ wrap.id = 'mokoThemeFab';
+ wrap.className = posClassFromBody();
- // Light label
- var lblL = document.createElement('span');
- lblL.className = 'label';
- lblL.textContent = 'Light';
+ // Light label
+ var lblL = document.createElement('span');
+ lblL.className = 'label';
+ lblL.textContent = 'Light';
- // Switch
- var switchWrap = document.createElement('button');
- switchWrap.id = 'mokoThemeSwitch';
- switchWrap.type = 'button';
- switchWrap.setAttribute('role', 'switch');
- switchWrap.setAttribute('aria-label', 'Toggle dark mode');
- switchWrap.setAttribute('aria-checked', 'false'); // updated after init
+ // Switch
+ var switchWrap = document.createElement('button');
+ switchWrap.id = 'mokoThemeSwitch';
+ switchWrap.type = 'button';
+ switchWrap.setAttribute('role', 'switch');
+ switchWrap.setAttribute('aria-label', 'Toggle dark mode');
+ switchWrap.setAttribute('aria-checked', 'false'); // updated after init
- var track = document.createElement('span');
- track.className = 'switch';
- var knob = document.createElement('span');
- knob.className = 'knob';
- track.appendChild(knob);
- switchWrap.appendChild(track);
+ var track = document.createElement('span');
+ track.className = 'switch';
+ var knob = document.createElement('span');
+ knob.className = 'knob';
+ track.appendChild(knob);
+ switchWrap.appendChild(track);
- // Dark label
- var lblD = document.createElement('span');
- lblD.className = 'label';
- lblD.textContent = 'Dark';
+ // Dark label
+ var lblD = document.createElement('span');
+ lblD.className = 'label';
+ lblD.textContent = 'Dark';
- // Auto button
- var auto = document.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 button
+ var auto = document.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';
- // Behavior
- switchWrap.addEventListener('click', function () {
- var current = (docEl.getAttribute('data-bs-theme') || 'light').toLowerCase();
- var next = current === 'dark' ? 'light' : 'dark';
- applyTheme(next);
- setStored(next);
- });
+ // Behavior
+ switchWrap.addEventListener('click', function () {
+ var current = (docEl.getAttribute('data-bs-theme') || 'light').toLowerCase();
+ var next = current === 'dark' ? 'light' : 'dark';
+ applyTheme(next);
+ setStored(next);
+ });
- auto.addEventListener('click', function () {
- clearStored();
- applyTheme(systemTheme());
- });
+ auto.addEventListener('click', function () {
+ clearStored();
+ applyTheme(systemTheme());
+ });
- // Respond to OS changes only when not user-forced
- var onMql = function () {
- if (!getStored()) applyTheme(systemTheme());
- };
- if (typeof mql.addEventListener === 'function') mql.addEventListener('change', onMql);
- else if (typeof mql.addListener === 'function') mql.addListener(onMql);
+ // Respond to OS changes only when not user-forced
+ var onMql = function () {
+ if (!getStored()) applyTheme(systemTheme());
+ };
+ if (typeof mql.addEventListener === 'function') mql.addEventListener('change', onMql);
+ else if (typeof mql.addListener === 'function') mql.addListener(onMql);
- // Initial state
- var initial = getStored() || systemTheme();
- switchWrap.setAttribute('aria-checked', initial === 'dark' ? 'true' : 'false');
+ // Initial state
+ var initial = getStored() || systemTheme();
+ switchWrap.setAttribute('aria-checked', initial === 'dark' ? 'true' : 'false');
- // Mount
- wrap.appendChild(lblL);
- wrap.appendChild(switchWrap);
- wrap.appendChild(lblD);
- wrap.appendChild(auto);
- document.body.appendChild(wrap);
+ // Mount
+ wrap.appendChild(lblL);
+ wrap.appendChild(switchWrap);
+ wrap.appendChild(lblD);
+ wrap.appendChild(auto);
+ document.body.appendChild(wrap);
- // Debug helper
- window.mokoThemeFabStatus = function () {
- var el = document.getElementById('mokoThemeFab');
- if (!el) return { mounted: false };
- var r = el.getBoundingClientRect();
- return {
- mounted: true,
- rect: { top: r.top, left: r.left, width: r.width, height: r.height },
- zIndex: window.getComputedStyle(el).zIndex,
- posClass: el.className
- };
- };
+ // Debug helper
+ window.mokoThemeFabStatus = function () {
+ var el = document.getElementById('mokoThemeFab');
+ if (!el) return { mounted: false };
+ var r = el.getBoundingClientRect();
+ return {
+ mounted: true,
+ rect: { top: r.top, left: r.left, width: r.width, height: r.height },
+ zIndex: window.getComputedStyle(el).zIndex,
+ posClass: el.className
+ };
+ };
- // Outline if invisible
- setTimeout(function () {
- var r = wrap.getBoundingClientRect();
- if (r.width < 10 || r.height < 10) {
- wrap.classList.add('debug-outline');
- console.warn('[moko] Theme FAB mounted but appears too small — check CSS collisions.');
- }
- }, 50);
- }
+ // Outline if invisible
+ setTimeout(function () {
+ var r = wrap.getBoundingClientRect();
+ if (r.width < 10 || r.height < 10) {
+ wrap.classList.add('debug-outline');
+ console.warn('[moko] Theme FAB mounted but appears too small — check CSS collisions.');
+ }
+ }, 50);
+ }
- function init() {
- initTheme();
- buildToggle();
- }
+ function init() {
+ initTheme();
+ buildToggle();
+ }
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', init);
- } else {
- init();
- }
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', init);
+ } else {
+ init();
+ }
})();
diff --git a/media/templates/site/moko-cassiopeia/js/gtm.js b/media/templates/site/moko-cassiopeia/js/gtm.js
index e69de29..05c2482 100644
--- a/media/templates/site/moko-cassiopeia/js/gtm.js
+++ b/media/templates/site/moko-cassiopeia/js/gtm.js
@@ -0,0 +1,347 @@
+/*
+ =========================================================================
+ Copyright (C) 2025 Moko Consulting
+ This file is part of a Moko Consulting project.
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see https://www.gnu.org/licenses/ .
+ =========================================================================
+ FILE INFORMATION
+ DEFGROUP: Joomla Template
+ FILE: media/templates/site/moko-cassiopeia/js/gtm.js
+ HEADER VERSION: 1.0
+ VERSION: 2.0
+ BRIEF: Safe, configurable Google Tag Manager loader for Moko-Cassiopeia.
+ PATH: media/templates/site/moko-cassiopeia/js/gtm.js
+ NOTE: Place the