@flood-md/agent 0.2.11 → 0.2.13

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 (69) hide show
  1. package/DESIGN.md +10 -1
  2. package/README.md +9 -4
  3. package/SKILL.md +16 -5
  4. package/dist/catalog.json +816 -232
  5. package/dist/materials/component-alert-dialog.md +1 -0
  6. package/dist/materials/component-app-shell.md +3 -1
  7. package/dist/materials/component-bar-chart.md +52 -0
  8. package/dist/materials/component-bar-list.md +41 -0
  9. package/dist/materials/component-box-plot.md +46 -0
  10. package/dist/materials/component-bullet-chart.md +43 -0
  11. package/dist/materials/component-code-snippet.md +3 -1
  12. package/dist/materials/component-collection-toolbar.md +4 -1
  13. package/dist/materials/component-command-palette.md +1 -0
  14. package/dist/materials/component-copy-button.md +2 -0
  15. package/dist/materials/component-data-table.md +21 -3
  16. package/dist/materials/component-dialog.md +2 -0
  17. package/dist/materials/component-donut-chart.md +46 -0
  18. package/dist/materials/component-drawer.md +2 -0
  19. package/dist/materials/component-dumbbell-chart.md +46 -0
  20. package/dist/materials/component-editable.md +4 -0
  21. package/dist/materials/component-heading.md +1 -1
  22. package/dist/materials/component-heatmap.md +45 -0
  23. package/dist/materials/component-histogram.md +46 -0
  24. package/dist/materials/component-image-preview.md +1 -0
  25. package/dist/materials/component-line-chart.md +50 -0
  26. package/dist/materials/component-menu.md +2 -0
  27. package/dist/materials/component-range-chart.md +46 -0
  28. package/dist/materials/component-scatter-chart.md +48 -0
  29. package/dist/materials/component-section.md +1 -1
  30. package/dist/materials/component-sheet.md +50 -0
  31. package/dist/materials/component-sparkline.md +41 -0
  32. package/dist/materials/component-table.md +3 -1
  33. package/dist/materials/component-toolbar.md +1 -0
  34. package/dist/materials/component-waterfall-chart.md +47 -0
  35. package/dist/materials/guide-agent-knowledge.md +5 -5
  36. package/dist/materials/guide-agents.md +35 -2
  37. package/dist/materials/guide-charts.md +34 -0
  38. package/dist/materials/guide-foundations.md +2 -2
  39. package/dist/materials/guide-installation.md +6 -6
  40. package/dist/materials/guide-introduction.md +2 -1
  41. package/dist/materials/guide-motion.md +19 -10
  42. package/dist/materials/guide-skills.md +10 -0
  43. package/dist/materials/recipe-collection-views.md +72 -47
  44. package/dist/materials/recipe-navigation-workspace.md +3 -0
  45. package/dist/materials/recipe-record-management.md +109 -61
  46. package/knowledge.json +16 -0
  47. package/lib/inspect.d.ts +14 -2
  48. package/lib/inspect.mjs +65 -0
  49. package/manifest.json +11 -1
  50. package/package.json +1 -1
  51. package/references/component-families.md +14 -0
  52. package/references/composition.md +12 -0
  53. package/references/flood-composition/SKILL.md +7 -0
  54. package/references/flood-data-display/SKILL.md +114 -0
  55. package/references/flood-feedback/SKILL.md +12 -0
  56. package/references/flood-forms/SKILL.md +5 -0
  57. package/references/flood-hierarchy/SKILL.md +4 -0
  58. package/references/flood-interface-content/SKILL.md +7 -0
  59. package/references/flood-motion/SKILL.md +3 -0
  60. package/references/flood-overlays/SKILL.md +11 -0
  61. package/references/flood-records/SKILL.md +32 -0
  62. package/references/flood-screen-composition/SKILL.md +48 -0
  63. package/references/flood-spacing/SKILL.md +7 -0
  64. package/references/flood-verification/SKILL.md +32 -0
  65. package/references/flood-visual-review/SKILL.md +59 -0
  66. package/references/rendered-review.md +49 -3
  67. package/references/routing.md +2 -1
  68. package/rules.json +37 -1
  69. package/workflows.json +22 -0
package/lib/inspect.mjs CHANGED
@@ -13,6 +13,7 @@ export function inspectSourceUI(source,options={}) {
13
13
  };
14
14
  if(format==='jsx'){
15
15
  for(const match of source.matchAll(/\b(?:window|globalThis)\.(confirm|alert|prompt)\s*\(/g))record(match,'composition.native-dialog',match[1]==='confirm'?'AlertDialog':match[1]==='prompt'?'Dialog':'Alert','Native browser dialog candidate. Review the actual call and use the installed Flood owner unless native UI is explicitly required.');
16
+ for(const match of source.matchAll(/<AppShell\b[^<>]*?\s+scroll\s*=\s*(?:(["'])page\1|\{\s*(["'])page\2\s*\})/g))record(match,'composition.page-scroll','AppShell / ScrollArea','AppShell page mode uses document scrolling. For a full-window application, use content mode and verify the Flood viewport owns vertical overflow. Document layouts may deliberately use page mode.');
16
17
  for(const match of source.matchAll(/<(select|button)\b|<input\b[^>]*\btype\s*=\s*["'](date|time|checkbox|radio|range)["']/g)){
17
18
  const role=match[1]||match[2],owner={select:'Select',button:'Button',date:'DatePicker',time:'TimeField',checkbox:'Checkbox',radio:'Radio',range:'Slider'}[role];
18
19
  record(match,'composition.native-control',owner,'Raw control candidate. Review whether an existing Flood component owns this role; native form/table structure and deliberate documented adapters are separate cases.');
@@ -29,6 +30,50 @@ export function inspectSourceUI(source,options={}) {
29
30
  return {schemaVersion:1,issues,truncated,notChecked:['Text matching is not parsing: comments, strings and examples can match; aliases, dynamic types and indirect calls can be missed. Review source context.','This function reads only the supplied text. It does not execute it, open files or inspect imports, component capability, rendered layout or editorial necessity.']};
30
31
  }
31
32
 
33
+ /** Assert the scroll contract of a full-window AppShell in a settled browser state. */
34
+ export function assertWorkspaceScroll({rootSelector = '.flood-app-shell', expectOverflow} = {}) {
35
+ const prefix = 'Flood workspace scroll';
36
+ if (typeof document === 'undefined') throw new Error(`${prefix}: run this check in the rendered browser document`);
37
+ const roots = document.querySelectorAll(rootSelector);
38
+ if (roots.length !== 1 || !roots[0].matches('.flood-app-shell[data-scroll="content"]')) {
39
+ throw new Error(`${prefix}: select one workspace rendered with AppShell scroll="content" (${rootSelector})`);
40
+ }
41
+ const root = roots[0];
42
+ const viewport = root.querySelector(':scope > .flood-app-shell__workspace > .flood-app-shell__main > .flood-scroll-area > .flood-app-shell__scroll');
43
+ const viewportStyle = viewport && getComputedStyle(viewport);
44
+ if (!viewport || viewport.clientHeight === 0 || !['auto', 'scroll'].includes(viewportStyle.overflowY) || viewport.dataset.scrollbars !== 'overlay') {
45
+ throw new Error(`${prefix}: the AppShell content must have a visible, enhanced vertical Flood ScrollArea`);
46
+ }
47
+
48
+ const documentGutter = innerWidth - document.documentElement.clientWidth;
49
+ const scrollOwner = document.scrollingElement ?? document.documentElement;
50
+ const documentOverflow = scrollOwner.scrollHeight - scrollOwner.clientHeight;
51
+ if (documentGutter > 1 || documentOverflow > 1) {
52
+ throw new Error(`${prefix}: the document has ${documentOverflow}px vertical overflow and a ${documentGutter}px gutter. Contain overflow in the workspace.`);
53
+ }
54
+
55
+ const workspaceOverflow = viewport.scrollHeight - viewport.clientHeight;
56
+ const hasOverflow = workspaceOverflow > 1;
57
+ if (expectOverflow === true && !hasOverflow) {
58
+ throw new Error(`${prefix}: the populated fixture must overflow the workspace viewport`);
59
+ }
60
+ if (expectOverflow === false && hasOverflow) {
61
+ throw new Error(`${prefix}: expected the workspace content to fit, but it overflows by ${workspaceOverflow}px`);
62
+ }
63
+ // Flood intentionally exposes native scrollbars inside the viewport in forced colors.
64
+ if (!matchMedia('(forced-colors: active)').matches) {
65
+ const viewportGutter = viewport.offsetWidth - viewport.clientWidth
66
+ - parseFloat(viewportStyle.borderLeftWidth) - parseFloat(viewportStyle.borderRightWidth);
67
+ if (viewportGutter > 1) {
68
+ throw new Error(`${prefix}: a native scrollbar reserves ${viewportGutter}px inside the Flood viewport`);
69
+ }
70
+ if (hasOverflow && !viewport.parentElement.querySelector(':scope > .flood-scroll-area__track--vertical')) {
71
+ throw new Error(`${prefix}: the overflowing workspace has no vertical Flood scrollbar`);
72
+ }
73
+ }
74
+ return {documentGutter, documentOverflow, workspaceOverflow};
75
+ }
76
+
32
77
  /** Read-only DOM observations. Pass this self-contained function to page.evaluate. */
33
78
  export function inspectRenderedUI(options = {}) {
34
79
  if (typeof document === 'undefined') throw new Error('inspectRenderedUI must run in the rendered browser document');
@@ -51,6 +96,26 @@ export function inspectRenderedUI(options = {}) {
51
96
  return matches.slice(0, limit);
52
97
  };
53
98
  if(root===document&&document.documentElement.scrollWidth>innerWidth+1)addIssue({id:'layout.page-overflow',target:{tag:'html',id:document.documentElement.id||null,className:document.documentElement.getAttribute('class')||'',label:'Document'},offset:document.documentElement.scrollWidth-innerWidth,message:'The document extends beyond the viewport. Review the actual overflow owner at this text size; dense content can scroll locally. Hiding page overflow does not repair the layout.'});
99
+ const documentGutter = innerWidth - document.documentElement.clientWidth;
100
+ const scrollOwner = document.scrollingElement;
101
+ const recordTables = select('.flood-data-table');
102
+ const table = recordTables.find(element => {
103
+ const main = element.closest('main.flood-app-shell__main');
104
+ const shell = main?.closest('.flood-app-shell[data-scroll="page"]');
105
+ if (!shell || shell.parentElement?.closest('.flood-app-shell')) return false;
106
+ const {top, width} = shell.getBoundingClientRect();
107
+ return top + scrollY <= 1 && width >= document.documentElement.clientWidth - 1;
108
+ });
109
+ const reservedGutter = documentGutter > 1 && scrollOwner && scrollOwner.scrollHeight > scrollOwner.clientHeight + 1;
110
+ const recordView = table || (reservedGutter && recordTables[0]);
111
+ if (recordView) addIssue({
112
+ id: 'layout.record-scroll-owner',
113
+ target: target(recordView),
114
+ offset: documentGutter,
115
+ message: table
116
+ ? 'A full-window record workspace uses AppShell page mode. Use content mode so Flood owns vertical scrolling even when the OS currently hides its scrollbar.'
117
+ : 'A document scrollbar consumes width on this record view. Compare full and filtered views with classic scrollbars and check whether a Flood ScrollArea should own vertical overflow.',
118
+ });
54
119
  for (const button of select('button.flood-button, button.flood-icon-button')) {
55
120
  // Text is inspected outside real icon slots, SVGs and visually hidden names.
56
121
  const walker = document.createTreeWalker(button, NodeFilter.SHOW_TEXT);
package/manifest.json CHANGED
@@ -117,6 +117,11 @@
117
117
  "target": ".agents/skills/flood-ui/references/flood-verification/SKILL.md",
118
118
  "kind": "skill"
119
119
  },
120
+ {
121
+ "source": "references/flood-visual-review/SKILL.md",
122
+ "target": ".agents/skills/flood-ui/references/flood-visual-review/SKILL.md",
123
+ "kind": "skill"
124
+ },
120
125
  {
121
126
  "source": "references/knowledge.md",
122
127
  "target": ".agents/skills/flood-ui/references/knowledge.md",
@@ -142,6 +147,11 @@
142
147
  "target": ".agents/skills/flood-ui/references/flood-hierarchy/SKILL.md",
143
148
  "kind": "skill"
144
149
  },
150
+ {
151
+ "source": "references/flood-screen-composition/SKILL.md",
152
+ "target": ".agents/skills/flood-ui/references/flood-screen-composition/SKILL.md",
153
+ "kind": "skill"
154
+ },
145
155
  {
146
156
  "source": "references/flood-records/SKILL.md",
147
157
  "target": ".agents/skills/flood-ui/references/flood-records/SKILL.md",
@@ -158,7 +168,7 @@
158
168
  "kind": "reference"
159
169
  }
160
170
  ],
161
- "version": "0.2.11",
171
+ "version": "0.2.13",
162
172
  "installedEntry": ".agents/skills/flood-ui/SKILL.md",
163
173
  "pathBase": "source is package-relative; target is relative to the host project root"
164
174
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flood-md/agent",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "type": "module",
5
5
  "description": "Versioned Flood design instructions for coding agents.",
6
6
  "license": "MIT",
@@ -18,6 +18,7 @@ chosen siblings and intentional differences in development notes, outside the UI
18
18
  | Command collection | Toolbar/Menu owners, action sizes and keyboard ownership |
19
19
  | Floating surface | Existing overlay material, layer placement, inset and focus restoration |
20
20
  | Named content or record | Typography, hierarchy and metadata owners, not a new title scale |
21
+ | Data visualization | LineChart data-mark stroke weight, quiet plot grid, exact-value inspection and stable geometry |
21
22
 
22
23
  Reuse these owners inside the new component. Extend the smallest missing owner
23
24
  before adding a composite override. For example, the Toolbar that draws an
@@ -89,6 +90,10 @@ override leaves fields and composed controls inconsistent. Keep absolute
89
90
  material colors separate from contextual control roles and verify the nearest
90
91
  nested owner resets those roles. Preserve accent focus and destructive meaning.
91
92
 
93
+ Vertical pill Toolbar keeps one column on a shared center axis. Use named
94
+ icon-only actions and a consistent control size for a compact rail. Use a
95
+ rounded vertical Toolbar with consistently labeled controls when text is needed.
96
+
92
97
  BulkActionBar is a one-row capsule for a small set of selection commands. Keep
93
98
  one to three visible commands, prefer two, and disclose the remainder through
94
99
  its overflow owner. Do not wrap this floating rail into a second row or use it
@@ -128,6 +133,15 @@ focus bounds and overflow thresholds. Exercise resize while an action or popup
128
133
  has focus. After a shared-owner correction, inspect another consumer. A green
129
134
  build or token reuse alone does not establish visual kinship.
130
135
 
136
+ Check the same component in a real host composition. Record the geometry that
137
+ should remain stable as state changes. For example, a table cell editor may
138
+ open over its cell, but entering edit mode should keep the row height and
139
+ column widths stable. Then exercise commit and cancel with a long value. If
140
+ the failure repeats, fix the first owner that can enforce the relationship: a
141
+ semantic token for a shared role, the primitive for its own states, or the
142
+ composite for how siblings fit. Add guidance when callers can already choose
143
+ the right behavior through the public API.
144
+
131
145
  ## Keep the contract discoverable
132
146
 
133
147
  In Flood source, update declarations, component examples, applicable guidance
@@ -43,6 +43,18 @@ adapter such as @/ui/button may re-export Flood, but does not change React APIs.
43
43
  Before handing off, inspect a real composed screen at narrow and wide widths,
44
44
  not only isolated controls. See [verification](verification.md).
45
45
 
46
+ Choose the scroll owner when laying out a screen. In an application workspace
47
+ with fixed chrome or floating collection actions, use AppShell with
48
+ `scroll="content"`. For a padded workspace, set `scrollContentInset="none"`
49
+ when that prop is available and the existing edge padding clears the rails.
50
+ Use the document as scroll owner for pages designed to flow as one document.
51
+ Apply the workspace recipe to filterable or pageable record queues with floating
52
+ actions even when they have no persistent top bar. Keep viewport-fixed actions
53
+ outside the scrolling content. Table's horizontal ScrollArea handles wide
54
+ columns independently.
55
+ When testing a floating selection bar, select the first row and check that the
56
+ viewport and the table keep the same inline size as the overlay rail appears.
57
+
46
58
  For constrained overflow, use installed ScrollArea when available. Set height or
47
59
  maxHeight on its viewport, choose the needed axis, and provide a useful accessible
48
60
  name. Rails overlay content with insets; keep essential content out of the rail
@@ -52,6 +52,13 @@ If discovery finds no suitable component, state the missing capability; do not
52
52
  claim that the library has no owner without checking. Keep this decision record
53
53
  in development notes, never as extra explanatory text in the product.
54
54
 
55
+ For an unfamiliar composition, find the closest runnable recipe and reuse the
56
+ relationship it demonstrates. For example, use `recipe:record-management` to see
57
+ how a DataTable row opens a Drawer while the list preserves scroll and filters.
58
+ Use `recipe:table-bulk-actions` when a selection needs shared commands and
59
+ confirmation. Check the recipe against the installed contracts and adapt it to
60
+ the host's actual task and data.
61
+
55
62
  - Reuse the matching component with its supported props and tokens.
56
63
  - If spacing or alignment is wrong, inspect both the primitive and the parent
57
64
  composition. Fix the owner of the relationship. Keep the primitive intact.
@@ -60,6 +60,42 @@ the interface-content workflow for contextual placement.
60
60
  Keep identifiers, such as postal codes and account numbers, aligned as text
61
61
  even when they contain only digits. Preserve formatted units and use raw sort
62
62
  values when localized text or rich cells would sort differently.
63
+ - For a collection that users repeatedly filter, preserve the important column
64
+ tracks at the same viewport as results change. Compare the populated, filtered
65
+ and no-results states. A table can keep its outer width while its headers move
66
+ because the body is empty. Where stable scan positions matter, use the
67
+ supported column sizing to keep the tracks instead of sizing from the rows.
68
+ Bounded Table and DataTable already keep clearance for their own overlay rail.
69
+ Reuse that clearance and compare column edges across the overflow threshold.
70
+ - Offer column visibility when users need different subsets of fields for real
71
+ tasks in the same table. Leave it off for compact tables with a fixed task.
72
+ Use one layout control per table. If the screen already has View options or
73
+ Display settings, put column visibility there and pass `hiddenColumnIds`.
74
+ Otherwise enable `showColumnVisibility`. If the table already has search and
75
+ filters, use the `toolbar` render function and put its Columns control in
76
+ `CollectionToolbar.actions` to share the existing tool row. Keep the record
77
+ identity visible with `hideable: false` and save preferences by column ID in
78
+ the host. Keep layout preferences independent of the data query. Verify that
79
+ visibility changes preserve page, selection and sort.
80
+ - Enable resizing for columns with variable-length content when readers need
81
+ control over width. Use logical start pinning for record identity and logical
82
+ end for recurring actions when horizontal scrolling would hide them. Persist
83
+ widths by column ID with visibility, and verify keyboard resize, reset, RTL
84
+ and access to the unpinned middle at the smallest intended width.
85
+ - Choose short one-line column labels and use DataTable's `unit` badge for
86
+ a shared short unit. Preserve the complete label when a narrow column
87
+ truncates it. Compare the label, sort icon and resize grip on the same row.
88
+ - Use DataTable's row disclosure for short details the reader needs while
89
+ scanning parent records. Compose a named nested Table for related line items.
90
+ Keep the disclosure and any record-opening action independent. Use a Drawer
91
+ or separate page for longer detail or editing tasks.
92
+ - Use Sparkline when the shape of a series helps a comparison. Supply a label
93
+ that describes the trend, use a shared scale for comparing magnitudes, and
94
+ show decision-critical numbers as text. If a rich trend cell is sortable,
95
+ define the metric it sorts by and supply its raw value.
96
+ Keep the same tone across rows of one metric. A soft area fill supports the
97
+ stroke and follows the same gaps. Reserve semantic tones for meaning and
98
+ keep numbers and labels readable independently of color.
63
99
  - DescriptionList expresses named values; DataList/DataListItem express records.
64
100
  Card/Section/Surface organize groups without inventing a second typography or
65
101
  spacing system. A heading's semantic level does not prescribe its visual size.
@@ -71,6 +107,79 @@ the interface-content workflow for contextual placement.
71
107
  - Preserve native image alt/fallback semantics and aspect constraints. Decorative
72
108
  artwork should not duplicate an adjacent accessible identity.
73
109
 
110
+ ## Choose a chart by the question
111
+
112
+ Use Metric for a current value, Sparkline for a compact trend in a row,
113
+ LineChart for comparing observations over ordered, equally spaced categories,
114
+ BarChart for comparing discrete groups such as actual and planned values per
115
+ team, and BarList for ranking a few comparable nonnegative values. Sort BarList
116
+ items in the host and retain their exact labels, values and units. Use the same
117
+ domain or max across panels that readers must compare. Keep zero distinct
118
+ from a missing observation and identify comparison series by line pattern
119
+ as well as color. In a LineChart review, traverse dates by keyboard and check
120
+ that the value readout exposes missing data without inventing a value.
121
+ Keep the value readout compact and close to the active marker, within the plot's
122
+ bounds. Keep the marker clear where the readout approaches the edge. Show the
123
+ active category on the axis, where it stays tied to the guide. Exercise a dense
124
+ series as well as a short one and keep only the axis labels that fit.
125
+ Enable LineChart's numeric axis when the reader needs to estimate levels
126
+ or compare them at a glance.
127
+ Use DonutChart for mutually exclusive parts of one total. Group small categories
128
+ only when a combined bucket is meaningful, and prefer BarList for precise
129
+ comparisons between similar values. Check zero and empty separately. Keep the
130
+ center readout as the single source for an inspected category's name and share.
131
+ Keep pointer inspection continuous through the visual gaps between segments.
132
+ Check that the center readout moves directly to the next share at each boundary.
133
+ Give segments the same visual emphasis when the readout shows the total. Keep
134
+ category colors stable and emphasize only the inspected segment's outline.
135
+ Use a quiet categorical palette and the same accent and translucent fill as
136
+ the other charts. Reserve feedback colors for data that actually carries
137
+ success, warning or error meaning.
138
+ Keep the LineChart and BarChart legends off by default. The inspection readout
139
+ already names the series. Enable showLegend when a reader needs to identify
140
+ series before interacting or when the chart is presented as a static image.
141
+ Use Heatmap to find dense and quiet intersections across two labelled axes.
142
+ Compare matrices on the same max and keep missing observations distinct from
143
+ zero. Check exact values by keyboard and pointer with both axis labels present.
144
+ Keep hit areas contiguous across visual gutters so inspection stays continuous.
145
+ Show exact values in a compact tooltip anchored to the inspected cell. Check
146
+ that it stays inside the chart at the edges and leaves the matrix in place.
147
+ Anchor every BarChart to a shared zero baseline. Use stacked bars for additive
148
+ parts and grouped bars for alternatives such as actual versus plan. Keep the
149
+ series order consistent across stacks. Check positive and negative directions,
150
+ missing values, and exact values with pointer and keyboard at the narrowest width.
151
+ Use BarChart's percent layout to compare how the composition changes across
152
+ categories with different totals. Keep the raw values in the readout and leave
153
+ the column empty when its total is zero.
154
+ Use smooth interpolation only when it preserves the observed extrema and
155
+ breaks at missing values. Keep rank labels and values aligned independently
156
+ of the fill widths.
157
+ Use the same accent, translucent fills, tabular values and fast highlight
158
+ motion across chart families. Use the LineChart stroke weight for data marks
159
+ and keep guides, grids and tooltip borders quieter.
160
+ Use ScatterChart for paired numeric observations, RangeChart for observed
161
+ intervals, and BulletChart for actual values against targets. Give every axis
162
+ or bound its unit and keep shared domains consistent across panels.
163
+ Use WaterfallChart to explain a sequence of changes and checkpoints. Use
164
+ Histogram to show frequencies across numeric intervals and BoxPlot to compare
165
+ summaries across groups. Label the units and keep bin edges or scales consistent
166
+ when comparing distributions. Name the meaning of the whiskers in the chart
167
+ context when it affects interpretation.
168
+ Keep Histogram bins contiguous for inspection. A small visual inset separates
169
+ the marks while preserving the numeric interval and its full hit area.
170
+ When a filter applies to several views of one dataset, derive every view from
171
+ the same filtered observations. Keep comparable scales and bin edges stable
172
+ across filter changes so a change in height reflects the data.
173
+ For Histogram and BoxPlot cards in one row, set a shared
174
+ `--flood-chart-plot-height` to align their tick rows. State shared units once
175
+ in the surrounding title and keep them in exact values or axis names.
176
+ Use DumbbellChart for two measurements of the same group. Preserve endpoint
177
+ identity with hollow and filled marks even when the values cross or coincide.
178
+ Keep a pointer guide continuous across the plot
179
+ while the readout shows exact recorded samples. A visual marker may follow
180
+ the curve between samples where data is continuous. Preserve gaps in the
181
+ series and keep keyboard inspection tied to discrete samples.
182
+
74
183
  ## Choose the information, not all available slots
75
184
 
76
185
  For record lists/details, apply the [records skill](../flood-records/SKILL.md)
@@ -140,6 +249,11 @@ property text. A summary outside the panel needs its property named again.
140
249
  Use CollectionToolbar for the search/filter query row, with accepted summaries
141
250
  and a staged editor in filterContent. Keep saved views outside it. The fieldset
142
251
  uses normal Tab navigation; do not place its editable search in a roving Toolbar.
252
+ When a view or status selector occupies the start of a shared row, set
253
+ `align="end"` on CollectionToolbar to place search and filters as a group at
254
+ the trailing edge. Compare the last visible control to the row's content edge,
255
+ including when there is only a quick filter and no Filters button. Let the groups
256
+ wrap in order at a narrower size.
143
257
  Reuse FilterGroup for finite-choice drafts. The host owns validation, Apply,
144
258
  Cancel, request execution and reset scope; canClear must include quickFilters
145
259
  state when that slot is used. Preserve any-match meaning in summaryPrefix.
@@ -35,6 +35,14 @@ visible even when reducing decorative emphasis.
35
35
 
36
36
  ## Scope feedback to its operation
37
37
 
38
+ Use a floating ToastRegion for the result of a discrete action in a collection
39
+ that is still usable. Keep a failed action's toast available while its retry
40
+ is offered, and preserve the operation's captured targets. Start at bottom-end
41
+ and keep the toast clear of selection actions. Use an inline Alert when the message belongs to
42
+ the affected section, for example when a read failure blocks the table itself.
43
+ Keep its action on the same visual axis as the message in a short titleless
44
+ row. Use Flood Button variants so hover and press inherit the Alert tone.
45
+
38
46
  Associate a message with the operation and record that produced it. Preserve
39
47
  entered data after refusal and keep a useful error while that operation remains
40
48
  unresolved. A successful retry clears/replaces its failure. Explicitly discarding
@@ -48,6 +56,10 @@ that distinction; the feedback primitive only presents the supplied state.
48
56
 
49
57
  ## Evidence
50
58
 
59
+ After a collection action, check that its result is visible at the current
60
+ scroll position and that success, refusal, retry and dismissal leave the
61
+ table header and scroll height in place.
62
+
51
63
  Trigger the operation and observe each applicable transition, including failure
52
64
  and retry. Also follow failure → explicit discard → list → reopen a saved record;
53
65
  the abandoned draft's failure must be gone and the saved data unchanged. Distinguish
@@ -36,6 +36,11 @@ brief did not enumerate every affordance of choosing a date.
36
36
  - Error is invalid; warning/success/info are advisory, not validation algorithms.
37
37
  Host validation decides the error and useful message. Keep native constraints,
38
38
  invalid focus and the accessible message association coherent.
39
+ - For a validation message users need while correcting a value, render it with
40
+ the associated Field. An application-specific error should remain visible
41
+ during correction. Preserve the native form constraint and focus on the first
42
+ invalid field, then check the message and nearby controls after the failed
43
+ submission. Native validity by itself does not verify the error presentation.
39
44
 
40
45
  For visual roles and rhythm, read the [hierarchy skill](../flood-hierarchy/SKILL.md).
41
46
  Fieldset legendSize="section" is for an independent section; a short form may
@@ -21,6 +21,10 @@ this workflow makes that meaning visible.
21
21
 
22
22
  - Dialog owns its task heading and the body inset. Its dark title uses the
23
23
  dialog-title role (1.25rem / 600); it is distinct from compact popup captions.
24
+ - For independent blocks inside a record Drawer, use Section with
25
+ `headingSize="group"` when installed. Keep the Drawer title one level stronger
26
+ visually. Set the semantic heading level separately. Start with a tighter gap
27
+ from each heading to its content and space-8 between independent sections.
24
28
  - Field owns the label-to-control relationship: space-1 (.25rem) in the dark
25
29
  profile. DateField/TimeField already use that relationship. Leave room between
26
30
  independent fields instead of increasing the gap inside every label/control pair.
@@ -38,6 +38,13 @@ Do not hide essential instructions or risks behind a tooltip merely
38
38
  to make a screen quieter. Preserve accessible names and associations when reducing
39
39
  visible copy; use the component's documented hideLabel API where appropriate.
40
40
 
41
+ For a bulk confirmation, put the action and its scope first. Use the title for
42
+ the count when it reads naturally there. If the count belongs in the body, give
43
+ it the first sentence. Put a meaningful consequence on a separate line or in a
44
+ separate paragraph. Let each thought wrap naturally on narrow screens. Preserve
45
+ the dialog's accessible description and check singular and plural copy.
46
+ AlertDialog preserves a newline in its string description.
47
+
41
48
  ## Separate prototype provenance from product state
42
49
 
43
50
  An explicitly requested local prototype or fixture-backed test app does not need
@@ -22,6 +22,9 @@ opacity and transform on bounded visual parts. Keep an anchored overlay's
22
22
  positioning root stable while a child moves. Animate color only where the old and
23
23
  new colors keep required information legible. Keep focus outlines and error
24
24
  messages immediate. Apply hover treatment only to devices that can hover.
25
+ For ToastRegion, animate each arriving card as a unit from its placement edge.
26
+ Keep the region anchored and its announcement available as soon as it appears.
27
+ Inline toasts can fade without moving surrounding content.
25
28
  Keep compression off disabled controls, text editors and joined control
26
29
  surfaces. Verify release and cancellation without a layout shift.
27
30
  Treat disclosure headers as part of their enclosing surface. Keep their
@@ -31,6 +31,11 @@ Modal and nonmodal focus are different: do not add a trap to every floating
31
31
  surface or remove a modal's background inertness. Escape dismisses the active
32
32
  layer; a nested menu/select must not also close its parent dialog. Restore opener
33
33
  focus unless the host intentionally moved it elsewhere.
34
+ When a Menu or Dialog-family action can remove or disable its opener, pass
35
+ `getFallbackFocus` to resolve a reachable target after the close commits.
36
+ Choose the next surviving record by its identity or return to the search
37
+ field when the action leaves an empty result. Test focus with the opener
38
+ still present, after its removal and after a deliberate focus change.
34
39
 
35
40
  Task Dialog titles and body insets use their own recipe; do not reuse compact
36
41
  popup caption typography for the modal task. The
@@ -56,6 +61,12 @@ DescriptionList or Fieldset as appropriate. Put the next action in the footer
56
61
  when it must stay reachable during scrolling. Avoid repeating the heading
57
62
  as a section name or showing two equivalent dismiss actions in a clean state.
58
63
 
64
+ Use Sheet when a short touch task, navigation list or option list needs the
65
+ width of the phone. Keep the current choice visible on its trigger and compose
66
+ single-choice options with ListBox. Commit on selection, keep the previous value
67
+ on dismissal, and return focus to the trigger. Use one scrolling body and keep
68
+ long content, the close action and safe-area padding reachable.
69
+
59
70
  Overlay material establishes the nested neutral control context automatically.
60
71
  Compare its fields, secondary actions, selection and supporting chips with their
61
72
  canvas counterparts. Avoid opaque dark action islands or hiding the entire
@@ -69,6 +69,32 @@ button provides the keyboard entry. Keep checkbox, links and menus independent.
69
69
  For a real destination, preserve a Link. Use the table toolbar and matching
70
70
  edge inset when the heading, filters, cells and footer share one surface.
71
71
 
72
+ For transient selection commands, look up `recipe:collection-views` in the
73
+ installed catalog. For a full-window record workspace with a changing row count,
74
+ use `AppShell scroll="content" scrollOrientation="vertical"` as the vertical
75
+ scroll owner, including when the page has no app chrome. If workspace padding
76
+ already clears the overlay rail, set `scrollContentInset="none"` to keep the
77
+ content width stable when the rail appears. Keep fixed actions outside that
78
+ ScrollArea and wide table scrolling inside the table. Test populated and empty
79
+ views with space-reserving system scrollbars enabled. Check which element
80
+ scrolls, that the document reserves zero scrollbar width, and that table edges
81
+ stay put when the app scrollbar appears or disappears.
82
+
83
+ Place BulkActionBar in a fixed host centered near the bottom
84
+ of the viewport. Keep the host outside the table toolbar. Budget any needed
85
+ bottom clearance in the base layout so selecting rows preserves both the table
86
+ position and the scroll height. Use `showSelection={false}` when BulkActionBar displays the count.
87
+ The table still announces selection and can show its result range and pagination.
88
+ When a bordered Surface wraps a flush table, apply `overflow: clip` to that
89
+ frame. Keep horizontal scrolling on the table's own ScrollArea. Verify the
90
+ outline at both lower corners with a visible footer and check keyboard focus at
91
+ the frame's edges.
92
+
93
+ If a detail table's total summarizes its rows, put it in Table's `tfoot`. Use a
94
+ row header for the label and align the amount with the corresponding numeric
95
+ column. The existing footer border separates it from the last item. Use an
96
+ external summary when its scope includes data beyond the table.
97
+
72
98
  Give a queue's summaries only the prominence they earn in the task. If a
73
99
  count changes which work to pick up, make the relevant scope clear. If the
74
100
  table already exposes the decision, compare a quiet inline count with a
@@ -117,6 +143,12 @@ reapply the current filter to the updated data. If the source row disappears,
117
143
  return focus to a surviving list control such as search. In a long list, verify
118
144
  the scroll position and focus separately after both Save and Cancel.
119
145
 
146
+ For a table-to-Drawer flow, give DataTable's primary action the record title
147
+ and open the same Drawer from the row surface and keyboard action. Group facts
148
+ in DescriptionList and related rows in a captioned Table. Keep the Drawer body
149
+ as the vertical scroll owner and keep the edit or save action in its footer.
150
+ Use floating feedback for the save result so the table stays in place.
151
+
120
152
  Keep search and a frequently used filter visible when there is room. Put
121
153
  occasional or grouped criteria behind a named Filters action. Show applied
122
154
  criteria at the list edge so users can tell why a record is missing.
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: flood-screen-composition
3
+ description: Choose the layout, reading order and first useful action for a Flood screen. Use for new screens or when an existing page is hard to scan, compare or act on.
4
+ ---
5
+
6
+ # Compose for the user's task
7
+
8
+ Identify the information the user needs to find, the decision they need to
9
+ make, and what they can do next. Arrange the first viewport so that it reveals
10
+ the page's purpose and the next useful content or control. Keep local actions
11
+ with the item or region they affect. A passive view may need no primary button.
12
+
13
+ Choose a screen structure before choosing surfaces, cards or emphasis.
14
+
15
+ | User task | Useful starting structure | Inspect in the rendered screen |
16
+ | --- | --- | --- |
17
+ | Understand an offer on a landing page | Lead with the offer and a relevant next action. Put product evidence near the claim it supports. Use a split hero when the visual helps explain the product. | Read the opening with the image absent and at narrow width. The offer, evidence and action still follow a meaningful order. |
18
+ | Find or compare records | Put search and filters next to their results. Use a list for recognition and a table when readers compare the same attributes across rows. | Find an item by title, then compare one value across several rows without losing the column or confusing it with status. |
19
+ | Monitor or decide | Start with the decision or the signal that changes it. Put a summary near the chart, queue or record that explains it. Use separate surfaces for genuinely independent scopes. | Identify what needs attention and follow the visible path to its detail or action. Remove repeated summaries and metrics with no decision to support. |
20
+ | Complete a form or edit | Keep related fields in reading order. Show a review step when correcting a consequential submission warrants one. Preserve entered answers when going back. | Follow labels, input, error and next action with the keyboard. Exercise Back or Cancel and verify which data and focus survive. |
21
+ | Find an answer in documentation | Use informative section headings and place examples next to the explanation they demonstrate. Add an outline when the document has enough sections to make it useful. | Find an answer by scanning headings, then locate its example without reading unrelated sections. |
22
+
23
+ Use [composition](../flood-composition/SKILL.md) to choose the installed
24
+ component owners. Use [hierarchy](../flood-hierarchy/SKILL.md) when related
25
+ titles, groups and controls need visual separation.
26
+
27
+ ## Treat scanning patterns as observations
28
+
29
+ F-shaped scanning can appear in undifferentiated prose. Give readers useful
30
+ section headings and put distinguishing words early. A diagonal or Z-shaped
31
+ path can be a hypothesis for a sparse, image-led composition. Judge it using
32
+ that screen's content and task. For repeated comparisons, keep equivalent
33
+ labels or values on predictable tracks. Check the semantic and keyboard order
34
+ as columns stack or writing direction changes. A screenshot alone cannot
35
+ establish where users look.
36
+
37
+ ## Review the assembled screen
38
+
39
+ Inspect one real populated screen at the intended width and the narrowest
40
+ supported width or enlarged text size. Walk the task without relying on
41
+ explanatory copy. Check whether a heading, surface, badge or metric earns its
42
+ place by identifying scope, grouping related content or supporting a decision.
43
+ Follow an empty or failure state when relevant. Record one concrete layout
44
+ decision and the observed result outside the interface.
45
+
46
+ See [NN/g's eyetracking research](https://www.nngroup.com/articles/text-scanning-patterns-eyetracking/),
47
+ its [study of alternating image–text layouts](https://www.nngroup.com/articles/zigzag-page-layout/),
48
+ and the [GOV.UK review-before-submission pattern](https://design-system.service.gov.uk/patterns/check-answers/).
@@ -74,6 +74,13 @@ and compact states. Center an icon-only rail against the full rail, not the
74
74
  remainder after a one-sided gutter. A scrollbar appearing must not shift body
75
75
  tracks relative to the fixed header/footer. Full-viewport workspaces without
76
76
  document overflow must not reserve a document scrollbar strip.
77
+ For a floating action bar, size its host to the actual count, commands and close
78
+ control. Keep the count slot stable across digit changes and bound the panel to
79
+ the viewport. Measure the clearance below the last row with the panel open.
80
+ Compare scroll height, available content width and table position before and
81
+ after selection. Check a viewport where all rows fit and one where the last
82
+ row needs scrolling. Put required clearance in the base layout so selection
83
+ keeps the same scroll geometry.
77
84
  Test expanded/compact, missing icons, badges/disclosures, long labels, RTL and
78
85
  enlarged text. Measure rendered glyph centers, text starts and action centers
79
86
  across distant rows; include the header and footer. Correct the owning primitive
@@ -8,6 +8,8 @@ description: Verify Flood component or composed-interface changes against applic
8
8
  Read [verification](../verification.md), the host's scripts and the changed
9
9
  component's contract. Use project-root flood/rules.json to identify applicable
10
10
  rule IDs; it is an index of guidance, not an automatic pass/fail policy engine.
11
+ For visible UI changes, use [visual review](../flood-visual-review/SKILL.md) to
12
+ exercise the affected states, inspect captures and record the evidence.
11
13
 
12
14
  ## Bound the coverage
13
15
 
@@ -81,6 +83,10 @@ about repeated copy or metadata in the verification notes.
81
83
  Use the [rendered review observer](../rendered-review.md) when local browser
82
84
  tooling is available. Inspect findings and exceptions, then review hierarchy and
83
85
  copy separately; no findings is not an editorial or visual-quality pass.
86
+ For full-window workspaces, run the
87
+ [workspace scroll assertion](../rendered-review.md#require-workspace-scroll-in-browser-tests)
88
+ on overflowing content and after filtering or another action that shrinks the
89
+ view. Use the same assertion in the independent review of each clean agent run.
84
90
  Review host JSX/CSS with inspectSourceUI from that entry too, then resolve the
85
91
  actual owner at each candidate location. Include layout and cancel/confirmation
86
92
  paths, not just fields. A native browser dialog can be absent from a DOM snapshot;
@@ -117,3 +123,29 @@ agent instruction, screenshot or accessibility scanner cannot independently prov
117
123
  all behavior or certify conformance. A local build does not prove registry
118
124
  publication, website deployment or a host backend save. Keep installation upgrades
119
125
  deliberate and preserve customized/linked destination protections.
126
+
127
+ ## Compare agent guidance in clean runs
128
+
129
+ When evaluating a rule or skill, give each fresh session the same short task,
130
+ starting project, reference material and tool access. Keep the model, reasoning
131
+ effort, library implementation and review viewport fixed. Change only the
132
+ guidance being tested. When comparing models, keep the guidance fixed too. Do
133
+ not pass along prior attempts, reviewer feedback or fixes.
134
+
135
+ Decide what to inspect before running the task. Check the same states for task
136
+ completion, correct component ownership, hierarchy, necessary copy and behavior.
137
+ For a discovery comparison, vary the entry point while leaving the guidance
138
+ available in both runs. Check the trace for the entry and selected references.
139
+ For an application comparison, make the same entry available explicitly in both
140
+ runs and vary the instruction under test. Check what the agent actually built.
141
+ Use an unfamiliar task as well as an example already documented in the guidance.
142
+
143
+ For visual comparisons, give a fresh reviewer the task, expected behavior and
144
+ settled renders or live previews. Hide which variant produced each result.
145
+ Walk the same interaction in each and cite the exact state and visible evidence
146
+ for each finding. Check API choice and mechanics through source or browser
147
+ assertions, and use the rendered comparison for hierarchy, copy and density.
148
+
149
+ Keep failed attempts and record missing evidence. A single pair of runs can
150
+ reveal a failure mode. Repeat clean runs before attributing a difference to the
151
+ guidance or the model.