1/* NJ Small Business Playbook: theme toggle (2026-07-23). 2 Light is the default. Dark only when the user clicks the toggle; 3 the choice persists in localStorage "njpb-theme". The tiny inline 4 head script on each page applies the saved choice before paint; 5 this file builds the button and handles clicks. */ 6(function () { 7 'use strict'; 8 var KEY = 'njpb-theme'; 9 var root = document.documentElement; 10 11 function isDark() { return root.getAttribute('data-theme') === 'dark'; } 12 13 function metaSwap(dark) { 14 var m = document.querySelector('meta[name="theme-color"]'); 15 if (m) m.setAttribute('content', dark ? '#131A16' : '#14322A'); 16 } 17 18 function label(btn, dark) { 19 var t = dark ? 'Switch to light theme' : 'Switch to dark theme'; 20 btn.setAttribute('aria-pressed', String(dark)); 21 btn.setAttribute('aria-label', t); 22 btn.title = t; 23 } 24 25 function build() { 26 var host = document.querySelector('.top-in') || document.querySelector('.nav-in'); 27 if (!host) return null; 28 var b = document.createElement('button'); 29 b.type = 'button'; 30 b.className = 'theme-toggle'; 31 b.id = 'themeToggle'; 32 b.innerHTML = 33 '<svg class="tt-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M21 12.8A9 9 0 1 1 11.2 3 7 7 0 0 0 21 12.8z"/></svg>' + 34 '<svg class="tt-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>'; 35 host.appendChild(b); 36 return b; 37 } 38 39 function init() { 40 var btn = build(); 41 if (!btn) return; 42 label(btn, isDark()); 43 metaSwap(isDark()); 44 btn.addEventListener('click', function () { 45 var dark = !isDark(); 46 if (dark) root.setAttribute('data-theme', 'dark'); 47 else root.removeAttribute('data-theme'); 48 label(btn, dark); 49 metaSwap(dark); 50 try { localStorage.setItem(KEY, dark ? 'dark' : 'light'); } catch (e) { /* private mode: stay per-page */ } 51 }); 52 } 53 54 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); 55 else init(); 56})();
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.