← back to Commercialrealestate

public/crcp-theme.js

33 lines

/* CRCP shared day/night toggle — auto-injects a button into the page header,
   persists to localStorage (key: crcp-theme), applies before paint via the inline
   head-guard each page also carries. Zero deps. */
(function () {
  var root = document.documentElement;
  function label(t) {
    var b = document.getElementById('crcpThemeToggle'); if (!b) return;
    b.innerHTML = (t === 'light' ? '🌙' : '☀️') + ' <span>' + (t === 'light' ? 'Night' : 'Day') + '</span>';
  }
  function apply(t) {
    root.setAttribute('data-theme', t);
    try { localStorage.setItem('crcp-theme', t); } catch (e) { }
    label(t);
  }
  function current() { var t; try { t = localStorage.getItem('crcp-theme'); } catch (e) { } return t === 'light' ? 'light' : 'dark'; }

  function mount() {
    if (document.getElementById('crcpThemeToggle')) { label(current()); return; }
    var btn = document.createElement('button');
    btn.id = 'crcpThemeToggle'; btn.type = 'button';
    btn.title = 'Toggle day / night'; btn.setAttribute('aria-label', 'Toggle day / night theme');
    btn.addEventListener('click', function () { apply(root.getAttribute('data-theme') === 'light' ? 'dark' : 'light'); });
    // prefer an existing header nav; else the first <header>; else fixed top-right
    var host = document.querySelector('header .nav') || document.querySelector('header');
    if (host) { host.appendChild(btn); }
    else { btn.style.cssText += ';position:fixed;top:12px;right:14px;z-index:99999'; document.body.appendChild(btn); }
    label(current());
  }
  // ensure a theme is set even if a page lacks the inline head-guard
  if (!root.getAttribute('data-theme')) root.setAttribute('data-theme', current());
  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', mount); else mount();
})();