@flood-md/agent 0.2.12 → 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 (57) 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 +742 -214
  5. package/dist/materials/component-alert-dialog.md +1 -0
  6. package/dist/materials/component-app-shell.md +1 -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 +2 -0
  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-dialog.md +2 -0
  16. package/dist/materials/component-donut-chart.md +46 -0
  17. package/dist/materials/component-drawer.md +2 -0
  18. package/dist/materials/component-dumbbell-chart.md +46 -0
  19. package/dist/materials/component-heatmap.md +45 -0
  20. package/dist/materials/component-histogram.md +46 -0
  21. package/dist/materials/component-image-preview.md +1 -0
  22. package/dist/materials/component-line-chart.md +50 -0
  23. package/dist/materials/component-menu.md +2 -0
  24. package/dist/materials/component-range-chart.md +46 -0
  25. package/dist/materials/component-scatter-chart.md +48 -0
  26. package/dist/materials/component-sheet.md +1 -0
  27. package/dist/materials/component-table.md +1 -1
  28. package/dist/materials/component-waterfall-chart.md +47 -0
  29. package/dist/materials/guide-agent-knowledge.md +5 -5
  30. package/dist/materials/guide-agents.md +35 -2
  31. package/dist/materials/guide-charts.md +34 -0
  32. package/dist/materials/guide-foundations.md +2 -2
  33. package/dist/materials/guide-installation.md +6 -6
  34. package/dist/materials/guide-introduction.md +2 -1
  35. package/dist/materials/guide-motion.md +12 -0
  36. package/dist/materials/guide-skills.md +10 -0
  37. package/dist/materials/recipe-collection-views.md +3 -0
  38. package/dist/materials/recipe-navigation-workspace.md +3 -0
  39. package/dist/materials/recipe-record-management.md +92 -58
  40. package/knowledge.json +16 -0
  41. package/lib/inspect.d.ts +14 -2
  42. package/lib/inspect.mjs +63 -9
  43. package/manifest.json +11 -1
  44. package/package.json +1 -1
  45. package/references/component-families.md +10 -0
  46. package/references/flood-composition/SKILL.md +7 -0
  47. package/references/flood-data-display/SKILL.md +85 -0
  48. package/references/flood-forms/SKILL.md +5 -0
  49. package/references/flood-overlays/SKILL.md +5 -0
  50. package/references/flood-records/SKILL.md +13 -4
  51. package/references/flood-screen-composition/SKILL.md +48 -0
  52. package/references/flood-verification/SKILL.md +32 -0
  53. package/references/flood-visual-review/SKILL.md +59 -0
  54. package/references/rendered-review.md +49 -3
  55. package/references/routing.md +2 -1
  56. package/rules.json +34 -2
  57. package/workflows.json +22 -0
package/knowledge.json CHANGED
@@ -21,6 +21,11 @@
21
21
  "name": "Data & feedback",
22
22
  "description": "Structured content, files and honest operation states."
23
23
  },
24
+ {
25
+ "id": "charts",
26
+ "name": "Charts",
27
+ "description": "Visualize trends, comparisons, distributions and change."
28
+ },
24
29
  {
25
30
  "id": "quality",
26
31
  "name": "Quality",
@@ -65,10 +70,16 @@
65
70
  "verification": [
66
71
  "quality"
67
72
  ],
73
+ "visual-review": [
74
+ "quality"
75
+ ],
68
76
  "interface-content": [
69
77
  "composition",
70
78
  "quality"
71
79
  ],
80
+ "screen-composition": [
81
+ "composition"
82
+ ],
72
83
  "hierarchy": [
73
84
  "foundations",
74
85
  "composition"
@@ -247,6 +258,10 @@
247
258
  "content": [
248
259
  "data-feedback"
249
260
  ],
261
+ "charts": [
262
+ "charts",
263
+ "data-feedback"
264
+ ],
250
265
  "feedback": [
251
266
  "data-feedback"
252
267
  ]
@@ -328,6 +343,7 @@
328
343
  }
329
344
  ],
330
345
  "documentGroups": {
346
+ "charts.md": ["charts", "data-feedback", "composition"],
331
347
  "recipes/record-management.md": ["data-feedback", "composition"],
332
348
  "recipes/settings-workspace.md": ["interaction", "composition"],
333
349
  "README.md": [
package/lib/inspect.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export interface InspectionTarget {tag:string;id:string|null;className:string;label:string;}
2
- export interface InspectionIssue {id:'icons.text-glyph'|'icons.unslotted-svg'|'table.mixed-row-centre'|'table.word-fragment'|'copy.action-echo'|'copy.unowned-support'|'forms.track-drift'|'forms.content-track-drift'|'layout.page-overflow';target:InspectionTarget;related?:InspectionTarget;message:string;offset?:number;word?:string;}
2
+ export interface InspectionIssue {id:'icons.text-glyph'|'icons.unslotted-svg'|'table.mixed-row-centre'|'table.word-fragment'|'copy.action-echo'|'copy.unowned-support'|'forms.track-drift'|'forms.content-track-drift'|'layout.page-overflow'|'layout.record-scroll-owner';target:InspectionTarget;related?:InspectionTarget;message:string;offset?:number;word?:string;}
3
3
  export interface RenderedUIInspection {
4
4
  schemaVersion:1;issues:InspectionIssue[];copy:InspectionTarget[];
5
5
  fields:(InspectionTarget&{x:number;y:number;width:number;height:number})[];
@@ -7,6 +7,18 @@ export interface RenderedUIInspection {
7
7
  }
8
8
  /** Invoke inside a browser document, e.g. page.evaluate(inspectRenderedUI). No mutation or network calls. */
9
9
  export declare function inspectRenderedUI(options?:{rootSelector?:string;maxElements?:number}):RenderedUIInspection;
10
- export interface SourceUIIssue {id:'composition.native-dialog'|'composition.native-control'|'composition.layout-owner'|'composition.scaled-minimum';line:number;column:number;excerpt:string;owner:string;message:string;}
10
+ export interface WorkspaceScrollOptions {
11
+ /** Selector for one full-window AppShell. Defaults to .flood-app-shell. */
12
+ rootSelector?: string;
13
+ /** Set true for overflowing fixtures or false for fixtures whose content must fit. */
14
+ expectOverflow?: boolean;
15
+ }
16
+ /** Run with page.evaluate after the workspace settles. Throws on a broken scroll contract. */
17
+ export declare function assertWorkspaceScroll(options?: WorkspaceScrollOptions): {
18
+ documentGutter: number;
19
+ documentOverflow: number;
20
+ workspaceOverflow: number;
21
+ };
22
+ export interface SourceUIIssue {id:'composition.native-dialog'|'composition.native-control'|'composition.page-scroll'|'composition.layout-owner'|'composition.scaled-minimum';line:number;column:number;excerpt:string;owner:string;message:string;}
11
23
  /** Text observations, not an AST or conformance check. No file access, execution or network. */
12
24
  export declare function inspectSourceUI(source:string,options?:{format?:'jsx'|'css';maxFindings?:number}):{schemaVersion:1;issues:SourceUIIssue[];truncated:boolean;notChecked:string[]};
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');
@@ -53,15 +98,24 @@ export function inspectRenderedUI(options = {}) {
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.'});
54
99
  const documentGutter = innerWidth - document.documentElement.clientWidth;
55
100
  const scrollOwner = document.scrollingElement;
56
- if (documentGutter > 1 && scrollOwner && scrollOwner.scrollHeight > scrollOwner.clientHeight + 1) {
57
- const table = select('.flood-data-table').find(visible);
58
- if (table) addIssue({
59
- id: 'layout.record-scroll-owner',
60
- target: target(table),
61
- offset: documentGutter,
62
- message: 'A document scrollbar consumes width on this record view. Compare full and filtered views with classic scrollbars. For a full-window workspace, use AppShell content scrolling so changes in row count keep the table edges in place.',
63
- });
64
- }
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
+ });
65
119
  for (const button of select('button.flood-button, button.flood-icon-button')) {
66
120
  // Text is inspected outside real icon slots, SVGs and visually hidden names.
67
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.12",
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.12",
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
@@ -132,6 +133,15 @@ focus bounds and overflow thresholds. Exercise resize while an action or popup
132
133
  has focus. After a shared-owner correction, inspect another consumer. A green
133
134
  build or token reuse alone does not establish visual kinship.
134
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
+
135
145
  ## Keep the contract discoverable
136
146
 
137
147
  In Flood source, update declarations, component examples, applicable guidance
@@ -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,13 @@ 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.
63
70
  - Offer column visibility when users need different subsets of fields for real
64
71
  tasks in the same table. Leave it off for compact tables with a fixed task.
65
72
  Use one layout control per table. If the screen already has View options or
@@ -100,6 +107,79 @@ the interface-content workflow for contextual placement.
100
107
  - Preserve native image alt/fallback semantics and aspect constraints. Decorative
101
108
  artwork should not duplicate an adjacent accessible identity.
102
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
+
103
183
  ## Choose the information, not all available slots
104
184
 
105
185
  For record lists/details, apply the [records skill](../flood-records/SKILL.md)
@@ -169,6 +249,11 @@ property text. A summary outside the panel needs its property named again.
169
249
  Use CollectionToolbar for the search/filter query row, with accepted summaries
170
250
  and a staged editor in filterContent. Keep saved views outside it. The fieldset
171
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.
172
257
  Reuse FilterGroup for finite-choice drafts. The host owns validation, Apply,
173
258
  Cancel, request execution and reset scope; canClear must include quickFilters
174
259
  state when that slot is used. Preserve any-match meaning in summaryPrefix.
@@ -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
@@ -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
@@ -72,10 +72,13 @@ edge inset when the heading, filters, cells and footer share one surface.
72
72
  For transient selection commands, look up `recipe:collection-views` in the
73
73
  installed catalog. For a full-window record workspace with a changing row count,
74
74
  use `AppShell scroll="content" scrollOrientation="vertical"` as the vertical
75
- scroll owner, including when the page has no app chrome. Keep fixed actions
76
- outside that ScrollArea. Test a populated view and a filtered or empty view in a
77
- browser with space-reserving scrollbars. Compare the table's inline edges
78
- and the document's client width across those views.
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.
79
82
 
80
83
  Place BulkActionBar in a fixed host centered near the bottom
81
84
  of the viewport. Keep the host outside the table toolbar. Budget any needed
@@ -140,6 +143,12 @@ reapply the current filter to the updated data. If the source row disappears,
140
143
  return focus to a surviving list control such as search. In a long list, verify
141
144
  the scroll position and focus separately after both Save and Cancel.
142
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
+
143
152
  Keep search and a frequently used filter visible when there is room. Put
144
153
  occasional or grouped criteria behind a named Filters action. Show applied
145
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/).
@@ -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.
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: flood-visual-review
3
+ description: Review rendered Flood UI with Playwright or equivalent browser tooling. Use for visual bugs, screenshot feedback, new or changed UI, and visual regressions across interaction states.
4
+ ---
5
+
6
+ # Review the UI in the browser
7
+
8
+ Open the actual route or component preview with representative data. For a
9
+ reported issue, reproduce its state with the user's viewport, input and browser
10
+ engine when relevant and available. For a new or changed UI, start with the user's
11
+ main task and exercise the affected states. A visual review request can produce
12
+ findings alone. When implementing a fix, repeat the same interaction after it.
13
+
14
+ ## Capture and inspect
15
+
16
+ Use the project's Playwright setup or equivalent browser tooling. Reach states
17
+ with clicks, keyboard and scroll. Wait for fonts and the intended stable state
18
+ before a still capture. Keep motion enabled when investigating a jump or flicker;
19
+ use consecutive frames, video or a trace with screenshots. Confirm layout shifts
20
+ with measurements before and after the action when possible.
21
+
22
+ Save a screenshot of the changed region in its surrounding layout, then open the
23
+ image and inspect it at its intended size. Crop a detail if needed. For a fix,
24
+ capture before and after with the same data, viewport, scroll position and state
25
+ when the original is available. Keep the artifacts in the host's test output or
26
+ another ignored local directory and link the relevant evidence in the handoff.
27
+
28
+ | Surface | What to exercise and look for |
29
+ | --- | --- |
30
+ | Table or collection | Select and clear rows, apply a filter through to zero results, then open any affected row detail. Compare column tracks, clipping at rounded edges and whether the toolbar, scrollbar or selection actions shift the table. |
31
+ | Drawer, dialog or popup | Inspect the open state with real content, scroll to the last action and close it. Check the rhythm between title, description and body, internal clipping, overlay placement and visible keyboard focus. |
32
+ | Form or navigation | Walk the relevant keyboard path. Compare label/control gaps, peer text and icon axes, long labels and hierarchy. Exercise an affected error, expansion or selection. For failed submit, verify the message is readable during correction and check what receives focus. |
33
+
34
+ When a workspace changes height, use a browser with classic scrollbars enabled
35
+ and force overflow. Verify that the intended region scrolls. Compare its content
36
+ edges and `innerWidth - document.documentElement.clientWidth` before and after
37
+ filtering. A browser with hidden or overlay system rails can mask the gutter.
38
+ Use the [workspace scroll assertion](../rendered-review.md#require-workspace-scroll-in-browser-tests)
39
+ in both states so the browser test fails if the document takes over scrolling.
40
+
41
+ Check the affected scope at the normal viewport and at a supported narrow or
42
+ enlarged-text setting when space is part of the risk. Read the rendered copy as
43
+ part of the task. Look for duplicated labels, decorative status and instructions
44
+ that repeat what the surrounding UI already says. Use the existing [rendered
45
+ review observer](../rendered-review.md) for additional clues if available.
46
+
47
+ ## Resolve and verify
48
+
49
+ For each material finding, record the route and state, the action to reproduce
50
+ it, the visible symptom, and a screenshot or measurement. Start with problems
51
+ that block the task, hide content or confuse the next action. If a bug repeats,
52
+ locate its shared owner using the [component family contract](../component-families.md)
53
+ and check another affected use after the fix.
54
+
55
+ Use browser assertions for stable invariants such as bounds, focus or scroll
56
+ position. A passing assertion still leaves visual hierarchy, copy and balance
57
+ to inspect. Report the states actually reviewed and any missing evidence. If the
58
+ target cannot run, or images cannot be inspected, say which visual checks remain
59
+ open and report the evidence you could obtain.