Motion & Polish (the app's visual flourishes)
A master switch plus one toggle per visual flourish — the small animations and transitions that make the app feel finished. Everything is on by default, one switch turns it all off at once, an explicit opt-out is never overridden, and every effect quiets itself under your system's reduce-motion setting and Low-Power mode.
What it is
Settings → Appearance → Motion & Polish. A master switch plus per-effect toggles for Omniscio's visual flourishes. Everything is ON by default since 2026-07-16 — the polish is part of the first impression. The safety levers are unchanged: turning the master OFF still kills every effect at once, a user's explicit opt-out (master or per-effect) is never overridden, and all motion auto-quiets under the OS "reduce motion" setting and Omniscio's Low-Power mode. (Before 2026-07-16 the master defaulted off and only the "Liveliness" tier lit up with it; the flip unified everything to default-on.)
Mirrors the Chat Depth dial's plumbing: settings → Zod → a data-polish-* attribute on
<html> → gated CSS (or a component-level gate for motion that CSS can't express). Engineering
invariants + the tests that lock them: motion-polish-contract.md.
Where to find it
Settings → Appearance → Motion & Polish — the master switch and the per-effect toggles behind it.
How it behaves
How gating works
motionPolishEnabled(master, default on) gates EVERYTHING. An explicit master-off renders nothing — the one-switch kill.- Each effect has its own boolean, all default on (
?? trueat the gate mirrors the Zod.default(true), so a config that predates a key still gets the polished default; an explicit per-effectfalsesurvives independently). - The pure helper
computePolishAttributes(settings)(src/renderer/src/lib/motion-polish.ts) is the single source of truth;isPolishEffectOn(settings, effect)is its boolean form for component wiring. Both window roots (main + detached) apply the attributes. - Persistent-mode effects use a
data-polish-*attribute; transient/one-shot effects (Inbox Zero) gate viaisPolishEffectOnin a hook (an attribute can't represent a one-shot event). - Settings persist as DELTAS, so the default flip reaches every install that never touched the
toggles; only a persisted
falsekeeps an effect off.
The effects (all default on under the master)
| Toggle | What it does |
|---|---|
Interactive surfaces (polishInteractive) |
Buttons lift with a soft tinted shadow on hover. |
Dashboard motion (polishDashboard) |
Insights (codebase-stats) numbers count up from zero, and the stat cards cascade in when the panel opens. |
Ambient backgrounds (polishAmbient) |
A slow drifting accent gradient behind the big welcome ("No session selected") and "All clear" inbox screens. |
Depth & elevation (polishDepth) |
Panels and cards lift with a soft shadow. |
View crossfades (polishViewCrossfade) |
The Dashboard fades instead of hard-swapping on view change. |
Glide on reorder (polishGlideReorder) |
Needs-You / Pinned sidebar rows slide into place and their sections collapse smoothly, so everything below (including the "Live Sessions" divider) re-settles in sync instead of snapping when the list re-sorts. |
Inbox Zero celebration (polishInboxZero) |
A calm "you're all caught up" moment (soft glow + self-drawing check) when you clear the last inbox item. |
Related: the always-on butter layer (not toggles)
Separate from these toggles, a base layer of one-shot interaction feedback is always on (like the dialog entrance): the segmented-control active pill glides between options, inbox rows fade in on arrival and height-collapse on dismiss, button loading spinners fade in, and count badges pop once when their number changes. Same safety rules (one-shot, reduced-motion + low-power kills); detail: buttery-microinteractions-contract.md.
Notes
- Accessibility / performance: every animated effect is killed by BOTH
prefers-reduced-motionandhtml.low-power; effects animate transform/opacity only (60fps) and stay off the performance-critical chat-bubble surface (owned by Chat Depth) and the virtualized session list. - Adding a new effect: follow the end-to-end chain in the contract (type + default → Zod → gate →
both app roots → CSS/component → settings toggle → search keywords →
npm run settings:catalog). A missing link = a dead toggle. - History: motion-polish-toggles-postmortem.md.
Related
- chat-depth.md — the sibling appearance dial whose plumbing this mirrors.
- low-power-mode.md — the mode that quiets every animated effect.
- perf-status.md — what the app does when the machine is under load.
Last verified 2026-09-23