MokoCassiopeia includes a fully implemented dark and light theme switcher built on Bootstrap 5’s data-bs-theme attribute system. Both themes are first-class — light theme in :root, dark theme overrides in :root[data-bs-theme='dark']. Switching is instant, no page reload, preference persisted across sessions.

How It Works

The switcher toggles data-bs-theme on <html> between light and dark. Over 200 CSS custom properties swap instantly. Two scopes: :root (light defaults, active always) and :root[data-bs-theme='dark'] (dark overrides).

Toggle Button

Place a mod_custom module in topbar or menu position:

<button id="theme-toggle" style="background:transparent;border:none;cursor:pointer;color:inherit">
  <i class="fa-solid fa-sun  theme-icon-dark"></i>
  <i class="fa-solid fa-moon theme-icon-light"></i>
</button>
<style>
  [data-bs-theme="dark"]  .theme-icon-light { display:none }
  [data-bs-theme="light"] .theme-icon-dark  { display:none }
</style>

JavaScript

Add inline to <head> before stylesheets to prevent flash-of-wrong-theme:

(function () {{
  var KEY  = 'mokaCassiopeiaTheme';
  var root = document.documentElement;
  var t    = localStorage.getItem(KEY) || 'dark';
  root.setAttribute('data-bs-theme', t);
  document.addEventListener('DOMContentLoaded', function () {{
    var btn = document.getElementById('theme-toggle');
    if (!btn) return;
    btn.addEventListener('click', function () {{
      var next = root.getAttribute('data-bs-theme') === 'dark' ? 'light' : 'dark';
      root.setAttribute('data-bs-theme', next);
      localStorage.setItem(KEY, next);
    }});
  }});
}})();

Customise Light Theme

:root {{
  --body-bg: #f4f6f9;
  --color-primary: #1a3a6e;
}}

Customise Dark Theme

:root[data-bs-theme='dark'] {{
  --body-bg: #060a0f;
  --accent-color-primary: #5aa0ff;
}}

System Preference

var t = localStorage.getItem('mokaCassiopeiaTheme')
  || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
Tip: Test both themes after any CSS variable change.