1/* ============================================================ 2 settings.js â SETTINGS (System Preferences) 3 Appearance (light/dark), wallpaper, accent, reduced motion. 4 All persisted to localStorage and applied live. 5 ============================================================ */ 6 7const WALLS = { 8 // the ones we made â Cmd + Z originals first (matches the mobile wallpaper order) 9 "Kato's Doodle": 'url("/assets/img/walls/kato-doodle.png") center/cover no-repeat', // Kato's own Paint creation 10 'Poker Dogs': 'url("/assets/img/walls/poker-dogs.webp") center/cover no-repeat', 11 'Sticker Table':'url("/assets/img/walls/sticker-table.webp") center/cover no-repeat', 12 'Swama': 'url("/assets/img/walls/swama.webp") center/cover no-repeat', 13 'Cracked Paint':'url("/assets/img/walls/cracked-paint.webp") center/cover no-repeat', 14 'Distress': 'url("/assets/img/walls/distress.webp") center/cover no-repeat', 15 'Patchwork': 'url("/assets/img/walls/patchwork.webp") center/cover no-repeat', 16 'Boro': 'url("/assets/img/walls/boro.svg") center/cover no-repeat', // indigo 17 'Mono': 'url("/assets/img/walls/mono-paper.svg") center/cover no-repeat', // paper (light) 18 // Removed the 3 near-identical all-black âZ stock walls (undo-dark / noho / underdog) â 19 // they read as duplicates in the picker. Every remaining tile is a distinct image. 20 // ("Default" theme-adaptive tile, "Icons" + "Happy Mac" removed earlier.) 21}; 22const ACCENTS = { Blue: '#0a84ff', Red: '#ff453a', Green: '#28c840', Amber: '#febc2e', Purple: '#bf5af2', Mono: '#8a8a90' }; 23const root = document.documentElement; 24const setWall = (g) => { const d = document.getElementById('wall-layer'); if (d) d.style.background = g || ''; }; 25 26export function mountSettings(el, ctx) { 27 el.classList.add('settings'); 28 const theme = root.dataset.theme || 'dark'; 29 el.innerHTML = ` 30 <div class="set-pad"> 31 <span class="app-tag">SETTINGS.app</span> 32 <h1 style="font-family:var(--display)">System Preferences</h1> 33 34 <div class="set-group"><label>Appearance</label> 35 <div class="set-seg"> 36 <button class="set-mode ${theme==='light'?'on':''}" data-mode="light">âï¸ Light</button> 37 <button class="set-mode ${theme==='dark'?'on':''}" data-mode="dark">â¾ Dark</button> 38 </div> 39 </div> 40 41 <div class="set-group"><label>Wallpaper</label><div class="set-walls"></div></div> 42 <div class="set-group"><label>Accent</label><div class="set-accents"></div></div> 43 <div class="set-group"><label>Screen saver â idle time</label> 44 <div class="set-seg set-ss"></div> 45 </div> 46 <div class="set-group set-row"><label>Reduce motion</label><input type="checkbox" class="set-rm"/></div> 47 <div class="set-group set-row"><label>Replay boot sequence next visit</label><input type="checkbox" class="set-boot"/></div> 48 </div>`; 49 50 /* appearance â switch theme only; the chosen wallpaper is kept, not reset */ 51 el.querySelectorAll('.set-mode').forEach((b) => b.onclick = () => { 52 const m = b.dataset.mode; 53 root.dataset.theme = m; 54 localStorage.setItem('cz-theme', m); 55 el.querySelectorAll('.set-mode').forEach((x) => x.classList.toggle('on', x === b)); 56 ctx.toast(m === 'light' ? 'âï¸' : 'â¾', 'Appearance', m[0].toUpperCase() + m.slice(1)); 57 }); 58 59 /* wallpaper â highlight whichever one is actually applied */ 60 const walls = el.querySelector('.set-walls'); 61 const curWall = localStorage.getItem('cz-wall'); 62 // with no override stored, the applied wall IS the theme default (paper in light, 63 // âZ monogram in dark) â highlight that tile so the picker matches what's on screen. 64 const themeDefaultG = theme === 'light' ? WALLS['Mono'] : null; // dark default wall isn't a picker tile 65 Object.entries(WALLS).forEach(([name, g]) => { 66 const b = document.createElement('button'); 67 const isCur = curWall ? curWall === g : g === themeDefaultG; 68 b.className = 'set-wall' + (isCur ? ' on' : ''); 69 b.style.background = g || 'var(--wall)'; b.title = name; 70 b.onclick = () => { 71 setWall(g); 72 if (g) localStorage.setItem('cz-wall', g);
72 else localStorage.removeItem('cz-wall'); 73 walls.querySelectorAll('.set-wall').forEach((x) => x.classList.remove('on')); b.classList.add('on'); 74 ctx.toast('ð¼ï¸', 'Wallpaper', name); 75 }; 76 walls.appendChild(b); 77 }); 78 79 /* screen saver idle time */ 80 const SS = [['Off', 0], ['1 min', 1], ['3 min', 3], ['5 min', 5], ['10 min', 10]]; 81 const ssEl = el.querySelector('.set-ss'); 82 const curIdle = (() => { const v = parseFloat(localStorage.getItem('cz-ss-idle')); return isNaN(v) ? 5 : v; })(); 83 SS.forEach(([label, min]) => { 84 const b = document.createElement('button'); 85 b.className = 'set-mode' + (min === curIdle ? ' on' : ''); 86 b.textContent = label; 87 b.onclick = () => { 88 ssEl.querySelectorAll('.set-mode').forEach((x) => x.classList.toggle('on', x === b)); 89 window.__screensaver && window.__screensaver.setIdle(min); 90 ctx.toast('ð¥ï¸', 'Screen saver', min ? `Starts after ${label} idle` : 'Off'); 91 }; 92 ssEl.appendChild(b); 93 }); 94 95 /* accent */ 96 const accents = el.querySelector('.set-accents'); 97 const savedAccent = localStorage.getItem('cz-accent') || ACCENTS.Blue; 98 Object.entries(ACCENTS).forEach(([name, c]) => { 99 const b = document.createElement('button'); 100 b.className = 'set-accent' + (c === savedAccent ? ' on' : ''); 101 b.style.background = c; b.title = name; 102 b.onclick = () => { 103 root.style.setProperty('--accent', c); localStorage.setItem('cz-accent', c); 104 accents.querySelectorAll('.set-accent').forEach((x) => x.classList.remove('on')); b.classList.add('on'); 105 ctx.toast('ð¨', 'Accent', name); 106 }; 107 accents.appendChild(b); 108 }); 109 110 /* toggles */ 111 const rm = el.querySelector('.set-rm'); rm.checked = root.classList.contains('rm'); 112 rm.onchange = (e) => { root.classList.toggle('rm', e.target.checked); ctx.toast('â', 'Reduced motion', e.target.checked ? 'On' : 'Off'); }; 113 el.querySelector('.set-boot').onchange = (e) => { 114 if (e.target.checked) sessionStorage.removeItem('cz-booted'); else sessionStorage.setItem('cz-booted', '1'); 115 }; 116}
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.