@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.
- package/DESIGN.md +10 -1
- package/README.md +9 -4
- package/SKILL.md +16 -5
- package/dist/catalog.json +816 -232
- package/dist/materials/component-alert-dialog.md +1 -0
- package/dist/materials/component-app-shell.md +3 -1
- package/dist/materials/component-bar-chart.md +52 -0
- package/dist/materials/component-bar-list.md +41 -0
- package/dist/materials/component-box-plot.md +46 -0
- package/dist/materials/component-bullet-chart.md +43 -0
- package/dist/materials/component-code-snippet.md +3 -1
- package/dist/materials/component-collection-toolbar.md +4 -1
- package/dist/materials/component-command-palette.md +1 -0
- package/dist/materials/component-copy-button.md +2 -0
- package/dist/materials/component-data-table.md +21 -3
- package/dist/materials/component-dialog.md +2 -0
- package/dist/materials/component-donut-chart.md +46 -0
- package/dist/materials/component-drawer.md +2 -0
- package/dist/materials/component-dumbbell-chart.md +46 -0
- package/dist/materials/component-editable.md +4 -0
- package/dist/materials/component-heading.md +1 -1
- package/dist/materials/component-heatmap.md +45 -0
- package/dist/materials/component-histogram.md +46 -0
- package/dist/materials/component-image-preview.md +1 -0
- package/dist/materials/component-line-chart.md +50 -0
- package/dist/materials/component-menu.md +2 -0
- package/dist/materials/component-range-chart.md +46 -0
- package/dist/materials/component-scatter-chart.md +48 -0
- package/dist/materials/component-section.md +1 -1
- package/dist/materials/component-sheet.md +50 -0
- package/dist/materials/component-sparkline.md +41 -0
- package/dist/materials/component-table.md +3 -1
- package/dist/materials/component-toolbar.md +1 -0
- package/dist/materials/component-waterfall-chart.md +47 -0
- package/dist/materials/guide-agent-knowledge.md +5 -5
- package/dist/materials/guide-agents.md +35 -2
- package/dist/materials/guide-charts.md +34 -0
- package/dist/materials/guide-foundations.md +2 -2
- package/dist/materials/guide-installation.md +6 -6
- package/dist/materials/guide-introduction.md +2 -1
- package/dist/materials/guide-motion.md +19 -10
- package/dist/materials/guide-skills.md +10 -0
- package/dist/materials/recipe-collection-views.md +72 -47
- package/dist/materials/recipe-navigation-workspace.md +3 -0
- package/dist/materials/recipe-record-management.md +109 -61
- package/knowledge.json +16 -0
- package/lib/inspect.d.ts +14 -2
- package/lib/inspect.mjs +65 -0
- package/manifest.json +11 -1
- package/package.json +1 -1
- package/references/component-families.md +14 -0
- package/references/composition.md +12 -0
- package/references/flood-composition/SKILL.md +7 -0
- package/references/flood-data-display/SKILL.md +114 -0
- package/references/flood-feedback/SKILL.md +12 -0
- package/references/flood-forms/SKILL.md +5 -0
- package/references/flood-hierarchy/SKILL.md +4 -0
- package/references/flood-interface-content/SKILL.md +7 -0
- package/references/flood-motion/SKILL.md +3 -0
- package/references/flood-overlays/SKILL.md +11 -0
- package/references/flood-records/SKILL.md +32 -0
- package/references/flood-screen-composition/SKILL.md +48 -0
- package/references/flood-spacing/SKILL.md +7 -0
- package/references/flood-verification/SKILL.md +32 -0
- package/references/flood-visual-review/SKILL.md +59 -0
- package/references/rendered-review.md +49 -3
- package/references/routing.md +2 -1
- package/rules.json +37 -1
- 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.
|
|
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
|
@@ -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.
|