diff --git a/src/packages/com_mokowaas/admin/src/Model/DashboardModel.php b/src/packages/com_mokowaas/admin/src/Model/DashboardModel.php
index b0706f4f..fbc9ab57 100644
--- a/src/packages/com_mokowaas/admin/src/Model/DashboardModel.php
+++ b/src/packages/com_mokowaas/admin/src/Model/DashboardModel.php
@@ -45,6 +45,14 @@ class DashboardModel extends BaseDatabaseModel
'protected' => false,
'configure_only' => false,
],
+ 'mokowaas_tos' => [
+ 'icon' => 'icon-globe',
+ 'category' => 'security',
+ 'label' => 'Offline Bypass',
+ 'description' => 'Keep selected pages (TOS, Privacy Policy) accessible during offline mode.',
+ 'protected' => false,
+ 'configure_only' => true,
+ ],
'mokowaas_devtools' => [
'icon' => 'icon-wrench',
'category' => 'tools',
diff --git a/src/packages/com_mokowaas/admin/src/Model/ExtensionsModel.php b/src/packages/com_mokowaas/admin/src/Model/ExtensionsModel.php
index e8402f12..76e3f6fa 100644
--- a/src/packages/com_mokowaas/admin/src/Model/ExtensionsModel.php
+++ b/src/packages/com_mokowaas/admin/src/Model/ExtensionsModel.php
@@ -96,6 +96,16 @@ class ExtensionsModel extends BaseDatabaseModel
'article' => 'https://mokoconsulting.tech/kb/mokogallerycalendar',
'protected' => false,
],
+ 'MokoJoomOpenGraph' => [
+ 'label' => 'MokoJoomOpenGraph',
+ 'description' => 'Open Graph meta tags for articles, categories, and pages. Controls Facebook, Twitter, and LinkedIn link previews.',
+ 'element' => 'pkg_mokoog',
+ 'type' => 'package',
+ 'icon' => 'icon-share-alt',
+ 'category' => 'Components',
+ 'article' => 'https://mokoconsulting.tech/kb/mokojoomopengraph',
+ 'protected' => false,
+ ],
];
private const GITEA_URL = 'https://git.mokoconsulting.tech';
diff --git a/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php b/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php
index eeb32781..506b3c04 100644
--- a/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php
+++ b/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php
@@ -1424,6 +1424,7 @@ class MokoWaaS extends CMSPlugin implements BootableExtensionInterface
$db->quote('mokowaas_firewall'),
$db->quote('mokowaas_tenant'),
$db->quote('mokowaas_devtools'),
+ $db->quote('mokowaas_tos'),
$db->quote('mod_mokowaas_cpanel'),
];
diff --git a/src/packages/plg_system_mokowaas_tos/language/en-GB/plg_system_mokowaas_tos.ini b/src/packages/plg_system_mokowaas_tos/language/en-GB/plg_system_mokowaas_tos.ini
new file mode 100644
index 00000000..7b75c1e1
--- /dev/null
+++ b/src/packages/plg_system_mokowaas_tos/language/en-GB/plg_system_mokowaas_tos.ini
@@ -0,0 +1,13 @@
+; MokoWaaS Terms of Service Plugin
+; Copyright (C) 2026 Moko Consulting. All rights reserved.
+; License: GPL-3.0-or-later
+
+PLG_SYSTEM_MOKOWAAS_TOS="System - MokoWaaS Offline Bypass"
+PLG_SYSTEM_MOKOWAAS_TOS_DESC="Keep selected pages (Terms of Service, Privacy Policy, etc.) accessible when the site is in offline mode."
+
+PLG_SYSTEM_MOKOWAAS_TOS_FIELDSET_BASIC="Offline-Accessible Pages"
+PLG_SYSTEM_MOKOWAAS_TOS_SLUG_LABEL="Menu Items to Keep Online"
+PLG_SYSTEM_MOKOWAAS_TOS_SLUG_DESC="Select menu items that remain accessible during offline mode. Hold Ctrl/Cmd for multiple."
+PLG_SYSTEM_MOKOWAAS_TOS_CHILDREN_LABEL="Include Child Menu Items"
+PLG_SYSTEM_MOKOWAAS_TOS_CHILDREN_DESC="Also allow access to child pages under the selected items."
+PLG_SYSTEM_MOKOWAAS_TOS_SEF_WARNING="SEF URLs are disabled - path matching requires SEF. Itemid fallback is active."
diff --git a/src/packages/plg_system_mokowaas_tos/language/en-GB/plg_system_mokowaas_tos.sys.ini b/src/packages/plg_system_mokowaas_tos/language/en-GB/plg_system_mokowaas_tos.sys.ini
new file mode 100644
index 00000000..cf84d46a
--- /dev/null
+++ b/src/packages/plg_system_mokowaas_tos/language/en-GB/plg_system_mokowaas_tos.sys.ini
@@ -0,0 +1,3 @@
+; MokoWaaS Terms of Service Plugin - System strings
+PLG_SYSTEM_MOKOWAAS_TOS="System - MokoWaaS Offline Bypass"
+PLG_SYSTEM_MOKOWAAS_TOS_DESC="Keep selected pages (Terms of Service, Privacy Policy, etc.) accessible when the site is in offline mode."
diff --git a/src/packages/plg_system_mokowaas_tos/mokowaas_tos.xml b/src/packages/plg_system_mokowaas_tos/mokowaas_tos.xml
new file mode 100644
index 00000000..57ad3388
--- /dev/null
+++ b/src/packages/plg_system_mokowaas_tos/mokowaas_tos.xml
@@ -0,0 +1,44 @@
+
+
+ System - MokoWaaS Offline Bypass
+ mokowaas_tos
+ Moko Consulting
+ 2026-06-02
+ Copyright (C) 2026 Moko Consulting. All rights reserved.
+ GPL-3.0-or-later
+ hello@mokoconsulting.tech
+ https://mokoconsulting.tech
+ 02.32.00
+ PLG_SYSTEM_MOKOWAAS_TOS_DESC
+ Moko\Plugin\System\MokoWaaSTos
+
+
+ src
+ services
+ language
+
+
+
+ en-GB/plg_system_mokowaas_tos.ini
+ en-GB/plg_system_mokowaas_tos.sys.ini
+
+
+
+
+
+
+
+
diff --git a/src/packages/plg_system_mokowaas_tos/services/provider.php b/src/packages/plg_system_mokowaas_tos/services/provider.php
new file mode 100644
index 00000000..8a7f163e
--- /dev/null
+++ b/src/packages/plg_system_mokowaas_tos/services/provider.php
@@ -0,0 +1,34 @@
+set(
+ PluginInterface::class,
+ function (Container $container) {
+ $dispatcher = $container->get(DispatcherInterface::class);
+ $plugin = new Tos($dispatcher, (array) PluginHelper::getPlugin('system', 'mokowaas_tos'));
+ $plugin->setApplication(Factory::getApplication());
+
+ return $plugin;
+ }
+ );
+ }
+};
diff --git a/src/packages/plg_system_mokowaas_tos/src/Extension/Tos.php b/src/packages/plg_system_mokowaas_tos/src/Extension/Tos.php
new file mode 100644
index 00000000..8ef01ed0
--- /dev/null
+++ b/src/packages/plg_system_mokowaas_tos/src/Extension/Tos.php
@@ -0,0 +1,172 @@
+ 'onAfterRoute',
+ ];
+ }
+
+ public function onAfterRoute(): void
+ {
+ $app = $this->getApplication();
+
+ if (!$app->isClient('site'))
+ {
+ return;
+ }
+
+ $config = $app->getConfig();
+
+ if (!$config->get('offline'))
+ {
+ return;
+ }
+
+ $slugs = $this->params->get('tos_slug', []);
+
+ if (\is_string($slugs))
+ {
+ $slugs = array_filter([trim($slugs)]);
+ }
+ else
+ {
+ $slugs = (array) $slugs;
+ }
+
+ if (empty($slugs))
+ {
+ return;
+ }
+
+ $includeChildren = (int) $this->params->get('include_children', 1);
+
+ if ($this->matchByPath($slugs, $config, $app, $includeChildren))
+ {
+ return;
+ }
+
+ $this->matchByItemId($slugs, $config, $app, $includeChildren);
+ }
+
+ private function matchByPath(array $slugs, $config, $app, int $includeChildren = 1): bool
+ {
+ $uri = Uri::getInstance();
+ $path = urldecode(trim($uri->getPath(), '/'));
+
+ $base = trim(Uri::base(true), '/');
+
+ if (!empty($base) && strpos($path, $base) === 0)
+ {
+ $path = trim(substr($path, \strlen($base)), '/');
+ }
+
+ if (empty($path) || $path === 'index.php')
+ {
+ return false;
+ }
+
+ foreach ($slugs as $slug)
+ {
+ $slug = trim((string) $slug);
+
+ if (empty($slug))
+ {
+ continue;
+ }
+
+ if ($path === $slug || ($includeChildren && strpos($path, $slug . '/') === 0))
+ {
+ $this->bypassOffline($config, $app);
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private function matchByItemId(array $slugs, $config, $app, int $includeChildren = 1): bool
+ {
+ $itemId = (int) $app->getInput()->getInt('Itemid', 0);
+
+ if (!$itemId)
+ {
+ return false;
+ }
+
+ try
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true)
+ ->select($db->quoteName('path'))
+ ->from($db->quoteName('#__menu'))
+ ->where($db->quoteName('id') . ' = ' . $itemId)
+ ->where($db->quoteName('published') . ' = 1')
+ ->where($db->quoteName('client_id') . ' = 0');
+ $db->setQuery($query);
+ $menuPath = trim((string) $db->loadResult(), '/');
+
+ if (empty($menuPath))
+ {
+ return false;
+ }
+
+ foreach ($slugs as $slug)
+ {
+ $slug = trim((string) $slug);
+
+ if (empty($slug))
+ {
+ continue;
+ }
+
+ if ($menuPath === $slug || ($includeChildren && strpos($menuPath, $slug . '/') === 0))
+ {
+ $this->bypassOffline($config, $app);
+
+ return true;
+ }
+ }
+ }
+ catch (\Throwable $e)
+ {
+ // Silent
+ }
+
+ return false;
+ }
+
+ private function bypassOffline($config, $app): void
+ {
+ $config->set('offline', 0);
+ $app->getInput()->set('tmpl', 'component');
+ }
+}
diff --git a/src/packages/plg_system_mokowaas_tos/src/Field/MenuslugField.php b/src/packages/plg_system_mokowaas_tos/src/Field/MenuslugField.php
new file mode 100644
index 00000000..c9dd7ede
--- /dev/null
+++ b/src/packages/plg_system_mokowaas_tos/src/Field/MenuslugField.php
@@ -0,0 +1,81 @@
+get('sef', true);
+
+ if (!$sef)
+ {
+ $options[] = (object) [
+ 'value' => '',
+ 'text' => Text::_('PLG_SYSTEM_MOKOWAAS_TOS_SEF_WARNING'),
+ 'disabled' => true,
+ ];
+ }
+ }
+ catch (\Throwable $e)
+ {
+ // Ignore
+ }
+
+ try
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true)
+ ->select($db->quoteName(['path', 'alias', 'title', 'menutype']))
+ ->from($db->quoteName('#__menu'))
+ ->where($db->quoteName('published') . ' = 1')
+ ->where($db->quoteName('client_id') . ' = 0')
+ ->where($db->quoteName('alias') . ' != ' . $db->quote(''))
+ ->order($db->quoteName('menutype') . ', ' . $db->quoteName('title'));
+ $db->setQuery($query);
+ $menuItems = $db->loadObjectList();
+
+ $lastMenuType = '';
+
+ foreach ($menuItems ?: [] as $item)
+ {
+ if ($item->menutype !== $lastMenuType)
+ {
+ if ($lastMenuType !== '')
+ {
+ $options[] = (object) ['value' => '', 'text' => '──────────────', 'disabled' => true];
+ }
+
+ $lastMenuType = $item->menutype;
+ }
+
+ $label = $item->title !== '' ? $item->title : ucwords(str_replace(['-', '_'], ' ', $item->alias));
+ $options[] = (object) ['value' => $item->path, 'text' => $label . ' (/' . $item->path . ')'];
+ }
+ }
+ catch (\Throwable $e)
+ {
+ // Silent
+ }
+
+ return $options;
+ }
+}
diff --git a/src/pkg_mokowaas.xml b/src/pkg_mokowaas.xml
index 5e7f2cb5..9ee89893 100644
--- a/src/pkg_mokowaas.xml
+++ b/src/pkg_mokowaas.xml
@@ -17,6 +17,7 @@
plg_system_mokowaas_firewall.zip
plg_system_mokowaas_tenant.zip
plg_system_mokowaas_devtools.zip
+ plg_system_mokowaas_tos.zip
com_mokowaas.zip
mod_mokowaas_cpanel.zip
plg_webservices_mokowaas.zip
diff --git a/src/script.php b/src/script.php
index 481deb61..7bf3d369 100644
--- a/src/script.php
+++ b/src/script.php
@@ -42,6 +42,7 @@ class Pkg_MokowaasInstallerScript
$this->enablePlugin('system', 'mokowaas_firewall');
$this->enablePlugin('system', 'mokowaas_tenant');
$this->enablePlugin('system', 'mokowaas_devtools');
+ $this->enablePlugin('system', 'mokowaas_tos');
$this->enablePlugin('webservices', 'mokowaas');
$this->enablePlugin('task', 'mokowaasdemo');
$this->enablePlugin('task', 'mokowaassync');
@@ -289,6 +290,7 @@ class Pkg_MokowaasInstallerScript
$db->quote('mokowaas_firewall'),
$db->quote('mokowaas_tenant'),
$db->quote('mokowaas_devtools'),
+ $db->quote('mokowaas_tos'),
$db->quote('com_mokowaas'),
$db->quote('mod_mokowaas_cpanel'),
$db->quote('mokowaasdemo'),