Reactor
Goal
A visual gut-check on how closely daily life is actually tracking the life I say I want. This month's one-off objectives sit above; below them is a switchboard of standing habits and behaviors, each one worth a positive or negative number depending on whether it's on or off. The running total — "net trajectory" — is the number that matters, not any single switch: too many negatives and the ship is drifting into a future I don't want; enough positives and it pulls the other way.
Four views, one tiny nav
A small nav bar up top switches between four views, all reading and writing the same state so they never drift out of sync:
- Reactor (the default landing view) — the circular power-core visual, as close to the whole page as it can get with just a "from switches ON / OFF" + Momentum + net-trajectory readout above it and a legend/hint below. The outer ring is one segment per switch, grouped and colored by category, lit when that switch is on. The center stays visually empty, like the core of a reactor, except for a ring of small LEDs — one per goal — green when done, red until then. Click or tab any segment or center LED to toggle it. A small "Full screen" button on the visual expands just the reactor (via the Fullscreen API), hiding everything else for a clean, single-focus view. The dashed outer bezel doubles as a momentum gauge — see "The momentum ring" below.
- Console (Goals) — the one-time goals as a checklist. Add one with "+ Add a goal" (text, optional target, optional "committed to someone else" tag) and remove any with its ×.
- Modules — the switchboard, in two densities per row. The default view is deliberately plain: category (the section heading), module name (read-only), notes (read-only, shown only if present), status/staleness LEDs, and the on/off lever — nothing to accidentally edit. Click Edit on a row to expand "Edit Module" mode, which adds on-value, off-value, build rate, decay rate, an editable notes field, a 📡 Signal button (see below), and a delete button. Click Done to collapse it back down. The "+ Add a switch" form (still simple: label, category, on/off value) lives here too.
- Settings — stale-day timing, category management, a Signals scaffolding section (see below), export/import, reset.
Toggle color means something specific
A toggle's color reads the value its current state carries, not just whether it's on or off — some switches are habits you want ON (make the bed), others are habits you want OFF (checked the phone within 5 minutes of waking), so "on" can't always mean "good." Four tones:
- Green — on, and that's a net positive.
- Red — the current state (on or off) is a net negative.
- Faded blue — off, and that's the point (a positive value earned by staying off).
- Grey — the current state is worth exactly 0.
This applies to the lever, its status LED, and the reactor ring's per-slice LED. It's a first pass — expect it to keep getting refined.
The momentum ring
The reactor's outermost dashed bezel spins — very slowly — to give a glanceable read on where things stand overall, separate from the numeric readouts. It's a straight percentage of how many switches are currently net-positive vs. net-negative (not weighted by how big any one switch's value is): speed = (positiveCount − negativeCount) / totalCount × 10, so it always lands somewhere in −10 to +10.
- Positive → spins clockwise, dashes tinted green. More positive, faster (though "fast" tops out at a full rotation every ~30s at the extreme +10 — this is meant to be ambient, not a stopwatch).
- Negative → spins counter-clockwise, dashes tinted red. Same speed scaling.
- Exactly zero (an even split, or no switches at all) → stationary, blinking a soft amber instead of spinning.
Momentum: the build/decay layer
This is the start of turning Reactor into something more gamified — rewarding staying in a good state, not just being in one at the instant you check. Every module (switch) now carries two more numbers, build and decay, both defaulting to 0 ("neutral" — no effect at all):
- Build — while a switch is ON, how fast it ramps up to counting its full
onValuetoward Momentum.0means it never ramps past zero credit;1means it reaches full credit after being held ON for about a day; higher numbers ramp faster. - Decay — the same idea while a switch is OFF, ramping toward its full
offValue.
Momentum (shown in the top dashboard, next to Net trajectory) is the sum of every switch's currently earned credit under this ramp — so it's always somewhere between 0 and the same ceiling Net trajectory already shows (the "→ N ceiling" subtext is that ceiling, i.e. exactly what Net trajectory reads right now). Flip a switch and its ramp resets — Momentum dips and has to climb back. Hold state, and it climbs. This is a first pass at the mechanic — the plan is to watch how it feels in real use and retune the formula (curve shape, whether flipping should keep partial credit, per-category weighting, etc.) rather than treat this as final.
Planned: signal output
Long-term, the idea is for Reactor to be able to fire real signals out to something like a Raspberry Pi or other small receiver — so a module turning on or off could cue a real-world action (a light in the room, for instance). Nothing here does that yet; what exists today is scaffolding for it to land in later without a rewrite:
- Settings → Signals has a disabled "enable signal output" toggle and a receiver-address field, plus
RX.state.signals({ enabled, receiver }) already flows through Export/Import so a future implementation has somewhere to read its config from. - Every switch's Edit Module panel has a 📡 Signal button that opens a panel explaining the plan — no per-switch signal config is stored yet, since the actual protocol (what a "signal" even is — a webhook? MQTT? something proprietary to the receiver?) isn't decided.
Current state
v1. Data lives in this browser's localStorage and can be exported to JSON and re-imported, so moving to a new browser or device is a manual but lossless step. Built as a small multi-file app (assets/data.js, assets/console-view.js, assets/reactor-view.js, assets/app.js, assets/styles.css) instead of one file, specifically so the next round of changes — a switchboard settings page, adjustable stale-day timing per switch, a daily-life "sci-fi cockpit" section with metal toggle aesthetics — have somewhere to land without a rewrite.
Notes
- No build step, no server —
assets/data.jsis the seed content (sample goals, sample categories, sample switches, meant to demonstrate the tool to a first-time visitor); anything added through the page itself (add/edit/remove a switch, category, or goal, flipping a lever) is stored in localStorage and wins over the seed on every later load. - Categories, switches, and goals are all fully editable from the page — add, rename, or remove any of them with no code edits required. Removing a category reassigns any of its switches to "Other" rather than deleting them. All three are included in Export/Import, same as settings and signals config —
RX.normalizeState()inassets/data.jsis the one place that shape gets brought up to current, shared by both a fresh page load and a picked Import file, specifically so importing an old file can't skip a migration a normal load would have run. - A file exported before categories/goals became editable state (i.e. from a version of this tool where they were hardcoded, not saved data) genuinely has no category or goal data to restore — that data never existed in exported form. Importing such a file correctly falls back to the current placeholder categories/goals rather than losing anything, since there was nothing to lose.
- The reactor view rebuilds its SVG on every state change — cheap at this scale (dozens of switches), so no incremental-diffing complexity was worth adding yet.
Planned (from the original design notes, not yet built)
- A second major section below the switchboard for looser, "daily life" habits with their own notes field, separate from this month's fixed goals.
- Per-switch signal output — see "Planned: signal output" above.
- Retuning the Momentum build/decay curve based on how it feels in actual use — see "Momentum: the build/decay layer" above.
Changelog
- v1.3 — Goals gained add/remove (previously fixed at seed time, only completion was editable); Modules split into a plain default view and an "Edit Module" mode (on/off value, build/decay rate, editable notes, delete, signal button) toggled per row; new build/decay rates per switch feed a new gamified Momentum dashboard stat, a lagging/ramping version of Net trajectory; the reactor's outer bezel now spins very slowly (direction/color/speed from the current positive-vs-negative split of all switches) as a momentum gauge; added Settings → Signals scaffolding and a per-switch 📡 Signal panel for the planned Raspberry-Pi-style signal output (documented above, not yet functional); import/export migration logic centralized into
RX.normalizeState()so importing an old file runs the same migrations a normal load does. - v1.2 — Reactor is now the default landing view and as close to full-page as possible, with its own "Full screen" button; nav split into four tabs (Reactor / Console (Goals) / Modules / Settings) instead of two, with Settings promoted from a dropdown panel to its own view; toggle color now reads the switch's current value (green/red/faded-blue/grey) instead of conflating "on" with "good"; sample switchboard content replaced again with more generic, stereotypical self-help examples.
- v1.1 — seed content replaced with generic sample data so the public copy of this tool doesn't carry anyone's real tasks or goals; categories moved from a fixed list into editable state, with add/rename/remove UI in Settings and inclusion in Export/Import.
- v1 — initial build: console view (milestones + switchboard) migrated in, new reactor core view added, split into a small multi-file app under
assets/.