aboutsummaryrefslogtreecommitdiff
path: root/docs/prototypes/2026-07-02-desktop-settings-panel-prototype-4.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/prototypes/2026-07-02-desktop-settings-panel-prototype-4.html')
-rw-r--r--docs/prototypes/2026-07-02-desktop-settings-panel-prototype-4.html166
1 files changed, 166 insertions, 0 deletions
diff --git a/docs/prototypes/2026-07-02-desktop-settings-panel-prototype-4.html b/docs/prototypes/2026-07-02-desktop-settings-panel-prototype-4.html
new file mode 100644
index 0000000..23d72fb
--- /dev/null
+++ b/docs/prototypes/2026-07-02-desktop-settings-panel-prototype-4.html
@@ -0,0 +1,166 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Desktop Settings — Prototype 4 (instrument cluster)</title>
+<link rel="stylesheet" href="desktop-settings-shared.css">
+<style>
+ /* Instrument cluster: ring gauges for the levels, a rotary deck for power. */
+ .gauge-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
+ .gauge {
+ background: var(--well); border: 1px solid var(--line); border-radius: 12px;
+ padding: 10px; display: flex; flex-direction: column; align-items: center; gap: 6px;
+ }
+ .g-ring {
+ width: 92px; height: 92px; border-radius: 50%;
+ display: flex; align-items: center; justify-content: center;
+ position: relative;
+ }
+ .g-ring::before {
+ content: ""; position: absolute; inset: 9px; border-radius: 50%;
+ background: var(--ground); border: 1px solid var(--plate-edge);
+ }
+ .g-val { position: relative; z-index: 1; color: var(--cream); font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
+ .g-val .u { color: var(--dim); font-size: 11px; }
+ .g-name { color: var(--steel); font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; }
+ .g-fader { width: 100%; }
+ .g-fader input[type=range] {
+ -webkit-appearance:none; appearance:none; width: 100%; height: 5px; border-radius: 5px;
+ background: var(--ground); border: 1px solid var(--line); outline: none;
+ }
+ .g-fader input[type=range]::-webkit-slider-thumb {
+ -webkit-appearance:none; width: 12px; height: 12px; border-radius: 50%;
+ background: var(--cream); border: 1px solid var(--gold); cursor: pointer;
+ }
+ .rotary { display: flex; align-items: center; gap: 10px; background: var(--well); border: 1px solid var(--line); border-radius: 12px; padding: 8px 12px; }
+ .rotary .dial { width: 40px; height: 40px; border-radius: 50%; border: 2px solid var(--key-edge); position: relative; background: linear-gradient(180deg,#23211e,#191715); }
+ .rotary .dial .tick { position: absolute; top: 3px; left: 50%; width: 2px; height: 12px; background: var(--gold); transform-origin: 50% 17px; }
+ .rotary .opts { display: flex; gap: 6px; flex: 1; }
+ .rotary .opt { flex: 1; text-align: center; font-size: 11px; color: var(--dim); cursor: pointer; padding: 4px 2px; border-radius: 6px; }
+ .rotary .opt.cur { color: var(--gold); font-weight: 700; }
+ .rotary .opt:hover { color: var(--silver); }
+</style>
+</head>
+<body class="ds-stage">
+ <div class="ds-caption">
+ <b>Direction 4 — Instrument cluster.</b> The most literal control panel:
+ brightness and keyboard read as needle-ring gauges, power profile is a rotary
+ selector, toggles are lamp rows. Leans hardest into the faceplate aesthetic.
+ </div>
+
+ <div class="ds-bar"><span>19:24</span><span class="gear">⚙</span></div>
+
+ <div class="ds-panel" id="panel">
+ <div class="ds-face">
+ <span class="glyph">⚙</span>
+ <span class="title">Settings</span>
+ <span class="sub" id="scene-sub"></span>
+ <span class="x">✕</span>
+ </div>
+ <div id="body"></div>
+ <div class="ds-toast" id="toast"></div>
+ <div class="ds-subview" id="subview"></div>
+ </div>
+
+<script src="desktop-settings-shared.js"></script>
+<script>
+const h = DS.h;
+const body = document.getElementById("body");
+const subview = document.getElementById("subview");
+DS.bindToast(document.getElementById("toast"));
+
+function openWallpaper() {
+ subview.innerHTML = "";
+ subview.appendChild(DS.wallpaperSubview(() => subview.classList.remove("open")));
+ subview.classList.add("open");
+}
+
+function gauge(key) {
+ const meta = DS.SLIDERS[key];
+ const v = DS.state[key];
+ const g = h("div", "gauge");
+ const ring = h("div", "g-ring");
+ ring.style.background = `conic-gradient(var(--gold) ${v * 3.6}deg, #1a1917 0)`;
+ ring.innerHTML = `<span class="g-val">${v}<span class="u">%</span></span>`;
+ g.appendChild(ring);
+ g.appendChild(h("div", "g-name", meta.name));
+ const fw = h("div", "g-fader");
+ const inp = h("input"); inp.type = "range"; inp.min = meta.floor; inp.max = 100; inp.value = v;
+ inp.oninput = () => { ring.style.background = `conic-gradient(var(--gold) ${inp.value*3.6}deg, #1a1917 0)`; ring.querySelector(".g-val").innerHTML = `${inp.value}<span class="u">%</span>`; };
+ inp.onchange = () => DS.setSlider(key, +inp.value, g);
+ fw.appendChild(inp); g.appendChild(fw);
+ return g;
+}
+
+function rotary() {
+ const r = h("div", "rotary");
+ const idx = DS.PROFILES.findIndex((p) => p.id === DS.state.powerprofile);
+ const dial = h("div", "dial");
+ const angle = -50 + idx * 50; // three positions
+ dial.innerHTML = `<span class="tick" style="transform:translateX(-50%) rotate(${angle}deg)"></span>`;
+ r.appendChild(dial);
+ const opts = h("div", "opts");
+ DS.PROFILES.forEach((p) => {
+ const o = h("div", "opt" + (p.id === DS.state.powerprofile ? " cur" : ""), p.label);
+ o.onclick = () => DS.setProfile(p.id, r);
+ opts.appendChild(o);
+ });
+ r.appendChild(opts);
+ return r;
+}
+
+function lampRow(key) {
+ const meta = DS.TOGGLES[key];
+ const on = DS.state[key];
+ const el = h("div", "ds-key" + (on ? " on" : ""));
+ el.innerHTML =
+ `<span class="ds-lamp ${on ? "gold" : "off"}"></span>` +
+ `<span class="k-glyph">${meta.glyph}</span>` +
+ `<span class="k-name">${meta.name}</span>` +
+ `<span class="k-state">${on ? meta.on : meta.off}</span>`;
+ el.onclick = () => DS.setToggle(key, el);
+ return el;
+}
+
+function render() {
+ body.innerHTML = "";
+ const col = h("div", "ds-col");
+
+ col.appendChild(DS.engrave("Levels"));
+ const gr = h("div", "gauge-row");
+ gr.appendChild(gauge("brightness"));
+ gr.appendChild(gauge("kbd"));
+ col.appendChild(gr);
+
+ col.appendChild(DS.engrave("Power profile"));
+ col.appendChild(rotary());
+
+ col.appendChild(DS.engrave("Toggles"));
+ const well = h("div", "ds-well ds-col");
+ ["autodim", "nightlight", "touchpad", "mouse", "dnd"].forEach((k) => well.appendChild(lampRow(k)));
+ if (DS.state.laptop) well.appendChild(lampRow("airplane"));
+ well.appendChild(lampRow("caffeine"));
+ col.appendChild(well);
+
+ col.appendChild(DS.engrave("Scenes"));
+ const scenes = h("div", "ds-grid4");
+ Object.keys(DS.SCENES).forEach((n) => scenes.appendChild(DS.sceneKey(n)));
+ col.appendChild(scenes);
+
+ col.appendChild(DS.engrave("Actions"));
+ const acts = h("div", "ds-grid3");
+ acts.appendChild(DS.actionBtn("Lock", "\u{f033e}", false));
+ acts.appendChild(DS.actionBtn("Suspend", "\u{f04b2}", false));
+ acts.appendChild(DS.actionBtn("Wallpaper", "\u{f021c}", false, openWallpaper));
+ col.appendChild(acts);
+
+ body.appendChild(col);
+ document.getElementById("scene-sub").textContent = DS.state.scene ? "▶ " + DS.state.scene : "";
+}
+
+DS.onChange(render);
+render();
+</script>
+</body>
+</html>