1// Managed OpenClaw site behaviour: colour-mode toggle (cross-fades the page) and the small-screen menu. 2(function () { 3 var root = document.documentElement; 4 var MODE_KEY = 'oc-color-mode'; 5 6 function currentMode() { return root.getAttribute('data-theme-mode') === 'light' ? 'light' : 'dark'; } 7 function applyMode(mode) { 8 root.setAttribute('data-theme', mode === 'light' ? 'openknot-light' : 'openknot'); 9 root.setAttribute('data-theme-mode', mode); 10 root.style.colorScheme = mode; 11 } 12 function labelToggles() { 13 var label = currentMode() === 'light' ? 'Switch to dark mode' : 'Switch to light mode'; 14 document.querySelectorAll('[data-theme-toggle]').forEach(function (button) { 15 button.setAttribute('aria-label', label); 16 button.setAttribute('title', label); 17 }); 18 } 19 function reducedMotion() { 20 try { return window.matchMedia('(prefers-reduced-motion: reduce)').matches; } catch (e) { return false; } 21 } 22 function toggleMode() { 23 var next = currentMode() === 'light' ? 'dark' : 'light'; 24 var apply = function () { 25 applyMode(next); 26 labelToggles(); 27 try { window.localStorage.setItem(MODE_KEY, next); } catch (e) { /* storage blocked: the choice lasts this visit */ } 28 }; 29 if (reducedMotion()) return apply(); 30 if (document.startViewTransition) { 31 try { document.startViewTransition(apply); return; } catch (e) { /* fall through */ } 32 } 33 root.setAttribute('data-theme-fade', ''); 34 apply(); 35 window.setTimeout(function () { root.removeAttribute('data-theme-fade'); }, 700); 36 } 37 38 // Until the visitor picks a mode, follow the browser when its setting changes. 39 try { 40 window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', function (event) { 41 var picked = null; 42 try { picked = window.localStorage.getItem(MODE_KEY); } catch (e) { picked = null; } 43 if (picked !== 'light' && picked !== 'dark') { applyMode(event.matches ? 'light' : 'dark'); labelToggles(); } 44 }); 45 } catch (e) { /* older browsers: the initial mode still follows the system */ } 46 47 document.addEventListener('DOMContentLoaded', function () { 48 labelToggles(); 49 document.querySelectorAll('[data-theme-toggle]').forEach(function (button) { 50 button.addEventListener('click', toggleMode); 51 }); 52 var menuButton = document.querySelector('[data-menu-toggle]'); 53 var links = document.getElementById('oc-nav-links'); 54 if (menuButton && links) { 55 menuButton.addEventListener('click', function () { 56 var open = links.classList.toggle('is-open'); 57 menuButton.setAttribute('aria-expanded', open ? 'true' : 'false'); 58 menuButton.setAttribute('aria-label', open ? 'Close menu' : 'Open menu'); 59 }); 60 } 61 }); 62})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.