@flood-md/agent 0.2.10 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/DESIGN.md +8 -5
  2. package/README.md +1 -1
  3. package/SKILL.md +11 -0
  4. package/dist/catalog.json +1914 -278
  5. package/dist/materials/component-app-shell.md +49 -0
  6. package/dist/materials/component-app-top-bar.md +36 -0
  7. package/dist/materials/component-autocomplete.md +54 -0
  8. package/dist/materials/component-bulk-action-bar.md +52 -0
  9. package/dist/materials/component-button.md +1 -0
  10. package/dist/materials/component-card.md +2 -2
  11. package/dist/materials/component-collapsible.md +1 -0
  12. package/dist/materials/component-collection-toolbar.md +69 -0
  13. package/dist/materials/component-collection-view-switcher.md +49 -0
  14. package/dist/materials/component-combobox.md +10 -0
  15. package/dist/materials/component-command-palette.md +53 -0
  16. package/dist/materials/component-copy-button.md +1 -0
  17. package/dist/materials/component-data-table.md +34 -4
  18. package/dist/materials/component-date-picker.md +1 -0
  19. package/dist/materials/component-date-range-picker.md +1 -0
  20. package/dist/materials/component-date-time-picker.md +2 -0
  21. package/dist/materials/component-date-time-range-picker.md +4 -0
  22. package/dist/materials/component-drawer.md +1 -0
  23. package/dist/materials/component-editable.md +4 -0
  24. package/dist/materials/component-figure.md +1 -1
  25. package/dist/materials/component-filter-condition.md +53 -0
  26. package/dist/materials/component-filter-group.md +55 -0
  27. package/dist/materials/component-heading.md +1 -1
  28. package/dist/materials/component-icon-button.md +2 -0
  29. package/dist/materials/component-menubar.md +41 -0
  30. package/dist/materials/component-multi-select.md +10 -0
  31. package/dist/materials/component-navigation-group.md +51 -0
  32. package/dist/materials/component-navigation-item.md +59 -0
  33. package/dist/materials/component-navigation-tree.md +8 -0
  34. package/dist/materials/component-overflow-actions.md +47 -0
  35. package/dist/materials/component-page-header.md +40 -0
  36. package/dist/materials/component-popover.md +2 -1
  37. package/dist/materials/component-radio-card.md +2 -2
  38. package/dist/materials/component-section.md +1 -1
  39. package/dist/materials/component-segmented-control.md +6 -4
  40. package/dist/materials/component-sheet.md +49 -0
  41. package/dist/materials/component-sidebar.md +64 -0
  42. package/dist/materials/component-sparkline.md +41 -0
  43. package/dist/materials/component-table.md +2 -0
  44. package/dist/materials/component-tabs.md +2 -0
  45. package/dist/materials/component-text.md +2 -2
  46. package/dist/materials/component-toggle.md +1 -0
  47. package/dist/materials/component-toolbar.md +5 -0
  48. package/dist/materials/component-tooltip.md +1 -1
  49. package/dist/materials/guide-agent-knowledge.md +13 -6
  50. package/dist/materials/guide-agents.md +8 -1
  51. package/dist/materials/guide-foundations.md +45 -2
  52. package/dist/materials/guide-installation.md +6 -6
  53. package/dist/materials/guide-interface-content.md +1 -1
  54. package/dist/materials/guide-introduction.md +4 -2
  55. package/dist/materials/guide-layout.md +39 -10
  56. package/dist/materials/guide-motion.md +66 -0
  57. package/dist/materials/guide-skills.md +9 -0
  58. package/dist/materials/recipe-collection-views.md +670 -0
  59. package/dist/materials/recipe-command-palette.md +31 -52
  60. package/dist/materials/recipe-filter-bar.md +12 -3
  61. package/dist/materials/recipe-grouped-form.md +5 -0
  62. package/dist/materials/recipe-navigation-workspace.md +222 -0
  63. package/dist/materials/recipe-record-management.md +310 -0
  64. package/dist/materials/recipe-record-workspace.md +207 -0
  65. package/dist/materials/recipe-settings-workspace.md +232 -0
  66. package/dist/materials/token-sys.color.context.base.action-disabled.json +41 -0
  67. package/dist/materials/token-sys.color.context.base.action-hover.json +41 -0
  68. package/dist/materials/token-sys.color.context.base.action-pressed.json +41 -0
  69. package/dist/materials/token-sys.color.context.base.action-rest.json +41 -0
  70. package/dist/materials/token-sys.color.context.base.avatar-background.json +41 -0
  71. package/dist/materials/token-sys.color.context.base.border-decorative.json +41 -0
  72. package/dist/materials/token-sys.color.context.base.divider-decorative.json +41 -0
  73. package/dist/materials/token-sys.color.context.base.field-background.json +41 -0
  74. package/dist/materials/token-sys.color.context.base.field-border.json +41 -0
  75. package/dist/materials/token-sys.color.context.base.field-disabled.json +41 -0
  76. package/dist/materials/token-sys.color.context.base.field-readonly.json +41 -0
  77. package/dist/materials/token-sys.color.context.base.indicator-track.json +41 -0
  78. package/dist/materials/token-sys.color.context.base.loading-placeholder.json +41 -0
  79. package/dist/materials/token-sys.color.context.base.muted-background.json +41 -0
  80. package/dist/materials/token-sys.color.context.base.on-surface-action-disabled.json +41 -0
  81. package/dist/materials/token-sys.color.context.base.on-surface-action-hover.json +41 -0
  82. package/dist/materials/token-sys.color.context.base.on-surface-action-pressed.json +41 -0
  83. package/dist/materials/token-sys.color.context.base.on-surface-action-rest.json +41 -0
  84. package/dist/materials/token-sys.color.context.base.selection-background.json +41 -0
  85. package/dist/materials/token-sys.color.context.base.supporting-background.json +41 -0
  86. package/dist/materials/token-sys.color.context.filled.action-disabled.json +41 -0
  87. package/dist/materials/token-sys.color.context.filled.action-hover.json +41 -0
  88. package/dist/materials/token-sys.color.context.filled.action-pressed.json +41 -0
  89. package/dist/materials/token-sys.color.context.filled.action-rest.json +41 -0
  90. package/dist/materials/token-sys.color.context.filled.avatar-background.json +41 -0
  91. package/dist/materials/token-sys.color.context.filled.border-decorative.json +41 -0
  92. package/dist/materials/token-sys.color.context.filled.divider-decorative.json +41 -0
  93. package/dist/materials/token-sys.color.context.filled.field-background.json +41 -0
  94. package/dist/materials/token-sys.color.context.filled.field-border.json +41 -0
  95. package/dist/materials/token-sys.color.context.filled.field-disabled.json +41 -0
  96. package/dist/materials/token-sys.color.context.filled.field-readonly.json +41 -0
  97. package/dist/materials/token-sys.color.context.filled.indicator-track.json +41 -0
  98. package/dist/materials/token-sys.color.context.filled.loading-placeholder.json +41 -0
  99. package/dist/materials/token-sys.color.context.filled.muted-background.json +41 -0
  100. package/dist/materials/token-sys.color.context.filled.selection-background.json +41 -0
  101. package/dist/materials/token-sys.color.context.filled.supporting-background.json +41 -0
  102. package/dist/materials/token-sys.color.field.readonly.json +41 -0
  103. package/dist/materials/token-sys.color.surface.avatar.json +41 -0
  104. package/dist/materials/token-sys.color.surface.current.json +41 -0
  105. package/dist/materials/token-sys.color.surface.muted.json +41 -0
  106. package/dist/materials/token-sys.color.surface.supporting.json +41 -0
  107. package/dist/materials/token-sys.motion.distance-panel.json +36 -0
  108. package/dist/materials/token-sys.motion.distance-small.json +36 -0
  109. package/dist/materials/token-sys.motion.duration-enter.json +36 -0
  110. package/dist/materials/token-sys.motion.duration-exit.json +36 -0
  111. package/dist/materials/token-sys.motion.duration-layer.json +36 -0
  112. package/dist/materials/token-sys.motion.duration-loop.json +36 -0
  113. package/dist/materials/token-sys.motion.duration-press.json +36 -0
  114. package/dist/materials/token-sys.motion.easing-enter.json +38 -0
  115. package/dist/materials/token-sys.motion.easing-exit.json +38 -0
  116. package/knowledge.json +115 -2
  117. package/lib/inspect.mjs +11 -0
  118. package/manifest.json +11 -1
  119. package/package.json +9 -3
  120. package/references/component-families.md +150 -0
  121. package/references/composition.md +16 -4
  122. package/references/customization.md +14 -0
  123. package/references/flood-composition/SKILL.md +4 -0
  124. package/references/flood-data-display/SKILL.md +146 -0
  125. package/references/flood-feedback/SKILL.md +37 -0
  126. package/references/flood-forms/SKILL.md +31 -0
  127. package/references/flood-foundations/SKILL.md +36 -0
  128. package/references/flood-hierarchy/SKILL.md +27 -7
  129. package/references/flood-interface-content/SKILL.md +33 -5
  130. package/references/flood-motion/SKILL.md +47 -0
  131. package/references/flood-navigation/SKILL.md +195 -0
  132. package/references/flood-overlays/SKILL.md +41 -0
  133. package/references/flood-records/SKILL.md +65 -2
  134. package/references/flood-spacing/SKILL.md +45 -0
  135. package/references/flood-verification/SKILL.md +20 -0
  136. package/references/interface-content-examples.md +4 -0
  137. package/references/rendered-review.md +5 -0
  138. package/references/spacing.md +30 -0
  139. package/rules.json +98 -8
  140. package/workflows.json +28 -3
@@ -1,66 +1,45 @@
1
1
  # Command palette
2
2
 
3
- Compose Dialog and CommandList when commands need a modal search surface. Keep
4
- routing, permissions and business actions in your application. This is a project
5
- recipe using the 0.2.7 source API, not another package export.
3
+ Use CommandPalette for a workspace-wide page finder or a set of searchable
4
+ commands. It shares filtering and keyboard behavior with CommandList and uses
5
+ Dialog for modal focus and dismissal. CommandPalette is available in the
6
+ unreleased 0.2.11 candidate.
6
7
 
7
8
  ```tsx
8
9
  "use client";
9
10
 
10
- import { useState } from "react";
11
- import { Button, CommandList, Dialog, FloodRoot } from "@flood-md/react";
12
-
13
- export function CommandPalette({ onCommand }: { onCommand: (id: string) => void }) {
14
- const [open, setOpen] = useState(false);
15
- const [query, setQuery] = useState("");
16
-
17
- function changeOpen(next: boolean) {
18
- if (next) setQuery("");
19
- setOpen(next);
20
- }
11
+ import { Button, CommandPalette, FloodRoot } from "@flood-md/react";
21
12
 
13
+ export function WorkspaceSearch({ onNavigate }: { onNavigate: (id: string) => void }) {
22
14
  return (
23
15
  <FloodRoot>
24
- <Dialog
25
- title="Commands"
26
- open={open}
27
- onOpenChange={changeOpen}
28
- trigger={props => <Button {...props} variant="subtle">Commands</Button>}
29
- >
30
- <CommandList
31
- label="Search commands"
32
- hideLabel
33
- query={query}
34
- onQueryChange={setQuery}
35
- items={[
36
- { id: "new-project", label: "New project", group: "Projects", keywords: ["create"] },
37
- { id: "recent-projects", label: "Recent projects", group: "Projects" },
38
- { id: "settings", label: "Open settings", group: "Workspace" },
39
- ]}
40
- onAction={id => {
41
- changeOpen(false);
42
- onCommand(id);
43
- }}
44
- />
45
- </Dialog>
16
+ <CommandPalette
17
+ title="Go to page"
18
+ searchLabel="Search pages"
19
+ placeholder="Search pages…"
20
+ emptyMessage="No matching pages."
21
+ trigger={props => <Button {...props} variant="subtle">Go to page</Button>}
22
+ items={[
23
+ { id: "projects", label: "All projects", group: "Projects" },
24
+ { id: "assigned", label: "Assigned to me", group: "Projects", keywords: ["mine"] },
25
+ { id: "inbox", label: "Inbox", group: "Workspace" },
26
+ ]}
27
+ onAction={onNavigate}
28
+ />
46
29
  </FloodRoot>
47
30
  );
48
31
  }
49
32
  ```
50
33
 
51
- Import the Flood stylesheet once at your application entry. If this component
52
- already lives inside FloodRoot, reuse that scope instead of adding another one.
53
-
54
- Dialog owns modal focus, Escape, outside dismissal and trigger focus restoration.
55
- CommandList owns filtering, grouped results and keyboard invocation. Opening the
56
- palette clears its query; closing it does not execute a command. Escape stays
57
- available to Dialog rather than being consumed by the search control.
58
-
59
- `onCommand` identifies a host-owned action. It is not awaited: keep saving state,
60
- errors and navigation in your application. An action may move focus to its own
61
- destination; the layer should preserve that deliberate focus change.
62
-
63
- Add a global shortcut only at the application boundary, with your own editing,
64
- permission and nested-layer policy. Do not display a shortcut hint until that
65
- shortcut actually works. No shortcut, router, fuzzy-ranking service or command
66
- permission engine is installed by this recipe.
34
+ Import the Flood stylesheet once. Keep the trigger inside the existing FloodRoot.
35
+ Translate the dialog title, search label, placeholder, close label and state
36
+ messages. The title and search label remain available to assistive technology.
37
+ Use comfortable density by default and compact density for denser workspaces.
38
+
39
+ Opening focuses the search input. Arrow keys move through available results.
40
+ Enter or click calls the host action and requests closure. Escape, the close
41
+ button and optional outside dismissal close without invoking an action. Use
42
+ open/onOpenChange when the host owns visibility. A local query starts from
43
+ defaultQuery on each opening. For a controlled query, the host owns persistence
44
+ and reset. Set loading while replacing results asynchronously. The application
45
+ owns requests, permissions, actions, routing and any global shortcut.
@@ -1,5 +1,8 @@
1
1
  # Filter bar
2
2
 
3
+ For staged conditions and persisted query definitions, see
4
+ [Collection views](collection-views.md) and its two working consumers.
5
+
3
6
  Compose existing Field, SearchInput, Select and Button. Filtering belongs to the
4
7
  host collection, not to DataTable. This recipe filters the full local data set
5
8
  before handing it to the table and resets page and selection when filters change.
@@ -54,6 +57,12 @@ values. Expose active filters as removable Tag components when the filter set
54
57
  gets larger; do not add a duplicate generic FilterBar component just for layout.
55
58
 
56
59
  For remote data, debounce or submit at the host boundary, cancel obsolete requests
57
- and map loading/error states explicitly. Do not pass an individual server page to
58
- this client-paginated DataTable or interpret the page aggregate as server-wide
59
- selection. Use Table + Pagination for a remote query contract.
60
+ and map loading/error states explicitly. Use DataTable paginationMode="server" for an individual server page with explicit
61
+ controlled page/sort and totalRows; do not interpret its select-page checkbox as
62
+ server-wide selection. Table + Pagination remains available for a host-owned
63
+ contract. Follow recipe:record-workspace for request generations and recovery.
64
+
65
+ When reviewing a dense toolbar, compare the filled edges and the text inside
66
+ each control. Shared edges and consistent heights can communicate grouping
67
+ even with small gaps. Judge the applied criteria and the filter trigger with
68
+ long values and at the width where the toolbar wraps.
@@ -64,3 +64,8 @@ Independent sections use Fieldset legendSize="section" and keep one shared outer
64
64
  Grid across peer groups. Field labels retain the compact inner gap; Stack owns
65
65
  row separation. The hierarchy workflow explains why section titles and choice
66
66
  captions are different roles.
67
+
68
+ Compare a short and a wrapped legend with the same fields. Check the visible
69
+ gap from the legend to its first field and from the previous group to the
70
+ legend. Use the [visible weight review](../layout.md#review-visible-weight)
71
+ before changing the shared grid or a group gap.
@@ -0,0 +1,222 @@
1
+ # Navigation workspace
2
+
3
+ [Open the working workspace](/playground/navigation).
4
+
5
+ The workspace compares a standalone Sidebar with a GlobalRail + ContextBar
6
+ composition. Both use the same Sidebar and NavigationTree owners. GlobalRail and
7
+ ContextBar describe their responsibilities here; they are not additional package
8
+ exports. The example's project, inbox and file records live in memory.
9
+ Use the account menu in the footer to switch between Flood Studio and Flood Labs.
10
+ The navigation header shares the height of the workspace toolbar. The expanded
11
+ Sidebar puts the service mark at the start and the collapse control at the end.
12
+ On the compact rail, the toggle replaces the mark on hover or keyboard focus.
13
+ On touch, the toggle stays visible.
14
+ Labs adds nested project collections for testing long labels and scrolling.
15
+ The host remembers the last route and expanded branches per workspace during
16
+ the session. It validates a remembered route against the target workspace and
17
+ falls back to the project overview if that destination is unavailable.
18
+ The **Go to page** action uses CommandPalette. It searches the
19
+ current workspace and expands the selected destination's parent branches.
20
+ On navigation, the host moves focus to the destination heading.
21
+
22
+ ## Choose the hierarchy
23
+
24
+ If the sidebar has one group whose title repeats the app or workspace context,
25
+ use `hideLabel` and keep the group's accessible name. When showing a group title,
26
+ align it with the labels of its destinations.
27
+
28
+ Use one Sidebar when the application has a small destination hierarchy. Separate
29
+ global and contextual navigation when switching domains changes the available
30
+ destinations. The global rail stays flat and stable; its active module is a
31
+ location, while the contextual destination is a page. An open ContextBar replaces
32
+ the need for a second copy of its destinations in a global flyout.
33
+
34
+ On narrow hosts, limit the expanded pane to a share of available width and keep
35
+ the working heading and primary controls reachable. The playground condenses
36
+ the toolbar and keeps wide table content in the table's own scroll area.
37
+
38
+ Keep module, route, expansion and context visibility independent. Anchor the
39
+ visibility control in the persistent rail header. When the context is hidden,
40
+ hover a rail module to preview its contextual links in a flyout that fills the
41
+ available rail height with top and bottom insets, even for short lists.
42
+ The preview preserves focus and stays open while the pointer crosses into the
43
+ panel. Click or use the keyboard to open it for interaction. Escape returns
44
+ focus to the module when it owned focus. Choosing a destination closes the flyout and keeps the
45
+ context docked or hidden as the user last set it. Browser Back restores the route.
46
+ Use real links and host routing. A modified click must remain a browser action
47
+ rather than changing the current tab's module through an unconditional handler.
48
+
49
+ ## Compose the panes
50
+
51
+ | Region or behavior | Flood owner |
52
+ | --- | --- |
53
+ | Workspace landmarks, skip target and scroll boundary | AppShell, SkipLink and ScrollArea |
54
+ | Shared identity, breadcrumbs and global commands | AppTopBar, Breadcrumb, Button and CommandPalette |
55
+ | Current page title and page actions | PageHeader |
56
+ | Docked rail and grouped destinations | Sidebar, NavigationGroup and NavigationTree |
57
+ | Temporary navigation on a narrow host | Drawer with the same destination definitions |
58
+ | Account commands and identity | Menu, Avatar and Button |
59
+
60
+ Use AppShell's default content scrolling for a bounded workspace. Give an
61
+ embedded shell an explicit block size. Choose `scroll="page"` for natural
62
+ document scrolling. Place a persistent top bar and footer in the shell slots,
63
+ and PageHeader inside main. The shell has a skip target and owns the scroll
64
+ boundary; the host owns routes and persisted choices.
65
+
66
+ For a single Sidebar, opt into `navigationDrawer` with a width threshold in CSS
67
+ pixels and a `renderContent(close)` function. AppShell observes its own width.
68
+ The playground uses 480 px for the classic Sidebar profile. Pass a `topBar`
69
+ render function to place the named trigger with the existing toolbar controls.
70
+ The Rail + Context example keeps its separate pane visibility and hover flyout.
71
+
72
+ Share accepted route and branch state between Sidebar and Drawer. Close the
73
+ Drawer on an accepted destination and focus the destination heading. Escape
74
+ or explicit dismissal restores focus to the trigger. When a resize removes
75
+ the focused dock or Drawer, AppShell transfers focus to the new trigger or
76
+ the work region, respectively.
77
+
78
+ This host-owned layout uses Flood components. In the 0.2.11 source candidate,
79
+ NavigationItem owns the shared row, NavigationGroup owns related items and their
80
+ optional heading, and NavigationTree composes rows into a destination hierarchy.
81
+ Sidebar places these owners between its fixed header and footer. The caller
82
+ supplies icons, identity controls and accepted route state; keep layout CSS in the
83
+ host and import the matching Flood stylesheet once. These candidate APIs require
84
+ matching installed declarations and are not added to an older npm release by
85
+ reading this recipe.
86
+
87
+ ```tsx
88
+ "use client";
89
+ import type { ReactNode } from "react";
90
+ import { AppShell, AppTopBar, FloodRoot, Sidebar, type SidebarProps } from "@flood-md/react";
91
+ import "@flood-md/react/styles.css";
92
+
93
+ type Props = {
94
+ global: SidebarProps;
95
+ context: SidebarProps;
96
+ contextVisible: boolean;
97
+ header: ReactNode;
98
+ children: ReactNode;
99
+ };
100
+
101
+ export function NavigationWorkspace({
102
+ global, context, contextVisible, header, children,
103
+ }: Props) {
104
+ return (
105
+ <FloodRoot>
106
+ <AppShell
107
+ navigation={<>
108
+ <Sidebar {...global} collapsed collapsible={false} currentKind="location" />
109
+ {contextVisible && <Sidebar {...context} currentKind="page" />}
110
+ </>}
111
+ topBar={<AppTopBar start={header} />}
112
+ scrollOrientation="vertical"
113
+ >
114
+ {children}
115
+ </AppShell>
116
+ </FloodRoot>
117
+ );
118
+ }
119
+ ```
120
+
121
+ A bounded parent can supply the height instead of `100dvh`. Reserve remaining
122
+ height with flex/grid rather than subtracting an assumed toolbar height: labels
123
+ and tooling can wrap at enlarged text. Sidebar owns the middle navigation scroll
124
+ viewport; AppShell owns the main content viewport. Table overflow remains inside
125
+ the table's owner. Header and footer do not scroll with their navigation lists.
126
+
127
+ ## Compose the row before the shell
128
+
129
+ Use NavigationItem for a destination, command or disclosure rather than a local
130
+ button-shaped row. A destination has an href and keeps native Link behavior. A
131
+ command has onAction and uses Button. A branch without a destination uses one
132
+ full-row disclosure target; a destination with children keeps the link and the
133
+ disclosure as separate sibling controls inside one coherent row surface. Clicking
134
+ the link must not also change the branch's expansion. A disclosure must not be
135
+ nested inside the link.
136
+
137
+ Current destination, ancestor of the current destination, accepted expansion and
138
+ keyboard focus are distinct states. The row owns its visual surface across the
139
+ label and disclosure; do not paint a shorter selected pill only behind the link
140
+ or add the trailing inset twice. Leading art, label and real trailing anatomy
141
+ share deliberate tracks. A supporting chevron can use a smaller IconButton
142
+ iconSize while retaining the normal control target.
143
+
144
+ NavigationTree remains the recursive owner: it composes NavigationItem, manages
145
+ the accepted expandedValues set and presents compact branches through Popover.
146
+ The popup can include a branch's own destination and its children. A standalone
147
+ compact NavigationItem does not create a hidden child hierarchy on its own.
148
+
149
+ ## Configure groups and fixed regions
150
+
151
+ NavigationGroup can omit its label, hide a supplied visual label, add a meaningful
152
+ headingAction, show a separator or expose its own disclosure. Its expanded state
153
+ is independent of NavigationTree branch expansion and Sidebar width. A collapsible
154
+ group needs a nonempty label; hideLabel keeps the toggle's accessible name even
155
+ when the visual title is omitted. collapseDisabled affects that group disclosure,
156
+ not arbitrary child links or actions.
157
+
158
+ In compact presentation, group contents stay reachable and the group toggle is
159
+ hidden. This presentation does not overwrite the accepted expanded state: returning
160
+ to expanded navigation restores the group's prior choice. A supplied heading
161
+ action remains available on the compact axis rather than disappearing with text.
162
+
163
+ SidebarGroup exposes the group label, hideLabel, headingAction, separator and
164
+ collapsible/expanded configuration when Sidebar assembles the hierarchy. Start
165
+ these optional additions empty. Use a section title only when it distinguishes
166
+ related destinations; a title already provided by the pane need not be repeated.
167
+ Use branchGuides within a group when several levels of nesting need a visible
168
+ guide. Use trailingAction for an independent action alongside row metadata.
169
+ headerSeparator and footerSeparator are independent, opt-in Sidebar choices,
170
+ not mandatory lines around every fixed region.
171
+
172
+ Header and footer content must follow the same mode contract as the body. In
173
+ expanded navigation, identity and utility rows use the agreed icon/text tracks.
174
+ In compact navigation, measure the actual brand, toggle, destination and account
175
+ hit-area centers against the full rail center. A centered footer wrapper is not
176
+ proof that its Menu trigger or Avatar is centered. Adapt the identity content
177
+ deliberately while preserving its accessible name and useful recognition cue.
178
+
179
+ ## Presentation and content
180
+
181
+ Sidebar's quiet recipe uses restrained inactive text and rectangular current
182
+ rows; standard retains stronger pill geometry. Compare these against the main
183
+ work area, not only in isolation. Preserve explicit icon sizes, shared inline
184
+ tracks and a common top anchor across adjacent panes. Omitting a collapse button
185
+ must not shorten one header and lift its entire navigation above the other.
186
+
187
+ Use `SidebarGroup.hideLabel` when the pane header already names the only group.
188
+ Its navigation landmark keeps its label. Add badges only for meaningful counts or
189
+ states, not to fill every destination. Account utilities and workspace settings
190
+ belong in deliberate fixed slots rather than a second contextual destination list.
191
+
192
+ ## State and focus ownership
193
+
194
+ Keep search and filters in their applicable module. An inactive Projects filter
195
+ must not create a Clear filters action in Inbox, and clearing Inbox search must
196
+ not modify the accepted Projects query. Validate the entire route, including
197
+ extra or missing path segments, before deriving a title or current destination.
198
+
199
+ Preserve surviving focus. When a focused record, action or pane disappears and
200
+ focus falls to the document body, the host restores it to an intentional stable
201
+ destination, such as the main heading. Do not refocus the heading on every data
202
+ render or steal focus from another surviving control. A visibility toggle can
203
+ keep focus on itself before removing its pane. A dialog whose original trigger
204
+ disappeared needs the same explicit fallback when it closes.
205
+
206
+ ## Verify the workspace
207
+
208
+ Check both layouts, module/page current semantics, hidden context through module
209
+ changes and Back, modified links, branch disclosure and independent scrolling.
210
+ Exercise both a full-row branch toggle and a destination-plus-disclosure row;
211
+ include a host refusing an expansion request. Configure group headings, actions,
212
+ separators and collapse independently, then switch compact mode without losing
213
+ the accepted group choice or destinations. Compare actual header/footer trigger
214
+ centers with body controls, including the account trigger, rather than inspecting
215
+ the middle list alone. Check current/hover/focus surfaces across the complete row.
216
+ Compare visible glyphs as well as their slots. If the same glyph reads off-axis
217
+ across several states, review its artwork before moving the shared hit area.
218
+ Exercise a filter in one module followed by search in another; remove the focused
219
+ row; close a dialog after its original row disappears. Review normal desktop,
220
+ short desktop windows, 1280 px with a 24 px root, RTL and forced colors. Visual
221
+ review and executed checks are separate evidence; the guidance itself is not a
222
+ pass certificate.