# Page Layout and Action Guidelines This document defines the binding composition grammar for headed GovOPlaN pages. Core owns the reusable anatomy; each module owns its domain actions, wording, authorization, consequences, and data state. ## Required Page Frame - Use `PageLayout` for every headed standalone, workspace, or embedded page. - Declare exactly one semantic `archetype`; do not infer page intent from the `mode`, which controls geometry and scroll ownership only. - Use `WorkspaceFrame` for a full-height module surface and `WorkspaceLayout` only where navigation/content or list/detail panes are genuinely part of the interaction. - Put page-wide feedback in `PageLayout` notices. Use `DismissibleAlert` for a recoverable warning or failure and `StatePanel` when the entire surface is loading, empty, unavailable, or blocked. - Do not reproduce shared page padding, heading, toolbar, form-grid, section, table, dialog, or breakpoint CSS in a module. ## Semantic Page Archetypes | Archetype | Use when | | --- | --- | | `overview` | The page summarizes health, metrics, or several peer areas without owning one primary collection or draft. | | `collection` | The primary object is a searchable/listable collection and Create, when available, applies to that collection. | | `detail` | The page primarily presents one record, report, or immutable projection. | | `editor` | The page owns one explicit draft with Save and Discard behavior. | | `workspace` | The page coordinates several panes, stages, or task-local operations that cannot honestly be reduced to one record or draft. | The archetype remains stable for the current interaction. A page may switch from `overview` to `editor` when the user explicitly enters configuration mode. It must not call a page an editor merely because a dialog or an inline filter is editable. ## Page Action Rules Pass one `PageActionBar` to the `PageLayout` `actions` slot. The variant makes the page's intent inspectable and preserves the same keyboard and visual order across modules. | Page kind | Leading group | Trailing group | | --- | --- | --- | | Overview | Reload when refreshable, then context | Help, then ordinary primary actions | | Collection | Reload when refreshable, then collection context such as export | Help, then Create at the far right | | Detail | Reload when refreshable, then object context | Help, ordinary primary actions, then a separated destructive group | | Editor | Reload only when refresh is a distinct safe operation, then context | Dirty state, Help, ordinary primary actions, separated destructive actions, Discard, then Save at the far right | | Workspace | Reload when the coordinated projection can become stale, then task context | Help, ordinary primary actions, then a separated destructive group | Reload means re-fetch or re-evaluate the current surface. A page declaring `refreshable` must provide it, and a non-refreshable page must not use Reload as a synonym for Cancel, Reset, or Discard. Reload never silently destroys a dirty draft. Create is a collection-wide action and is not duplicated in a persistent side panel. Save is present only where the page owns an editable draft; a read-only detail page must not display a disabled or inert Save merely to fill the slot. Editor bars always keep Discard and Save visible. They expose `clean`, `dirty`, and `saving` status through a live status label. In the clean or saving state, the central component disables both persistence actions and supplies the standard explanation. A module may add a more specific validation, policy, or permission blocker while the draft is dirty. The editor must register its draft with `useUnsavedDraftGuard` (or a shared hook that uses the same registration contract), so browser unload, route navigation, section changes, and the explicit Discard path cannot silently lose work. Destructive page actions use `destructiveActions`; never put a danger action in `contextActions` or the ordinary primary group. Core renders a persistent visual and semantic boundary before this group. In an editor it precedes the Discard/Save pair, keeping Save in the final keyboard and visual position. `PageActionBar` controls non-editor placement and owns the standard editor persistence buttons. Other actions continue to use central `Button`, `IconButton`, or `TableActionGroup` components. When an action is visible but unavailable because of permission, target, policy, state, or validation, keep it in its stable slot and supply `disabledReason`. Do not silently hide a normally applicable action. ## Forms and Dialogs - Compose forms from `FormLayout`/`FormGrid`, `FormSection`, and `FormField`. - Use `FieldLabel` through `FormField` for every field that is not genuinely self-explanatory; record justified omissions in the owning UI ledger. - Use `Dialog`, `DialogForm`, `DialogSection`, and `DialogActions` for modal work. A dialog can be domain-specific while its anatomy remains central. - Use `useUnsavedDraftGuard` for explicit Discard and guarded navigation on an editable page or dialog. - Explain irreversible or operationally consequential actions before the commit button, including reversibility and durable evidence. ## Collections and Details - Use `FilterBar` for collection query controls and `DataGrid` for tabular collections. Keep a single ordered `TableActionGroup` action set per table. - Use `MetricGrid`/`MetricCard` for summary measures, `Card` or `ContentSection` for logical sections, and `DescriptionList` for labelled facts. - Preserve loaded data after a refresh failure and mark it stale; offer Reload as the recovery action. Distinguish initial loading, empty, unavailable, permission-blocked, conflict, success, and retry states. ## Review Evidence Every new or changed page must have structural evidence for its page frame, semantic archetype and slot order, refresh declaration, shared component usage, stable disabled actions, dirty guard, destructive boundary, and module-owned help identity. Type checks enforce conditional Reload and editor persistence props. Product checks reject undeclared archetypes and ad-hoc headed action fragments. Browser conformance confirms keyboard order, live dirty-state changes, accessibility, destructive separation, narrow wrapping, and screenshot geometry.