Documents v0.9.0 · previews run the real runtime · experimental features are marked exp

Control Center

advanced example

A real settings form: native radios, a checkbox and a text field. Reactive CSS binds them to four states that drive a live preview; saving stays with the browser and your server. Change a setting, then follow it from the control to the state and the result.

usesnative
<form>radiocheckbox:has():user-invalid@media
source
preview · runtimelocal state · nothing saved
trace

Interact with the preview to see how state flows through CSS. Every value here is observed in the running preview.

no script needed
/* Layout and typography live in base.css, shared by both versions. */
/* ── State ───────────────────────────────── */
/* In memory only. Saving is the form's job. */
.control-center {
--theme: state("light");
--accent: state("ember");
--notify: state(true);
--name: state("Alex Rivera");
}
/* ── Controls → state ────────────────────── */
/* Each control copies its value into the form's state when it changes. */
.theme input:on(change) { --theme: set(event(value)); }
.accent input:on(change) { --accent: set(event(value)); }
.notify input:on(change) { --notify: set(event(checked)); }
.profile input:on(input) { --name: set(event(value)); }
/* A form reset puts the controls back to their HTML defaults: the states follow. */
.control-center:on(reset) {
--theme: set("light");
--accent: set("ember");
--notify: set(true);
--name: set("Alex Rivera");
}
/* ── Theme ───────────────────────────────── */
.control-center {
--bg: #fbfaf7;
--fg: #1c1917;
--muted: #78716c;
background: var(--bg);
color: var(--fg);
transition: background 200ms, color 200ms;
}
.control-center:when(--theme == "dark") {
--bg: #1c1917;
--fg: #f5f5f4;
--muted: #a8a29e;
}
@media (prefers-color-scheme: dark) {
.control-center:when(--theme == "system") {
--bg: #1c1917;
--fg: #f5f5f4;
--muted: #a8a29e;
}
}
/* ── Accent ──────────────────────────────── */
.control-center { --tint: #c8462c; }
.control-center:when(--accent == "moss") { --tint: #3f7a5a; }
.control-center:when(--accent == "slate") { --tint: #4d6284; }
/* ── Native control states ───────────────── */
.theme label:has(:checked) {
background: var(--fg);
color: var(--bg);
}
.control-center input {
accent-color: var(--tint);
}
.notify input:checked {
background: var(--tint);
}
.profile input:user-invalid {
border-color: #b42318;
}
/* ── Notifications ───────────────────────── */
.notify .status::after {
content: when(--notify, "On", "Muted");
}
/* ── Live preview ────────────────────────── */
.preview .avatar { background: var(--tint); }
.preview .name::after { content: var(--name); }
.preview .bell {
opacity: when(--notify, 1, 0.4);
}
.preview .badge {
display: none;
background: var(--tint);
}
.preview .badge:when(--notify) {
display: inline-grid;
}
.preview .alert {
border-color: when(--notify, var(--tint), var(--muted));
opacity: when(--notify, 1, 0.6);
}
.preview .alert-text::after {
content: when(--notify, "Sam replied to your comment", "Notifications are muted");
}
inspector

Select any red expression or state name in style.css, a step in the trace, or a row in the state panel. Hover previews it, a click pins it.

Keyboard: Tab reaches each expression; Enter pins it, Escape clears it.

stateowned by .control-center
statevalueprevious
Appearance
Notifications
Profile

Changing state is not saving data

The same controls feed two separate paths. One updates the page as you type. The other only runs when the form is submitted.

live · in memory · Reactive CSS
inputbind:state()preview

Runs on every keystroke and click. A state lives in memory and resets on reload. Reactive CSS has no storage, never writes to localStorage and makes no network requests.

saved · native HTML and your server
<form>submitPOST /settingsserver

The browser validates and sends every named control, with or without Reactive CSS. Persistence, authentication and server-side validation stay in your application.

  • Unchecked checkboxes are left out of submitted data. Treat a missing notifications field as off on the server.
  • Reset is native too. The form restores its HTML defaults and the :on(reset) rule restores each state’s initial value, so keep the two in agreement.
  • The preview runs the real runtime in a sandboxed frame. Save settings is stopped before it is sent and shows the form data instead, because this page has no server.