forked from unom/punktfunk
P1's core on GTK (design/client-settings-profiles.md §5.1). The same surface now edits either layer: a scope switcher at the top of General swaps between "Default settings" and one profile's overrides. Deliberately not a second editor — a parallel one would drift from this one field by field, which is exactly what the "one settings UI" principle is there to prevent. Three decisions carry the design's semantics into this file: - Rows always show the EFFECTIVE value — the global underneath with the profile's overrides applied — so a row the profile doesn't touch reads as the live global. That is what "inherit by default" has to look like. - Overrides are recorded ON TOUCH, never by diffing values at save time. A profile may therefore pin a value that happens to equal today's global and keep it when the global later moves. The handlers that record this are installed after the seed pass, or opening a profile would override every row in it. - Only profileable rows render in profile scope. Auto-wake, the library toggle, the decoder and GPU pickers, the audio endpoints, the forwarded-pad picker and the detected pad list are facts about this device or this network, not about "Game vs Work" (§3's tier G/H), so they simply aren't there. Switching scope closes the dialog — which commits the layer being edited — and asks the app to re-open in the new one, so there is a single code path that builds the rows and no ambiguity about commit ordering. Both scopes read the controls through one shared closure; the tri-state resolution row is the obvious trap if they ever diverged. Create / Rename / Duplicate / Delete live in the switcher's group. Names are unique case-insensitively and the prompt refuses duplicates in place rather than after the dialog is gone. Delete counts what actually breaks — hosts that fall back to the defaults, pinned cards that disappear — and leaves bindings dangling on purpose: they resolve as "no profile" everywhere, and rewriting every host record here would be a second, racier source of truth. `PUNKTFUNK_SHOT_SETTINGS_SCOPE` puts the screenshot scene into profile scope, so both halves of the surface are capturable. Verified on .21 under Xvfb: the switcher, the per-profile actions and the tier filtering render, and the Statistics row seeds to the Game profile's "Detailed" rather than the global's value. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>