samsa/docs/superpowers/specs/2026-03-22-settings-ui-design.md
Franz Kafka 8e9aae062b
Some checks failed
Build and Push Docker Image / build-and-push (push) Failing after 11s
Mirror to GitHub / mirror (push) Failing after 5s
Tests / test (push) Successful in 42s
rename: kafka → samsa
Full project rename from kafka to samsa (after Gregor Samsa, who
woke one morning from uneasy dreams to find himself transformed).

- Module: github.com/metamorphosis-dev/kafka → samsa
- Binary: cmd/kafka/ → cmd/samsa/
- CSS: kafka.css → samsa.css
- UI: all 'kafka' product names, titles, localStorage keys → samsa
- localStorage keys: kafka-theme → samsa-theme, kafka-engines → samsa-engines
- OpenSearch: ShortName, LongName, description, URLs updated
- AGPL headers: 'kafka' → 'samsa'
- Docs, configs, examples updated
- Cache key prefix: kafka: → samsa:
2026-03-22 23:44:55 +00:00

3 KiB
Raw Blame History

Settings UI Design — samsa

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

const DEFAULT_PREFS = {
  theme: "system",
  engines: ["wikipedia", "arxiv", "crossref", "braveapi", "qwant", "duckduckgo", "github", "reddit", "bing"],
  safeSearch: "moderate",
  format: "html"
};

Persistence

// Written on every interaction
localStorage.setItem('samsa_prefs', JSON.stringify({ ... }));

// Read on page load — merge with DEFAULT_PREFS
const saved = JSON.parse(localStorage.getItem('samsa_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 <body>
  • samsa.css — popover styles, toggle switch styles, bottom sheet styles for mobile
  • settings.js — localStorage read/write, theme application, panel toggle, aria attributes, focus trap