diff --git a/docs/superpowers/specs/2026-03-22-settings-ui-design.md b/docs/superpowers/specs/2026-03-22-settings-ui-design.md new file mode 100644 index 0000000..8029dc8 --- /dev/null +++ b/docs/superpowers/specs/2026-03-22-settings-ui-design.md @@ -0,0 +1,80 @@ +# Settings UI Design — kafka + +**Date:** 2026-03-22 +**Status:** Approved + +## Overview + +A lightweight preferences popover anchored to the top-right, just below the header. Triggered by a gear icon, it lets users adjust theme, enabled engines, and search defaults without leaving their current page. All changes auto-save to `localStorage` on every interaction. + +## Layout & Structure + +- **Trigger**: Gear icon (⚙️) in the top-right header, aligned with the header's right edge +- **Panel**: 280px wide, max-height 420px, scrollable internally, rounded corners, subtle shadow, anchored top-right (drops down from trigger, like a dropdown) +- **Close**: × button in panel header, click outside the panel, or pressing Escape +- **No Save button** — every interaction immediately writes to `localStorage` + +## Interaction Flow + +1. User clicks ⚙️ → panel drops down from top-right (200ms ease) +2. User toggles/clicks → changes apply instantly to DOM + write to `localStorage` +3. User clicks × or outside or Escape → panel closes, settings persist +4. **Accessibility**: Focus is trapped within the panel while open. Trigger button uses `aria-expanded` and `aria-controls`. Escape key closes the panel. + +## Mid-Search Changes + +When opened during an active search on `results.html`: +- Engine toggles update `localStorage` immediately, but **current results remain unchanged** +- A subtle inline note below the engines section: *"Engine changes apply to your next search"* + +## Sections + +### Appearance + +- Three theme buttons: ☀️ Light / 🌙 Dark / 💻 System +- Clicking immediately applies via `document.body.classList` + writes to localStorage +- "System" reads `prefers-color-scheme` and updates on change + +### Engines + +- 2-column grid of toggle switches for all 9 engines +- Each row: engine name + toggle switch +- Enabled = filled accent color; Disabled = gray outline + +### Search Defaults + +- Safe search: dropdown (Moderate / Strict / Off) +- Default format: dropdown (HTML / JSON / CSV) + +## Default State + +```js +const DEFAULT_PREFS = { + theme: "system", + engines: ["wikipedia", "arxiv", "crossref", "braveapi", "qwant", "duckduckgo", "github", "reddit", "bing"], + safeSearch: "moderate", + format: "html" +}; +``` + +## Persistence + +```js +// Written on every interaction +localStorage.setItem('kafka_prefs', JSON.stringify({ ... })); + +// Read on page load — merge with DEFAULT_PREFS +const saved = JSON.parse(localStorage.getItem('kafka_prefs') || '{}'); +const prefs = { ...DEFAULT_PREFS, ...saved }; +``` + +## Responsive Behavior + +- **Mobile (<768px)**: Panel becomes a **bottom sheet** — 100% width, slides up from the bottom, top corners rounded, max-height 70vh. Trigger moves to a fixed bottom-right FAB button. +- Panel never covers the search input + +## Applied to Existing Code + +- `base.html` — add gear button in header, panel markup at end of `` +- `kafka.css` — popover styles, toggle switch styles, bottom sheet styles for mobile +- `settings.js` — localStorage read/write, theme application, panel toggle, aria attributes, focus trap