/* * theme.js — переключатель светлой/тёмной темы dmwells.design * * Подключение: в . * Тема до первой отрисовки ставится короткой инлайн-строкой в , * поэтому defer не даёт вспышки. * * На странице должна быть кнопка с id="theme-btn". * Необязательно: * сбрасывает сохранённую тему (используется на главной). * * Выбор хранится в localStorage['dmw-theme'] = 'dark' | 'light'. */ (function () { var KEY = 'dmw-theme'; var root = document.documentElement; var script = document.currentScript; function read() { try { return localStorage.getItem(KEY); } catch (e) { return null; } } function write(v) { try { localStorage.setItem(KEY, v); } catch (e) {} } function isDark() { return root.getAttribute('data-theme') === 'dark'; } function apply(dark) { if (dark) root.setAttribute('data-theme', 'dark'); else root.removeAttribute('data-theme'); } function syncLabel() { var b = document.getElementById('theme-btn'); if (b) b.setAttribute('aria-label', isDark() ? 'Светлая тема' : 'Тёмная тема'); } if (script && script.hasAttribute('data-reset')) { try { localStorage.removeItem(KEY); } catch (e) {} } else if (read() === 'dark') { apply(true); } document.addEventListener('click', function (e) { var b = e.target.closest && e.target.closest('#theme-btn'); if (!b) return; var dark = !isDark(); apply(dark); write(dark ? 'dark' : 'light'); syncLabel(); }); if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', syncLabel); else syncLabel(); window.addEventListener('storage', function (e) { if (e.key === KEY) { apply(e.newValue === 'dark'); syncLabel(); } }); })(); /* Меню проектов в шапке (кружок с закладкой) */ (function () { function init() { var btn = document.getElementById('bk-btn'), menu = document.getElementById('bk-menu'); if (!btn || !menu) return; function setOpen(o) { menu.hidden = !o; btn.setAttribute('aria-expanded', o ? 'true' : 'false'); } btn.addEventListener('click', function (e) { e.stopPropagation(); setOpen(menu.hidden); }); menu.addEventListener('click', function (e) { e.stopPropagation(); }); document.addEventListener('click', function () { setOpen(false); }); document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && !menu.hidden) { setOpen(false); btn.focus(); } }); window.addEventListener('scroll', function () { if (!menu.hidden) setOpen(false); }, { passive: true }); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); else init(); })();