# 07 · Settings

Astrolabe lets users tune appearance, the spec editor, preview performance, and date formatting. Rather than a separate Settings modal, **each preference lives next to what it affects and applies immediately** — the appearance theme is a header toggle, editor preferences sit in the editor pane, render performance in the preview pane, and date formatting in the library. All settings persist locally and apply across sessions on the same device. Settings load at startup; any unknown or missing value falls back to its factory default, so older or partial saved settings never break the app.

> **Why distributed, not a modal (resolved).** Settings were originally specified as one central modal with an explicit Apply/Cancel commit. A design review (see _Architecture 10 · Interaction & Feedback_) moved them to per-pane, live-applied controls: it matches how theme and preview fit mode already work, lets a change’s effect be seen in the very pane being configured, and keeps each settings block independently extensible. The settings, options, and defaults below are unchanged — only their presentation and commit model changed.

## Opening the settings

- **Appearance (UI theme)** is a one-click toggle in the application header.
- **Editor**, **Performance**, and **Formatting** clusters are each opened by a small **settings (gear) control** in the toolbar of the pane they govern — the editor pane, the preview pane, and the library, respectively. The control discloses a popover of that cluster’s controls.
- The keyboard shortcut **Cmd/Ctrl+,** opens the **Editor** settings cluster (the primary configuration surface).
- A disclosed popover is dismissed with **Esc** (which returns focus to its gear) or by clicking outside it; at most one settings popover is open at a time.

## Settings

### Appearance

Controls the overall UI theme. Choosing the Dark theme switches the whole application chrome to a dark presentation.

| Setting  | Options     | Default |
| -------- | ----------- | ------- |
| UI theme | Light, Dark | Light   |

The UI theme is a one-click **header toggle** (shipped in M1.5). It reads and
writes the persisted `ui.theme` value directly and applies immediately — there is
no separate Appearance control to keep in sync.

### Editor

These settings configure the spec editor used to edit Vega-Lite specs (see _Spec Editor & Draft/Published Workflow_). They take effect in the editing surface for the snippet spec.

| Setting      | Options / Range                                    | Default |
| ------------ | -------------------------------------------------- | ------- |
| Font size    | 10–18 px (integer)                                 | 12 px   |
| Editor theme | Auto + explicit overrides (provisional — see note) | Auto    |
| Minimap      | On / Off                                           | Off     |
| Word wrap    | On / Off                                           | On      |
| Line numbers | On / Off                                           | On      |
| Tab size     | Integer number of spaces                           | 2       |

- Font size is chosen along a 10–18 range; the current value is shown alongside the control.
- Editor theme controls the syntax/color presentation inside the editor. **Provisional (to be finalized as we implement the editor):** the default is **Auto**, which derives the editor theme from the app UI theme (light app theme → light editor theme, dark → dark), using custom Monaco themes that match the app chrome. The user may override Auto with an explicit editor theme; the exact override list (custom themes, and whether to include High Contrast or the stock Monaco themes) is deferred. Stored as `editor.theme` with an `'auto'` sentinel for the follow-the-app default.
- Minimap toggles the condensed overview strip beside the editor.
- Word wrap toggles soft wrapping of long lines.
- Line numbers toggles the line-number gutter.
- Tab size sets the indentation width applied while editing.

### Performance

| Setting         | Range       | Default |
| --------------- | ----------- | ------- |
| Render debounce | 500–5000 ms | 1500 ms |

- Render debounce is the delay after the user stops typing before the preview re-renders (see _Live Preview_).
- Tradeoff: a lower value makes the preview feel snappier and more immediate but re-renders more often and uses more CPU; a higher value keeps the app calmer and lighter but makes the preview feel laggier behind the spec.
- The current value is shown alongside the control.

### Formatting

Governs how dates are rendered throughout the app, for example the timestamps shown in the _Snippet Library_ list.

| Setting            | Options                 | Default |
| ------------------ | ----------------------- | ------- |
| Date format        | Smart, ISO 8601, Custom | Smart   |
| Custom date format | Free-text format string | (empty) |

- **Smart**: relative, human-friendly rendering (e.g. "Today", "Yesterday", "3d ago", falling back to a full date for older items).
- **ISO 8601**: a full ISO 8601 timestamp.
- **Custom**: dates render using the user-supplied format string.
- The custom format string field is only relevant when Date format is set to Custom; it is shown only in that case (placeholder guidance such as `yyyy-MM-dd HH:mm`).

## Related persisted preferences (documented elsewhere)

The following preferences also persist locally across sessions and, like the clusters above, are managed by controls in the pane they affect; they are documented in their own sections:

- **Preview fit mode** — how the preview is sized/fit; see _Live Preview_.
- **Chart theme** — which config charts render and export with (`ui.chartTheme`); see _Live Preview → Chart theme_.
- **Snippet sort preference** — the snippet list's sort field and direction; see _Snippet Library_.

## Behaviors

- **Live apply**: Every control applies its change immediately — there is no Apply/Cancel commit step. The effect is visible in the pane being configured (the editor reflows, the preview re-renders at the new debounce, the library re-formats its dates), so no separate confirmation is needed. This matches the always-live header theme toggle and preview Fit control.
- **Reset to defaults**: The **Editor** cluster offers a Reset that restores the editor settings to their factory defaults. (Other clusters are single, self-evident controls; there is no global "reset everything" — each control is individually reversible.)
- **No dirty / discard state**: Because changes commit as made, there is no "unsaved changes" indicator and nothing to discard on dismiss; closing a settings popover simply hides it.
- **Startup load**: Settings are read on startup and applied to the UI, editor, preview, and library; missing or unrecognized values silently use their defaults.
