Summary
Explore a trimmed-down e-ink mode for the client so deckd can run as a long-lived control surface on an e-ink Android device (Boox / Bigme class), reviving the original "dedicated low-power display" idea while keeping the web-app renderer.
Assume black-and-white (2-colour) e-ink for this work. Colour e-ink (Kaleido 3) is muted and lower-res on the colour layer; designing mono-first is simpler and degrades gracefully to colour panels. Parked for now — filing to dive in later.
Why deckd is a good fit
The core deck is a static button grid that only repaints on discrete events (focus switch, button press) — exactly what e-ink holds well at ~zero power. The work is not "make the app work on e-ink"; it's isolating the few live/animated elements that break e-ink and giving them an e-ink behaviour. Most of that is an extension of the existing prefers-reduced-motion / .a11y-high-contrast paths.
Known live/animated offenders (from a code pass)
- Meters/stats — 1 Hz updates, each firing a 250 ms width+colour transition + HSL gradient recompute (
client/src/MeterCell.tsx:122, client/src/meter-store.ts). Worst offender: constant partial refresh → ghosting. Mono panel also has no equivalent for the HSL fill gradient (needs fill-% / hatching / number).
- Pulsing indicators — connection dot (1.1 s) and media playback dot (1.6 s) animate forever with no semantic need.
- Press feedback — 80 ms scale-down + brightness filter.
- Jogstrip momentum scroll — continuous motion; replace with page-step on e-ink.
Grid layout itself (client/src/ButtonGrid.tsx, CSS Grid, fixed-pixel cells, no transforms) is already e-ink-friendly.
The one hard constraint
A browser tab cannot control the e-ink refresh mode. Refresh-mode control (full vs A2/fast vs Super-Refresh) is native-only via the Onyx SDK, applied to Android Views incl. WebView (OnyxAndroidDemo). This forks the effort:
- Path A — browser + "e-ink mode" (cheap, do first): a client mode/toggle that kills animation, freezes/strips meter transitions, renders mono-first, disables momentum. Works on any e-ink Android browser, zero native code, reuses PWA +
?demo= / gallery infra. Also useful as a generic "static/low-power" theme on normal phones. At the mercy of the device's global refresh setting.
- Path B — thin native WebView wrapper (unlocks the appliance vision): small Kotlin shell loading the existing client, using the Onyx SDK for per-view refresh mode, kiosk/fullscreen, wake/doze management, and a full refresh on layout switch to clear ghosting. Keeps 100% of the React renderer. Only path that gives true always-on.
Power / connection reality
An e-ink Android tablet running Chrome + persistent WebSocket + Wi-Fi is not a low-power appliance the way dedicated e-ink firmware is (panel is ~0W at rest; SoC/radio/wake-lock aren't). Doze/Wi-Fi sleep will repeatedly drop the socket. Decide between:
- Presence model — static image at rest, reconnect on tap (battery-friendly), vs
- Always-on wake lock — usable instantly but burns battery (conflicts with the low-power goal; Path B gets native control here).
Open questions to resolve when we pick this up
Scope for a first cut (Path A)
An e-ink mode toggle (settings + ?eink=1 dev override, matching the existing query-param pattern) that: disables all animations/pulses, freezes meter transitions (or hides live widgets), forces a high-contrast mono palette (borders/icons/labels carry identity, not fills), and disables jogstrip momentum. Eyeball-able in the existing gallery/?demo= infra with no hardware.
Captured from a research discussion; not yet started.
Summary
Explore a trimmed-down e-ink mode for the client so deckd can run as a long-lived control surface on an e-ink Android device (Boox / Bigme class), reviving the original "dedicated low-power display" idea while keeping the web-app renderer.
Assume black-and-white (2-colour) e-ink for this work. Colour e-ink (Kaleido 3) is muted and lower-res on the colour layer; designing mono-first is simpler and degrades gracefully to colour panels. Parked for now — filing to dive in later.
Why deckd is a good fit
The core deck is a static button grid that only repaints on discrete events (focus switch, button press) — exactly what e-ink holds well at ~zero power. The work is not "make the app work on e-ink"; it's isolating the few live/animated elements that break e-ink and giving them an e-ink behaviour. Most of that is an extension of the existing
prefers-reduced-motion/.a11y-high-contrastpaths.Known live/animated offenders (from a code pass)
client/src/MeterCell.tsx:122,client/src/meter-store.ts). Worst offender: constant partial refresh → ghosting. Mono panel also has no equivalent for the HSL fill gradient (needs fill-% / hatching / number).Grid layout itself (
client/src/ButtonGrid.tsx, CSS Grid, fixed-pixel cells, no transforms) is already e-ink-friendly.The one hard constraint
A browser tab cannot control the e-ink refresh mode. Refresh-mode control (full vs A2/fast vs Super-Refresh) is native-only via the Onyx SDK, applied to Android Views incl. WebView (OnyxAndroidDemo). This forks the effort:
?demo=/ gallery infra. Also useful as a generic "static/low-power" theme on normal phones. At the mercy of the device's global refresh setting.Power / connection reality
An e-ink Android tablet running Chrome + persistent WebSocket + Wi-Fi is not a low-power appliance the way dedicated e-ink firmware is (panel is ~0W at rest; SoC/radio/wake-lock aren't). Doze/Wi-Fi sleep will repeatedly drop the socket. Decide between:
Open questions to resolve when we pick this up
Scope for a first cut (Path A)
An e-ink mode toggle (settings +
?eink=1dev override, matching the existing query-param pattern) that: disables all animations/pulses, freezes meter transitions (or hides live widgets), forces a high-contrast mono palette (borders/icons/labels carry identity, not fills), and disables jogstrip momentum. Eyeball-able in the existing gallery/?demo=infra with no hardware.Captured from a research discussion; not yet started.