# App dialog primitives These React-owned components define reusable app chrome, not content or integration behavior. - `ModalShell` owns the centered overlay, dismissal, focus trap, and focus return. - `SectionedDialog` owns the Settings-style title, vertical section navigation, icon-strip mobile layout, and scrolling content panel. Settings and Feedback supply section definitions and content. - `focusable` provides DOM-ordered keyboard targets and resolves the foreground dialog from its overlay layer; the Settings folder picker and account popup use it without adopting the sectioned layout. - `ActionButton` is the app-wide action control. Settings, the header update action, and edition panels share its neutral and primary styles; placement-specific spacing stays with the consumer. - `FormControlGroup` pairs a single-line input, select, or read-only code value with adjacent `ActionButton`s. Choose density once on the group; do not size each child separately. ## Form sizing Use `FormControlGroup` for a field with utility actions such as Copy or Reset: ```tsx Reset ``` The default `compact` density uses `--ui-form-control-height` (36px). `regular` uses `--ui-touch-target` (44px). Coarse-pointer devices promote compact groups to 44px so inputs and buttons remain equally touchable. The 25px `--ui-control-height` token belongs to dense editor controls, not settings forms. The field fills available width; actions use their label width plus shared horizontal padding. Use short utility action labels in these inline groups; long actions belong in a separate row. Buttons retain a minimum height rather than a fixed height so wrapping text can grow. Input colors, borders, focus styling, and behavior remain owned by the input. The group normalizes single-line control geometry. Keep labels, validation messages, and outer spacing outside the group. Put labels above the group when the available form width is narrow (use a container query), and avoid fixed-width action columns or button-specific height overrides. A standalone `ActionButton` retains its 44px default. Verify paired heights, usable field width, focus, and overflow in a desktop browser and a touch viewport when migrating a form. The search and command palettes use their own shared `../palette-dialog/PaletteDialog`; they have a search-input/list interaction model instead of sections. The Obsidian-compatible `Modal` in `src/plugin/obsidian-stubs.ts` is an imperative plugin API. The ATProto account popup remains a separate auth flow. Sharing their layout would conflate different interactions.