diff --git a/media/templates/site/moko-cassiopeia/css/global/colors/dark/colors_alternative.css b/media/templates/site/moko-cassiopeia/css/global/colors/dark/colors_alternative.css
new file mode 100644
index 0000000..c7d0121
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/css/global/colors/dark/colors_alternative.css
@@ -0,0 +1,351 @@
+/*!
+ * @package Joomla.Site
+ * @subpackage Templates.moko-cassiopeia
+ * @file /media/templates/sote/moko-cassiopeia/css/global/dark/colors_alternative.css
+ *
+ * @copyright 2025 Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ *
+ * Website: https://mokoconsulting.tech
+ * Email: hello@mokoconsulting.tech
+ * Phone: +1 (931) 279-6313
+ */
+
+/* -----------------------------------------------
+ * 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/colors/dark/colors_standard.css b/media/templates/site/moko-cassiopeia/css/global/colors/dark/colors_standard.css
new file mode 100644
index 0000000..8a2ebd9
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/css/global/colors/dark/colors_standard.css
@@ -0,0 +1,351 @@
+/*!
+ * @package Joomla.Site
+ * @subpackage Templates.moko-cassiopeia
+ * @file /media/templates/sote/moko-cassiopeia/css/global/dark/colors_standard.css
+ *
+ * @copyright 2025 Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ *
+ * Website: https://mokoconsulting.tech
+ * Email: hello@mokoconsulting.tech
+ * Phone: +1 (931) 279-6313
+ */
+
+/* -----------------------------------------------
+ * 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/colors/dark/index.html b/media/templates/site/moko-cassiopeia/css/global/colors/dark/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/css/global/colors/dark/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/colors/index.html b/media/templates/site/moko-cassiopeia/css/global/colors/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/css/global/colors/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/colors/light/colors_alternative.css b/media/templates/site/moko-cassiopeia/css/global/colors/light/colors_alternative.css
new file mode 100644
index 0000000..79f199a
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/css/global/colors/light/colors_alternative.css
@@ -0,0 +1,551 @@
+/*!
+ * @package Joomla.Site
+ * @subpackage Templates.moko-cassiopeia
+ * @file /media/templates/sote/moko-cassiopeia/css/global/light/colors_alternative.css
+ *
+ * @copyright 2025 Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ *
+ * Website: https://mokoconsulting.tech
+ * Email: hello@mokoconsulting.tech
+ * Phone: +1 (931) 279-6313
+ */
+
+/* -----------------------------------------------
+ * LIGHT THEME
+ * --------------------------------------------- */
+
+:root[data-bs-theme="light"] {
+ color-scheme: light;
+ --color-primary: #112855;
+ --accent-color-primary: #3f8ff0;
+ --accent-color-secondary: #3f8ff0;
+
+ --mainmenu-nav-link-color: white;
+
+ --color-link: #224FAA;
+ --color-hover: var(--accent-color-primary);
+
+ --header-background-image: url('../../../../../../media/templates/site/moko-cassiopeia/images/bg.svg');
+ --header-background-attachment: fixed;
+ --header-background-repeat: repeat;
+ --header-background-size: auto;
+
+ --container-below-topbar-bg-image: ;
+ --container-below-topbar-bg-color ;
+ --container-below-topbar-bg-position: auto;
+ --container-below-topbar-bg-attachment: fixed;
+ --container-below-topbar-bg-repeat: repeat;
+ --container-below-topbar-bg-size: auto;
+ --container-below-topbar-border: ;
+ --container-below-topbar-border-radius: ;
+
+ --container-top-a-bg-image: ;
+ --container-top-a-bg-color: ;
+ --container-top-a-bg-position: auto;
+ --container-top-a-bg-attachment: fixed;
+ --container-top-a-bg-repeat: repeat;
+ --container-top-a-bg-size: auto;
+ --container-top-a-border: ;
+ --container-top-a-border-radius: ;
+
+ --container-top-b-bg-image: ;
+ --container-top-b-bg-color: ;
+ --container-top-b-bg-position: auto;
+ --container-top-b-bg-attachment: fixed;
+ --container-top-b-bg-repeat: repeat;
+ --container-top-b-bg-size: auto;
+ --container-top-b-border: ;
+ --container-top-b-border-radius: ;
+
+ --container-toc-bg: var(--mainmenu-nav-link-color);
+ --container-toc-color: var(--color-primary);
+
+ --container-sidebar-bg-image: ;
+ --container-sidebar-bg-color: ;
+ --container-sidebar-bg-position: auto;
+ --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: auto;
+ --container-bottom-a-bg-attachment: fixed;
+ --container-bottom-a-bg-repeat: repeat;
+ --container-bottom-a-bg-size: auto;
+ --container-bottom-a-border: ;
+ --container-bottom-a-border-radius: ;
+
+ --container-bottom-b-bg-image: ;
+ --container-bottom-b-bg-color: ;
+ --container-bottom-b-bg-position: auto;
+ --container-bottom-b-bg-attachment: fixed;
+ --container-bottom-b-bg-repeat: repeat;
+ --container-bottom-b-bg-size: auto;
+ --container-bottom-b-border: ;
+ --container-bottom-b-border-radius: ;
+
+ --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);
+
+ --blue: #010156;
+ --black: #000;
+ --indigo: #6812f3;
+ --purple: #6f42c2;
+ --pink: #e93f8e;
+ --red: #a51f18;
+ --orange: #fd7e17;
+ --yellow: #ad6200;
+ --green: #448344;
+ --teal: #5abfdd;
+ --cyan: #30638d;
+ --white: #fff;
+ --gray-100: #f9fafb;
+ --gray-200: #eaedf0;
+ --gray-300: #dfe3e7;
+ --gray-400: #ced4da;
+ --gray-500: #adb5bd;
+ --gray-600: #6d757e;
+ --gray-700: #484f56;
+ --gray-800: #353b41;
+ --gray-900: #22262a;
+ --primary: #010156;
+ --secondary: #6d757e;
+ --success: #448344;
+ --info: #30638d;
+ --warning: #ad6200;
+ --danger: #a51f18;
+ --light: #f9fafb;
+ --dark: #353b41;
+ --primary-rgb: 1, 1, 86;
+ --secondary-rgb: 109, 117, 126;
+ --success-rgb: 68, 131, 68;
+ --info-rgb: 48, 99, 141;
+ --warning-rgb: 173, 98, 0;
+ --danger-rgb: 165, 31, 24;
+ --light-rgb: 249, 250, 251;
+ --dark-rgb: 53, 59, 65;
+ --primary-text-emphasis: #002;
+ --secondary-text-emphasis: #2c2f32;
+ --success-text-emphasis: #1b351b;
+ --info-text-emphasis: #132838;
+ --warning-text-emphasis: #452700;
+ --danger-text-emphasis: #420c09;
+ --light-text-emphasis: #484f56;
+ --dark-text-emphasis: #484f56;
+ --primary-bg-subtle: #ccd;
+ --secondary-bg-subtle: #e2e3e5;
+ --success-bg-subtle: #dae6da;
+ --info-bg-subtle: #d6e0e8;
+ --warning-bg-subtle: #efe0cc;
+ --danger-bg-subtle: #edd2d1;
+ --light-bg-subtle: #fcfcfd;
+ --dark-bg-subtle: #ced4da;
+ --primary-border-subtle: #99b;
+ --secondary-border-subtle: #c5c8cb;
+ --success-border-subtle: #b4ceb4;
+ --info-border-subtle: #acc1d1;
+ --warning-border-subtle: #dec099;
+ --danger-border-subtle: #dba5a2;
+ --light-border-subtle: #eaedf0;
+ --dark-border-subtle: #adb5bd;
+ --white-rgb: 255, 255, 255;
+ --black-rgb: 0, 0, 0;
+ --font-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ --font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+ --gradient: linear-gradient(180deg, #ffffff26, #fff0);
+ --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: #22262a;
+ --body-color-rgb: 34, 38, 42;
+ --body-bg: #fff;
+ --body-bg-rgb: 255, 255, 255;
+ --emphasis-color: #000;
+ --emphasis-color-rgb: 0, 0, 0;
+ --secondary-color: #22262abf;
+ --secondary-color-rgb: 34, 38, 42;
+ --secondary-bg: #eaedf0;
+ --secondary-bg-rgb: 234, 237, 240;
+ --tertiary-color: #22262a80;
+ --tertiary-color-rgb: 34, 38, 42;
+ --tertiary-bg: #f9fafb;
+ --tertiary-bg-rgb: 249, 250, 251;
+ --heading-color: inherit;
+ --link-color: #224faa;
+ --link-color-rgb: 34, 79, 170;
+ --link-decoration: underline;
+ --link-hover-color: #424077;
+ --link-hover-color-rgb: 66, 64, 119;
+ --code-color: #e93f8e;
+ --highlight-color: #22262a;
+ --highlight-bg: #fbeea8;
+ --border-width: 1px;
+ --border-style: solid;
+ --border-color: #dfe3e7;
+ --border-color-translucent: #0000002d;
+ --border-radius: .25rem;
+ --border-radius-sm: .2rem;
+ --border-radius-lg: .3rem;
+ --border-radius-xl: .3rem;
+ --border-radius-xxl: 2rem;
+ --border-radius-2xl: var(--border-radius-xxl)*2;
+ --border-radius-pill: 50rem;
+ --box-shadow: 0 .5rem 1rem #00000026;
+ --box-shadow-sm: 0 .125rem .25rem #00000013;
+ --box-shadow-lg: 0 1rem 3rem #0000002d;
+ --box-shadow-inset: inset 0 1px 2px #00000013;
+ --focus-ring-width: .25rem;
+ --focus-ring-opacity: .25;
+ --focus-ring-color: #01015640;
+ --form-valid-color: #448344;
+ --form-valid-border-color: #448344;
+ --form-invalid-color: #a51f18;
+ --form-invalid-border-color: #a51f18;
+}
+
+.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: hsl(210, 11%, 15%);
+ --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;
+}
+
+.btn-primary {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(240, 98%, 17%);
+ --btn-border-color: hsl(240, 98%, 17%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #010149;
+ --btn-hover-border-color: #010145;
+ --btn-focus-shadow-rgb: 39, 39, 111;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #010145;
+ --btn-active-border-color: #010141;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(240, 98%, 17%);
+ --btn-disabled-border-color: hsl(240, 98%, 17%);
+}
+
+.btn-secondary {
+ --btn-color: --nav-text-color;
+ --btn-bg: --nav-bg-color;
+ --btn-border-color: hsl(210, 7%, 46%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #5d636b;
+ --btn-hover-border-color: #575e65;
+ --btn-focus-shadow-rgb: gray;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #575e65;
+ --btn-active-border-color: #52585f;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(210, 7%, 46%);
+ --btn-disabled-border-color: hsl(210, 7%, 46%);
+}
+
+.btn-success {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(120, 32%, 39%);
+ --btn-border-color: hsl(120, 32%, 39%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #3a6f3a;
+ --btn-hover-border-color: #366936;
+ --btn-focus-shadow-rgb: 96, 150, 96;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #366936;
+ --btn-active-border-color: #336233;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(120, 32%, 39%);
+ --btn-disabled-border-color: hsl(120, 32%, 39%);
+}
+
+.btn-info {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(207, 49%, 37%);
+ --btn-border-color: hsl(207, 49%, 37%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #295478;
+ --btn-hover-border-color: #264f71;
+ --btn-focus-shadow-rgb: 79, 122, 158;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #264f71;
+ --btn-active-border-color: #244a6a;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(207, 49%, 37%);
+ --btn-disabled-border-color: hsl(207, 49%, 37%);
+}
+
+.btn-warning {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(34, 100%, 34%);
+ --btn-border-color: hsl(34, 100%, 34%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #935300;
+ --btn-hover-border-color: #8a4e00;
+ --btn-focus-shadow-rgb: 185, 122, 38;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #8a4e00;
+ --btn-active-border-color: #824a00;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(34, 100%, 34%);
+ --btn-disabled-border-color: hsl(34, 100%, 34%);
+}
+
+.btn-danger {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(3, 75%, 37%);
+ --btn-border-color: hsl(3, 75%, 37%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #8c1a14;
+ --btn-hover-border-color: #841913;
+ --btn-focus-shadow-rgb: 179, 65, 59;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #841913;
+ --btn-active-border-color: #7c1712;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(3, 75%, 37%);
+ --btn-disabled-border-color: hsl(3, 75%, 37%);
+}
+
+.btn-light {
+ --btn-color: hsl(0, 0%, 0%);
+ --btn-bg: hsl(210, 17%, 98%);
+ --btn-border-color: hsl(210, 17%, 98%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: #d4d5d5;
+ --btn-hover-border-color: #c7c8c9;
+ --btn-focus-shadow-rgb: 212, 213, 213;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: #c7c8c9;
+ --btn-active-border-color: #bbbcbc;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 0%);
+ --btn-disabled-bg: hsl(210, 17%, 98%);
+ --btn-disabled-border-color: hsl(210, 17%, 98%);
+}
+
+.btn-dark {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(210, 10%, 23%);
+ --btn-border-color: hsl(210, 10%, 23%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #53585e;
+ --btn-hover-border-color: #494f54;
+ --btn-focus-shadow-rgb: 83, 88, 94;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #5d6267;
+ --btn-active-border-color: #494f54;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(210, 10%, 23%);
+ --btn-disabled-border-color: hsl(210, 10%, 23%);
+}
+
+.btn-outline-primary {
+ --btn-color: hsl(240, 98%, 17%);
+ --btn-border-color: hsl(240, 98%, 17%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(240, 98%, 17%);
+ --btn-hover-border-color: hsl(240, 98%, 17%);
+ --btn-focus-shadow-rgb: 1, 1, 86;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(240, 98%, 17%);
+ --btn-active-border-color: hsl(240, 98%, 17%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(240, 98%, 17%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(240, 98%, 17%);
+ --gradient: none;
+}
+
+.btn-outline-secondary {
+ --btn-color: hsl(210, 7%, 46%);
+ --btn-border-color: hsl(210, 7%, 46%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(210, 7%, 46%);
+ --btn-hover-border-color: hsl(210, 7%, 46%);
+ --btn-focus-shadow-rgb: 109, 117, 126;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(210, 7%, 46%);
+ --btn-active-border-color: hsl(210, 7%, 46%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 7%, 46%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 7%, 46%);
+ --gradient: none;
+}
+
+.btn-outline-success {
+ --btn-color: hsl(120, 32%, 39%);
+ --btn-border-color: hsl(120, 32%, 39%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(120, 32%, 39%);
+ --btn-hover-border-color: hsl(120, 32%, 39%);
+ --btn-focus-shadow-rgb: 68, 131, 68;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(120, 32%, 39%);
+ --btn-active-border-color: hsl(120, 32%, 39%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(120, 32%, 39%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(120, 32%, 39%);
+ --gradient: none;
+}
+
+.btn-outline-info {
+ --btn-color: hsl(207, 49%, 37%);
+ --btn-border-color: hsl(207, 49%, 37%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(207, 49%, 37%);
+ --btn-hover-border-color: hsl(207, 49%, 37%);
+ --btn-focus-shadow-rgb: 48, 99, 141;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(207, 49%, 37%);
+ --btn-active-border-color: hsl(207, 49%, 37%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(207, 49%, 37%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(207, 49%, 37%);
+ --gradient: none;
+}
+
+.btn-outline-warning {
+ --btn-color: hsl(34, 100%, 34%);
+ --btn-border-color: hsl(34, 100%, 34%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(34, 100%, 34%);
+ --btn-hover-border-color: hsl(34, 100%, 34%);
+ --btn-focus-shadow-rgb: 173, 98, 0;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(34, 100%, 34%);
+ --btn-active-border-color: hsl(34, 100%, 34%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(34, 100%, 34%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(34, 100%, 34%);
+ --gradient: none;
+}
+
+.btn-outline-danger {
+ --btn-color: hsl(3, 75%, 37%);
+ --btn-border-color: hsl(3, 75%, 37%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(3, 75%, 37%);
+ --btn-hover-border-color: hsl(3, 75%, 37%);
+ --btn-focus-shadow-rgb: 165, 31, 24;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(3, 75%, 37%);
+ --btn-active-border-color: hsl(3, 75%, 37%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(3, 75%, 37%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(3, 75%, 37%);
+ --gradient: none;
+}
+
+.btn-outline-light {
+ --btn-color: hsl(210, 17%, 98%);
+ --btn-border-color: hsl(210, 17%, 98%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(210, 17%, 98%);
+ --btn-hover-border-color: hsl(210, 17%, 98%);
+ --btn-focus-shadow-rgb: 249, 250, 251;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(210, 17%, 98%);
+ --btn-active-border-color: hsl(210, 17%, 98%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 17%, 98%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 17%, 98%);
+ --gradient: none;
+}
+
+.btn-outline-dark {
+ --btn-color: hsl(210, 10%, 23%);
+ --btn-border-color: hsl(210, 10%, 23%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(210, 10%, 23%);
+ --btn-hover-border-color: hsl(210, 10%, 23%);
+ --btn-focus-shadow-rgb: 53, 59, 65;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(210, 10%, 23%);
+ --btn-active-border-color: hsl(210, 10%, 23%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 10%, 23%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 10%, 23%);
+ --gradient: none;
+}
+
+.btn-link {
+ --btn-font-weight: 400;
+ --btn-color: var(--link-color);
+ --btn-bg: transparent;
+ --btn-border-color: transparent;
+ --btn-hover-color: var(--link-hover-color);
+ --btn-hover-border-color: transparent;
+ --btn-active-color: var(--link-hover-color);
+ --btn-active-border-color: transparent;
+ --btn-disabled-color: hsl(210, 7%, 46%);
+ --btn-disabled-border-color: transparent;
+ --btn-box-shadow: none;
+ --btn-focus-shadow-rgb: 39, 39, 111;
+ text-decoration: underline;
+}
diff --git a/media/templates/site/moko-cassiopeia/css/global/colors/light/colors_standard.css b/media/templates/site/moko-cassiopeia/css/global/colors/light/colors_standard.css
new file mode 100644
index 0000000..f6a3065
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/css/global/colors/light/colors_standard.css
@@ -0,0 +1,551 @@
+/*!
+ * @package Joomla.Site
+ * @subpackage Templates.moko-cassiopeia
+ * @file /media/templates/sote/moko-cassiopeia/css/global/light/colors_standard.css
+ *
+ * @copyright 2025 Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ *
+ * Website: https://mokoconsulting.tech
+ * Email: hello@mokoconsulting.tech
+ * Phone: +1 (931) 279-6313
+ */
+
+/* -----------------------------------------------
+ * LIGHT THEME
+ * --------------------------------------------- */
+
+:root[data-bs-theme="light"] {
+ color-scheme: light;
+ --color-primary: #112855;
+ --accent-color-primary: #3f8ff0;
+ --accent-color-secondary: #3f8ff0;
+
+ --mainmenu-nav-link-color: white;
+
+ --color-link: #224FAA;
+ --color-hover: var(--accent-color-primary);
+
+ --header-background-image: url('../../../../../../media/templates/site/moko-cassiopeia/images/bg.svg');
+ --header-background-attachment: fixed;
+ --header-background-repeat: repeat;
+ --header-background-size: auto;
+
+ --container-below-topbar-bg-image: ;
+ --container-below-topbar-bg-color ;
+ --container-below-topbar-bg-position: auto;
+ --container-below-topbar-bg-attachment: fixed;
+ --container-below-topbar-bg-repeat: repeat;
+ --container-below-topbar-bg-size: auto;
+ --container-below-topbar-border: ;
+ --container-below-topbar-border-radius: ;
+
+ --container-top-a-bg-image: ;
+ --container-top-a-bg-color: ;
+ --container-top-a-bg-position: auto;
+ --container-top-a-bg-attachment: fixed;
+ --container-top-a-bg-repeat: repeat;
+ --container-top-a-bg-size: auto;
+ --container-top-a-border: ;
+ --container-top-a-border-radius: ;
+
+ --container-top-b-bg-image: ;
+ --container-top-b-bg-color: ;
+ --container-top-b-bg-position: auto;
+ --container-top-b-bg-attachment: fixed;
+ --container-top-b-bg-repeat: repeat;
+ --container-top-b-bg-size: auto;
+ --container-top-b-border: ;
+ --container-top-b-border-radius: ;
+
+ --container-toc-bg: var(--mainmenu-nav-link-color);
+ --container-toc-color: var(--color-primary);
+
+ --container-sidebar-bg-image: ;
+ --container-sidebar-bg-color: ;
+ --container-sidebar-bg-position: auto;
+ --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: auto;
+ --container-bottom-a-bg-attachment: fixed;
+ --container-bottom-a-bg-repeat: repeat;
+ --container-bottom-a-bg-size: auto;
+ --container-bottom-a-border: ;
+ --container-bottom-a-border-radius: ;
+
+ --container-bottom-b-bg-image: ;
+ --container-bottom-b-bg-color: ;
+ --container-bottom-b-bg-position: auto;
+ --container-bottom-b-bg-attachment: fixed;
+ --container-bottom-b-bg-repeat: repeat;
+ --container-bottom-b-bg-size: auto;
+ --container-bottom-b-border: ;
+ --container-bottom-b-border-radius: ;
+
+ --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);
+
+ --blue: #010156;
+ --black: #000;
+ --indigo: #6812f3;
+ --purple: #6f42c2;
+ --pink: #e93f8e;
+ --red: #a51f18;
+ --orange: #fd7e17;
+ --yellow: #ad6200;
+ --green: #448344;
+ --teal: #5abfdd;
+ --cyan: #30638d;
+ --white: #fff;
+ --gray-100: #f9fafb;
+ --gray-200: #eaedf0;
+ --gray-300: #dfe3e7;
+ --gray-400: #ced4da;
+ --gray-500: #adb5bd;
+ --gray-600: #6d757e;
+ --gray-700: #484f56;
+ --gray-800: #353b41;
+ --gray-900: #22262a;
+ --primary: #010156;
+ --secondary: #6d757e;
+ --success: #448344;
+ --info: #30638d;
+ --warning: #ad6200;
+ --danger: #a51f18;
+ --light: #f9fafb;
+ --dark: #353b41;
+ --primary-rgb: 1, 1, 86;
+ --secondary-rgb: 109, 117, 126;
+ --success-rgb: 68, 131, 68;
+ --info-rgb: 48, 99, 141;
+ --warning-rgb: 173, 98, 0;
+ --danger-rgb: 165, 31, 24;
+ --light-rgb: 249, 250, 251;
+ --dark-rgb: 53, 59, 65;
+ --primary-text-emphasis: #002;
+ --secondary-text-emphasis: #2c2f32;
+ --success-text-emphasis: #1b351b;
+ --info-text-emphasis: #132838;
+ --warning-text-emphasis: #452700;
+ --danger-text-emphasis: #420c09;
+ --light-text-emphasis: #484f56;
+ --dark-text-emphasis: #484f56;
+ --primary-bg-subtle: #ccd;
+ --secondary-bg-subtle: #e2e3e5;
+ --success-bg-subtle: #dae6da;
+ --info-bg-subtle: #d6e0e8;
+ --warning-bg-subtle: #efe0cc;
+ --danger-bg-subtle: #edd2d1;
+ --light-bg-subtle: #fcfcfd;
+ --dark-bg-subtle: #ced4da;
+ --primary-border-subtle: #99b;
+ --secondary-border-subtle: #c5c8cb;
+ --success-border-subtle: #b4ceb4;
+ --info-border-subtle: #acc1d1;
+ --warning-border-subtle: #dec099;
+ --danger-border-subtle: #dba5a2;
+ --light-border-subtle: #eaedf0;
+ --dark-border-subtle: #adb5bd;
+ --white-rgb: 255, 255, 255;
+ --black-rgb: 0, 0, 0;
+ --font-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ --font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+ --gradient: linear-gradient(180deg, #ffffff26, #fff0);
+ --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: #22262a;
+ --body-color-rgb: 34, 38, 42;
+ --body-bg: #fff;
+ --body-bg-rgb: 255, 255, 255;
+ --emphasis-color: #000;
+ --emphasis-color-rgb: 0, 0, 0;
+ --secondary-color: #22262abf;
+ --secondary-color-rgb: 34, 38, 42;
+ --secondary-bg: #eaedf0;
+ --secondary-bg-rgb: 234, 237, 240;
+ --tertiary-color: #22262a80;
+ --tertiary-color-rgb: 34, 38, 42;
+ --tertiary-bg: #f9fafb;
+ --tertiary-bg-rgb: 249, 250, 251;
+ --heading-color: inherit;
+ --link-color: #224faa;
+ --link-color-rgb: 34, 79, 170;
+ --link-decoration: underline;
+ --link-hover-color: #424077;
+ --link-hover-color-rgb: 66, 64, 119;
+ --code-color: #e93f8e;
+ --highlight-color: #22262a;
+ --highlight-bg: #fbeea8;
+ --border-width: 1px;
+ --border-style: solid;
+ --border-color: #dfe3e7;
+ --border-color-translucent: #0000002d;
+ --border-radius: .25rem;
+ --border-radius-sm: .2rem;
+ --border-radius-lg: .3rem;
+ --border-radius-xl: .3rem;
+ --border-radius-xxl: 2rem;
+ --border-radius-2xl: var(--border-radius-xxl)*2;
+ --border-radius-pill: 50rem;
+ --box-shadow: 0 .5rem 1rem #00000026;
+ --box-shadow-sm: 0 .125rem .25rem #00000013;
+ --box-shadow-lg: 0 1rem 3rem #0000002d;
+ --box-shadow-inset: inset 0 1px 2px #00000013;
+ --focus-ring-width: .25rem;
+ --focus-ring-opacity: .25;
+ --focus-ring-color: #01015640;
+ --form-valid-color: #448344;
+ --form-valid-border-color: #448344;
+ --form-invalid-color: #a51f18;
+ --form-invalid-border-color: #a51f18;
+}
+
+.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: hsl(210, 11%, 15%);
+ --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;
+}
+
+.btn-primary {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(240, 98%, 17%);
+ --btn-border-color: hsl(240, 98%, 17%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #010149;
+ --btn-hover-border-color: #010145;
+ --btn-focus-shadow-rgb: 39, 39, 111;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #010145;
+ --btn-active-border-color: #010141;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(240, 98%, 17%);
+ --btn-disabled-border-color: hsl(240, 98%, 17%);
+}
+
+.btn-secondary {
+ --btn-color: --nav-text-color;
+ --btn-bg: --nav-bg-color;
+ --btn-border-color: hsl(210, 7%, 46%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #5d636b;
+ --btn-hover-border-color: #575e65;
+ --btn-focus-shadow-rgb: gray;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #575e65;
+ --btn-active-border-color: #52585f;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(210, 7%, 46%);
+ --btn-disabled-border-color: hsl(210, 7%, 46%);
+}
+
+.btn-success {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(120, 32%, 39%);
+ --btn-border-color: hsl(120, 32%, 39%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #3a6f3a;
+ --btn-hover-border-color: #366936;
+ --btn-focus-shadow-rgb: 96, 150, 96;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #366936;
+ --btn-active-border-color: #336233;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(120, 32%, 39%);
+ --btn-disabled-border-color: hsl(120, 32%, 39%);
+}
+
+.btn-info {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(207, 49%, 37%);
+ --btn-border-color: hsl(207, 49%, 37%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #295478;
+ --btn-hover-border-color: #264f71;
+ --btn-focus-shadow-rgb: 79, 122, 158;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #264f71;
+ --btn-active-border-color: #244a6a;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(207, 49%, 37%);
+ --btn-disabled-border-color: hsl(207, 49%, 37%);
+}
+
+.btn-warning {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(34, 100%, 34%);
+ --btn-border-color: hsl(34, 100%, 34%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #935300;
+ --btn-hover-border-color: #8a4e00;
+ --btn-focus-shadow-rgb: 185, 122, 38;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #8a4e00;
+ --btn-active-border-color: #824a00;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(34, 100%, 34%);
+ --btn-disabled-border-color: hsl(34, 100%, 34%);
+}
+
+.btn-danger {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(3, 75%, 37%);
+ --btn-border-color: hsl(3, 75%, 37%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #8c1a14;
+ --btn-hover-border-color: #841913;
+ --btn-focus-shadow-rgb: 179, 65, 59;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #841913;
+ --btn-active-border-color: #7c1712;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(3, 75%, 37%);
+ --btn-disabled-border-color: hsl(3, 75%, 37%);
+}
+
+.btn-light {
+ --btn-color: hsl(0, 0%, 0%);
+ --btn-bg: hsl(210, 17%, 98%);
+ --btn-border-color: hsl(210, 17%, 98%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: #d4d5d5;
+ --btn-hover-border-color: #c7c8c9;
+ --btn-focus-shadow-rgb: 212, 213, 213;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: #c7c8c9;
+ --btn-active-border-color: #bbbcbc;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 0%);
+ --btn-disabled-bg: hsl(210, 17%, 98%);
+ --btn-disabled-border-color: hsl(210, 17%, 98%);
+}
+
+.btn-dark {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(210, 10%, 23%);
+ --btn-border-color: hsl(210, 10%, 23%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #53585e;
+ --btn-hover-border-color: #494f54;
+ --btn-focus-shadow-rgb: 83, 88, 94;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #5d6267;
+ --btn-active-border-color: #494f54;
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(210, 10%, 23%);
+ --btn-disabled-border-color: hsl(210, 10%, 23%);
+}
+
+.btn-outline-primary {
+ --btn-color: hsl(240, 98%, 17%);
+ --btn-border-color: hsl(240, 98%, 17%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(240, 98%, 17%);
+ --btn-hover-border-color: hsl(240, 98%, 17%);
+ --btn-focus-shadow-rgb: 1, 1, 86;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(240, 98%, 17%);
+ --btn-active-border-color: hsl(240, 98%, 17%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(240, 98%, 17%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(240, 98%, 17%);
+ --gradient: none;
+}
+
+.btn-outline-secondary {
+ --btn-color: hsl(210, 7%, 46%);
+ --btn-border-color: hsl(210, 7%, 46%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(210, 7%, 46%);
+ --btn-hover-border-color: hsl(210, 7%, 46%);
+ --btn-focus-shadow-rgb: 109, 117, 126;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(210, 7%, 46%);
+ --btn-active-border-color: hsl(210, 7%, 46%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 7%, 46%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 7%, 46%);
+ --gradient: none;
+}
+
+.btn-outline-success {
+ --btn-color: hsl(120, 32%, 39%);
+ --btn-border-color: hsl(120, 32%, 39%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(120, 32%, 39%);
+ --btn-hover-border-color: hsl(120, 32%, 39%);
+ --btn-focus-shadow-rgb: 68, 131, 68;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(120, 32%, 39%);
+ --btn-active-border-color: hsl(120, 32%, 39%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(120, 32%, 39%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(120, 32%, 39%);
+ --gradient: none;
+}
+
+.btn-outline-info {
+ --btn-color: hsl(207, 49%, 37%);
+ --btn-border-color: hsl(207, 49%, 37%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(207, 49%, 37%);
+ --btn-hover-border-color: hsl(207, 49%, 37%);
+ --btn-focus-shadow-rgb: 48, 99, 141;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(207, 49%, 37%);
+ --btn-active-border-color: hsl(207, 49%, 37%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(207, 49%, 37%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(207, 49%, 37%);
+ --gradient: none;
+}
+
+.btn-outline-warning {
+ --btn-color: hsl(34, 100%, 34%);
+ --btn-border-color: hsl(34, 100%, 34%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(34, 100%, 34%);
+ --btn-hover-border-color: hsl(34, 100%, 34%);
+ --btn-focus-shadow-rgb: 173, 98, 0;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(34, 100%, 34%);
+ --btn-active-border-color: hsl(34, 100%, 34%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(34, 100%, 34%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(34, 100%, 34%);
+ --gradient: none;
+}
+
+.btn-outline-danger {
+ --btn-color: hsl(3, 75%, 37%);
+ --btn-border-color: hsl(3, 75%, 37%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(3, 75%, 37%);
+ --btn-hover-border-color: hsl(3, 75%, 37%);
+ --btn-focus-shadow-rgb: 165, 31, 24;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(3, 75%, 37%);
+ --btn-active-border-color: hsl(3, 75%, 37%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(3, 75%, 37%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(3, 75%, 37%);
+ --gradient: none;
+}
+
+.btn-outline-light {
+ --btn-color: hsl(210, 17%, 98%);
+ --btn-border-color: hsl(210, 17%, 98%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(210, 17%, 98%);
+ --btn-hover-border-color: hsl(210, 17%, 98%);
+ --btn-focus-shadow-rgb: 249, 250, 251;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(210, 17%, 98%);
+ --btn-active-border-color: hsl(210, 17%, 98%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 17%, 98%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 17%, 98%);
+ --gradient: none;
+}
+
+.btn-outline-dark {
+ --btn-color: hsl(210, 10%, 23%);
+ --btn-border-color: hsl(210, 10%, 23%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(210, 10%, 23%);
+ --btn-hover-border-color: hsl(210, 10%, 23%);
+ --btn-focus-shadow-rgb: 53, 59, 65;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(210, 10%, 23%);
+ --btn-active-border-color: hsl(210, 10%, 23%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 10%, 23%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 10%, 23%);
+ --gradient: none;
+}
+
+.btn-link {
+ --btn-font-weight: 400;
+ --btn-color: var(--link-color);
+ --btn-bg: transparent;
+ --btn-border-color: transparent;
+ --btn-hover-color: var(--link-hover-color);
+ --btn-hover-border-color: transparent;
+ --btn-active-color: var(--link-hover-color);
+ --btn-active-border-color: transparent;
+ --btn-disabled-color: hsl(210, 7%, 46%);
+ --btn-disabled-border-color: transparent;
+ --btn-box-shadow: none;
+ --btn-focus-shadow-rgb: 39, 39, 111;
+ text-decoration: underline;
+}
diff --git a/media/templates/site/moko-cassiopeia/css/global/colors/light/index.html b/media/templates/site/moko-cassiopeia/css/global/colors/light/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/media/templates/site/moko-cassiopeia/css/global/colors/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/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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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/moko-cassiopeia-main.zip b/moko-cassiopeia-main.zip
new file mode 100644
index 0000000..b266558
Binary files /dev/null and b/moko-cassiopeia-main.zip differ
diff --git a/templates/moko-cassiopeia/component.php b/templates/moko-cassiopeia/component.php
new file mode 100644
index 0000000..841d12e
--- /dev/null
+++ b/templates/moko-cassiopeia/component.php
@@ -0,0 +1,88 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+
+/** @var Joomla\CMS\Document\HtmlDocument $this */
+
+$app = Factory::getApplication();
+$wa = $this->getWebAssetManager();
+
+// Color Theme
+$paramsColorName = $this->params->get('colorName', 'colors_standard');
+$assetColorName = 'theme.' . $paramsColorName;
+$wa->registerAndUseStyle($assetColorName, 'media/templates/site/moko-cassiopeia/css/global/' . $paramsColorName . '.css');
+
+// Use a font scheme if set in the template style options
+$paramsFontScheme = $this->params->get('useFontScheme', false);
+$fontStyles = '';
+
+if ($paramsFontScheme) {
+ if (stripos($paramsFontScheme, 'https://') === 0) {
+ $this->getPreloadManager()->preconnect('https://fonts.googleapis.com/', ['crossorigin' => 'anonymous']);
+ $this->getPreloadManager()->preconnect('https://fonts.gstatic.com/', ['crossorigin' => 'anonymous']);
+ $this->getPreloadManager()->preload($paramsFontScheme, ['as' => 'style', 'crossorigin' => 'anonymous']);
+ $wa->registerAndUseStyle('fontscheme.current', $paramsFontScheme, [], ['media' => 'print', 'rel' => 'lazy-stylesheet', 'onload' => 'this.media=\'all\'', 'crossorigin' => 'anonymous']);
+
+ if (preg_match_all('/family=([^?:]*):/i', $paramsFontScheme, $matches) > 0) {
+ $fontStyles = '--font-family-body: "' . str_replace('+', ' ', $matches[1][0]) . '", sans-serif;
+ --font-family-headings: "' . str_replace('+', ' ', isset($matches[1][1]) ? $matches[1][1] : $matches[1][0]) . '", sans-serif;
+ --font-weight-normal: 400;
+ --font-weight-headings: 700;';
+ }
+ } else {
+ $wa->registerAndUseStyle('fontscheme.current', $paramsFontScheme, ['version' => 'auto'], ['media' => 'print', 'rel' => 'lazy-stylesheet', 'onload' => 'this.media=\'all\'']);
+ $this->getPreloadManager()->preload($wa->getAsset('style', 'fontscheme.current')->getUri() . '?' . $this->getMediaVersion(), ['as' => 'style']);
+ }
+}
+
+// Enable assets
+$wa->usePreset('template.moko-cassiopeia.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr'))
+ ->useStyle('template.active.language')
+ ->useStyle('template.user')
+ ->useScript('template.user')
+ ->addInlineStyle(":root {
+ --hue: 214;
+ --template-bg-light: #f0f4fb;
+ --template-text-dark: #495057;
+ --template-text-light: #ffffff;
+ --template-link-color: #2a69b8;
+ --template-special-color: #001B4C;
+ $fontStyles
+ }");
+
+
+// Override 'template.active' asset to set correct ltr/rtl dependency
+$wa->registerStyle('template.active', '', [], [], ['template.moko-cassiopeia.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr')]);
+
+// Browsers support SVG favicons
+$this->addHeadLink(HTMLHelper::_('image', 'joomla-favicon.svg', '', [], true, 1), 'icon', 'rel', ['type' => 'image/svg+xml']);
+$this->addHeadLink(HTMLHelper::_('image', 'favicon.ico', '', [], true, 1), 'alternate icon', 'rel', ['type' => 'image/vnd.microsoft.icon']);
+$this->addHeadLink(HTMLHelper::_('image', 'joomla-favicon-pinned.svg', '', [], true, 1), 'mask-icon', 'rel', ['color' => '#000']);
+
+// Defer font awesome
+$wa->getAsset('style', 'fontawesome')->setAttribute('rel', 'lazy-stylesheet');
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/custom.php b/templates/moko-cassiopeia/custom.php
new file mode 100644
index 0000000..b7b611a
--- /dev/null
+++ b/templates/moko-cassiopeia/custom.php
@@ -0,0 +1,30 @@
+' . $js_code . '';
+ }
+ echo $js_code;
+ }
+?>
+Custom code included here
diff --git a/templates/moko-cassiopeia/darkmode-toggle.js b/templates/moko-cassiopeia/darkmode-toggle.js
new file mode 100644
index 0000000..e69de29
diff --git a/templates/moko-cassiopeia/error.php b/templates/moko-cassiopeia/error.php
new file mode 100644
index 0000000..1caa0e2
--- /dev/null
+++ b/templates/moko-cassiopeia/error.php
@@ -0,0 +1,269 @@
+params;
+$wa = $this->getWebAssetManager();
+
+// ------------------ Params ------------------
+$colorLight = (string) $params->get('colorLightName', 'colors_standard');
+$colorDark = (string) $params->get('colorDarkName', 'colors_standard');
+$themeFab = (int) $params->get('theme_fab_enabled', 1);
+$fABodyPos = (string) $params->get('theme_fab_pos', 'br');
+$gtmEnabled = (int) $params->get('googletagmanager', 0);
+$gtmId = (string) $params->get('googletagmanagerid', '');
+$fa6KitCode = (string) $params->get('fA6KitCode', '');
+$stickyHeader = (bool) $params->get('stickyHeader', 0);
+$brandEnabled = (int) $params->get('brand', 1);
+$siteDescription = (string) $params->get('siteDescription', '');
+
+// Drawer icon params (escaped)
+$params_leftIcon = htmlspecialchars($params->get('drawerLeftIcon', 'fa-solid fa-chevron-right'), ENT_QUOTES, 'UTF-8');
+$params_rightIcon = htmlspecialchars($params->get('drawerRightIcon', 'fa-solid fa-chevron-left'), ENT_QUOTES, 'UTF-8');
+
+// ------------------ Styles ------------------
+$wa->useStyle('template.base');
+$wa->useStyle('template.user');
+$wa->useStyle('vendor.vmbasic');
+$wa->useStyle('vendor.gable');
+
+// Light/Dark variable sheets (load before consumers)
+if ($wa->assetExists('style', 'template.light.' . $colorLight)) {
+ $wa->useStyle('template.light.' . $colorLight);
+}
+if ($wa->assetExists('style', 'template.dark.' . $colorDark)) {
+ $wa->useStyle('template.dark.' . $colorDark);
+}
+
+// ------------------ Scripts ------------------
+$wa->useScript('theme-init.js');
+if ($themeFab === 1) {
+ $wa->useScript('darkmode-toggle.js');
+}
+if ($gtmEnabled === 1) {
+ $wa->useScript('gtm.js');
+}
+
+// Optional Font Awesome 6 Kit (preferred) or FA5 fallback
+if (!empty($fa6KitCode)) {
+ HTMLHelper::_('script', 'https://kit.fontawesome.com/' . rawurlencode($fa6KitCode) . '.js', [
+ 'crossorigin' => 'anonymous'
+ ]);
+} else {
+ HTMLHelper::_('stylesheet', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css', ['version' => 'auto'], [
+ 'crossorigin' => 'anonymous',
+ 'referrerpolicy' => 'no-referrer',
+ ]);
+}
+
+// ------------------ Context (logo, bootstrap needs) ------------------
+$sitename = htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8');
+
+// Build logo/title
+if ($params->get('logoFile')) {
+ $logo = HTMLHelper::_(
+ 'image',
+ Uri::root(false) . htmlspecialchars($params->get('logoFile'), ENT_QUOTES),
+ $sitename,
+ ['loading' => 'eager', 'decoding' => 'async'],
+ false,
+ 0
+ );
+} elseif ($params->get('siteTitle')) {
+ $logo = '' . htmlspecialchars($params->get('siteTitle'), ENT_COMPAT, 'UTF-8') . ' ';
+} else {
+ $logo = HTMLHelper::_('image', 'full_logo.png', $sitename, ['class' => 'logo d-inline-block', 'loading' => 'eager', 'decoding' => 'async'], true, 0);
+}
+
+// ------------------ Error details ------------------
+$errorObj = isset($this->error) && is_object($this->error) ? $this->error : null;
+$errorCode = $errorObj ? (int) $errorObj->getCode() : 500;
+$errorMsg = $errorObj ? $errorObj->getMessage() : Text::_('JERROR_AN_ERROR_HAS_OCCURRED');
+$debugOn = defined('JDEBUG') && JDEBUG;
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Debug mode is ON — detailed error information is shown below.
+
+
+
+
+
+ Class
+
+
+ Code
+ getCode(); ?>
+
+ Message
+ getMessage(), ENT_QUOTES, 'UTF-8'); ?>
+
+ File
+ getFile(), ENT_QUOTES, 'UTF-8'); ?> : getLine(); ?>
+
+
+
+
+ getTrace() : []; ?>
+
+
+
+
+
+ $frame) :
+ $file = $frame['file'] ?? '[internal]';
+ $line = isset($frame['line']) ? (int) $frame['line'] : 0;
+ $func = $frame['function'] ?? '';
+ $class= $frame['class'] ?? '';
+ $type = $frame['type'] ?? '';
+ ?>
+
+ # ()
+
+
+
+
+
+
No stack trace available.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/favicon.ico b/templates/moko-cassiopeia/favicon.ico
new file mode 100644
index 0000000..710b9c8
Binary files /dev/null and b/templates/moko-cassiopeia/favicon.ico differ
diff --git a/templates/moko-cassiopeia/html/com_contact/contact/default.php b/templates/moko-cassiopeia/html/com_contact/contact/default.php
new file mode 100644
index 0000000..9286424
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_contact/contact/default.php
@@ -0,0 +1,177 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\Helper\ContentHelper;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Layout\FileLayout;
+use Joomla\CMS\Layout\LayoutHelper;
+use Joomla\CMS\Plugin\PluginHelper;
+use Joomla\CMS\Router\Route;
+use Joomla\Component\Contact\Site\Helper\RouteHelper;
+
+$tparams = $this->item->params;
+$canDo = ContentHelper::getActions('com_contact', 'category', $this->item->catid);
+$canEdit = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by === Factory::getUser()->id);
+$htag = $tparams->get('show_page_heading') ? 'h2' : 'h1';
+?>
+
+
diff --git a/templates/moko-cassiopeia/html/com_contact/contact/index.html b/templates/moko-cassiopeia/html/com_contact/contact/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_contact/contact/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_contact/default.php b/templates/moko-cassiopeia/html/com_contact/default.php
new file mode 100644
index 0000000..9286424
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_contact/default.php
@@ -0,0 +1,177 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\Helper\ContentHelper;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Layout\FileLayout;
+use Joomla\CMS\Layout\LayoutHelper;
+use Joomla\CMS\Plugin\PluginHelper;
+use Joomla\CMS\Router\Route;
+use Joomla\Component\Contact\Site\Helper\RouteHelper;
+
+$tparams = $this->item->params;
+$canDo = ContentHelper::getActions('com_contact', 'category', $this->item->catid);
+$canEdit = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by === Factory::getUser()->id);
+$htag = $tparams->get('show_page_heading') ? 'h2' : 'h1';
+?>
+
+
diff --git a/templates/moko-cassiopeia/html/com_contact/index.html b/templates/moko-cassiopeia/html/com_contact/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_contact/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/article/index.html b/templates/moko-cassiopeia/html/com_content/article/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/article/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/article/toc-left.php b/templates/moko-cassiopeia/html/com_content/article/toc-left.php
new file mode 100644
index 0000000..6c2e6c3
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/article/toc-left.php
@@ -0,0 +1,158 @@
+item->params;
+$canEdit = $params->get('access-edit');
+$user = Factory::getUser();
+$info = $params->get('info_block_position', 0);
+$htag = $this->params->get('show_page_heading') ? 'h2' : 'h1';
+
+// Check if associations are implemented. If they are, define the parameter.
+$assocParam = (Associations::isEnabled() && $params->get('show_associations'));
+$currentDate = Factory::getDate()->format('Y-m-d H:i:s');
+$isNotPublishedYet = $this->item->publish_up > $currentDate;
+$isExpired = !is_null($this->item->publish_down) && $this->item->publish_down < $currentDate;
+?>
+
+
+ params->get('show_page_heading')) : ?>
+
+ item->pagination) && !$this->item->paginationposition && $this->item->paginationrelative) {
+ echo $this->item->pagination;
+ }
+ ?>
+
+ get('show_modify_date') || $params->get('show_publish_date') || $params->get('show_create_date')
+ || $params->get('show_hits') || $params->get('show_category') || $params->get('show_parent_category') || $params->get('show_author') || $assocParam; ?>
+
+ get('show_title')) : ?>
+
+
+
+ $params, 'item' => $this->item]); ?>
+
+
+
+ item->event->afterDisplayTitle; ?>
+
+
+ $this->item, 'params' => $params, 'position' => 'above']); ?>
+
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tagLayout = new FileLayout('joomla.content.tags'); ?>
+
+ item->tagLayout->render($this->item->tags->itemTags); ?>
+
+
+
+ item->event->beforeDisplayContent; ?>
+
+ get('urls_position', 0) === 0) : ?>
+ loadTemplate('links'); ?>
+
+ get('access-view')) : ?>
+ item); ?>
+ item->pagination) && !$this->item->paginationposition && !$this->item->paginationrelative) :
+ echo $this->item->pagination;
+ endif;
+ ?>
+
+
+ ' . Text::_('TPL_MOKO-CASSIOPEIA_TOC') . '';
+ ?>
+
+
+ item->text;
+ ?>
+
+
+
+
+
+
+ $this->item, 'params' => $params, 'position' => 'below']); ?>
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tagLayout = new FileLayout('joomla.content.tags'); ?>
+ item->tagLayout->render($this->item->tags->itemTags); ?>
+
+
+
+ item->pagination) && $this->item->paginationposition && !$this->item->paginationrelative) :
+ echo $this->item->pagination;
+ ?>
+
+ get('urls_position', 0) === 1) : ?>
+ loadTemplate('links'); ?>
+
+
+ get('show_noauth') == true && $user->get('guest')) : ?>
+ item); ?>
+ item->introtext); ?>
+
+ get('show_readmore') && $this->item->fulltext != null) : ?>
+ getMenu(); ?>
+ getActive(); ?>
+ id; ?>
+
+ setVar('return', base64_encode(RouteHelper::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language))); ?>
+ $this->item, 'params' => $params, 'link' => $link]); ?>
+
+
+ item->pagination) && $this->item->paginationposition && $this->item->paginationrelative) :
+ echo $this->item->pagination;
+ ?>
+
+
+ item->event->afterDisplayContent; ?>
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/article/toc-right.php b/templates/moko-cassiopeia/html/com_content/article/toc-right.php
new file mode 100644
index 0000000..cb65cb7
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/article/toc-right.php
@@ -0,0 +1,160 @@
+item->params;
+$canEdit = $params->get('access-edit');
+$user = Factory::getUser();
+$info = $params->get('info_block_position', 0);
+$htag = $this->params->get('show_page_heading') ? 'h2' : 'h1';
+
+// Check if associations are implemented. If they are, define the parameter.
+$assocParam = (Associations::isEnabled() && $params->get('show_associations'));
+$currentDate = Factory::getDate()->format('Y-m-d H:i:s');
+$isNotPublishedYet = $this->item->publish_up > $currentDate;
+$isExpired = !is_null($this->item->publish_down) && $this->item->publish_down < $currentDate;
+?>
+
+
+ params->get('show_page_heading')) : ?>
+
+ item->pagination) && !$this->item->paginationposition && $this->item->paginationrelative) {
+ echo $this->item->pagination;
+ }
+ ?>
+
+ get('show_modify_date') || $params->get('show_publish_date') || $params->get('show_create_date')
+ || $params->get('show_hits') || $params->get('show_category') || $params->get('show_parent_category') || $params->get('show_author') || $assocParam; ?>
+
+ get('show_title')) : ?>
+
+
+
+ $params, 'item' => $this->item]); ?>
+
+
+
+ item->event->afterDisplayTitle; ?>
+
+
+ $this->item, 'params' => $params, 'position' => 'above']); ?>
+
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tagLayout = new FileLayout('joomla.content.tags'); ?>
+
+ item->tagLayout->render($this->item->tags->itemTags); ?>
+
+
+
+ item->event->beforeDisplayContent; ?>
+
+ get('urls_position', 0) === 0) : ?>
+ loadTemplate('links'); ?>
+
+ get('access-view')) : ?>
+ item); ?>
+ item->pagination) && !$this->item->paginationposition && !$this->item->paginationrelative) :
+ echo $this->item->pagination;
+ endif;
+ ?>
+
+
+ ' . Text::_('TPL_MOKO-CASSIOPEIA_TOC') . '';
+ ?>
+
+
+
+ item->text;
+ ?>
+
+
+
+
+
+
+ $this->item, 'params' => $params, 'position' => 'below']); ?>
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tagLayout = new FileLayout('joomla.content.tags'); ?>
+ item->tagLayout->render($this->item->tags->itemTags); ?>
+
+
+
+ item->pagination) && $this->item->paginationposition && !$this->item->paginationrelative) :
+ echo $this->item->pagination;
+ ?>
+
+ get('urls_position', 0) === 1) : ?>
+ loadTemplate('links'); ?>
+
+
+ get('show_noauth') == true && $user->get('guest')) : ?>
+ item); ?>
+ item->introtext); ?>
+
+ get('show_readmore') && $this->item->fulltext != null) : ?>
+ getMenu(); ?>
+ getActive(); ?>
+ id; ?>
+
+ setVar('return', base64_encode(RouteHelper::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language))); ?>
+ $this->item, 'params' => $params, 'link' => $link]); ?>
+
+
+ item->pagination) && $this->item->paginationposition && $this->item->paginationrelative) :
+ echo $this->item->pagination;
+ ?>
+
+
+ item->event->afterDisplayContent; ?>
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/categories/default.php b/templates/moko-cassiopeia/html/com_content/categories/default.php
new file mode 100644
index 0000000..e7f4505
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/categories/default.php
@@ -0,0 +1,33 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Layout\LayoutHelper;
+
+// Add strings for translations in Javascript.
+Text::script('JGLOBAL_EXPAND_CATEGORIES');
+Text::script('JGLOBAL_COLLAPSE_CATEGORIES');
+
+/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
+$wa = $this->document->getWebAssetManager();
+$wa->getRegistry()->addExtensionRegistryFile('com_categories');
+$wa->usePreset('com_categories.shared-categories-accordion');
+
+?>
+
+ loadTemplate('items');
+ ?>
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/categories/default_items.php b/templates/moko-cassiopeia/html/com_content/categories/default_items.php
new file mode 100644
index 0000000..9e2db70
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/categories/default_items.php
@@ -0,0 +1,77 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Router\Route;
+use Joomla\Component\Content\Site\Helper\RouteHelper;
+
+if ($this->maxLevelcat != 0 && count($this->items[$this->parent->id]) > 0) :
+ ?>
+
+ items[$this->parent->id] as $id => $item) : ?>
+ params->get('show_empty_categories_cat') || $item->numitems || count($item->getChildren())) : ?>
+
+
+
+ getChildren()) > 0 && $this->maxLevelcat > 1) : ?>
+
+
+
+
+
+ params->get('show_description_image') && $item->getParams()->get('image')) : ?>
+ getParams()->get('image'), $item->getParams()->get('image_alt')); ?>
+
+ params->get('show_subcat_desc_cat') == 1) : ?>
+ description) : ?>
+
+ description, '', 'com_content.categories'); ?>
+
+
+
+
+ getChildren()) > 0 && $this->maxLevelcat > 1) : ?>
+
+ items[$item->id] = $item->getChildren();
+ $this->parent = $item;
+ $this->maxLevelcat--;
+ echo $this->loadTemplate('items');
+ $this->parent = $item->getParent();
+ $this->maxLevelcat++;
+ ?>
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/categories/index.html b/templates/moko-cassiopeia/html/com_content/categories/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/categories/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/category/blog.php b/templates/moko-cassiopeia/html/com_content/category/blog.php
new file mode 100644
index 0000000..f17f23d
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/category/blog.php
@@ -0,0 +1,143 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Layout\FileLayout;
+use Joomla\CMS\Layout\LayoutHelper;
+
+$app = Factory::getApplication();
+
+$this->category->text = $this->category->description;
+$app->triggerEvent('onContentPrepare', [$this->category->extension . '.categories', &$this->category, &$this->params, 0]);
+$this->category->description = $this->category->text;
+
+$results = $app->triggerEvent('onContentAfterTitle', [$this->category->extension . '.categories', &$this->category, &$this->params, 0]);
+$afterDisplayTitle = trim(implode("\n", $results));
+
+$results = $app->triggerEvent('onContentBeforeDisplay', [$this->category->extension . '.categories', &$this->category, &$this->params, 0]);
+$beforeDisplayContent = trim(implode("\n", $results));
+
+$results = $app->triggerEvent('onContentAfterDisplay', [$this->category->extension . '.categories', &$this->category, &$this->params, 0]);
+$afterDisplayContent = trim(implode("\n", $results));
+
+$htag = $this->params->get('show_page_heading') ? 'h2' : 'h1';
+
+?>
+
+ params->get('show_page_heading')) : ?>
+
+
+
+ params->get('show_category_title', 1)) : ?>
+ <>
+ category->title; ?>
+ >
+
+
+
+ params->get('show_cat_tags', 1) && !empty($this->category->tags->itemTags)) : ?>
+ category->tagLayout = new FileLayout('joomla.content.tags'); ?>
+ category->tagLayout->render($this->category->tags->itemTags); ?>
+
+
+ params->get('show_description', 1) || $this->params->def('show_description_image', 1)) : ?>
+
+ params->get('show_description_image') && $this->category->getParams()->get('image')) : ?>
+ $this->category->getParams()->get('image'),
+ 'alt' => empty($this->category->getParams()->get('image_alt')) && empty($this->category->getParams()->get('image_alt_empty')) ? false : $this->category->getParams()->get('image_alt'),
+ ]
+ ); ?>
+
+
+ params->get('show_description') && $this->category->description) : ?>
+ category->description, '', 'com_content.category'); ?>
+
+
+
+
+
+ lead_items) && empty($this->link_items) && empty($this->intro_items)) : ?>
+ params->get('show_no_articles', 1)) : ?>
+
+
+
+
+
+
+
+ lead_items)) : ?>
+
+ lead_items as &$item) : ?>
+
+ item = &$item;
+ echo $this->loadTemplate('item');
+ ?>
+
+
+
+
+
+ intro_items)) : ?>
+ params->get('blog_class', ''); ?>
+ params->get('num_columns') > 1) : ?>
+ params->get('multi_column_order', 0) === 0 ? ' masonry-' : ' columns-'; ?>
+ params->get('num_columns'); ?>
+
+
+ intro_items as $key => &$item) : ?>
+
+ item = & $item;
+ echo $this->loadTemplate('item');
+ ?>
+
+
+
+
+
+ link_items)) : ?>
+
+ loadTemplate('links'); ?>
+
+
+
+ maxLevel != 0 && !empty($this->children[$this->category->id])) : ?>
+
+ params->get('show_category_heading_title_text', 1) == 1) : ?>
+
+
+ loadTemplate('children'); ?>
+
+ params->def('show_pagination', 1) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->pagesTotal > 1)) : ?>
+
+ params->def('show_pagination_results', 1)) : ?>
+
+ pagination->getPagesCounter(); ?>
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/category/blog_children.php b/templates/moko-cassiopeia/html/com_content/category/blog_children.php
new file mode 100644
index 0000000..dd9827c
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/category/blog_children.php
@@ -0,0 +1,86 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Router\Route;
+use Joomla\Component\Content\Site\Helper\RouteHelper;
+
+$lang = Factory::getLanguage();
+$user = Factory::getUser();
+$groups = $user->getAuthorisedViewLevels();
+
+if ($this->maxLevel != 0 && count($this->children[$this->category->id]) > 0) : ?>
+ children[$this->category->id] as $id => $child) : ?>
+
+ access, $groups)) : ?>
+ params->get('show_empty_categories') || $child->numitems || count($child->getChildren())) : ?>
+
+ isRtl()) : ?>
+
+
+
+
+
+ params->get('show_subcat_desc') == 1) : ?>
+ description) : ?>
+
+ description, '', 'com_content.category'); ?>
+
+
+
+
+ maxLevel > 1 && count($child->getChildren()) > 0) : ?>
+
+ children[$child->id] = $child->getChildren();
+ $this->category = $child;
+ $this->maxLevel--;
+ echo $this->loadTemplate('children');
+ $this->category = $child->getParent();
+ $this->maxLevel++;
+ ?>
+
+
+
+
+
+
+
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\Language\Associations;
+use Joomla\CMS\Layout\LayoutHelper;
+use Joomla\CMS\Router\Route;
+use Joomla\CMS\Uri\Uri;
+use Joomla\Component\Content\Administrator\Extension\ContentComponent;
+use Joomla\Component\Content\Site\Helper\RouteHelper;
+
+// Create a shortcut for params.
+$params = $this->item->params;
+$canEdit = $this->item->params->get('access-edit');
+$info = $params->get('info_block_position', 0);
+
+// Check if associations are implemented. If they are, define the parameter.
+$assocParam = (Associations::isEnabled() && $params->get('show_associations'));
+
+$currentDate = Factory::getDate()->format('Y-m-d H:i:s');
+$isUnpublished = ($this->item->state == ContentComponent::CONDITION_UNPUBLISHED || $this->item->publish_up > $currentDate)
+ || ($this->item->publish_down < $currentDate && $this->item->publish_down !== null);
+
+?>
+
+item); ?>
+
+
+
+
+
+item); ?>
+
+
+ $params, 'item' => $this->item]); ?>
+
+
+
+ get('show_modify_date') || $params->get('show_publish_date') || $params->get('show_create_date')
+ || $params->get('show_hits') || $params->get('show_category') || $params->get('show_parent_category') || $params->get('show_author') || $assocParam); ?>
+
+
+ $this->item, 'params' => $params, 'position' => 'above']); ?>
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tags->itemTags); ?>
+
+
+ get('show_intro')) : ?>
+
+ item->event->afterDisplayTitle; ?>
+
+
+
+ item->event->beforeDisplayContent; ?>
+
+ item->introtext; ?>
+
+
+
+ $this->item, 'params' => $params, 'position' => 'below']); ?>
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tags->itemTags); ?>
+
+
+
+ get('show_readmore') && $this->item->readmore) :
+ if ($params->get('access-view')) :
+ $link = Route::_(RouteHelper::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language));
+ else :
+ $menu = Factory::getApplication()->getMenu();
+ $active = $menu->getActive();
+ $itemId = $active->id;
+ $link = new Uri(Route::_('index.php?option=com_users&view=login&Itemid=' . $itemId, false));
+ $link->setVar('return', base64_encode(RouteHelper::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language)));
+ endif; ?>
+
+ $this->item, 'params' => $params, 'link' => $link]); ?>
+
+
+
+
+
+
+
+
+ item->event->afterDisplayContent; ?>
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/category/blog_links.php b/templates/moko-cassiopeia/html/com_content/category/blog_links.php
new file mode 100644
index 0000000..792c341
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/category/blog_links.php
@@ -0,0 +1,27 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Router\Route;
+use Joomla\Component\Content\Site\Helper\RouteHelper;
+
+?>
+
+
+ link_items as $item) : ?>
+
+
+ title; ?>
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/category/default.php b/templates/moko-cassiopeia/html/com_content/category/default.php
new file mode 100644
index 0000000..0f7745b
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/category/default.php
@@ -0,0 +1,25 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Layout\LayoutHelper;
+
+?>
+
+
+subtemplatename = 'articles';
+echo LayoutHelper::render('joomla.content.category_default', $this);
+?>
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/category/default_articles.php b/templates/moko-cassiopeia/html/com_content/category/default_articles.php
new file mode 100644
index 0000000..f079f29
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/category/default_articles.php
@@ -0,0 +1,349 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Component\ComponentHelper;
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Associations;
+use Joomla\CMS\Language\Multilanguage;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Router\Route;
+use Joomla\CMS\Uri\Uri;
+use Joomla\Component\Content\Administrator\Extension\ContentComponent;
+use Joomla\Component\Content\Site\Helper\AssociationHelper;
+use Joomla\Component\Content\Site\Helper\RouteHelper;
+
+/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
+$wa = $this->document->getWebAssetManager();
+$wa->useScript('com_content.articles-list');
+
+// Create some shortcuts.
+$n = count($this->items);
+$listOrder = $this->escape($this->state->get('list.ordering'));
+$listDirn = $this->escape($this->state->get('list.direction'));
+$langFilter = false;
+
+// Tags filtering based on language filter
+if (($this->params->get('filter_field') === 'tag') && (Multilanguage::isEnabled())) {
+ $tagfilter = ComponentHelper::getParams('com_tags')->get('tag_list_language_filter');
+
+ switch ($tagfilter) {
+ case 'current_language':
+ $langFilter = Factory::getApplication()->getLanguage()->getTag();
+ break;
+
+ case 'all':
+ $langFilter = false;
+ break;
+
+ default:
+ $langFilter = $tagfilter;
+ }
+}
+
+// Check for at least one editable article
+$isEditable = false;
+
+if (!empty($this->items)) {
+ foreach ($this->items as $article) {
+ if ($article->params->get('access-edit')) {
+ $isEditable = true;
+ break;
+ }
+ }
+}
+
+$currentDate = Factory::getDate()->format('Y-m-d H:i:s');
+?>
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/category/default_children.php b/templates/moko-cassiopeia/html/com_content/category/default_children.php
new file mode 100644
index 0000000..942c59a
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/category/default_children.php
@@ -0,0 +1,85 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Router\Route;
+use Joomla\Component\Content\Site\Helper\RouteHelper;
+
+$lang = Factory::getLanguage();
+$user = Factory::getUser();
+$groups = $user->getAuthorisedViewLevels();
+?>
+
+children[$this->category->id]) > 0) : ?>
+ children[$this->category->id] as $id => $child) : ?>
+
+ access, $groups)) : ?>
+ params->get('show_empty_categories') || $child->getNumItems(true) || count($child->getChildren())) : ?>
+
+ isRtl()) : ?>
+
+
+
+
+ params->get('show_subcat_desc') == 1) : ?>
+ description) : ?>
+
+ description, '', 'com_content.category'); ?>
+
+
+
+
+ getChildren()) > 0 && $this->maxLevel > 1) : ?>
+
+ children[$child->id] = $child->getChildren();
+ $this->category = $child;
+ $this->maxLevel--;
+ echo $this->loadTemplate('children');
+ $this->category = $child->getParent();
+ $this->maxLevel++;
+ ?>
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/category/index.html b/templates/moko-cassiopeia/html/com_content/category/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/category/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/featured/default.php b/templates/moko-cassiopeia/html/com_content/featured/default.php
new file mode 100644
index 0000000..8214b33
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/featured/default.php
@@ -0,0 +1,75 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+?>
+
+ params->get('show_page_heading') != 0) : ?>
+
+
+
+ lead_items)) : ?>
+
+ lead_items as &$item) : ?>
+
+ item = & $item;
+ echo $this->loadTemplate('item');
+ ?>
+
+
+
+
+
+ intro_items)) : ?>
+ params->get('blog_class', ''); ?>
+ params->get('num_columns') > 1) : ?>
+ params->get('multi_column_order', 0) === 0 ? ' masonry-' : ' columns-'; ?>
+ params->get('num_columns'); ?>
+
+
+ intro_items as $key => &$item) : ?>
+
+ item = & $item;
+ echo $this->loadTemplate('item');
+ ?>
+
+
+
+
+
+ link_items)) : ?>
+
+ loadTemplate('links'); ?>
+
+
+
+ params->def('show_pagination', 2) == 1 || ($this->params->get('show_pagination') == 2 && $this->pagination->pagesTotal > 1)) : ?>
+
+ params->def('show_pagination_results', 1)) : ?>
+
+ pagination->getPagesCounter(); ?>
+
+
+ pagination->getPagesLinks(); ?>
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/featured/default_item.php b/templates/moko-cassiopeia/html/com_content/featured/default_item.php
new file mode 100644
index 0000000..07d526b
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/featured/default_item.php
@@ -0,0 +1,121 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\Language\Associations;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Layout\LayoutHelper;
+use Joomla\CMS\Router\Route;
+use Joomla\CMS\Uri\Uri;
+use Joomla\Component\Content\Administrator\Extension\ContentComponent;
+use Joomla\Component\Content\Site\Helper\RouteHelper;
+
+// Create a shortcut for params.
+$params = &$this->item->params;
+$canEdit = $this->item->params->get('access-edit');
+$info = $this->item->params->get('info_block_position', 0);
+
+// Check if associations are implemented. If they are, define the parameter.
+$assocParam = (Associations::isEnabled() && $params->get('show_associations'));
+
+$currentDate = Factory::getDate()->format('Y-m-d H:i:s');
+$isExpired = !is_null($this->item->publish_down) && $this->item->publish_down < $currentDate;
+$isNotPublishedYet = $this->item->publish_up > $currentDate;
+$isUnpublished = $this->item->state == ContentComponent::CONDITION_UNPUBLISHED || $isNotPublishedYet || $isExpired;
+?>
+
+item); ?>
+
+
+
+
+
+
+ get('show_title')) : ?>
+
+ get('link_titles') && $params->get('access-view')) : ?>
+
+ escape($this->item->title); ?>
+
+
+ escape($this->item->title); ?>
+
+
+
+
+ item->state == ContentComponent::CONDITION_UNPUBLISHED) : ?>
+
+
+
+
+
+
+
+
+
+
+ $params, 'item' => $this->item]); ?>
+
+
+
+ item->event->afterDisplayTitle; ?>
+
+
+ get('show_modify_date') || $params->get('show_publish_date') || $params->get('show_create_date')
+ || $params->get('show_hits') || $params->get('show_category') || $params->get('show_parent_category') || $params->get('show_author') || $assocParam); ?>
+
+
+ $this->item, 'params' => $params, 'position' => 'above']); ?>
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tags->itemTags); ?>
+
+
+
+ item->event->beforeDisplayContent; ?>
+
+ item->introtext; ?>
+
+
+
+ $this->item, 'params' => $params, 'position' => 'below']); ?>
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tags->itemTags); ?>
+
+
+
+ get('show_readmore') && $this->item->readmore) :
+ if ($params->get('access-view')) :
+ $link = Route::_(RouteHelper::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language));
+ else :
+ $menu = Factory::getApplication()->getMenu();
+ $active = $menu->getActive();
+ $itemId = $active->id;
+ $link = new Uri(Route::_('index.php?option=com_users&view=login&Itemid=' . $itemId, false));
+ $link->setVar('return', base64_encode(RouteHelper::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language)));
+ endif; ?>
+
+ $this->item, 'params' => $params, 'link' => $link]); ?>
+
+
+
+
+
+
+
+
+
+
+item->event->afterDisplayContent; ?>
+
diff --git a/templates/moko-cassiopeia/html/com_content/featured/default_links.php b/templates/moko-cassiopeia/html/com_content/featured/default_links.php
new file mode 100644
index 0000000..87ff897
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/featured/default_links.php
@@ -0,0 +1,26 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Router\Route;
+use Joomla\Component\Content\Site\Helper\RouteHelper;
+
+?>
+
+ link_items as $item) : ?>
+
+
+ title; ?>
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/featured/index.html b/templates/moko-cassiopeia/html/com_content/featured/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/featured/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_content/index.html b/templates/moko-cassiopeia/html/com_content/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_content/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_engage/comments/default.php b/templates/moko-cassiopeia/html/com_engage/comments/default.php
new file mode 100644
index 0000000..e0ec457
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_engage/comments/default.php
@@ -0,0 +1,78 @@
+
+
diff --git a/templates/moko-cassiopeia/html/com_engage/comments/default_form.php b/templates/moko-cassiopeia/html/com_engage/comments/default_form.php
new file mode 100644
index 0000000..4f8f740
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_engage/comments/default_form.php
@@ -0,0 +1,90 @@
+get('comments_reply_bad_ux', 0) == 1) && empty($this->form->getValue('body'));
+
+HTMLHelper::_('behavior.formvalidator');
+?>
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_engage/comments/default_list.php b/templates/moko-cassiopeia/html/com_engage/comments/default_list.php
new file mode 100644
index 0000000..4e04e3f
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_engage/comments/default_list.php
@@ -0,0 +1,286 @@
+ 0];
+$parentNames = [0 => ''];
+
+foreach ($this->items as $comment):
+$user = !empty($comment->created_by) && empty($comment->name) ? UserFetcher::getUser($comment->created_by) : new User();
+
+if (empty($comment->created_by) || !empty($comment->name)) {
+ $user->name = $comment->name;
+ $user->email = $comment->email;
+}
+
+$parentIds[$comment->depth] = $comment->id;
+$parentNames[$comment->depth] = $user->name;
+// Deeper level comment. Indent with tags
+if ($comment->depth > $previousLevel):
+ ?>
+ depth; $level++): ?>
+
+
+
+
+
+ tag.
+else: ?>
+
+
+
+
+depth;
+$avatar = Avatar::getUserAvatar($comment->created_by, $maxAvatarWidth, $comment->email);
+$profile = Avatar::getProfileURL($user);
+$commentDate = Factory::getDate($comment->created)->setTimezone($this->userTimezone);
+$ipLookupURL = $this->getIPLookupURL($comment->ip);
+$isModified = !empty($comment->modified_by) && !empty($comment->modified) && (
+ empty($comment->created_by) || empty($comment->created) || (
+ ($comment->modified_by != $comment->created_by) &&
+ ($comment->modified != $comment->created)
+ )
+ );
+
+if ($isModified)
+{
+ if ($comment->modified_by == $comment->created_by)
+ {
+ // If the comment is modified by the created by user, use the public name determined at the top of the file.
+ $modifiedBy = $user->name;
+ }
+ else
+ {
+ // Someone else modified the comment. Use their name.
+ $modifiedUser = UserFetcher::getUser($comment->modified_by);
+ // If the user is no longer available, use '???'
+ $modifiedBy = ($modifiedUser === null || $modifiedUser->guest) ? Text::_('COM_ENGAGE_LBL_COMMENT_MODIFIED_NO_LONGER_AVAILABLE') : $modifiedUser->name;
+ }
+
+}
+
+$openListItem++;
+$this->ensureHasParentInfo($comment, $parentIds, $parentNames);
+$bsCommentStateClass = ($comment->enabled == 1) ? 'secondary' : (($comment->enabled == -3) ? 'warning' : 'danger')
+?>
+
+
+= 1; $level--): ?>
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_engage/comments/default_login.php b/templates/moko-cassiopeia/html/com_engage/comments/default_login.php
new file mode 100644
index 0000000..d08c718
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_engage/comments/default_login.php
@@ -0,0 +1,45 @@
+get('login_module', '-1');
+$moduleContent = (empty($loginModule) || ($loginModule === '-1')) ? '' : trim($this->loadModule($loginModule));
+$positionContent = trim($this->loadPosition('engage-login'));
+
+/**
+ * A reason for this to happen is that site owner wants discussion to be open to invitation-only members of the site but
+ * visible by anyone. This is mostly relevant in political organizations, NGOs and local / closed community
+ * organizations where a small number of people are openly discussing a public interest issue, but they don't want to
+ * allow random people to detract the conversation.
+ */
+if (empty($moduleContent) && empty($positionContent))
+{
+ return;
+}
+?>
+
+
+ = Text::_('COM_ENGAGE_COMMENTS_LOGIN_HEAD') ?>
+
+
+ = $moduleContent ?>
+ = $positionContent ?>
+
diff --git a/templates/moko-cassiopeia/html/com_engage/comments/index.html b/templates/moko-cassiopeia/html/com_engage/comments/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_engage/comments/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_engage/index.html b/templates/moko-cassiopeia/html/com_engage/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_engage/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/accordion_plans.php b/templates/moko-cassiopeia/html/com_osmembership/common/accordion_plans.php
new file mode 100644
index 0000000..734fffe
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/accordion_plans.php
@@ -0,0 +1,195 @@
+getClassMapping('row-fluid');
+$span7Class = $bootstrapHelper->getClassMapping('span7');
+$span5class = $bootstrapHelper->getClassMapping('span5');
+$imgClass = $bootstrapHelper->getClassMapping('img-polaroid');
+$btnClass = $bootstrapHelper->getClassMapping('btn');
+$btnPrimaryClass = $bootstrapHelper->getClassMapping('btn btn-primary');
+$clearfixClass = $bootstrapHelper->getClassMapping('clearfix');
+
+$defaultItemId = $Itemid;
+
+for ($i = 0 , $n = count($items) ; $i < $n ; $i++)
+{
+ $item = $items[$i];
+ $Itemid = OSMembershipHelperRoute::getPlanMenuId($item->id, $item->category_id, $defaultItemId);
+
+ if ($item->thumb)
+ {
+ $imgSrc = $rootUri . '/media/com_osmembership/' . $item->thumb;
+ }
+
+ if ($item->category_id)
+ {
+ $url = Route::_('index.php?option=com_osmembership&view=plan&catid=' . $item->category_id . '&id=' . $item->id . '&Itemid=' . $Itemid);
+ }
+ else
+ {
+ $url = Route::_('index.php?option=com_osmembership&view=plan&id=' . $item->id . '&Itemid=' . $Itemid);
+ }
+
+ if ($config->use_https)
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid), false, 1);
+ }
+ else
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid));
+ }
+
+ $symbol = $item->currency_symbol ?: $item->currency;
+ ?>
+
+
+
+
+
+ thumb)
+ {
+ ?>
+
+ short_description)
+ {
+ echo $item->short_description;
+ }
+ else
+ {
+ echo $item->description;
+ }
+ ?>
+
+
+ $item]); ?>
+
+
+
+
+ getLanguage();
+
+ if (in_array('subscribe', $actions))
+ {
+ if ($language->hasKey('OSM_SIGNUP_PLAN_' . $item->id))
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP_PLAN_' . $item->id;
+ }
+ else
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP';
+ }
+
+ if ($language->hasKey('OSM_RENEW_PLAN_' . $item->id))
+ {
+ $renewLanguageItem = 'OSM_RENEW_PLAN_' . $item->id;
+ }
+ else
+ {
+ $renewLanguageItem = 'OSM_RENEW';
+ }
+ ?>
+
+
+ id, $subscribedPlanIds) ? Text::_($renewLanguageItem) : Text::_($signUpLanguageItem); ?>
+
+
+ hasKey('OSM_UPGRADE_PLAN_' . $item->id))
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE_PLAN_' . $item->id;
+ }
+ else
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE';
+ }
+
+ if (count($item->upgrade_rules) > 1)
+ {
+ $link = Route::_('index.php?option=com_osmembership&view=upgrademembership&to_plan_id=' . $item->id . '&Itemid=' . OSMembershipHelperRoute::findView('upgrademembership', $Itemid));
+ }
+ else
+ {
+ $upgradeOptionId = $item->upgrade_rules[0]->id;
+ $link = Route::_('index.php?option=com_osmembership&task=register.process_upgrade_membership&upgrade_option_id=' . $upgradeOptionId . '&Itemid=' . $Itemid);
+ }
+ ?>
+
+
+
+
+
+ hide_details_button))
+ {
+ ?>
+
+
+
+
+
+
+
+
+
+
+ getDocument()
+ ->getWebAssetManager()
+ ->useScript('core');
+
+Text::script('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST');
+$message = "alert(Joomla.JText._('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'));";
+?>
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/batch_nocheck.php b/templates/moko-cassiopeia/html/com_osmembership/common/batch_nocheck.php
new file mode 100644
index 0000000..9e43b82
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/batch_nocheck.php
@@ -0,0 +1,24 @@
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/categories.php b/templates/moko-cassiopeia/html/com_osmembership/common/categories.php
new file mode 100644
index 0000000..a5b5955
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/categories.php
@@ -0,0 +1,56 @@
+getClassMapping('clearfix');
+
+for ($i = 0 , $n = count($items) ; $i < $n ; $i++)
+{
+ $item = $items[$i];
+ $link = Route::_(OSMembershipHelperRoute::getCategoryRoute($item->id, $Itemid));
+ ?>
+
+
+
+
+ title;?>
+
+ total_plans ;?> total_plans > 1 ? Text::_('OSM_PLANS') : Text::_('OSM_PLAN') ; ?>
+
+
+ description)
+ {
+ ?>
+
+ description);?>
+
+
+
+getDocument()
+ ->getWebAssetManager()
+ ->useScript('core');
+
+$rootUri = Uri::root(true);
+$minHeight = 130;
+
+if (isset($params))
+{
+ $minHeight = (int) $params->get('min_height', 130) ?: 130;
+}
+
+OSMembershipHelperJquery::responsiveEqualHeight('.osm-item-description-text', $minHeight);
+
+$subscribedPlanIds = OSMembershipHelperSubscription::getSubscribedPlans();
+
+if (isset($input) && $input->getInt('number_columns'))
+{
+ $numberColumns = $input->getInt('number_columns');
+}
+elseif (!empty($config->number_columns))
+{
+ $numberColumns = $config->number_columns;
+}
+else
+{
+ $numberColumns = 3;
+}
+
+if (!isset($categoryId))
+{
+ $categoryId = 0;
+}
+
+$span = intval(12 / $numberColumns);
+
+$btnClass = $bootstrapHelper->getClassMapping('btn');
+$btnPrimaryClass = $bootstrapHelper->getClassMapping('btn btn-primary');
+$imgClass = $bootstrapHelper->getClassMapping('img-polaroid');
+$spanClass = $bootstrapHelper->getClassMapping('span' . $span);
+$rowFluidClearfixClass = $bootstrapHelper->getClassMapping('row-fluid clearfix');
+$clearFixClass = $bootstrapHelper->getClassMapping('clearfix');
+?>
+
+id, $item->category_id, $defaultItemId);
+
+ if ($item->thumb)
+ {
+ $imgSrc = $rootUri . '/media/com_osmembership/' . $item->thumb;
+ }
+
+ $url = Route::_('index.php?option=com_osmembership&view=plan&catid=' . $item->category_id . '&id=' . $item->id . '&Itemid=' . $Itemid);
+
+ if ($config->use_https)
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid), false, 1);
+ }
+ else
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid));
+ }
+ ?>
+
+
+
+ thumb)
+ {
+ ?>
+
+
+
+ short_description)
+ {
+ $item->short_description = $item->description;
+ }
+ ?>
+
short_description; ?>
+
+
+ getLanguage();
+
+ if (in_array('subscribe', $actions))
+ {
+ if ($language->hasKey('OSM_SIGNUP_PLAN_' . $item->id))
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP_PLAN_' . $item->id;
+ }
+ else
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP';
+ }
+
+ if ($language->hasKey('OSM_RENEW_PLAN_' . $item->id))
+ {
+ $renewLanguageItem = 'OSM_RENEW_PLAN_' . $item->id;
+ }
+ else
+ {
+ $renewLanguageItem = 'OSM_RENEW';
+ }
+ ?>
+
+
+ id, $subscribedPlanIds) ? Text::_($renewLanguageItem) : Text::_($signUpLanguageItem); ?>
+
+
+ hasKey('OSM_UPGRADE_PLAN_' . $item->id))
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE_PLAN_' . $item->id;
+ }
+ else
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE';
+ }
+
+ if (count($item->upgrade_rules) > 1)
+ {
+ $link = Route::_('index.php?option=com_osmembership&view=upgrademembership&to_plan_id=' . $item->id . '&Itemid=' . OSMembershipHelperRoute::findView('upgrademembership', $Itemid));
+ }
+ else
+ {
+ $upgradeOptionId = $item->upgrade_rules[0]->id;
+ $link = Route::_('index.php?option=com_osmembership&task=register.process_upgrade_membership&upgrade_option_id=' . $upgradeOptionId . '&Itemid=' . $Itemid);
+ }
+ ?>
+
+
+
+
+
+ hide_details_button))
+ {
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/default_plans.php b/templates/moko-cassiopeia/html/com_osmembership/common/default_plans.php
new file mode 100644
index 0000000..ecd9b73
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/default_plans.php
@@ -0,0 +1,231 @@
+getClassMapping('row-fluid');
+$imgClass = $bootstrapHelper->getClassMapping('img-polaroid');
+$btnClass = $bootstrapHelper->getClassMapping('btn');
+$btnPrimaryClass = $bootstrapHelper->getClassMapping('btn btn-primary');
+$clearfixClass = $bootstrapHelper->getClassMapping('clearfix');
+
+$defaultItemId = $Itemid;
+
+if (isset($params))
+{
+ $showPlanInformation = $params->get('show_plan_information', 1);
+ $planInformationPosition = $params->get('plan_information_position', 0);
+}
+else
+{
+ $showPlanInformation = 1;
+ $planInformationPosition = 0;
+}
+
+if ($showPlanInformation && $planInformationPosition == 0)
+{
+ $leftClass = $bootstrapHelper->getClassMapping('span7');
+ $rightClass = $bootstrapHelper->getClassMapping('span5');
+}
+else
+{
+ $leftClass = $bootstrapHelper->getClassMapping('clearfix');
+ $rightClass = $bootstrapHelper->getClassMapping('clearfix');
+}
+
+for ($i = 0 , $n = count($items) ; $i < $n ; $i++)
+{
+ $item = $items[$i];
+ $Itemid = OSMembershipHelperRoute::getPlanMenuId($item->id, $item->category_id, $defaultItemId);
+
+ if ($item->thumb)
+ {
+ $imgSrc = $rootUri . '/media/com_osmembership/' . $item->thumb;
+ }
+
+ if ($item->category_id)
+ {
+ $url = Route::_('index.php?option=com_osmembership&view=plan&catid=' . $item->category_id . '&id=' . $item->id . '&Itemid=' . $Itemid);
+ }
+ else
+ {
+ $url = Route::_('index.php?option=com_osmembership&view=plan&id=' . $item->id . '&Itemid=' . $Itemid);
+ }
+
+ if ($config->use_https)
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid), false, 1);
+ }
+ else
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid));
+ }
+ ?>
+
+
+
+
+
+
+ $item]); ?>
+
+
+
+ thumb)
+ {
+ ?>
+
+ short_description)
+ {
+ echo $item->short_description;
+ }
+ else
+ {
+ echo $item->description;
+ }
+ ?>
+
+
+
+ $item]); ?>
+
+
+
+
+
+ getLanguage();
+
+ if (in_array('subscribe', $actions))
+ {
+ if ($language->hasKey('OSM_SIGNUP_PLAN_' . $item->id))
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP_PLAN_' . $item->id;
+ }
+ else
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP';
+ }
+
+ if ($language->hasKey('OSM_RENEW_PLAN_' . $item->id))
+ {
+ $renewLanguageItem = 'OSM_RENEW_PLAN_' . $item->id;
+ }
+ else
+ {
+ $renewLanguageItem = 'OSM_RENEW';
+ }
+ ?>
+
+
+ id, $subscribedPlanIds) ? Text::_($renewLanguageItem) : Text::_($signUpLanguageItem); ?>
+
+
+ hasKey('OSM_UPGRADE_PLAN_' . $item->id))
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE_PLAN_' . $item->id;
+ }
+ else
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE';
+ }
+
+ if (count($item->upgrade_rules) > 1)
+ {
+ $link = Route::_('index.php?option=com_osmembership&view=upgrademembership&to_plan_id=' . $item->id . '&Itemid=' . OSMembershipHelperRoute::findView('upgrademembership', $Itemid));
+ }
+ else
+ {
+ $upgradeOptionId = $item->upgrade_rules[0]->id;
+ $link = Route::_('index.php?option=com_osmembership&task=register.process_upgrade_membership&upgrade_option_id=' . $upgradeOptionId . '&Itemid=' . $Itemid);
+ }
+ ?>
+
+
+
+
+
+ hide_details_button))
+ {
+ ?>
+
+
+
+
+
+
+
+
+
+
+first_name . ' ' . $rowMember->last_name);
+}
+
+echo implode("\r\n", $names);
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/index.html b/templates/moko-cassiopeia/html/com_osmembership/common/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/paymentredirect.php b/templates/moko-cassiopeia/html/com_osmembership/common/paymentredirect.php
new file mode 100644
index 0000000..0dc2da4
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/paymentredirect.php
@@ -0,0 +1,36 @@
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/plan_custom_fields.php b/templates/moko-cassiopeia/html/com_osmembership/common/plan_custom_fields.php
new file mode 100644
index 0000000..c765448
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/plan_custom_fields.php
@@ -0,0 +1,45 @@
+getFieldset('basic') as $field)
+{
+ if ($field->getAttribute('hide'))
+ {
+ continue;
+ }
+?>
+
+
+ getAttribute('label')); ?>:
+
+
+ fieldsData->get($field->getAttribute('name')); ?>
+
+
+currency_symbol ?: $item->currency;
+?>
+
+ setup_fee > 0)
+ {
+ ?>
+
+
+ :
+
+
+ setup_fee, $config, $symbol); ?>
+
+
+ recurring_subscription && $item->trial_duration)
+ {
+ ?>
+
+
+ :
+
+
+ lifetime_membership)
+ {
+ echo Text::_('OSM_LIFETIME');
+ }
+ else
+ {
+ echo OSMembershipHelperSubscription::getDurationText($item->trial_duration, $item->trial_duration_unit);
+ }
+ ?>
+
+
+
+
+
+ :
+
+
+ trial_amount > 0)
+ {
+ echo OSMembershipHelper::formatCurrency($item->trial_amount, $config, $symbol);
+ }
+ else
+ {
+ echo Text::_('OSM_FREE');
+ }
+ ?>
+
+
+ expired_date))
+ {
+ ?>
+
+
+ :
+
+
+ lifetime_membership)
+ {
+ echo Text::_('OSM_LIFETIME');
+ }
+ else
+ {
+ echo OSMembershipHelperSubscription::getDurationText($item->subscription_length, $item->subscription_length_unit);
+ }
+ ?>
+
+
+
+
+
+ :
+
+
+ price > 0)
+ {
+ echo OSMembershipHelper::formatCurrency($item->price, $config, $symbol);
+ }
+ else
+ {
+ echo Text::_('OSM_FREE');
+ }
+ ?>
+
+
+ $item]);
+ }
+ ?>
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/priceduration.php b/templates/moko-cassiopeia/html/com_osmembership/common/priceduration.php
new file mode 100644
index 0000000..0978186
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/priceduration.php
@@ -0,0 +1,70 @@
+dec_point ?? '.';
+$thousands_sep = $config->thousands_sep ?? ',';
+
+if ($item->lifetime_membership)
+{
+ $subscriptionLengthText = Text::_('OSM_LIFETIME');
+}
+else
+{
+ $subscriptionLengthText = OSMembershipHelperSubscription::getDurationText($item->subscription_length, $item->subscription_length_unit, false);
+}
+
+if ($item->price > 0)
+{
+ $priceParts = explode('.', $item->price);
+
+ if ($priceParts[1] == '00' || $config->decimals === '0')
+ {
+ $numberDecimals = 0;
+ }
+ else
+ {
+ $numberDecimals = 2;
+ }
+
+ $symbol = $item->currency_symbol ?: $item->currency;
+
+ if (!$symbol)
+ {
+ $symbol = $config->currency_symbol;
+ }
+
+ if ($config->currency_position == 0)
+ {
+ echo $symbol . number_format($item->price, $numberDecimals, $dec_point, $thousands_sep) . ($subscriptionLengthText ? "/$subscriptionLengthText " : '');
+ }
+ else
+ {
+ echo number_format($item->price, $numberDecimals, $dec_point, $thousands_sep) . $symbol . ($subscriptionLengthText ? "/$subscriptionLengthText " : '');
+ }
+}
+else
+{
+ echo Text::_('OSM_FREE') . ($subscriptionLengthText ? " /$subscriptionLengthText " : '');
+}
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/pricingtable_circle_plans.php b/templates/moko-cassiopeia/html/com_osmembership/common/pricingtable_circle_plans.php
new file mode 100644
index 0000000..bbf8854
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/pricingtable_circle_plans.php
@@ -0,0 +1,237 @@
+getParams();
+}
+
+if (isset($input) && $input->getInt('recommended_plan_id'))
+{
+ $recommendedPlanId = $input->getInt('recommended_plan_id');
+}
+else
+{
+ $recommendedPlanId = (int) $params->get('recommended_campaign_id');
+}
+
+$standardPlanBackgroundColor = $params->get('standard_plan_color', '#00B69C');
+$recommendedPlanBackgroundColor = $params->get('recommended_plan_color', '#bF75500');
+$showDetailsButton = $params->get('show_details_button', 0);
+
+if (isset($input) && $input->getInt('number_columns'))
+{
+ $numberColumns = $input->getInt('number_columns');
+}
+elseif (isset($config->number_columns))
+{
+ $numberColumns = $config->number_columns;
+}
+else
+{
+ $numberColumns = 3;
+}
+
+$numberColumns = min($numberColumns, 5);
+
+if (!isset($categoryId))
+{
+ $categoryId = 0;
+}
+
+$span = intval(12 / $numberColumns);
+$imgClass = $bootstrapHelper->getClassMapping('img-polaroid');
+$spanClass = $bootstrapHelper->getClassMapping('span' . $span);
+
+$i = 0;
+$numberPlans = count($items);
+$defaultItemId = $Itemid;
+$rootUri = Uri::root(true);
+
+foreach ($items as $item)
+{
+ $Itemid = OSMembershipHelperRoute::getPlanMenuId($item->id, $item->category_id, $defaultItemId);
+
+ if ($item->thumb)
+ {
+ $imgSrc = $rootUri . '/media/com_osmembership/' . $item->thumb;
+ }
+
+ $url = Route::_('index.php?option=com_osmembership&view=plan&catid=' . $item->category_id . '&id=' . $item->id . '&Itemid=' . $Itemid);
+
+ if ($config->use_https)
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid), false, 1);
+ }
+ else
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid));
+ }
+
+ if (!$item->short_description)
+ {
+ $item->short_description = $item->description;
+ }
+
+ if ($item->id == $recommendedPlanId)
+ {
+ $recommended = true;
+ $backgroundColor = $recommendedPlanBackgroundColor;
+ }
+ else
+ {
+ $recommended = false;
+ $backgroundColor = $standardPlanBackgroundColor;
+ }
+
+ if ($i % $numberColumns == 0)
+ {
+ ?>
+
+
+
+
+
+
+ short_description;?>
+
+
+ getLanguage();
+
+ if (in_array('subscribe', $actions))
+ {
+ if ($language->hasKey('OSM_SIGNUP_PLAN_' . $item->id))
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP_PLAN_' . $item->id;
+ }
+ else
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP';
+ }
+
+ if ($language->hasKey('OSM_RENEW_PLAN_' . $item->id))
+ {
+ $renewLanguageItem = 'OSM_RENEW_PLAN_' . $item->id;
+ }
+ else
+ {
+ $renewLanguageItem = 'OSM_RENEW';
+ }
+ ?>
+
+
+ id, $subscribedPlanIds) ? Text::_($renewLanguageItem) : Text::_($signUpLanguageItem); ?>
+
+
+ hasKey('OSM_UPGRADE_PLAN_' . $item->id))
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE_PLAN_' . $item->id;
+ }
+ else
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE';
+ }
+
+ if (count($item->upgrade_rules) > 1)
+ {
+ $link = Route::_('index.php?option=com_osmembership&view=upgrademembership&to_plan_id=' . $item->id . '&Itemid=' . OSMembershipHelperRoute::findView('upgrademembership', $Itemid));
+ }
+ else
+ {
+ $upgradeOptionId = $item->upgrade_rules[0]->id;
+ $link = Route::_('index.php?option=com_osmembership&task=register.process_upgrade_membership&upgrade_option_id=' . $upgradeOptionId . '&Itemid=' . $Itemid);
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ' ;
+}
+?>
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/pricingtable_flat_plans.php b/templates/moko-cassiopeia/html/com_osmembership/common/pricingtable_flat_plans.php
new file mode 100644
index 0000000..b69920b
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/pricingtable_flat_plans.php
@@ -0,0 +1,233 @@
+getParams();
+}
+
+if (isset($input) && $input->getInt('recommended_plan_id'))
+{
+ $recommendedPlanId = $input->getInt('recommended_plan_id');
+}
+else
+{
+ $recommendedPlanId = (int) $params->get('recommended_campaign_id');
+}
+
+$standardPlanBackgroundColor = $params->get('standard_plan_color', '#00B69C');
+$recommendedPlanBackgroundColor = $params->get('recommended_plan_color', '#F75500');
+$showDetailsButton = $params->get('show_details_button', 0);
+
+if (isset($input) && $input->getInt('number_columns'))
+{
+ $numberColumns = $input->getInt('number_columns');
+}
+elseif (isset($config->number_columns))
+{
+ $numberColumns = $config->number_columns;
+}
+else
+{
+ $numberColumns = 3;
+}
+
+$numberColumns = min($numberColumns, 5);
+
+if (!isset($categoryId))
+{
+ $categoryId = 0;
+}
+
+$span = intval(12 / $numberColumns);
+$imgClass = $bootstrapHelper->getClassMapping('img-polaroid');
+$spanClass = $bootstrapHelper->getClassMapping('span' . $span);
+
+$i = 0;
+$numberPlans = count($items);
+$defaultItemId = $Itemid;
+$rootUri = Uri::root(true);
+
+foreach ($items as $item)
+{
+ $Itemid = OSMembershipHelperRoute::getPlanMenuId($item->id, $item->category_id, $defaultItemId);
+
+ if ($item->thumb)
+ {
+ $imgSrc = $rootUri . '/media/com_osmembership/' . $item->thumb;
+ }
+
+ $url = Route::_('index.php?option=com_osmembership&view=plan&catid=' . $item->category_id . '&id=' . $item->id . '&Itemid=' . $Itemid);
+
+ if ($config->use_https)
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid), false, 1);
+ }
+ else
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid));
+ }
+
+ if (!$item->short_description)
+ {
+ $item->short_description = $item->description;
+ }
+
+ if ($item->id == $recommendedPlanId)
+ {
+ $recommended = true;
+ $backgroundColor = $recommendedPlanBackgroundColor;
+ }
+ else
+ {
+ $recommended = false;
+ $backgroundColor = $standardPlanBackgroundColor;
+ }
+
+ if ($i % $numberColumns == 0)
+ {
+ ?>
+
+
+
+
+
+
+
+ short_description;?>
+
+
+ getLanguage();
+
+ if (in_array('subscribe', $actions))
+ {
+ if ($language->hasKey('OSM_SIGNUP_PLAN_' . $item->id))
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP_PLAN_' . $item->id;
+ }
+ else
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP';
+ }
+
+ if ($language->hasKey('OSM_RENEW_PLAN_' . $item->id))
+ {
+ $renewLanguageItem = 'OSM_RENEW_PLAN_' . $item->id;
+ }
+ else
+ {
+ $renewLanguageItem = 'OSM_RENEW';
+ }
+ ?>
+
+
+ id, $subscribedPlanIds) ? Text::_($renewLanguageItem) : Text::_($signUpLanguageItem); ?>
+
+
+ hasKey('OSM_UPGRADE_PLAN_' . $item->id))
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE_PLAN_' . $item->id;
+ }
+ else
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE';
+ }
+
+ if (count($item->upgrade_rules) > 1)
+ {
+ $link = Route::_('index.php?option=com_osmembership&view=upgrademembership&to_plan_id=' . $item->id . '&Itemid=' . OSMembershipHelperRoute::findView('upgrademembership', $Itemid));
+ }
+ else
+ {
+ $upgradeOptionId = $item->upgrade_rules[0]->id;
+ $link = Route::_('index.php?option=com_osmembership&task=register.process_upgrade_membership&upgrade_option_id=' . $upgradeOptionId . '&Itemid=' . $Itemid);
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ' ;
+}
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/pricingtable_plans.php b/templates/moko-cassiopeia/html/com_osmembership/common/pricingtable_plans.php
new file mode 100644
index 0000000..4e3e9f4
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/pricingtable_plans.php
@@ -0,0 +1,261 @@
+getParams();
+}
+
+// Background color settings
+$badgeBgColor = $params->get('recommended_badge_background_color');
+$headerBgColor = $params->get('header_background_color');
+$priceBgColor = $params->get('price_background_color');
+$recommendedPriceBgColor = $params->get('recommended_plan_price_background_color');
+
+if (isset($input) && $input->getInt('recommended_plan_id'))
+{
+ $recommendedPlanId = $input->getInt('recommended_plan_id');
+}
+else
+{
+ $recommendedPlanId = (int) $params->get('recommended_campaign_id');
+}
+
+$showDetailsButton = $params->get('show_details_button', 0);
+
+if (isset($input) && $input->getInt('number_columns'))
+{
+ $numberColumns = $input->getInt('number_columns');
+}
+elseif (isset($config->number_columns))
+{
+ $numberColumns = $config->number_columns ;
+}
+else
+{
+ $numberColumns = 3 ;
+}
+
+$numberColumns = min($numberColumns, 4);
+
+if (!isset($categoryId))
+{
+ $categoryId = 0;
+}
+
+$span = intval(12 / $numberColumns);
+
+$btnClass = $bootstrapHelper->getClassMapping('btn');
+$btnPrimaryClass = $bootstrapHelper->getClassMapping('btn btn-primary');
+$imgClass = $bootstrapHelper->getClassMapping('img-polaroid');
+$spanClass = $bootstrapHelper->getClassMapping('span' . $span);
+
+$rootUri = Uri::root(true);
+$i = 0;
+$numberPlans = count($items);
+$defaultItemId = $Itemid;
+
+foreach ($items as $item)
+{
+ $Itemid = OSMembershipHelperRoute::getPlanMenuId($item->id, $item->category_id, $defaultItemId);
+
+ if ($item->thumb)
+ {
+ $imgSrc = $rootUri . '/media/com_osmembership/' . $item->thumb;
+ }
+
+ $url = Route::_('index.php?option=com_osmembership&view=plan&catid=' . $item->category_id . '&id=' . $item->id . '&Itemid=' . $Itemid);
+
+ if ($config->use_https)
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid), false, 1);
+ }
+ else
+ {
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $Itemid));
+ }
+
+ if (!$item->short_description)
+ {
+ $item->short_description = $item->description;
+ }
+
+ if ($item->id == $recommendedPlanId)
+ {
+ $recommended = true;
+ }
+ else
+ {
+ $recommended = false;
+ }
+
+ if ($recommended && $recommendedPriceBgColor)
+ {
+ $planPriceBackgroundColor = $recommendedPriceBgColor;
+ }
+ elseif ($priceBgColor)
+ {
+ $planPriceBackgroundColor = $priceBgColor;
+ }
+ else
+ {
+ $planPriceBackgroundColor = '';
+ }
+
+ if ($i % $numberColumns == 0)
+ {
+ ?>
+
+
+
+
+
+
>
+
+
+
>
+
+
+ $item]); ?>
+
+
+
+
+ short_description;?>
+
+ getLanguage();
+ ?>
+
+ hasKey('OSM_SIGNUP_PLAN_' . $item->id))
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP_PLAN_' . $item->id;
+ }
+ else
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP';
+ }
+
+ if ($language->hasKey('OSM_RENEW_PLAN_' . $item->id))
+ {
+ $renewLanguageItem = 'OSM_RENEW_PLAN_' . $item->id;
+ }
+ else
+ {
+ $renewLanguageItem = 'OSM_RENEW';
+ }
+ ?>
+
+
+ id, $subscribedPlanIds) ? Text::_($renewLanguageItem) : Text::_($signUpLanguageItem); ?>
+
+
+ hasKey('OSM_UPGRADE_PLAN_' . $item->id))
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE_PLAN_' . $item->id;
+ }
+ else
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE';
+ }
+
+ if (count($item->upgrade_rules) > 1)
+ {
+ $link = Route::_('index.php?option=com_osmembership&view=upgrademembership&to_plan_id=' . $item->id . '&Itemid=' . OSMembershipHelperRoute::findView('upgrademembership', $Itemid));
+ }
+ else
+ {
+ $upgradeOptionId = $item->upgrade_rules[0]->id;
+ $link = Route::_('index.php?option=com_osmembership&task=register.process_upgrade_membership&upgrade_option_id=' . $upgradeOptionId . '&Itemid=' . $Itemid);
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ' ;
+}
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/renew_options.php b/templates/moko-cassiopeia/html/com_osmembership/common/renew_options.php
new file mode 100644
index 0000000..05b8822
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/renew_options.php
@@ -0,0 +1,129 @@
+
+
+ getIdentity()->id;
+ $renewOptionCount = 0;
+ $fieldSuffix = OSMembershipHelper::getFieldSuffix();
+
+ foreach ($this->planIds as $planId)
+ {
+ $plan = $this->plans[$planId];
+ $taxRate = 0;
+
+ if ($this->config->show_price_including_tax && !$this->config->setup_price_including_tax)
+ {
+ $taxRate = OSMembershipHelper::calculateMaxTaxRate($planId);
+ }
+
+ $symbol = $plan->currency_symbol ?: $plan->currency;
+ $renewOptions = $this->renewOptions[$planId] ?? [];
+
+ if (count($renewOptions))
+ {
+ foreach ($renewOptions as $renewOption)
+ {
+ $checked = '';
+
+ if ($renewOptionCount == 0)
+ {
+ $checked = ' checked="checked" ';
+ }
+
+ $renewOptionCount++;
+ $renewOptionLengthText = OSMembershipHelperSubscription::getDurationText($renewOption->renew_option_length, $renewOption->renew_option_length_unit);
+
+ $renewOptionText = Text::sprintf('OSM_RENEW_OPTION_TEXT', $plan->title, $renewOptionLengthText, OSMembershipHelper::formatCurrency($renewOption->price * (1 + $taxRate / 100), $this->config, $symbol));
+
+ if (strpos($renewOptionText, '[EXPIRED_DATE]'))
+ {
+ $expiredDate = OSMembershipHelperSubscription::getPlanExpiredDate($planId);
+
+ if ($expiredDate)
+ {
+ $expiredDate = HTMLHelper::_('date', $expiredDate, $this->config->date_format);
+ }
+
+ $renewOptionText = str_replace('[EXPIRED_DATE]', $expiredDate, $renewOptionText);
+ }
+ ?>
+
+ />
+
+
+ subscription_length, $plan->subscription_length_unit);
+
+ $renewalDiscountRule = OSMembershipHelperSubscription::getRenewalDiscount($userId, $planId);
+
+ if ($renewalDiscountRule)
+ {
+ if ($renewalDiscountRule->discount_type == 0)
+ {
+ $plan->price = round($plan->price * (1 - $renewalDiscountRule->discount_amount / 100), 2);
+ }
+ else
+ {
+ $plan->price = $plan->price - $renewalDiscountRule->discount_amount;
+ }
+
+ if ($plan->price < 0)
+ {
+ $plan->price = 0;
+ }
+ }
+
+ $renewOptionText = Text::sprintf('OSM_RENEW_OPTION_TEXT', $plan->title, $subscriptionLengthText, OSMembershipHelper::formatCurrency($plan->price * (1 + $taxRate / 100), $this->config, $symbol));
+
+ if (strpos($renewOptionText, '[EXPIRED_DATE]'))
+ {
+ $expiredDate = OSMembershipHelperSubscription::getPlanExpiredDate($plan->id);
+
+ if ($expiredDate)
+ {
+ $expiredDate = HTMLHelper::_('date', $expiredDate, $this->config->date_format);
+ }
+
+ $renewOptionText = str_replace('[EXPIRED_DATE]', $expiredDate, $renewOptionText);
+ }
+ ?>
+
+ />
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/restrictionmsg.php b/templates/moko-cassiopeia/html/com_osmembership/common/restrictionmsg.php
new file mode 100644
index 0000000..a020cfa
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/restrictionmsg.php
@@ -0,0 +1,31 @@
+' . $introText . '';
+}
+?>
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/subscriptions_history.php b/templates/moko-cassiopeia/html/com_osmembership/common/subscriptions_history.php
new file mode 100644
index 0000000..89abd4b
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/subscriptions_history.php
@@ -0,0 +1,176 @@
+get('db');
+$query = $db->getQuery(true)
+ ->select('COUNT(*)')
+ ->from('#__osmembership_plugins')
+ ->where('published = 1')
+ ->where('name NOT LIKE "os_offline%"');
+$db->setQuery($query);
+$hasOnlinePaymentPlugin = $db->loadResult() > 0;
+
+$makePaymentItemid = OSMembershipHelperRoute::getViewRoute('payment', $this->Itemid);
+
+$cols = 5;
+
+$bootstrapHelper = OSMembershipHelperBootstrap::getInstance();
+$centerClass = $bootstrapHelper->getClassMapping('center');
+$hiddenPhoneClass = $bootstrapHelper->getClassMapping('hidden-phone');
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ config->activate_invoice_feature)
+ {
+ $cols++ ;
+ ?>
+
+
+
+
+
+
+
+ items) ; $i < $n ; $i++) {
+ $row = $this->items[$i];
+ $k = 1 - $k;
+ $link = Route::_('index.php?option=com_osmembership&view=subscription&id=' . $row->id . '&Itemid=' . $this->Itemid);
+ $symbol = $row->currency_symbol ?: $row->currency;
+ ?>
+
+
+ plan_title; ?>
+
+
+ created_date, $this->config->date_format); ?>
+
+
+ from_date, $this->config->date_format); ?>
+
+ lifetime_membership || $row->to_date == '2099-12-31 23:59:59')
+ {
+ echo Text::_('OSM_LIFETIME');
+ }
+ else
+ {
+ echo HTMLHelper::_('date', $row->to_date, $this->config->date_format);
+ }
+ ?>
+
+
+
+ gross_amount, $this->config, $symbol)?>
+
+
+ published)
+ {
+ case 0 :
+ echo Text::_('OSM_PENDING');
+
+ if ($this->config->enable_subscription_payment && $row->gross_amount > 0 && $hasOnlinePaymentPlugin)
+ {
+ ?>
+
+
+
+ config->activate_invoice_feature)
+ {
+ ?>
+
+ invoice_number)
+ {
+ ?>
+ config); ?>
+
+
+
+
+
+
+ total > $pagination->limit))
+ {
+ ?>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/subscriptions_pdf.php b/templates/moko-cassiopeia/html/com_osmembership/common/subscriptions_pdf.php
new file mode 100644
index 0000000..fd626e3
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/subscriptions_pdf.php
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+ No
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ first_name; ?>
+ last_name; ?>
+ plan; ?>
+ from_date . ' / ' . $row->to_date; ?>
+ email; ?>
+ created_date; ?>
+ amount; ?>
+
+ published)
+ {
+ case 0:
+ echo Text::_('OSM_PENDING');
+ break;
+ case 1:
+ echo Text::_('OSM_ACTIVE');
+ break;
+ case 2:
+ echo Text::_('OSM_EXPIRED');
+ break;
+ case 3 :
+ echo Text::_('OSM_CANCELLED_PENDING');
+ break ;
+ case 4 :
+ echo Text::_('OSM_CANCELLED_REFUNDED');
+ break ;
+ }
+ ?>
+
+ id; ?>
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/common/upgrade_options.php b/templates/moko-cassiopeia/html/com_osmembership/common/upgrade_options.php
new file mode 100644
index 0000000..f27993a
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/common/upgrade_options.php
@@ -0,0 +1,48 @@
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/index.html b/templates/moko-cassiopeia/html/com_osmembership/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default.php
new file mode 100644
index 0000000..9c549e5
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default.php
@@ -0,0 +1,141 @@
+ true, 'sanitize' => false]);
+
+$config = OSMembershipHelper::getConfig();
+$editor = Editor::getInstance($config->get('editor') ?: Factory::getApplication()->get('editor'));
+$translatable = Multilanguage::isEnabled() && count($this->languages);
+$bootstrapHelper = OSMembershipHelperBootstrap::getInstance();
+$rowFluid = $bootstrapHelper->getClassMapping('row-fluid');
+$span8 = $bootstrapHelper->getClassMapping('span7');
+$span4 = $bootstrapHelper->getClassMapping('span5');
+
+HTMLHelper::_('formbehavior.chosen', '.advSelect');
+
+Factory::getApplication()
+ ->getDocument()
+ ->getWebAssetManager()
+ ->useScript('core')
+ ->useScript('showon')
+ ->registerAndUseScript('com_osmembership.site-mplan-default', 'media/com_osmembership/js/site-mplan-default.min.js');
+
+$keys = ['OSM_ENTER_PLAN_TITLE', 'OSM_ENTER_SUBSCRIPTION_LENGTH', 'OSM_PRICE_REQUIRED', 'OSM_INVALID_SUBSCRIPTION_LENGTH'];
+OSMembershipHelperHtml::addJSStrings($keys);
+?>
+
+
item->id > 0 ? Text::_('OSM_EDIT_PLAN') : Text::_('OSM_ADD_PLAN'); ?>
+
+ render(); ?>
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_advanced_settings.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_advanced_settings.php
new file mode 100644
index 0000000..52635ba
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_advanced_settings.php
@@ -0,0 +1,173 @@
+getClassMapping('row-fluid');
+$controlGroupClass = $bootstrapHelper->getClassMapping('control-group');
+$controlLabelClass = $bootstrapHelper->getClassMapping('control-label');
+$controlsClass = $bootstrapHelper->getClassMapping('controls');
+?>
+
+item->id && !$this->item->recurring_subscription)
+{
+?>
+
+
+
+
+
+ lists['subscription_start_date_option'];?>
+
+
+ '1']); ?>'>
+
+
+
+
+ planParams->get('subscription_start_date'), 'subscription_start_date', 'subscription_start_date', '%Y-%m-%d %H:%M:%S') ; ?>
+
+
+ '2']); ?>'>
+
+
+
+
+ lists['subscription_start_date_field'];?>
+
+
+
+
+
+
+
+
+ lists['free_plan_subscription_status'];?>
+
+
+
+
+
+
+
+ lists['login_redirect_menu_id']; ?>
+
+
+
+
+
+
+
+ lists['number_fields_per_row']; ?>
+
+
+
+
+
+
+
+ lists['payment_methods'];?>
+
+
+
+
+
+
+
+ lists['currency'];?>
+
+
+
+
+
+
+
+
+
+
+
+
+ item->publish_up, 'publish_up', 'publish_up', $this->datePickerFormat . ' %H:%M:%S', ['class' => 'input-medium']); ?>
+
+
+
+
+
+
+
+ item->publish_down, 'publish_down', 'publish_down', $this->datePickerFormat . ' %H:%M:%S', ['class' => 'input-medium']); ?>
+
+
+
+
+
+
+
+ item->terms_and_conditions_article_id, 'terms_and_conditions_article_id'); ?>
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_general.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_general.php
new file mode 100644
index 0000000..9ec11c0
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_general.php
@@ -0,0 +1,166 @@
+getClassMapping('row-fluid');
+$controlGroupClass = $bootstrapHelper->getClassMapping('control-group');
+$controlLabelClass = $bootstrapHelper->getClassMapping('control-label');
+$controlsClass = $bootstrapHelper->getClassMapping('controls');
+?>
+
+
+
+
+
+
+
+ lists['category_id']; ?>
+
+
+
+
+
+
+
+
+ lists['subscription_length_unit']; ?>
+
+
+
+
+
+
+
+ item->expired_date, 'expired_date', 'expired_date', $this->datePickerFormat) ; ?>
+
+
+item->expired_date)
+{
+?>
+
+
+
+
+
+ lists['prorated_signup_cost'];?>
+
+
+
+
+
+
+
+
+
+ lists['lifetime_membership'];?>
+
+
+
+
+
+
+
+
+ lists['enable_renewal']; ?>
+
+
+
+
+
+
+
+ lists['access']; ?>
+
+
+lists['published']))
+ {
+ ?>
+
+
+
+
+
+ lists['published']; ?>
+
+
+
+
+
+
+
+
+ display('short_description', $this->item->short_description, '100%', '250', '75', '10') ; ?>
+
+
+
+
+
+
+
+ display('description', $this->item->description, '100%', '250', '75', '10') ; ?>
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_group_membership.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_group_membership.php
new file mode 100644
index 0000000..41c26a8
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_group_membership.php
@@ -0,0 +1,45 @@
+getClassMapping('row-fluid');
+$controlGroupClass = $bootstrapHelper->getClassMapping('control-group');
+$controlLabelClass = $bootstrapHelper->getClassMapping('control-label');
+$controlsClass = $bootstrapHelper->getClassMapping('controls');
+?>
+
+
+
+
+
+ lists['number_members_type']; ?>
+
+
+ '0']); ?>'>
+
+
+
+
+
+
+
+ '1']); ?>'>
+
+
+
+
+ lists['number_members_field']; ?>
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_member_card.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_member_card.php
new file mode 100644
index 0000000..1c2fe3c
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_member_card.php
@@ -0,0 +1,46 @@
+getClassMapping('row-fluid');
+$controlGroupClass = $bootstrapHelper->getClassMapping('control-group');
+$controlLabelClass = $bootstrapHelper->getClassMapping('control-label');
+$controlsClass = $bootstrapHelper->getClassMapping('controls');
+
+?>
+
+
+
+
+
+ item->activate_member_card_feature); ?>
+
+
+
+
+
+
+
+ item->card_bg_image, 'card_bg_image'); ?>
+
+
+
+
+
+
+
+ display('card_layout', $this->item->card_layout, '100%', '550', '75', '8') ;?>
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_messages.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_messages.php
new file mode 100644
index 0000000..fae9e81
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_messages.php
@@ -0,0 +1,194 @@
+getClassMapping('row-fluid');
+$controlGroupClass = $bootstrapHelper->getClassMapping('control-group');
+$controlLabelClass = $bootstrapHelper->getClassMapping('control-label');
+$controlsClass = $bootstrapHelper->getClassMapping('controls');
+?>
+
+
+
+
+
+
+ display('subscription_form_message', $this->item->subscription_form_message, '100%', '250', '75', '10'); ?>
+
+
+
+
+
+
+
+
+ display('user_email_body', $this->item->user_email_body, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('user_email_body_offline', $this->item->user_email_body_offline, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('admin_email_body', $this->item->admin_email_body, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('thanks_message', $this->item->thanks_message, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('thanks_message_offline', $this->item->thanks_message_offline, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+
+ display('subscription_approved_email_body', $this->item->subscription_approved_email_body, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+
+ display('user_renew_email_body', $this->item->user_renew_email_body, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('user_renew_email_body_offline', $this->item->user_renew_email_body_offline, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('admin_renew_email_body', $this->item->admin_renew_email_body, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('user_upgrade_email_body', $this->item->user_upgrade_email_body, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('user_upgrade_email_body_offline', $this->item->user_upgrade_email_body_offline, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('admin_upgrade_email_body', $this->item->admin_upgrade_email_body, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('renew_thanks_message', $this->item->renew_thanks_message, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('renew_thanks_message_offline', $this->item->renew_thanks_message_offline, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('upgrade_thanks_message', $this->item->upgrade_thanks_message, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('upgrade_thanks_message_offline', $this->item->upgrade_thanks_message_offline, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('invoice_layout', $this->item->invoice_layout, '100%', '250', '75', '8'); ?>
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_metadata.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_metadata.php
new file mode 100644
index 0000000..3028781
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_metadata.php
@@ -0,0 +1,56 @@
+getClassMapping('row-fluid');
+$controlGroupClass = $bootstrapHelper->getClassMapping('control-group');
+$controlLabelClass = $bootstrapHelper->getClassMapping('control-label');
+$controlsClass = $bootstrapHelper->getClassMapping('controls');
+?>
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_recurring_settings.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_recurring_settings.php
new file mode 100644
index 0000000..9c17b56
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_recurring_settings.php
@@ -0,0 +1,81 @@
+getClassMapping('row-fluid');
+$controlGroupClass = $bootstrapHelper->getClassMapping('control-group');
+$controlLabelClass = $bootstrapHelper->getClassMapping('control-label');
+$controlsClass = $bootstrapHelper->getClassMapping('controls');
+?>
+
+
+
+
+
+
+ lists['recurring_subscription']; ?>
+
+
+ '1']); ?>'>
+
+
+
+
+
+
+
+ '1']); ?>'>
+
+
+
+
+
+ lists['trial_duration_unit']; ?>
+
+
+ '1']); ?>'>
+
+
+
+
+
+
+
+
+ item->number_payments > 0)
+ {
+ ?>
+
+
+
+
+
+ lists['last_payment_action']; ?>
+
+
+ '2']); ?>'>
+
+
+
+
+
+ lists['extend_duration_unit']; ?>
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_reminder_messages.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_reminder_messages.php
new file mode 100644
index 0000000..8c72f6b
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_reminder_messages.php
@@ -0,0 +1,75 @@
+getClassMapping('row-fluid');
+$controlGroupClass = $bootstrapHelper->getClassMapping('control-group');
+$controlLabelClass = $bootstrapHelper->getClassMapping('control-label');
+$controlsClass = $bootstrapHelper->getClassMapping('controls');
+?>
+
+
+
+
+
+
+
+ display('first_reminder_email_body', $this->item->first_reminder_email_body, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+
+ display('second_reminder_email_body', $this->item->second_reminder_email_body, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+
+ display('third_reminder_email_body', $this->item->third_reminder_email_body, '100%', '250', '75', '8'); ?>
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_reminders_settings.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_reminders_settings.php
new file mode 100644
index 0000000..051c8a1
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_reminders_settings.php
@@ -0,0 +1,62 @@
+getClassMapping('row-fluid');
+$controlGroupClass = $bootstrapHelper->getClassMapping('control-group');
+$controlLabelClass = $bootstrapHelper->getClassMapping('control-label');
+$controlsClass = $bootstrapHelper->getClassMapping('controls');
+?>
+
+
+
+
+
+
+ lists['send_first_reminder_time']; ?>
+
+
+
+
+
+
+
+ lists['send_second_reminder_time']; ?>
+
+
+
+
+
+
+
+ lists['send_third_reminder_time']; ?>
+
+
+ item->number_payments > 0)
+ {
+ ?>
+
+
+
+
+
+ lists['send_subscription_end_time']; ?>
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_renew_options.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_renew_options.php
new file mode 100644
index 0000000..7513c9c
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_renew_options.php
@@ -0,0 +1,34 @@
+prices as $renewOption)
+{
+ $formData['renew_options'][] = [
+ 'id' => $renewOption->id,
+ 'renew_option_length' => $renewOption->renew_option_length,
+ 'renew_option_length_unit' => $renewOption->renew_option_length_unit,
+ 'price' => $renewOption->price,
+ ];
+}
+
+$form->bind($formData);
+
+foreach ($form->getFieldset() as $field)
+{
+ echo $field->input;
+}
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_renewal_discounts.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_renewal_discounts.php
new file mode 100644
index 0000000..825f088
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_renewal_discounts.php
@@ -0,0 +1,34 @@
+renewalDiscounts as $renewalDiscount)
+{
+ $formData['renewal_discounts'][] = [
+ 'id' => $renewalDiscount->id,
+ 'number_days' => $renewalDiscount->number_days,
+ 'discount_type' => $renewalDiscount->discount_type,
+ 'discount_amount' => $renewalDiscount->discount_amount,
+ ];
+}
+
+$form->bind($formData);
+
+foreach ($form->getFieldset() as $field)
+{
+ echo $field->input;
+}
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/default_translation.php b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_translation.php
new file mode 100644
index 0000000..64cf5e4
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/default_translation.php
@@ -0,0 +1,223 @@
+getClassMapping('row-fluid');
+$controlGroupClass = $bootstrapHelper->getClassMapping('control-group');
+$controlLabelClass = $bootstrapHelper->getClassMapping('control-label');
+$controlsClass = $bootstrapHelper->getClassMapping('controls');
+
+echo HTMLHelper::_('bootstrap.startTabSet', 'plan-translation', ['active' => 'translation-page-' . $this->languages[0]->sef, 'recall' => true]);
+
+foreach ($this->languages as $language)
+{
+ $sef = $language->sef;
+ echo HTMLHelper::_('bootstrap.addTab', 'plan-translation', 'translation-page-' . $sef, $language->title . ' ');
+ ?>
+
+
+
+
+
+
+
+ display('short_description_' . $sef, $this->item->{'short_description_' . $sef}, '100%', '250', '75', '10') ; ?>
+
+
+
+
+
+
+
+ display('description_' . $sef, $this->item->{'description_' . $sef}, '100%', '250', '75', '10') ; ?>
+
+
+
+
+
+
+
+
+
+
+
+
+ display('subscription_form_message_' . $sef, $this->item->{'subscription_form_message_' . $sef}, '100%', '250', '75', '10') ; ?>
+
+
+
+
+
+
+
+
+ display('user_email_body_' . $sef, $this->item->{'user_email_body_' . $sef}, '100%', '250', '75', '8') ;?>
+
+
+
+
+
+
+
+ display('user_email_body_offline_' . $sef, $this->item->{'user_email_body_offline_' . $sef}, '100%', '250', '75', '8') ;?>
+
+
+
+
+
+
+
+ display('thanks_message_' . $sef, $this->item->{'thanks_message_' . $sef}, '100%', '250', '75', '8') ;?>
+
+
+
+
+
+
+
+ display('thanks_message_offline_' . $sef, $this->item->{'thanks_message_offline_' . $sef}, '100%', '250', '75', '8') ;?>
+
+
+
+
+
+
+
+
+ display('subscription_approved_email_body_' . $sef, $this->item->{'subscription_approved_email_body_' . $sef}, '100%', '250', '75', '8') ;?>
+
+
+
+
+
+
+
+
+
+
+ display('user_renew_email_body_' . $sef, $this->item->{'user_renew_email_body_' . $sef}, '100%', '250', '75', '8') ;?>
+
+
+
+
+
+
+
+ display('renew_thanks_message_' . $sef, $this->item->{'renew_thanks_message_' . $sef}, '100%', '250', '75', '8') ;?>
+
+
+
+
+
+
+
+ display('renew_thanks_message_offline_' . $sef, $this->item->{'renew_thanks_message_offline_' . $sef}, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('upgrade_thanks_message_' . $sef, $this->item->{'upgrade_thanks_message_' . $sef}, '100%', '250', '75', '8'); ?>
+
+
+
+
+
+
+
+ display('upgrade_thanks_message_offline_' . $sef, $this->item->{'upgrade_thanks_message_offline_' . $sef}, '100%', '250', '75', '8'); ?>
+
+
+
+ getClassMapping('row-fluid');
+$controlGroupClass = $bootstrapHelper->getClassMapping('control-group');
+$controlLabelClass = $bootstrapHelper->getClassMapping('control-label');
+$controlsClass = $bootstrapHelper->getClassMapping('controls');
+
+$form = Form::getInstance('upgrade_options', JPATH_ADMINISTRATOR . '/components/com_osmembership/view/plan/forms/upgrade_options.xml');
+$formData['upgrade_options'] = [];
+
+foreach ($this->upgradeRules as $upgradeOption)
+{
+ $formData['upgrade_options'][] = [
+ 'id' => $upgradeOption->id,
+ 'to_plan_id' => $upgradeOption->to_plan_id,
+ 'price' => $upgradeOption->price,
+ 'upgrade_prorated' => $upgradeOption->upgrade_prorated,
+ 'published' => $upgradeOption->published,
+ ];
+}
+
+$form->bind($formData);
+
+foreach ($form->getFieldset() as $field)
+{
+ echo $field->input;
+}
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplan/index.html b/templates/moko-cassiopeia/html/com_osmembership/mplan/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplan/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplans/default.php b/templates/moko-cassiopeia/html/com_osmembership/mplans/default.php
new file mode 100644
index 0000000..b9237cc
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplans/default.php
@@ -0,0 +1,238 @@
+getClassMapping('center');
+$cols = 10;
+$config = OSMembershipHelper::getConfig();
+?>
+
+ params->get('show_page_heading', 1))
+ {
+ if ($this->input->getInt('hmvc_call'))
+ {
+ $hTag = 'h2';
+ }
+ else
+ {
+ $hTag = 'h1';
+ }
+ ?>
+ < class="osm-heading">>
+ params->get('intro_text')))
+ {
+ ?>
+
+ params->get('intro_text')); ?>
+
+
+
+ render(); ?>
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplans/default_search_bar.bootstrap4.php b/templates/moko-cassiopeia/html/com_osmembership/mplans/default_search_bar.bootstrap4.php
new file mode 100644
index 0000000..8318353
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplans/default_search_bar.bootstrap4.php
@@ -0,0 +1,39 @@
+bootstrapHelper->getClassMapping('pull-left');
+?>
+
+
+ lists['filter_category_id']))
+ {
+ echo $this->lists['filter_category_id'];
+ }
+
+ echo $this->lists['filter_state'];
+ echo $this->pagination->getLimitBox();
+ ?>
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplans/default_search_bar.php b/templates/moko-cassiopeia/html/com_osmembership/mplans/default_search_bar.php
new file mode 100644
index 0000000..f1800d4
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplans/default_search_bar.php
@@ -0,0 +1,38 @@
+bootstrapHelper->getClassMapping('pull-left');
+?>
+
+
+
+
+
+
+
+
+
+ lists['filter_category_id']))
+ {
+ echo $this->lists['filter_category_id'];
+ }
+
+ echo $this->lists['filter_state'];
+
+ echo $this->pagination->getLimitBox();
+ ?>
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/mplans/index.html b/templates/moko-cassiopeia/html/com_osmembership/mplans/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/mplans/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/plan/default.php b/templates/moko-cassiopeia/html/com_osmembership/plan/default.php
new file mode 100644
index 0000000..8643c8a
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/plan/default.php
@@ -0,0 +1,176 @@
+item;
+
+$clearfixClass = $this->bootstrapHelper->getClassMapping('clearfix');
+
+if ($item->thumb)
+{
+ $imgSrc = Uri::base() . 'media/com_osmembership/' . $item->thumb;
+}
+
+if ($this->config->use_https)
+{
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $this->Itemid), false, 1);
+}
+else
+{
+ $signUpUrl = Route::_(OSMembershipHelperRoute::getSignupRoute($item->id, $this->Itemid));
+}
+
+$subscribedPlanIds = OSMembershipHelperSubscription::getSubscribedPlans();
+
+$showPlanInformation = $this->params->get('show_plan_information', 1);
+$planInformationPosition = $this->params->get('plan_information_position', 0);
+
+if ($showPlanInformation && $planInformationPosition == 0)
+{
+ $leftClass = $this->bootstrapHelper->getClassMapping('span7');
+ $rightClass = $this->bootstrapHelper->getClassMapping('span5');
+}
+else
+{
+ $leftClass = $this->bootstrapHelper->getClassMapping('clearfix');
+ $rightClass = $this->bootstrapHelper->getClassMapping('clearfix');
+}
+?>
+
+
+
+ params->get('page_heading'); ?>
+
+
+
+
+
+
+ $item]); ?>
+
+
+
+ thumb)
+ {
+ ?>
+
+ description)
+ {
+ echo $item->description;
+ }
+ else
+ {
+ echo $item->short_description;
+ }
+ ?>
+
+
+
+ $item]); ?>
+
+
+
+
+ renewOptions) || count($this->upgradeRules))
+ {
+ echo $this->loadTemplate('renew_upgrade');
+ }
+ ?>
+
+
+ getLanguage();
+
+ if (in_array('subscribe', $actions))
+ {
+ if ($language->hasKey('OSM_SIGNUP_PLAN_' . $item->id))
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP_PLAN_' . $item->id;
+ }
+ else
+ {
+ $signUpLanguageItem = 'OSM_SIGNUP';
+ }
+
+ if ($language->hasKey('OSM_RENEW_PLAN_' . $item->id))
+ {
+ $renewLanguageItem = 'OSM_RENEW_PLAN_' . $item->id;
+ }
+ else
+ {
+ $renewLanguageItem = 'OSM_RENEW';
+ }
+ ?>
+
+
+ id, $subscribedPlanIds) ? Text::_($renewLanguageItem) : Text::_($signUpLanguageItem); ?>
+
+
+ hasKey('OSM_UPGRADE_PLAN_' . $item->id))
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE_PLAN_' . $item->id;
+ }
+ else
+ {
+ $upgradeLanguageItem = 'OSM_UPGRADE';
+ }
+
+ if (count($item->upgrade_rules) > 1)
+ {
+ $link = Route::_('index.php?option=com_osmembership&view=upgrademembership&to_plan_id=' . $item->id . '&Itemid=' . OSMembershipHelperRoute::findView('upgrademembership', $this->Itemid));
+ }
+ else
+ {
+ $upgradeOptionId = $item->upgrade_rules[0]->id;
+ $link = Route::_('index.php?option=com_osmembership&task=register.process_upgrade_membership&upgrade_option_id=' . $upgradeOptionId . '&Itemid=' . $this->Itemid);
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/plan/default_renew_upgrade.php b/templates/moko-cassiopeia/html/com_osmembership/plan/default_renew_upgrade.php
new file mode 100644
index 0000000..2176c55
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/plan/default_renew_upgrade.php
@@ -0,0 +1,45 @@
+
+
+ renewOptions))
+ {
+ ?>
+
+ upgradeRules))
+ {
+ ?>
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/plan/index.html b/templates/moko-cassiopeia/html/com_osmembership/plan/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/plan/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/plans/columns.php b/templates/moko-cassiopeia/html/com_osmembership/plans/columns.php
new file mode 100644
index 0000000..bcee22a
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/plans/columns.php
@@ -0,0 +1,84 @@
+
+
+ params->get('show_page_heading', 1))
+ {
+ if ($this->category)
+ {
+ $pageHeading = $this->params->get('page_heading') ?: $this->category->title;
+ }
+ else
+ {
+ $pageHeading = $this->params->get('page_heading') ?: Text::_('OSM_SUBSCRIPTION_PLANS');
+ }
+
+ if ($this->input->getInt('hmvc_call'))
+ {
+ $hTag = 'h2';
+ }
+ else
+ {
+ $hTag = 'h1';
+ }
+ ?>
+ < class="osm-page-title">>
+ category->description))
+ {
+ $description = $this->category->description;
+ }
+ elseif (OSMembershipHelper::isValidMessage($this->params->get('intro_text')))
+ {
+ $description = $this->params->get('intro_text');
+ }
+ else
+ {
+ $description = '';
+ }
+
+ if ($description)
+ {
+ ?>
+
+
+
+ categories))
+ {
+ echo OSMembershipHelperHtml::loadCommonLayout('common/tmpl/categories.php', ['items' => $this->categories, 'categoryId' => $this->categoryId, 'config' => $this->config, 'Itemid' => $this->Itemid]);
+ }
+
+ if (count($this->items))
+ {
+ echo OSMembershipHelperHtml::loadCommonLayout('common/tmpl/columns_plans.php', ['items' => $this->items, 'input' => $this->input, 'config' => $this->config, 'Itemid' => $this->Itemid, 'categoryId' => $this->categoryId, 'bootstrapHelper' => $this->bootstrapHelper, 'params' => $this->params]);
+ }
+
+ if (!$this->input->getInt('hmvc_call') && ($this->pagination->total > $this->pagination->limit))
+ {
+ ?>
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/plans/default.php b/templates/moko-cassiopeia/html/com_osmembership/plans/default.php
new file mode 100644
index 0000000..e9980c7
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/plans/default.php
@@ -0,0 +1,83 @@
+
+
+ params->get('show_page_heading', 1))
+ {
+ if ($this->category)
+ {
+ $pageHeading = $this->params->get('page_heading') ?: $this->category->title;
+ }
+ else
+ {
+ $pageHeading = $this->params->get('page_heading') ?: Text::_('OSM_SUBSCRIPTION_PLANS');
+ }
+
+ if ($this->input->getInt('hmvc_call'))
+ {
+ $hTag = 'h2';
+ }
+ else
+ {
+ $hTag = 'h1';
+ }
+ ?>
+ < class="osm-page-title">>
+ category->description))
+ {
+ $description = $this->category->description;
+ }
+ elseif (OSMembershipHelper::isValidMessage($this->params->get('intro_text')))
+ {
+ $description = $this->params->get('intro_text');
+ }
+ else
+ {
+ $description = '';
+ }
+
+ if ($description)
+ {
+ ?>
+
+
+
+ categories))
+ {
+ echo OSMembershipHelperHtml::loadCommonLayout('common/tmpl/categories.php', ['items' => $this->categories, 'categoryId' => $this->categoryId, 'config' => $this->config, 'Itemid' => $this->Itemid]);
+ }
+
+ if (count($this->items))
+ {
+ echo OSMembershipHelperHtml::loadCommonLayout('common/tmpl/default_plans.php', ['items' => $this->items, 'input' => $this->input, 'config' => $this->config, 'Itemid' => $this->Itemid, 'categoryId' => $this->categoryId, 'bootstrapHelper' => $this->bootstrapHelper, 'params' => $this->params]);
+ }
+
+ if (!$this->input->getInt('hmvc_call') && ($this->pagination->total > $this->pagination->limit))
+ {
+ ?>
+
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/plans/index.html b/templates/moko-cassiopeia/html/com_osmembership/plans/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/plans/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/plans/pricingtable.php b/templates/moko-cassiopeia/html/com_osmembership/plans/pricingtable.php
new file mode 100644
index 0000000..0572e69
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/plans/pricingtable.php
@@ -0,0 +1,75 @@
+category ? $this->category->id : 0;
+?>
+
+ params->get('show_page_heading', 1))
+ {
+ if ($this->category)
+ {
+ $pageHeading = $this->params->get('page_heading') ?: $this->category->title;
+ }
+ else
+ {
+ $pageHeading = $this->params->get('page_heading') ?: Text::_('OSM_SUBSCRIPTION_PLANS');
+ }
+
+ if ($this->input->getInt('hmvc_call'))
+ {
+ $hTag = 'h2';
+ }
+ else
+ {
+ $hTag = 'h1';
+ }
+ ?>
+ < class="osm-page-title">>
+ category->description))
+ {
+ $description = $this->category->description;
+ }
+ elseif (OSMembershipHelper::isValidMessage($this->params->get('intro_text')))
+ {
+ $description = $this->params->get('intro_text');
+ }
+ else
+ {
+ $description = '';
+ }
+
+ if ($description)
+ {
+ ?>
+
+
+
+ categories))
+ {
+ echo OSMembershipHelperHtml::loadCommonLayout('common/tmpl/categories.php', ['items' => $this->categories, 'categoryId' => $this->categoryId, 'config' => $this->config, 'Itemid' => $this->Itemid]);
+ }
+
+ if (count($this->items))
+ {
+ echo OSMembershipHelperHtml::loadCommonLayout('common/tmpl/pricingtable_plans.php', ['items' => $this->items, 'input' => $this->input, 'config' => $this->config, 'Itemid' => $this->Itemid, 'categoryId' => $this->categoryId, 'bootstrapHelper' => $this->bootstrapHelper, 'params' => $this->params]);
+ }
+ ?>
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/plans/pricingtablecircle.php b/templates/moko-cassiopeia/html/com_osmembership/plans/pricingtablecircle.php
new file mode 100644
index 0000000..6361a88
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/plans/pricingtablecircle.php
@@ -0,0 +1,75 @@
+category ? $this->category->id : 0;
+?>
+
+ params->get('show_page_heading', 1))
+ {
+ if ($this->category)
+ {
+ $pageHeading = $this->params->get('page_heading') ?: $this->category->title;
+ }
+ else
+ {
+ $pageHeading = $this->params->get('page_heading') ?: Text::_('OSM_SUBSCRIPTION_PLANS');
+ }
+
+ if ($this->input->getInt('hmvc_call'))
+ {
+ $hTag = 'h2';
+ }
+ else
+ {
+ $hTag = 'h1';
+ }
+ ?>
+ < class="osm-page-title">>
+ category->description))
+ {
+ $description = $this->category->description;
+ }
+ elseif (OSMembershipHelper::isValidMessage($this->params->get('intro_text')))
+ {
+ $description = $this->params->get('intro_text');
+ }
+ else
+ {
+ $description = '';
+ }
+
+ if ($description)
+ {
+ ?>
+
+
+
+ categories))
+ {
+ echo OSMembershipHelperHtml::loadCommonLayout('common/tmpl/categories.php', ['items' => $this->categories, 'categoryId' => $this->categoryId, 'config' => $this->config, 'Itemid' => $this->Itemid]);
+ }
+
+ if (count($this->items))
+ {
+ echo OSMembershipHelperHtml::loadCommonLayout('common/tmpl/pricingtable_circle_plans.php', ['items' => $this->items, 'input' => $this->input, 'config' => $this->config, 'Itemid' => $this->Itemid, 'categoryId' => $this->categoryId, 'bootstrapHelper' => $this->bootstrapHelper, 'params' => $this->params]);
+ }
+ ?>
+
diff --git a/templates/moko-cassiopeia/html/com_osmembership/plans/pricingtableflat.php b/templates/moko-cassiopeia/html/com_osmembership/plans/pricingtableflat.php
new file mode 100644
index 0000000..80724d4
--- /dev/null
+++ b/templates/moko-cassiopeia/html/com_osmembership/plans/pricingtableflat.php
@@ -0,0 +1,75 @@
+category ? $this->category->id : 0;
+?>
+
+ params->get('show_page_heading', 1))
+ {
+ if ($this->category)
+ {
+ $pageHeading = $this->params->get('page_heading') ?: $this->category->title;
+ }
+ else
+ {
+ $pageHeading = $this->params->get('page_heading') ?: Text::_('OSM_SUBSCRIPTION_PLANS');
+ }
+
+ if ($this->input->getInt('hmvc_call'))
+ {
+ $hTag = 'h2';
+ }
+ else
+ {
+ $hTag = 'h1';
+ }
+ ?>
+ < class="osm-page-title">>
+ category->description))
+ {
+ $description = $this->category->description;
+ }
+ elseif (OSMembershipHelper::isValidMessage($this->params->get('intro_text')))
+ {
+ $description = $this->params->get('intro_text');
+ }
+ else
+ {
+ $description = '';
+ }
+
+ if ($description)
+ {
+ ?>
+
+
+
+ categories))
+ {
+ echo OSMembershipHelperHtml::loadCommonLayout('common/tmpl/categories.php', ['items' => $this->categories, 'categoryId' => $this->categoryId, 'config' => $this->config, 'Itemid' => $this->Itemid]);
+ }
+
+ if (count($this->items))
+ {
+ echo OSMembershipHelperHtml::loadCommonLayout('common/tmpl/pricingtable_flat_plans.php', ['items' => $this->items, 'input' => $this->input, 'config' => $this->config, 'Itemid' => $this->Itemid, 'categoryId' => $this->categoryId, 'bootstrapHelper' => $this->bootstrapHelper, 'params' => $this->params]);
+ }
+ ?>
+
diff --git a/templates/moko-cassiopeia/html/index.html b/templates/moko-cassiopeia/html/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/layouts/chromes/card.php b/templates/moko-cassiopeia/html/layouts/chromes/card.php
new file mode 100644
index 0000000..c2c02c4
--- /dev/null
+++ b/templates/moko-cassiopeia/html/layouts/chromes/card.php
@@ -0,0 +1,61 @@
+
+ * @copyright (C) 2025 Jonathan Miler || Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\Utilities\ArrayHelper;
+
+$module = $displayData['module'];
+$params = $displayData['params'];
+$attribs = $displayData['attribs'];
+
+if ($module->content === null || $module->content === '') {
+ return;
+}
+
+$moduleTag = $params->get('module_tag', 'div');
+$moduleAttribs = [];
+$moduleAttribs['class'] = $module->position . ' card ' . htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_QUOTES, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_QUOTES, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_QUOTES, 'UTF-8');
+$headerAttribs = [];
+$headerAttribs['class'] = $headerClass;
+
+// Only output a header class if it is not card-title
+if ($headerClass !== 'card-title') :
+ $headerAttribs['class'] = 'card-header ' . $headerClass;
+endif;
+
+// Only add aria if the moduleTag is not a div
+if ($moduleTag !== 'div') {
+ if ($module->showtitle) :
+ $moduleAttribs['aria-labelledby'] = 'mod-' . $module->id;
+ $headerAttribs['id'] = 'mod-' . $module->id;
+ else :
+ $moduleAttribs['aria-label'] = $module->title;
+ endif;
+}
+
+$header = '<' . $headerTag . ' ' . ArrayHelper::toString($headerAttribs) . '>' . $module->title . '' . $headerTag . '>';
+?>
+< >
+ showtitle && $headerClass !== 'card-title') : ?>
+
+
+
+ showtitle && $headerClass === 'card-title') : ?>
+
+
+ content; ?>
+
+>
+
diff --git a/templates/moko-cassiopeia/html/layouts/chromes/html5.php b/templates/moko-cassiopeia/html/layouts/chromes/html5.php
new file mode 100644
index 0000000..0100966
--- /dev/null
+++ b/templates/moko-cassiopeia/html/layouts/chromes/html5.php
@@ -0,0 +1,88 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ *
+ * html5 (chosen html5 tag and font header tags)
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\Utilities\ArrayHelper;
+
+$module = $displayData['module'];
+$params = $displayData['params'];
+
+//var_dump($module->position);
+
+if ((string) $module->content === '') {
+ return;
+}
+
+$moduleIcon = '';
+
+if ($module->position == 'sidebar-left' || $module->position == 'sidebar-right') {
+ switch ($module->module) {
+ case 'mod_virtuemart_cart':
+ $moduleIcon = '
+
+ ';
+ break;
+ case 'mod_virtuemart_category':
+ $moduleIcon = '
+
+ ';
+ break;
+ case 'mod_virtuemart_product':
+ $moduleIcon = '
+
+
+
+ ';
+ break;
+ default:
+ $moduleIcon = '';
+ }
+}
+
+$moduleTag = htmlspecialchars($params->get('module_tag', 'div'), ENT_QUOTES, 'UTF-8');
+$moduleAttribs = [];
+$moduleAttribs['class'] = 'moduletable ' . htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_QUOTES, 'UTF-8');
+$bootstrapSize = (int) $params->get('bootstrap_size', 0);
+$asideCol = ($module->position == 'sidebar-left' || $module->position == 'sidebar-right') ? ' col-md-6' : '';
+$footerCol = $module->position == 'footer' ? ' col-md-6' : '';
+$moduleAttribs['class'] .= $bootstrapSize !== 0 ? $footerCol . ' col-lg-' . $bootstrapSize : $asideCol;
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_QUOTES, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_QUOTES, 'UTF-8');
+$headerAttribs = [];
+$headerAttribs['class'] = 'module-title ';
+
+// Only output a header class if one is set
+if ($headerClass !== '') {
+ $headerAttribs['class'] = $headerClass;
+}
+
+// Only add aria if the moduleTag is not a div
+if ($moduleTag !== 'div') {
+ if ($module->showtitle) :
+ $moduleAttribs['aria-labelledby'] = 'mod-' . $module->id;
+ $headerAttribs['id'] = 'mod-' . $module->id;
+ else :
+ $moduleAttribs['aria-label'] = $module->title;
+ endif;
+}
+
+$header = '<' . $headerTag . ' ' . ArrayHelper::toString($headerAttribs) . '>' . $module->title . $moduleIcon . '' . $headerTag . '>';
+?>
+< >
+ showtitle) : ?>
+
+
+ content; ?>
+>
+
diff --git a/templates/moko-cassiopeia/html/layouts/chromes/index.html b/templates/moko-cassiopeia/html/layouts/chromes/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/layouts/chromes/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/layouts/chromes/noCard.php b/templates/moko-cassiopeia/html/layouts/chromes/noCard.php
new file mode 100644
index 0000000..f5be590
--- /dev/null
+++ b/templates/moko-cassiopeia/html/layouts/chromes/noCard.php
@@ -0,0 +1,55 @@
+
+ * @copyright (C) 2025 Jonathan Miler || Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\Utilities\ArrayHelper;
+
+$module = $displayData['module'];
+$params = $displayData['params'];
+$attribs = $displayData['attribs'];
+
+if ($module->content === null || $module->content === '') {
+ return;
+}
+
+$moduleTag = $params->get('module_tag', 'div');
+$moduleAttribs = [];
+$moduleAttribs['class'] = $module->position . ' no-card ' . htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_QUOTES, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_QUOTES, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_QUOTES, 'UTF-8');
+$headerAttribs = [];
+
+// Only output a header class if one is set
+if ($headerClass !== '') {
+ $headerAttribs['class'] = $headerClass;
+}
+
+// Only add aria if the moduleTag is not a div
+if ($moduleTag !== 'div') {
+ if ($module->showtitle) :
+ $moduleAttribs['aria-labelledby'] = 'mod-' . $module->id;
+ $headerAttribs['id'] = 'mod-' . $module->id;
+ else :
+ $moduleAttribs['aria-label'] = $module->title;
+ endif;
+}
+
+$header = '<' . $headerTag . ' ' . ArrayHelper::toString($headerAttribs) . '>' . $module->title . '' . $headerTag . '>';
+?>
+< >
+ showtitle) : ?>
+
+
+ content; ?>
+>
+
diff --git a/templates/moko-cassiopeia/html/layouts/index.html b/templates/moko-cassiopeia/html/layouts/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/layouts/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/mod_custom/banner.php b/templates/moko-cassiopeia/html/mod_custom/banner.php
new file mode 100644
index 0000000..2b8a89f
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_custom/banner.php
@@ -0,0 +1,34 @@
+
+ * @copyright (C) 2025 Jonathan Miler || Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Uri\Uri;
+
+$modId = 'mod-custom' . $module->id;
+
+if ($params->get('backgroundimage')) {
+ /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
+ $wa = $app->getDocument()->getWebAssetManager();
+ $wa->addInlineStyle('
+#' . $modId . '{background-image: url("' . Uri::root(true) . '/' . HTMLHelper::_('cleanImageURL', $params->get('backgroundimage'))->url . '");}
+', ['name' => $modId]);
+}
+?>
+
+
+
diff --git a/templates/moko-cassiopeia/html/mod_custom/hero.php b/templates/moko-cassiopeia/html/mod_custom/hero.php
new file mode 100644
index 0000000..1ec8c73
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_custom/hero.php
@@ -0,0 +1,34 @@
+
+ * @copyright (C) 2025 Jonathan Miler || Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Uri\Uri;
+
+$modId = 'mod-custom' . $module->id;
+
+if ($params->get('backgroundimage')) {
+ /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
+ $wa = $app->getDocument()->getWebAssetManager();
+ $wa->addInlineStyle('
+#' . $modId . '{background-image: url("' . Uri::root(true) . '/' . HTMLHelper::_('cleanImageURL', $params->get('backgroundimage'))->url . '");}
+', ['name' => $modId]);
+}
+?>
+
+
+
diff --git a/templates/moko-cassiopeia/html/mod_custom/index.html b/templates/moko-cassiopeia/html/mod_custom/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_custom/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/mod_gabble/default.php b/templates/moko-cassiopeia/html/mod_gabble/default.php
new file mode 100644
index 0000000..379d70f
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_gabble/default.php
@@ -0,0 +1,160 @@
+getSession();
+$config = $app->getParams('com_gabble');
+$document = Factory::getDocument();
+$document->addStyleSheet('media/com_gabble/css/gabble.css');
+$document->addStyleSheet('media/templates/site/cassiopeia_meaewellness/css/gable.css');
+$lang = Factory::getLanguage();
+$lang->load('com_gabble');
+
+Text::script('COM_GABBLE_TIMEOUT');
+
+if ( !$currentuser->get("id")){
+
+ echo '
+
+
+
'. Text::_('COM_GABBLE_LOGGEDIN') . '
+
+
+
';
+
+ return;
+
+}
+
+$input = $app->input;
+
+if ($input->get('option') == 'com_gabble') {
+
+ echo '
+
+
+
+
'. Text::_('COM_GABBLE_GABBLE_CHAT') . '
+
+
+
';
+
+ return;
+
+}
+
+$document->addScript('media/com_gabble/js/gabble_com.js');
+//$document->addScript('media/templates/site/cassiopeia_meaewellness/js/mod_gabblegabble_com.js');
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
" alt="OpenAI GPT">
+
+
+
+
+
+
+
+
+
+
">
+
+
+
+
+
+
+
+ Tabaoca
+
diff --git a/templates/moko-cassiopeia/html/mod_gabble/index.html b/templates/moko-cassiopeia/html/mod_gabble/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_gabble/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/mod_membershipplans/index.html b/templates/moko-cassiopeia/html/mod_membershipplans/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_membershipplans/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/mod_menu/collapse-metismenu.php b/templates/moko-cassiopeia/html/mod_menu/collapse-metismenu.php
new file mode 100644
index 0000000..925e889
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_menu/collapse-metismenu.php
@@ -0,0 +1,28 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+
+HTMLHelper::_('bootstrap.collapse');
+?>
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu.php b/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu.php
new file mode 100644
index 0000000..b1f1627
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu.php
@@ -0,0 +1,110 @@
+
+ * @copyright (C) 2025 Jonathan Miler || Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Helper\ModuleHelper;
+use Joomla\Utilities\ArrayHelper;
+
+/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
+$wa = $app->getDocument()->getWebAssetManager();
+$wa->registerAndUseScript('metismenu', 'media/templates/site/moko-cassiopeia/js/mod_menu/menu-metismenu.min.js', [], ['defer' => true], ['metismenujs']);
+
+$attributes = [];
+$attributes['class'] = 'mod-menu mod-menu_dropdown-metismenu metismenu mod-list ' . $class_sfx;
+
+if ($tagId = $params->get('tag_id', '')) {
+ $attributes['id'] = $tagId;
+}
+
+$start = (int) $params->get('startLevel', 1);
+
+?>
+>
+ &$item) {
+ // Skip sub-menu items if they are set to be hidden in the module's options
+ if (!$showAll && $item->level > $start) {
+ continue;
+ }
+
+ $itemParams = $item->getParams();
+ $class = [];
+ $class[] = 'metismenu-item item-' . $item->id . ' level-' . ($item->level - $start + 1);
+
+ if ($item->id == $default_id) {
+ $class[] = 'default';
+ }
+
+ if ($item->id == $active_id || ($item->type === 'alias' && $itemParams->get('aliasoptions') == $active_id)) {
+ $class[] = 'current';
+ }
+
+ if (in_array($item->id, $path)) {
+ $class[] = 'active';
+ } elseif ($item->type === 'alias') {
+ $aliasToId = $itemParams->get('aliasoptions');
+
+ if (count($path) > 0 && $aliasToId == $path[count($path) - 1]) {
+ $class[] = 'active';
+ } elseif (in_array($aliasToId, $path)) {
+ $class[] = 'alias-parent-active';
+ }
+ }
+
+ if ($item->type === 'separator') {
+ $class[] = 'divider';
+ }
+
+ if ($showAll) {
+ if ($item->deeper) {
+ $class[] = 'deeper';
+ }
+
+ if ($item->parent) {
+ $class[] = 'parent';
+ }
+ }
+
+ echo '';
+
+ switch ($item->type) :
+ case 'separator':
+ case 'component':
+ case 'heading':
+ case 'url':
+ require ModuleHelper::getLayoutPath('mod_menu', 'dropdown-metismenu_' . $item->type);
+ break;
+
+ default:
+ require ModuleHelper::getLayoutPath('mod_menu', 'dropdown-metismenu_url');
+ endswitch;
+
+ switch (true) :
+ // The next item is deeper.
+ case $showAll && $item->deeper:
+ echo '';
+ break;
+
+ // The next item is shallower.
+ case $item->shallower:
+ echo ' ';
+ echo str_repeat(' ', $item->level_diff);
+ break;
+
+ // The next item is on the same level.
+ default:
+ echo '';
+ break;
+ endswitch;
+}
+?>
+
diff --git a/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_component.php b/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_component.php
new file mode 100644
index 0000000..e8cc033
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_component.php
@@ -0,0 +1,79 @@
+
+ * @copyright (C) 2025 Jonathan Miler || Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Filter\OutputFilter;
+use Joomla\CMS\HTML\HTMLHelper;
+
+$attributes = [];
+
+if ($item->anchor_title) {
+ $attributes['title'] = $item->anchor_title;
+}
+
+if ($item->anchor_css) {
+ $attributes['class'] = $item->anchor_css;
+}
+
+if ($item->anchor_rel) {
+ $attributes['rel'] = $item->anchor_rel;
+}
+
+if ($item->id == $active_id) {
+ $attributes['aria-current'] = 'location';
+
+ if ($item->current) {
+ $attributes['aria-current'] = 'page';
+ }
+}
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+} elseif ($item->menu_image) {
+ // The link is an image, maybe with an own class
+ $image_attributes = [];
+
+ if ($item->menu_image_css) {
+ $image_attributes['class'] = $item->menu_image_css;
+ }
+
+ $linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes);
+
+ if ($itemParams->get('menu_text', 1)) {
+ $linktype .= '' . $item->title . ' ';
+ }
+}
+
+if ($item->browserNav == 1) {
+ $attributes['target'] = '_blank';
+} elseif ($item->browserNav == 2) {
+ $options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes';
+
+ $attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
+}
+
+echo HTMLHelper::link(OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);
+
+if ($showAll && $item->deeper) {
+ echo ' ';
+}
+
diff --git a/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_heading.php b/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_heading.php
new file mode 100644
index 0000000..6df3bd0
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_heading.php
@@ -0,0 +1,61 @@
+
+ * @copyright (C) 2025 Jonathan Miler || Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\Utilities\ArrayHelper;
+
+$attributes = [];
+
+if ($item->anchor_title) {
+ $attributes['title'] = $item->anchor_title;
+}
+
+$attributes['class'] = 'mod-menu__heading nav-header';
+$attributes['class'] .= $item->anchor_css ? ' ' . $item->anchor_css : null;
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+} elseif ($item->menu_image) {
+ // The link is an image, maybe with an own class
+ $image_attributes = [];
+
+ if ($item->menu_image_css) {
+ $image_attributes['class'] = $item->menu_image_css;
+ }
+
+ $linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes);
+
+ if ($itemParams->get('menu_text', 1)) {
+ $linktype .= '' . $item->title . ' ';
+ }
+}
+
+if ($showAll && $item->deeper) {
+ $attributes['class'] .= ' mm-collapsed mm-toggler mm-toggler-nolink';
+ $attributes['aria-haspopup'] = 'true';
+ $attributes['aria-expanded'] = 'false';
+ echo '' . $linktype . ' ';
+} else {
+ echo '' . $linktype . ' ';
+}
+
diff --git a/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_separator.php b/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_separator.php
new file mode 100644
index 0000000..640ae62
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_separator.php
@@ -0,0 +1,61 @@
+
+ * @copyright (C) 2025 Jonathan Miler || Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\Utilities\ArrayHelper;
+
+$attributes = [];
+
+if ($item->anchor_title) {
+ $attributes['title'] = $item->anchor_title;
+}
+
+$attributes['class'] = 'mod-menu__separator separator';
+$attributes['class'] .= $item->anchor_css ? ' ' . $item->anchor_css : null;
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+} elseif ($item->menu_image) {
+ // The link is an image, maybe with an own class
+ $image_attributes = [];
+
+ if ($item->menu_image_css) {
+ $image_attributes['class'] = $item->menu_image_css;
+ }
+
+ $linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes);
+
+ if ($itemParams->get('menu_text', 1)) {
+ $linktype .= '' . $item->title . ' ';
+ }
+}
+
+if ($showAll && $item->deeper) {
+ $attributes['class'] .= ' mm-collapsed mm-toggler mm-toggler-nolink';
+ $attributes['aria-haspopup'] = 'true';
+ $attributes['aria-expanded'] = 'false';
+ echo '' . $linktype . ' ';
+} else {
+ echo '' . $linktype . ' ';
+}
+
diff --git a/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_url.php b/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_url.php
new file mode 100644
index 0000000..391fa00
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_menu/dropdown-metismenu_url.php
@@ -0,0 +1,76 @@
+
+ * @copyright (C) 2025 Jonathan Miler || Moko Consulting
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Filter\OutputFilter;
+use Joomla\CMS\HTML\HTMLHelper;
+
+$attributes = [];
+
+if ($item->anchor_title) {
+ $attributes['title'] = $item->anchor_title;
+}
+
+if ($item->anchor_css) {
+ $attributes['class'] = $item->anchor_css;
+}
+
+if ($item->anchor_rel) {
+ $attributes['rel'] = $item->anchor_rel;
+}
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+} elseif ($item->menu_image) {
+ // The link is an image, maybe with an own class
+ $image_attributes = [];
+
+ if ($item->menu_image_css) {
+ $image_attributes['class'] = $item->menu_image_css;
+ }
+
+ $linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes);
+
+ if ($itemParams->get('menu_text', 1)) {
+ $linktype .= '' . $item->title . ' ';
+ }
+}
+
+if ($item->browserNav == 1) {
+ $attributes['target'] = '_blank';
+ $attributes['rel'] = 'noopener noreferrer';
+
+ if ($item->anchor_rel == 'nofollow') {
+ $attributes['rel'] .= ' nofollow';
+ }
+} elseif ($item->browserNav == 2) {
+ $options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,' . $params->get('window_open');
+
+ $attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
+}
+
+echo HTMLHelper::link(OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);
+
+if ($showAll && $item->deeper) {
+ echo ' ';
+}
+
diff --git a/templates/moko-cassiopeia/html/mod_menu/index.html b/templates/moko-cassiopeia/html/mod_menu/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_menu/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_cart/default.php b/templates/moko-cassiopeia/html/mod_virtuemart_cart/default.php
new file mode 100644
index 0000000..493e59e
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_cart/default.php
@@ -0,0 +1,99 @@
+prepareAjaxData(true);
+$view = vRequest::getCmd('view');
+?>
+
+
+
+
+ totalProductTxt ?>
+
+
+
+
+
+
+
+
+
+ _priceConfig['salesPrice'][0]) : ?>
+
+
+
+
+
+
+
+
+
+
+ products as $product) : ?>
+
+
+
+
+
+ _priceConfig['salesPrice'][0]) : ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ products) ? $data->billTotal : ''; ?>
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_cart/dropdown.php b/templates/moko-cassiopeia/html/mod_virtuemart_cart/dropdown.php
new file mode 100644
index 0000000..c6389bd
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_cart/dropdown.php
@@ -0,0 +1,107 @@
+prepareAjaxData(true);
+$view = vRequest::getCmd('view');
+?>
+
+
+
+
+
+
+
+
+ totalProductTxt ?>
+
+
+
+
+
+
+
+
+
+ _priceConfig['salesPrice'][0]) : ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_cart/index.html b/templates/moko-cassiopeia/html/mod_virtuemart_cart/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_cart/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_category/all.php b/templates/moko-cassiopeia/html/mod_virtuemart_category/all.php
new file mode 100644
index 0000000..a0d4eff
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_category/all.php
@@ -0,0 +1,44 @@
+get('level', 0);
+?>
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_category/current.php b/templates/moko-cassiopeia/html/mod_virtuemart_category/current.php
new file mode 100644
index 0000000..973a2a7
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_category/current.php
@@ -0,0 +1,67 @@
+getWebAssetManager();
+$wa->addInlineScript('jQuery(function($) {
+ $(\'.vm-menu-btn\').click(function(e){
+ e.stopPropagation();
+ e.preventDefault();
+ });
+ });
+');
+
+$category_id = vRequest::getInt ('virtuemart_category_id', 0);
+$sublevel = $params->get('level', 0);
+$btnIcon = '
+
+ ';
+?>
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_category/default.php b/templates/moko-cassiopeia/html/mod_virtuemart_category/default.php
new file mode 100644
index 0000000..e151aa9
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_category/default.php
@@ -0,0 +1,67 @@
+getWebAssetManager();
+$wa->addInlineScript('jQuery(function($) {
+ $(\'.vm-menu-btn\').click(function(e){
+ e.stopPropagation();
+ e.preventDefault();
+ });
+ });
+');
+
+$category_id = vRequest::getInt ('virtuemart_category_id', 0);
+$sublevel = $params->get('level', 0);
+$btnIcon = '
+
+ ';
+?>
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_category/index.html b/templates/moko-cassiopeia/html/mod_virtuemart_category/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_category/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_category/wall.php b/templates/moko-cassiopeia/html/mod_virtuemart_category/wall.php
new file mode 100644
index 0000000..dcdcb3b
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_category/wall.php
@@ -0,0 +1,28 @@
+addImages($categories);
+$categories_per_row = vmConfig::get('categories_per_row');
+$bscol = $module->position == 'sidebar-left' || $module->position == 'sidebar-right' ? '6' : '3';
+?>
+
+
+
+ virtuemart_category_id);
+ $catname = $category->category_name ;
+ ?>
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_currencies/default.php b/templates/moko-cassiopeia/html/mod_virtuemart_currencies/default.php
new file mode 100644
index 0000000..d24b9a7
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_currencies/default.php
@@ -0,0 +1,38 @@
+getCurrency($virtuemart_currency_id);
+?>
+
+
+
+
+
+
+
+
+ currency_code_3 . ' ' . $selectedCurrency->currency_symbol; ?>
+
+
+
+
+ *
+ * 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 .
+ -->
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_manufacturer/default.php b/templates/moko-cassiopeia/html/mod_virtuemart_manufacturer/default.php
new file mode 100644
index 0000000..305e83a
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_manufacturer/default.php
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+ virtuemart_manufacturer_id); ?>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_manufacturer/index.html b/templates/moko-cassiopeia/html/mod_virtuemart_manufacturer/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_manufacturer/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_product/default.php b/templates/moko-cassiopeia/html/mod_virtuemart_product/default.php
new file mode 100644
index 0000000..9474030
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_product/default.php
@@ -0,0 +1,167 @@
+showRating();
+
+$emptyStar = '
+
+ ';
+
+$star = '
+
+ ';
+
+$bscol = ' col-xl-' . floor (12 / $products_per_row);
+?>
+
+
+
+
+
+
+
+
+
+
+
>
+ images[0]) ? $product->images[0]->displayMediaThumb ('class="vm-products-module-img img-fluid"', FALSE) : '';
+ echo HTMLHelper::_ ('link', Route::_ ('index.php?option=com_virtuemart&view=productdetails&virtuemart_product_id=' . $product->virtuemart_product_id . '&virtuemart_category_id=' . $product->virtuemart_category_id), $image, array('title' => $product->product_name));
+ ?>
+
+
+
+ getRatingByProduct($product->virtuemart_product_id, true);
+ $maxrating = VmConfig::get('vm_maximum_rating_scale', 5);
+ ?>
+ rating)) : ?>
+
+
+
+
+ rating * 16; ?>
+
+
+
+
+
rating, 2) . '/' . $maxrating) ?>" data-bs-toggle="tooltip">
+
+
+
+
+
+
+
+ $product)); ?>
+
+
+ virtuemart_product_id . '&virtuemart_category_id=' .$product->virtuemart_category_id); ?>
+
+
+
+
+ product_s_desc, 60, ' ...') ?>
+
+
+
+ prices['salesPrice'])) {
+ echo $currency->createPriceDiv ('salesPrice', '', $product->prices, FALSE, FALSE, 1.0, TRUE);
+ }
+
+ if ($product->prices['discountAmount']) {
+ echo $currency->createPriceDiv ('basePriceWithTax', '', $product->prices, FALSE, FALSE, 1.0, TRUE);
+ }
+ }
+ ?>
+
+
+
+ $product)); ?>
+
+
+
+
+
+
+
+
+
+
+
+
+ images[0]) ? $product->images[0]->displayMediaThumb ('class="vm-products-module-img img-fluid"', FALSE) : '';
+ echo HTMLHelper::_ ('link', Route::_ ('index.php?option=com_virtuemart&view=productdetails&virtuemart_product_id=' . $product->virtuemart_product_id . '&virtuemart_category_id=' . $product->virtuemart_category_id), $image, array('title' => $product->product_name));
+ ?>
+
+
+ virtuemart_product_id . '&virtuemart_category_id=' .$product->virtuemart_category_id); ?>
+
+
+
+
+ prices['salesPrice'])) {
+ echo $currency->createPriceDiv ('salesPrice', '', $product->prices, FALSE, FALSE, 1.0, TRUE);
+ }
+
+ if ($product->prices['discountAmount']) {
+ echo $currency->createPriceDiv ('basePriceWithTax', '', $product->prices, FALSE, FALSE, 1.0, TRUE);
+ }
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_product/index.html b/templates/moko-cassiopeia/html/mod_virtuemart_product/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_product/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_search/default.php b/templates/moko-cassiopeia/html/mod_virtuemart_search/default.php
new file mode 100644
index 0000000..6776c11
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_search/default.php
@@ -0,0 +1,56 @@
+
+
+
diff --git a/templates/moko-cassiopeia/html/mod_virtuemart_search/index.html b/templates/moko-cassiopeia/html/mod_virtuemart_search/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/mod_virtuemart_search/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/html/tinymce/index.html b/templates/moko-cassiopeia/html/tinymce/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/html/tinymce/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/index.html b/templates/moko-cassiopeia/index.html
new file mode 100644
index 0000000..206e130
--- /dev/null
+++ b/templates/moko-cassiopeia/index.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/templates/moko-cassiopeia/index.php b/templates/moko-cassiopeia/index.php
new file mode 100644
index 0000000..da8515b
--- /dev/null
+++ b/templates/moko-cassiopeia/index.php
@@ -0,0 +1,484 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Uri\Uri;
+
+/** @var Joomla\CMS\Document\HtmlDocument $this */
+
+$app = Factory::getApplication();
+$input = $app->getInput();
+$wa = $this->getWebAssetManager();
+$params_ColorName = $this->params->get('colorName', 'colors_standard');
+$params_googletagmanager = $this->params->get('googletagmanager', false);
+$params_googletagmanagerid = $this->params->get('googletagmanagerid', null);
+$params_googleanalytics = $this->params->get('googleanalytics', false);
+$params_googleanalyticsid = $this->params->get('googleanalyticsid', null);
+$params_custom_head_start = $this->params->get('custom_head_start', null);
+$params_custom_head_end = $this->params->get('custom_head_end', null);
+$params_leftIcon = htmlspecialchars(
+ $this->params->get('drawerLeftIcon', 'fa-solid fa-chevron-left'),
+ ENT_COMPAT, 'UTF-8'
+);
+$params_rightIcon = htmlspecialchars(
+ $this->params->get('drawerRightIcon', 'fa-solid fa-chevron-right'),
+ ENT_COMPAT, 'UTF-8'
+);
+
+// Add Bootstrap 5 Support
+HTMLHelper::_('bootstrap.framework');
+HTMLHelper::_('bootstrap.loadCss', true);
+HTMLHelper::_('bootstrap.alert');
+HTMLHelper::_('bootstrap.button');
+HTMLHelper::_('bootstrap.carousel');
+HTMLHelper::_('bootstrap.collapse');
+HTMLHelper::_('bootstrap.dropdown');
+HTMLHelper::_('bootstrap.modal');
+HTMLHelper::_('bootstrap.offcanvas');
+HTMLHelper::_('bootstrap.popover');
+HTMLHelper::_('bootstrap.scrollspy');
+HTMLHelper::_('bootstrap.tab');
+HTMLHelper::_('bootstrap.tooltip');
+HTMLHelper::_('bootstrap.toast');
+
+// Detecting Active Variables
+$option = $input->getCmd('option', '');
+$view = $input->getCmd('view', '');
+$layout = $input->getCmd('layout', '');
+$task = $input->getCmd('task', '');
+$itemid = $input->getCmd('Itemid', '');
+$sitename = htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8');
+$menu = $app->getMenu()->getActive();
+$pageclass = $menu !== null ? $menu->getParams()->get('pageclass_sfx', '') : '';
+
+// Template path
+$templatePath = 'media/templates/site/moko-cassiopeia';
+
+// Color Theme
+$assetColorName = 'theme.' . $params_ColorName;
+$wa->registerAndUseStyle($assetColorName, $templatePath . '/css/global/' . $params_ColorName . '.css');
+
+// Use a font scheme if set in the template style options
+$params_FontScheme = $this->params->get('useFontScheme', false);
+$fontStyles = '';
+
+if ($params_FontScheme) {
+ if (stripos($params_FontScheme, 'https://') === 0) {
+ $this->getPreloadManager()->preconnect('https://fonts.googleapis.com/', ['crossorigin' => 'anonymous']);
+ $this->getPreloadManager()->preconnect('https://fonts.gstatic.com/', ['crossorigin' => 'anonymous']);
+ $this->getPreloadManager()->preload($params_FontScheme, ['as' => 'style', 'crossorigin' => 'anonymous']);
+ $wa->registerAndUseStyle('fontscheme.current', $params_FontScheme, [], ['media' => 'print', 'rel' => 'lazy-stylesheet', 'onload' => 'this.media=\'all\'', 'crossorigin' => 'anonymous']);
+
+ if (preg_match_all('/family=([^?:]*):/i', $params_FontScheme, $matches) > 0) {
+ $fontStyles = '--font-family-body: "' . str_replace('+', ' ', $matches[1][0]) . '", sans-serif;\n';
+ $fontStyles .= '--font-family-headings: "' . str_replace('+', ' ', isset($matches[1][1]) ? $matches[1][1] : $matches[1][0]) . '", sans-serif;\n';
+ $fontStyles .= '--font-weight-normal: 400;\n';
+ $fontStyles .= '--font-weight-headings: 700;';
+ }
+ } else {
+ $wa->registerAndUseStyle('fontscheme.current', $params_FontScheme, ['version' => 'auto'], ['media' => 'print', 'rel' => 'lazy-stylesheet', 'onload' => 'this.media=\'all\'']);
+ $this->getPreloadManager()->preload($wa->getAsset('style', 'fontscheme.current')->getUri() . '?' . $this->getMediaVersion(), ['as' => 'style']);
+ }
+}
+
+// Enable assets
+$wa->usePreset('template.MOKO-CASSIOPEIA.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr'))
+ ->useStyle('template.active.language')
+ ->useStyle('template.user')
+ ->useScript('template.user')
+ ->addInlineStyle(":root {\n --hue: 214;\n --template-bg-light: #f0f4fb;\n --template-text-dark: #495057;\n --template-text-light: #ffffff;\n --template-link-color: #2a69b8;\n --template-special-color: #001B4C;\n $fontStyles\n }");
+
+// Override 'template.active' asset for correct dependency
+$wa->registerStyle('template.active', '', [], [], ['template.MOKO-CASSIOPEIA.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr')]);
+
+// Logo file or site title
+if ($this->params->get('logoFile')) {
+ $logo = HTMLHelper::_('image', Uri::root(false) . htmlspecialchars($this->params->get('logoFile'), ENT_QUOTES), $sitename, ['loading' => 'eager', 'decoding' => 'async'], false, 0);
+} elseif ($this->params->get('siteTitle')) {
+ $logo = '' . htmlspecialchars($this->params->get('siteTitle'), ENT_COMPAT, 'UTF-8') . ' ';
+} else {
+ $logo = HTMLHelper::_('image', 'full_logo.png', $sitename, ['class' => 'logo d-inline-block', 'loading' => 'eager', 'decoding' => 'async'], true, 0);
+}
+
+$hasClass = '';
+if ($this->countModules('sidebar-left', true)) { $hasClass .= ' has-sidebar-left'; }
+if ($this->countModules('sidebar-right', true)) { $hasClass .= ' has-sidebar-right'; }
+if ($this->countModules('drawer-left', true)) { $hasClass .= ' has-drawer-left'; }
+if ($this->countModules('drawer-right', true)) { $hasClass .= ' has-drawer-right'; }
+
+$params_DrawerIconLeft = $this->params->get('drawerIconLeft', 'fas fa-chevron-right');
+$params_DrawerIconRight = $this->params->get('drawerIconRight', 'fas fa-chevron-left');
+
+// Container
+$wrapper = $this->params->get('fluidContainer') ? 'wrapper-fluid' : 'wrapper-static';
+
+$this->setMetaData('viewport', 'width=device-width, initial-scale=1');
+$stickyHeader = $this->params->get('stickyHeader') ? 'position-sticky sticky-top' : '';
+
+if ($this->params->get('fA6KitCode')) {
+ $fa6Kit = "https://kit.fontawesome.com/" . $this->params->get('fA6KitCode') . ".js";
+ JHtml::_('script', $fa6Kit, ['crossorigin' => 'anonymous']);
+} else {
+ $wa->getAsset('style', 'fontawesome')->setAttribute('rel', 'lazy-stylesheet');
+}
+// Add Bootstrap TOC CSS
+$this->addStyleSheet($templatePath . '/css/vendor/afeld/bootstrap-toc.min.css');
+
+// Add Bootstrap TOC JS (should be loaded after Bootstrap JS)
+$this->addScript($templatePath . '/js/vendor/afeld/bootstrap-toc.min.js');
+
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ countModules('banner', true)) : ?>
+
+
+
+
+
+ countModules('top-a', true)) : ?>
+
+
+
+
+
+ countModules('top-b', true)) : ?>
+
+
+
+
+
+ countModules('sidebar-left', true)) : ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ countModules('sidebar-right', true)) : ?>
+
+
+
+ countModules('bottom-a', true)) : ?>
+
+
+
+
+
+ countModules('bottom-b', true)) : ?>
+
+
+
+
+
+
+
+
+params->get('backTop') == 1) : ?>
+
+
+
+
+
+countModules('drawer-left', true)) : ?>
+
+
+
+
+countModules('drawer-right', true)) : ?>
+
+
+
+
+
+
+
+
Light
+
+
+
+
Dark
+
Auto
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/joomla.asset.json b/templates/moko-cassiopeia/joomla.asset.json
new file mode 100644
index 0000000..89f8c34
--- /dev/null
+++ b/templates/moko-cassiopeia/joomla.asset.json
@@ -0,0 +1,151 @@
+{
+ "$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
+ "name": "tpl_moko-cassiopeia",
+ "version": "02.00",
+ "description": "Moko-Cassiopeia template assets",
+ "license": "GPL-3.0-or-later",
+ "x-header":
+ {
+ "copyright_year": 2025,
+ "author": "Jonathan Miller",
+ "owner": "Moko Consulting",
+ "contact": "hello@mokoconsulting.tech",
+ "project": "Moko-Cassiopeia Template",
+ "spdx_license": "GPL-3.0-or-later",
+ "notice": "This file is part of a Moko Consulting project.",
+ "disclaimer": "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License; 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/."
+ },
+ "assets": [
+ {
+ "name": "template.base",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/template.css",
+ "attributes":
+ {
+ "media": "all"
+ }
+ },
+ {
+ "name": "template.user",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/user.css",
+ "attributes":
+ {
+ "media": "all"
+ }
+ },
+ {
+ "name": "template.editor",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/editor.css",
+ "attributes":
+ {
+ "media": "all"
+ }
+ },
+ {
+ "name": "vendor.vmbasic",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/vendor/vmbasic.css",
+ "attributes":
+ {
+ "media": "all"
+ }
+ },
+ {
+ "name": "vendor.gable",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/vendor/gable.css",
+ "attributes":
+ {
+ "media": "all"
+ }
+ },
+ {
+ "name": "vendor.bootstrap-toc",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/vendor/afeld/bootstrap-toc.min.css",
+ "attributes":
+ {
+ "media": "all"
+ }
+ },
+ {
+ "name": "template.light.colors_standard",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/global/colors/light/colors_standard.css"
+ },
+ {
+ "name": "template.light.colors_alternative",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/global/colors/light/colors_alternative.css"
+ },
+ {
+ "name": "template.light.colors_custom",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/global/colors/light/colors_custom.css"
+ },
+
+ {
+ "name": "template.dark.colors_standard",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/global/colors/dark/colors_standard.css"
+ },
+ {
+ "name": "template.dark.colors_alternative",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/global/colors/dark/colors_alternative.css"
+ },
+ {
+ "name": "template.dark.colors_custom",
+ "type": "style",
+ "uri": "media/templates/site/moko-cassiopeia/css/global/colors/dark/colors_custom.css"
+ },
+
+ {
+ "name": "template.js",
+ "type": "script",
+ "uri": "media/templates/site/moko-cassiopeia/js/template.js",
+ "attributes":
+ {
+ "defer": true
+ }
+ },
+ {
+ "name": "theme-init.js",
+ "type": "script",
+ "uri": "media/templates/site/moko-cassiopeia/js/theme-init.js",
+ "attributes":
+ {
+ "defer": true
+ }
+ },
+ {
+ "name": "darkmode-toggle.js",
+ "type": "script",
+ "uri": "media/templates/site/moko-cassiopeia/js/darkmode-toggle.js",
+ "attributes":
+ {
+ "defer": true
+ }
+ },
+ {
+ "name": "gtm.js",
+ "type": "script",
+ "uri": "media/templates/site/moko-cassiopeia/js/gtm.js",
+ "attributes":
+ {
+ "defer": true
+ }
+ },
+ {
+ "name": "vendor.bootstrap-toc.js",
+ "type": "script",
+ "uri": "media/templates/site/moko-cassiopeia/js/vendor/afeld/bootstrap-toc.min.js",
+ "attributes":
+ {
+ "defer": true
+ }
+ }
+ ]
+}
diff --git a/templates/moko-cassiopeia/offline.php b/templates/moko-cassiopeia/offline.php
new file mode 100644
index 0000000..f4a21d9
--- /dev/null
+++ b/templates/moko-cassiopeia/offline.php
@@ -0,0 +1,343 @@
+params
+ * @var string $this->language
+ * @var string $this->direction
+ */
+
+$app = Factory::getApplication();
+$doc = Factory::getDocument();
+$params = $this->params ?: $app->getTemplate(true)->params;
+$direction = $this->direction ?: 'ltr';
+
+/* -----------------------
+ Load ONLY template.css + colors_*.css (with min toggle)
+------------------------ */
+$useMin = !((int) $params->get('development_mode', 0) === 1);
+$assetSuffix = $useMin ? '.min' : '';
+$base = rtrim(Uri::root(true), '/') . '/templates/' . $this->template . '/css/';
+
+$doc->addStyleSheet($base . 'template' . $assetSuffix . '.css', ['version' => 'auto'], ['id' => 'moko-template']);
+/* If you have a template param for color variant, set it here; defaults to 'standard' */
+$colorKey = (string) ($params->get('colors', 'standard') ?: 'standard');
+$colorKey = preg_replace('~[^a-z0-9_-]~i', '', $colorKey);
+$doc->addStyleSheet($base . 'colors_' . $colorKey . $assetSuffix . '.css', ['version' => 'auto'], ['id' => 'moko-colors']);
+
+/* Bootstrap CSS/JS for accordion behavior; safe to keep. */
+HTMLHelper::_('bootstrap.loadCss', true, $doc);
+HTMLHelper::_('bootstrap.framework');
+
+/* -----------------------
+ Title + Meta (Include Site Name in Page Titles)
+------------------------ */
+$sitename = (string) $app->get('sitename');
+$baseTitle = Text::_('JGLOBAL_OFFLINE') ?: 'Offline';
+$snSetting = (int) $app->get('sitename_pagetitles', 0); // 0=no, 1=before, 2=after
+
+if ($snSetting === 1) {
+ $doc->setTitle(Text::sprintf('JPAGETITLE', $sitename, $baseTitle)); // Site Name BEFORE
+} elseif ($snSetting === 2) {
+ $doc->setTitle(Text::sprintf('JPAGETITLE', $baseTitle, $sitename)); // Site Name AFTER
+} else {
+ $doc->setTitle($baseTitle);
+}
+$doc->setMetaData('robots', 'noindex, nofollow');
+
+/* -----------------------
+ Offline content from Global Config
+------------------------ */
+$displayOfflineMessage = (int) $app->get('display_offline_message', 1); // 0|1|2
+$offlineMessage = trim((string) $app->get('offline_message', ''));
+
+/* -----------------------
+ Brand (mutually exclusive: logoFile OR siteTitle)
+------------------------ */
+if ($params->get('logoFile')) {
+ $logo = HTMLHelper::_(
+ 'image',
+ Uri::root(false) . htmlspecialchars((string) $params->get('logoFile'), ENT_QUOTES, 'UTF-8'),
+ $sitename,
+ [
+ 'class' => 'logo d-inline-block',
+ 'loading' => 'eager',
+ 'decoding' => 'async',
+ 'style' => 'max-height:64px;height:auto;width:auto;'
+ ],
+ false,
+ 0
+ );
+} elseif ($params->get('siteTitle')) {
+ $logo = ''
+ . htmlspecialchars((string) $params->get('siteTitle'), ENT_COMPAT, 'UTF-8')
+ . ' ';
+} else {
+ $logo = HTMLHelper::_(
+ 'image',
+ 'full_logo.png',
+ $sitename,
+ [
+ 'class' => 'logo d-inline-block',
+ 'loading' => 'eager',
+ 'decoding' => 'async',
+ 'style' => 'max-height:64px;height:auto;width:auto;'
+ ],
+ true,
+ 0
+ );
+}
+
+$brandTagline = (string) ($params->get('brand_tagline') ?: $params->get('siteDescription') ?: '');
+$showTagline = (int) $params->get('show_brand_tagline', 0);
+$showSwitcher = (int) $params->get('show_theme_switcher', 1);
+
+/* -----------------------
+ Login routes & Users
+------------------------ */
+$action = Route::_('index.php', true);
+$return = base64_encode(Uri::base());
+$allowRegistration = (bool) ComponentHelper::getParams('com_users')->get('allowUserRegistration', 0);
+
+if (class_exists('\Joomla\Component\Users\Site\Helper\RouteHelper')) {
+ $resetUrl = \Joomla\Component\Users\Site\Helper\RouteHelper::getResetRoute();
+ $remindUrl = \Joomla\Component\Users\Site\Helper\RouteHelper::getRemindRoute();
+ $registrationUrl = \Joomla\Component\Users\Site\Helper\RouteHelper::getRegistrationRoute();
+} else {
+ $resetUrl = Route::_('index.php?option=com_users&view=reset');
+ $remindUrl = Route::_('index.php?option=com_users&view=remind');
+ $registrationUrl = Route::_('index.php?option=com_users&view=registration');
+}
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ countModules('offline')) : ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/moko-cassiopeia/templateDetails.xml b/templates/moko-cassiopeia/templateDetails.xml
new file mode 100644
index 0000000..6246ea5
--- /dev/null
+++ b/templates/moko-cassiopeia/templateDetails.xml
@@ -0,0 +1,237 @@
+
+
+
+
+ https://raw.githubusercontent.com/mokoconsulting-tech/MokoUpdates/refs/heads/main/joomla/moko-cassiopeia/updates.xml
+
+ moko-cassiopeia
+ 02.00
+ 2025-08-23
+ Jonathan Miller || Moko Consulting
+ hello@mokoconsulting.tech
+ (C)GNU General Public License Version 2 - 2025 Moko Consulting
+ TPL_MOKO-CASSIOPEIA_XML_DESCRIPTION
+ 1
+
+ component.php
+ error.php
+ index.php
+ joomla.asset.json
+ offline.php
+ templateDetails.xml
+ html
+
+
+ media/templates/site/moko-cassiopeia/css/editor.css
+
+
+ js
+ css
+ images
+ fonts
+
+
+ topbar
+ below-topbar
+ below-logo
+ menu
+ search
+ banner
+ top-a
+ top-b
+ main-top
+ main-bottom
+ breadcrumbs
+ sidebar-left
+ sidebar-right
+ bottom-a
+ bottom-b
+ footer-menu
+ footer
+ debug
+ offline-header
+ offline
+ offline-footer
+ drawer-left
+ drawer-right
+
+
+ en-GB/tpl_moko-cassiopeia.ini
+ en-GB/tpl_moko-cassiopeia.sys.ini
+ en-US/tpl_moko-cassiopeia.ini
+ en-US/tpl_moko-cassiopeia.sys.ini
+
+
+
+
+
+
+
+ TPL_MOKO-CASSIOPEIA_STATIC
+ TPL_MOKO-CASSIOPEIA_FLUID
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+
+ JNO
+ JYES
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+ Switch (Light↔Dark)
+ Radios (Light/Dark/System)
+ No visible control
+
+
+ System
+ Light
+ Dark
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+
+
+
+ TPL_MOKO-CASSIOPEIA_COLOR_NAME_STANDARD
+ TPL_MOKO-CASSIOPEIA_COLOR_NAME_ALTERNATIVE
+ TPL_MOKO-CASSIOPEIA_COLOR_NAME_CUSTOM
+
+
+ TPL_MOKO-CASSIOPEIA_COLOR_NAME_STANDARD
+ TPL_MOKO-CASSIOPEIA_COLOR_NAME_ALTERNATIVE
+ TPL_MOKO-CASSIOPEIA_COLOR_NAME_CUSTOM
+
+
+
+
+
+ JNONE
+
+ Roboto (local)
+
+
+ Fira Sans (web)
+ Roboto + Noto Sans (web)
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+
+
+
+ JNO
+ JYES
+
+
+ Bottom-right
+ Bottom-left
+ Top-right
+ Top-left
+
+
+
+
+