diff --git a/docs/designs/decisions/ui/DL-431.md b/docs/designs/decisions/ui/DL-431.md new file mode 100644 index 000000000..d76ca82bc --- /dev/null +++ b/docs/designs/decisions/ui/DL-431.md @@ -0,0 +1,6 @@ +--- +id: DL-431 +decision: "Settings is one view with a section nav (vertical `.cx-tabs` links, a horizontal strip under a 560px pane) that shows one section at a time; each section is a route, `/settings/:section`, part of the view's `RouteMatch`. Bare `/settings` is not canonical: the catch-all becomes `RedirectCanonical`, which sends a view to `routePath` of its parsed route, so `/settings` lands on the first section" +status: "Active (Matt, 2026-10-07)" +record: ../../ui/compass-settings/design.md#a3--route +--- diff --git a/docs/designs/decisions/ui/DL-432.md b/docs/designs/decisions/ui/DL-432.md new file mode 100644 index 000000000..22b188fad --- /dev/null +++ b/docs/designs/decisions/ui/DL-432.md @@ -0,0 +1,6 @@ +--- +id: DL-432 +decision: "Settings has no Tracker section: the client-side tracker editor and `AppStore.setTrackerConfig` are deleted, since the config they edit reaches only the fixture seam and the server maps tracker status (DL-129); a server-backed Tracker section returns with the tracker contract" +status: "Active (Matt, 2026-10-08)" +record: ../../ui/compass-settings/design.md#resolved-questions +--- diff --git a/docs/designs/decisions/ui/DL-433.md b/docs/designs/decisions/ui/DL-433.md new file mode 100644 index 000000000..000e5355c --- /dev/null +++ b/docs/designs/decisions/ui/DL-433.md @@ -0,0 +1,6 @@ +--- +id: DL-433 +decision: "A Settings row is a two-column grid, label and help on the left and the control on the right, with a line between rows and no card, radius, or fill; controls are only `.cx-input`, `.cx-select`, and `.cx-btn` (`aria-pressed` buttons for two or three choices); Settings adds no box style and no switch primitive" +status: "Active (Matt, 2026-10-07)" +record: ../../ui/compass-settings/design.md#a2--layout +--- diff --git a/docs/designs/decisions/ui/DL-434.md b/docs/designs/decisions/ui/DL-434.md new file mode 100644 index 000000000..3dedf0fcf --- /dev/null +++ b/docs/designs/decisions/ui/DL-434.md @@ -0,0 +1,6 @@ +--- +id: DL-434 +decision: "The Settings save model is per section, with no page-level Save: a device preference applies and stores on click; each Providers action is its own RPC with its own pending and error state on its row; read-only rows have none" +status: "Active (Matt, 2026-10-07)" +record: ../../ui/compass-settings/design.md#a4--save-model-per-section +--- diff --git a/docs/designs/decisions/ui/DL-435.md b/docs/designs/decisions/ui/DL-435.md new file mode 100644 index 000000000..65b555adc --- /dev/null +++ b/docs/designs/decisions/ui/DL-435.md @@ -0,0 +1,6 @@ +--- +id: DL-435 +decision: "Compass has no in-app usage-data control: the deployer decides at build time whether a build sends usage data. A control may be added later; none is planned" +status: "Active (Matt, 2026-10-08)" +record: ../../ui/compass-settings/design.md#resolved-questions +--- diff --git a/docs/designs/decisions/ui/DL-436.md b/docs/designs/decisions/ui/DL-436.md new file mode 100644 index 000000000..655056762 --- /dev/null +++ b/docs/designs/decisions/ui/DL-436.md @@ -0,0 +1,6 @@ +--- +id: DL-436 +decision: "Settings openers (`Mod+,`, `G S`, the palette, the sidebar link) follow DL-390 with no exception: a plain open navigates the focused view to the last Settings section shown in the window, bare `/settings` redirects to the first, and only `Mod`+click or middle-click opens a deduped tab" +status: "Active (Matt, 2026-10-08)" +record: ../../ui/compass-settings/design.md#a3--route +--- diff --git a/docs/designs/ui/compass-settings/design.md b/docs/designs/ui/compass-settings/design.md new file mode 100644 index 000000000..005245b85 --- /dev/null +++ b/docs/designs/ui/compass-settings/design.md @@ -0,0 +1,322 @@ +# Compass Settings page + +Builds on: brand parity (`compass-brand-parity/design.md`, open PR #1915: +square corners, weights, surfaces, `--cx-border-field`, text-entry +primitives), [UX foundation](../compass-ux-foundation/design.md) +Refs: RIG-4775 (this record); RIG-3121 (Providers, task E5 of the +[gateway OAuth enrollment record](../../server/compass-gateway-oauth-enrollment/design.md)); +ledger DL-431 to DL-436 +Depends on: brand-parity T9 (S1); enrollment E3 (S5) + +## Problem / Intent + +Matt's ask: "Settings styling and layout are bad, and we likely need many +more settings. Write a full settings design (sections, which settings +exist, layout), then implement." + +Today Settings is one page that edits the tracker config. Defects (from +`SettingsView.tsx`, the `.settings-*` rules in `app.css`, and +`settings.png`): + +1. **Bespoke boxes.** `.settings-input`/`.settings-select` and + `.settings-btn*` copy `.cx-input` and `.cx-btn`. +2. **Raw sizes and bold.** `14px`/`12px` heads at weight `600`, `11px` + labels, a `10px` gap; none is a token. +3. **Rounded cards.** `.settings-section` has `--cx-radius-md`. +4. **Fixed widths and wrapping.** `100px` and `140px` status columns clip + long names; the `flex-wrap` fields row breaks into ragged lines. +5. **One page, no sections.** Editor and model registry share one scroll + and one route. +6. **The one edit does little.** The store always uses the fixture seam, + which ignores its `_config`; `setTrackerConfig` rebuilds it, but only + the handle reaches the fixture queue. The kind and the status map + change nothing, and the server maps tracker status itself (DL-129). + Nothing shows the server, account, motion, or providers. + +Brand-parity T2a and T9 fix defects 2 and 3 (they sweep every radius and +`font-weight: 600` in `app.css`). This record fixes the rest: one view +with a section nav, a route per section, one row anatomy on the shared +primitives, and a save model per section. It deletes the tracker editor +(defect 6). + +## Approach + +### A1 — Sections and settings + +Four sections, in nav order. + +- **General** (`general`): Server URL (`connection.baseUrl`, the + transport's URL in both hosts); Mode (`shellMode()`: none → Browser, + `"embedded"` → Embedded server, `"client"`/`"setup"`/`"reopen"` → + Remote server, since setup reaches the app only by connecting and + reopen never mounts it); Server version (`version`, `api_version`, and + `rev` from `GetServerInfo`; "Not connected" when `store.daemon().live` + is false); Signed in as (`store.caller()` handle and display name); a + Keyboard shortcuts button that opens the overlay. New. +- **Appearance** (`appearance`): Reduce motion, Follow system or Always, + per device in localStorage `compass.settings.reduceMotion`. Always sets + `:root[data-reduce="on"]`, which the CSS honors and nothing sets. New. +- **Models** (`models`): the model registry, read-only. Exists. +- **Providers** (`providers`): enrollment E5 (A5). Needs E3 + (`ProviderEnrollmentService`), not yet in the proto, Go, or the UI. + +Not in this record: a Tracker section (DL-432: S4 deletes the editor; a +server-backed one returns with the tracker contract); a usage-data +control (DL-435: the deployer decides at build time); server URL edits +(deferred, native server URL record OQ-5); browser sign-out (no +signed-out boot path); a day theme (D2, "later"); key remap (deferred; a +Keyboard section comes with it); notifications (none exist); Secrets +(`SecretsService` overlaps the Providers key entry; its own design after +E5); Replay tour (a General row once the tour UI merges); +`GetAgentConfigInfo` (fleet member names, not a preference; a later +Fleet section); pins and window layout (set in place). + +### A2 — Layout + +`.settings-view` is a grid of two columns: the section nav and the body. + +- **Nav.** `