@tekyzinc/gsd-t 2.69.13 → 2.70.11
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/CHANGELOG.md +21 -0
- package/commands/gsd-t-design-audit.md +82 -1
- package/commands/gsd-t-design-decompose.md +8 -1
- package/commands/gsd-t-execute.md +85 -4
- package/commands/gsd-t-quick.md +22 -3
- package/package.json +1 -1
- package/templates/stacks/design-to-code.md +123 -25
- package/templates/widget-contract.md +38 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GSD-T are documented here. Updated with each release.
|
|
4
4
|
|
|
5
|
+
## [2.70.11] - 2026-04-06
|
|
6
|
+
|
|
7
|
+
### Added (design pipeline — DOM box model inspection + layout arithmetic)
|
|
8
|
+
- **DOM Box Model Inspection** — new mandatory verification step for fixed-height containers. Uses Playwright to evaluate `offsetHeight` vs `scrollHeight` for each child element. Flags elements where `offsetHeight > scrollHeight * 1.5` as INFLATED (symptom: `flex: 1` on a content element inflating its box beyond content size). Added to: `gsd-t-execute` (Step 5.5 inside Design Verification Agent), `gsd-t-quick` (step 8 inside Design Verification Agent), `gsd-t-design-audit` (Step 3.75).
|
|
9
|
+
- **Internal Layout Arithmetic** — widget contract template now requires computed height budgets for fixed-height cards: `card_height - padding - header = body_available`, then `child1 + gap1 + child2 + ... = total_content ≤ body_available`. Forces the agent to write the math before coding — prevents `gap: 12px` when only `gap: 8px` fits.
|
|
10
|
+
- **Flex Centering Anti-Pattern Rule** — `design-to-code.md` Section 8 now explicitly prohibits `flex: 1` on content elements (KPI, labels, text) for centering. Rule: `flex: 1` belongs on containers, `justify-content: center` on the parent. Children keep natural size.
|
|
11
|
+
- **4 new verification checklist items** in `design-to-code.md` and `widget-contract.md`: box model inspection, layout arithmetic, no content flex:1, inflated element detection.
|
|
12
|
+
|
|
13
|
+
### Why
|
|
14
|
+
BDS horizontal stacked bar cards required 5 user-prompted fix iterations to get spacing right. Root cause: agent used `flex: 1` on `.kpi` to center it vertically, which inflated the element to 144px (content was 40px), displacing the chart section. The property comparison table and SVG overlay both missed this because the *positions* were close enough — the problem was *how space was distributed*, not where elements landed. DOM box model inspection catches the cause (inflated element) not just the symptom (displaced sibling).
|
|
15
|
+
|
|
16
|
+
## [2.70.10] - 2026-04-06
|
|
17
|
+
|
|
18
|
+
### Added (design pipeline — 2 new capabilities)
|
|
19
|
+
- **Design System Detection** — all design pipeline commands now ask for a design system / component library URL upfront before extraction or implementation. If provided, the agent fetches the library docs, catalogs available components, and maps design elements to library primitives (use library components instead of building custom). Added to: `gsd-t-design-decompose` (Step 0.4), `gsd-t-design-audit` (Step 0), `design-to-code.md` (new Section 1 — all subsequent sections renumbered). Verification checklist updated with 2 new items.
|
|
20
|
+
- **SVG Structural Overlay Comparison** — new mandatory verification layer that exports the Figma frame as SVG, parses element positions/dimensions/colors from the SVG DOM, maps to built DOM bounding boxes, and compares geometry mechanically (≤2px = MATCH, 3-5px = REVIEW, >5px = DEVIATION). Catches aggregate spacing drift, alignment issues, and proportion errors that pass property-level checks but are visually wrong. Added to: `gsd-t-execute` (Step 5 inside Design Verification Agent), `gsd-t-quick` (step 7 inside Design Verification Agent), `gsd-t-design-audit` (Step 3.5), `design-to-code.md` (Target 3 + workflow step 7 + checklist item).
|
|
21
|
+
|
|
22
|
+
### Why
|
|
23
|
+
- **Design system**: Building custom cards, tables, tabs, and buttons from scratch when a library like shadcn-vue already provides them wastes effort and produces inferior results (missing accessibility, focus states, interactive states). Asking upfront eliminates redundant work.
|
|
24
|
+
- **SVG overlay**: The property-level comparison table catches wrong values but misses aggregate visual drift — spacing rhythm, alignment, proportions that are individually correct but collectively off. SVG structural diff is mechanical and non-interpretive: geometry vs geometry, no agent reasoning required.
|
|
25
|
+
|
|
5
26
|
## [2.69.13] - 2026-04-05
|
|
6
27
|
|
|
7
28
|
### Fixed (design-to-code pipeline — extraction + verification)
|
|
@@ -17,6 +17,12 @@ Extract from `$ARGUMENTS`:
|
|
|
17
17
|
If Figma source is missing → ask user: "Provide the Figma file key or URL"
|
|
18
18
|
If built app target is missing → check if a dev server is running. If not → ask user: "Provide the route or URL of the built page to audit"
|
|
19
19
|
|
|
20
|
+
**Design system / component library?**
|
|
21
|
+
- Ask user: "Is a design system or component library being used (e.g., shadcn-vue, Vuetify, Radix, MUI)? If so, provide the URL."
|
|
22
|
+
- If yes → fetch the docs, note which components the library provides and their default styling (padding, radius, shadows, colors)
|
|
23
|
+
- Factor into Step 3 comparisons: deviations that match library defaults (not Figma) may indicate "used library default instead of design value" — flag as a distinct deviation category
|
|
24
|
+
- If no → proceed as normal
|
|
25
|
+
|
|
20
26
|
## Step 1: Map the Figma Design — Node-Level Decomposition
|
|
21
27
|
|
|
22
28
|
### 1a. Get the page tree
|
|
@@ -142,9 +148,84 @@ For each widget, produce a comparison table with **minimum 10 rows per widget**
|
|
|
142
148
|
| **MEDIUM** | Wrong alignment, color, or order that looks incorrect but doesn't change meaning | Legend left instead of center; segment order reversed; wrong shade |
|
|
143
149
|
| **LOW** | Minor sizing or spacing that's barely noticeable | 2px padding difference; slight font-size mismatch |
|
|
144
150
|
|
|
151
|
+
## Step 3.5: SVG Structural Overlay Comparison (MANDATORY)
|
|
152
|
+
|
|
153
|
+
After the per-widget property comparison, run a mechanical SVG-based diff to catch aggregate visual drift that individual property checks miss.
|
|
154
|
+
|
|
155
|
+
1. **Export the Figma frame as SVG**:
|
|
156
|
+
- Use the Figma REST API or MCP to export the page/frame as SVG
|
|
157
|
+
- If export is unavailable, ask the user to export and provide the SVG path
|
|
158
|
+
- Store the SVG at `.gsd-t/design-verify/{page-name}-figma.svg`
|
|
159
|
+
|
|
160
|
+
2. **Parse the SVG DOM**: extract every `<rect>`, `<text>`, `<circle>`, `<path>`, `<g>` with their positions (x, y), dimensions (width, height), fills, strokes, and text content
|
|
161
|
+
|
|
162
|
+
3. **Screenshot the built page** at the same viewport width via Playwright
|
|
163
|
+
|
|
164
|
+
4. **Map SVG elements → built DOM elements** by:
|
|
165
|
+
- Text content matching (highest confidence)
|
|
166
|
+
- Position proximity (x,y within 10px tolerance)
|
|
167
|
+
- Dimensional similarity (width/height within 10% tolerance)
|
|
168
|
+
|
|
169
|
+
5. **Compare each mapped pair**:
|
|
170
|
+
|
|
171
|
+
| Check | SVG Value | Built Value | Threshold |
|
|
172
|
+
|-------|-----------|-------------|-----------|
|
|
173
|
+
| Position (x,y) | SVG coordinates | DOM bounding box | ≤2px = MATCH, 3-5px = REVIEW, >5px = DEVIATION |
|
|
174
|
+
| Dimensions (w,h) | SVG width/height | DOM width/height | ≤2px = MATCH, 3-5px = REVIEW, >5px = DEVIATION |
|
|
175
|
+
| Colors | SVG fill/stroke hex | Computed CSS color | Exact hex = MATCH |
|
|
176
|
+
| Text content | SVG `<text>` | DOM textContent | Exact = MATCH |
|
|
177
|
+
|
|
178
|
+
6. **Produce SVG structural diff table**:
|
|
179
|
+
|
|
180
|
+
```markdown
|
|
181
|
+
### SVG Structural Diff
|
|
182
|
+
|
|
183
|
+
| # | SVG Element | SVG Position | Built Position | Δ px | Verdict |
|
|
184
|
+
|---|-------------|-------------|----------------|------|---------|
|
|
185
|
+
| 1 | stat-card-1 rect | (24, 120) 320×200 | (24, 118) 320×204 | 2/4 | ⚠ REVIEW |
|
|
186
|
+
| 2 | chart-title text | (40, 140) | (40, 140) | 0 | ✅ MATCH |
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
7. **Unmapped elements**:
|
|
190
|
+
- SVG elements with no DOM match → flag as "MISSING IN BUILD"
|
|
191
|
+
- DOM elements with no SVG match → flag as "EXTRA — not in design"
|
|
192
|
+
|
|
193
|
+
8. **Visual overlay** (optional but recommended):
|
|
194
|
+
- Render SVG in browser at target viewport size
|
|
195
|
+
- Overlay on built page screenshot with 50% opacity or difference blend mode
|
|
196
|
+
- Save to `.gsd-t/design-verify/{page-name}-overlay.png`
|
|
197
|
+
|
|
198
|
+
This step catches spacing rhythm, alignment drift, and proportion issues that pass the per-widget property check but are visually wrong in aggregate.
|
|
199
|
+
|
|
200
|
+
## Step 3.75: DOM Box Model Inspection (MANDATORY for fixed-height containers)
|
|
201
|
+
|
|
202
|
+
For each card/widget with a fixed height, inspect the internal space distribution:
|
|
203
|
+
|
|
204
|
+
1. **Evaluate in browser** (via Playwright) for each card body child:
|
|
205
|
+
- `offsetHeight` (layout box size), `scrollHeight` (content size), `flex-grow` (computed)
|
|
206
|
+
|
|
207
|
+
2. **Flag inflated elements**: any element where `offsetHeight > scrollHeight * 1.5`
|
|
208
|
+
- This means `flex: 1` or `flex-grow: 1` is inflating the element's box beyond its content
|
|
209
|
+
- Severity: HIGH — "`.kpi` offsetHeight=144px but content only needs 40px — inflated by flex growth"
|
|
210
|
+
|
|
211
|
+
3. **Verify layout arithmetic**: sum all child `offsetHeight` values + computed gaps. Compare against card body `offsetHeight`:
|
|
212
|
+
- Sum > body → content overflows (❌ DEVIATION)
|
|
213
|
+
- Sum < body by >20px with no centering strategy → space is unaccounted (❌ DEVIATION)
|
|
214
|
+
|
|
215
|
+
4. **Produce box model table** per widget:
|
|
216
|
+
|
|
217
|
+
```markdown
|
|
218
|
+
### Box Model: {widget-name}
|
|
219
|
+
|
|
220
|
+
| # | Element | offsetHeight | scrollHeight | flex-grow | Verdict |
|
|
221
|
+
|---|---------|-------------|-------------|-----------|---------|
|
|
222
|
+
| 1 | .kpi | 144px | 40px | 1 | ❌ INFLATED |
|
|
223
|
+
| 2 | .chart | 74px | 74px | 0 | ✅ MATCH |
|
|
224
|
+
```
|
|
225
|
+
|
|
145
226
|
## Step 4: Summary Report
|
|
146
227
|
|
|
147
|
-
After all widgets are audited, produce a summary:
|
|
228
|
+
After all widgets are audited (property tables + SVG structural diff + box model), produce a summary:
|
|
148
229
|
|
|
149
230
|
```markdown
|
|
150
231
|
## Design Audit Summary
|
|
@@ -32,7 +32,14 @@ Run these checks, log results to user inline:
|
|
|
32
32
|
3. **Design source provided?**
|
|
33
33
|
- Required: Figma URL, image path, or prototype URL in `$ARGUMENTS`
|
|
34
34
|
- If missing → ask user: "Provide the design source (Figma URL, image path, or prototype URL)"
|
|
35
|
-
4. **
|
|
35
|
+
4. **Design system / component library?**
|
|
36
|
+
- Ask user: "Is a design system or component library being used (e.g., shadcn-vue, Vuetify, Radix, MUI, Ant Design)? If so, provide the URL."
|
|
37
|
+
- If yes → fetch the docs landing page, catalog available components (cards, tables, tabs, charts, buttons, etc.)
|
|
38
|
+
- Record in working memory: which design elements can be mapped to library primitives vs. built custom
|
|
39
|
+
- Factor into Step 2 classification: if the library provides a component (e.g., `Card`, `Table`, `Tabs`), the element contract should reference it as the implementation target
|
|
40
|
+
- Factor into Step 3 widget composition: library layout primitives (e.g., `Grid`, `Flex`, `Sheet`) inform widget structure
|
|
41
|
+
- If no → proceed as normal (all components built custom)
|
|
42
|
+
5. **Load the chart taxonomy (MANDATORY)**
|
|
36
43
|
- READ `templates/design-chart-taxonomy.md` from the GSD-T package (or `~/.claude/` if installed)
|
|
37
44
|
- This is the **CLOSED SET** of valid element names. You MUST pick from this list. Inventing new element names is FORBIDDEN without user approval to extend the taxonomy.
|
|
38
45
|
- Keep the taxonomy in working memory while classifying — every element you identify MUST be matched against it
|
|
@@ -748,19 +748,100 @@ Rules:
|
|
|
748
748
|
- NEVER write 'Appears to match' or 'Looks correct' — measure and verify
|
|
749
749
|
- If the table has fewer than 30 rows for a full-page comparison, you skipped elements
|
|
750
750
|
|
|
751
|
-
## Step 5:
|
|
751
|
+
## Step 5: SVG Structural Overlay Comparison (MANDATORY)
|
|
752
|
+
|
|
753
|
+
After the property-level comparison, run a mechanical SVG-based diff to catch
|
|
754
|
+
aggregate visual drift that individual property checks miss.
|
|
755
|
+
|
|
756
|
+
1. Export the Figma frame as SVG:
|
|
757
|
+
- Use the Figma REST API or MCP to export the page/frame as SVG
|
|
758
|
+
- If export is unavailable, ask the user to export and provide the SVG path
|
|
759
|
+
- Store the SVG at .gsd-t/design-verify/{page-name}-figma.svg
|
|
760
|
+
2. Parse the SVG DOM: extract every <rect>, <text>, <circle>, <path>, <g>
|
|
761
|
+
with their positions (x, y), dimensions (width, height), fills, strokes,
|
|
762
|
+
and text content
|
|
763
|
+
3. Screenshot the built page at the same viewport width via Playwright
|
|
764
|
+
4. Inspect the built page DOM: extract element bounding boxes, computed
|
|
765
|
+
styles (colors, dimensions), and text content
|
|
766
|
+
5. Map SVG elements → built DOM elements by:
|
|
767
|
+
- Text content matching (highest confidence)
|
|
768
|
+
- Position proximity (x,y within 10px tolerance)
|
|
769
|
+
- Dimensional similarity (width/height within 10% tolerance)
|
|
770
|
+
6. For each mapped pair, compare:
|
|
771
|
+
- Position: SVG (x,y) vs DOM bounding box (x,y). Within 2px = MATCH
|
|
772
|
+
- Dimensions: SVG (w,h) vs DOM (w,h). Within 2px = MATCH
|
|
773
|
+
- Colors: SVG fill/stroke vs computed CSS color. Exact hex = MATCH
|
|
774
|
+
- Text: SVG <text> content vs DOM textContent. Exact = MATCH
|
|
775
|
+
7. Produce an SVG structural diff table:
|
|
776
|
+
| # | SVG Element | SVG Position | Built Position | Δ px | Verdict |
|
|
777
|
+
Threshold: ≤2px = ✅ MATCH, 3-5px = ⚠ REVIEW, >5px = ❌ DEVIATION
|
|
778
|
+
8. Unmapped SVG elements (no DOM match) → flag as MISSING IN BUILD
|
|
779
|
+
Unmapped DOM elements (no SVG match) → flag as EXTRA IN BUILD
|
|
780
|
+
9. Generate a visual overlay image (optional but recommended):
|
|
781
|
+
- Render SVG in browser at target viewport size
|
|
782
|
+
- Overlay on built page screenshot with 50% opacity or difference blend
|
|
783
|
+
- Save to .gsd-t/design-verify/{page-name}-overlay.png
|
|
784
|
+
|
|
785
|
+
This step catches spacing rhythm, alignment drift, and proportion issues
|
|
786
|
+
that pass the property-level check but are visually wrong in aggregate.
|
|
787
|
+
|
|
788
|
+
## Step 5.5: DOM Box Model Inspection (MANDATORY for fixed-height containers)
|
|
789
|
+
|
|
790
|
+
The property table catches wrong values. The SVG overlay catches wrong positions.
|
|
791
|
+
This step catches wrong SPACE DISTRIBUTION — elements whose box model is inflated
|
|
792
|
+
by flex growth, pushing siblings out of position even when the visual appears close.
|
|
793
|
+
|
|
794
|
+
For each card/widget with a fixed height (container_height is not 'auto'):
|
|
795
|
+
|
|
796
|
+
1. Use Playwright to evaluate in the browser:
|
|
797
|
+
```javascript
|
|
798
|
+
// For each child element of the card body:
|
|
799
|
+
const children = await page.$$eval('.card-body > *', els =>
|
|
800
|
+
els.map(el => ({
|
|
801
|
+
selector: el.className,
|
|
802
|
+
offsetHeight: el.offsetHeight,
|
|
803
|
+
scrollHeight: el.scrollHeight,
|
|
804
|
+
computedFlex: getComputedStyle(el).flex,
|
|
805
|
+
computedFlexGrow: getComputedStyle(el).flexGrow,
|
|
806
|
+
}))
|
|
807
|
+
);
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
2. Flag any element where `offsetHeight > scrollHeight * 1.5`:
|
|
811
|
+
This means the element's layout box is ≥50% larger than its content.
|
|
812
|
+
Symptom: element is using `flex: 1` or `flex-grow: 1` and inflating.
|
|
813
|
+
❌ DEVIATION (severity HIGH): '{selector} offsetHeight={X}px but
|
|
814
|
+
content only needs {scrollHeight}px — inflated by flex growth.
|
|
815
|
+
Fix: remove flex:1 from this element, apply justify-content:center
|
|
816
|
+
on its parent container instead.'
|
|
817
|
+
|
|
818
|
+
3. Verify layout arithmetic:
|
|
819
|
+
- Read the widget contract's Internal Layout Arithmetic section
|
|
820
|
+
- Sum all child offsetHeights + computed gaps
|
|
821
|
+
- Compare against the card body's offsetHeight
|
|
822
|
+
- If sum > body height → ❌ DEVIATION: content overflows
|
|
823
|
+
- If sum < body height by >20px with no centering strategy → ❌ DEVIATION
|
|
824
|
+
|
|
825
|
+
4. Produce box model table:
|
|
826
|
+
| # | Element | offsetHeight | scrollHeight | flex-grow | Verdict |
|
|
827
|
+
|---|---------|-------------|-------------|-----------|---------|
|
|
828
|
+
| 1 | .kpi | 144px | 40px | 1 | ❌ INFLATED |
|
|
829
|
+
| 2 | .chart | 74px | 74px | 0 | ✅ MATCH |
|
|
830
|
+
|
|
831
|
+
## Step 6: Report Deviations
|
|
752
832
|
|
|
753
833
|
For each ❌ DEVIATION, write a specific finding:
|
|
754
834
|
'Design: {exact value}. Implementation: {exact value}. File: {path}:{line}'
|
|
755
835
|
|
|
756
|
-
Write the FULL comparison table
|
|
757
|
-
|
|
836
|
+
Write the FULL comparison table (property-level from Step 4 + SVG structural
|
|
837
|
+
from Step 5) to .gsd-t/contracts/design-contract.md under a
|
|
838
|
+
'## Verification Status' section.
|
|
758
839
|
|
|
759
840
|
Any ❌ DEVIATION → also append to .gsd-t/qa-issues.md with severity HIGH
|
|
760
841
|
and tag [VISUAL]:
|
|
761
842
|
| {date} | gsd-t-execute | Step 5.25 | opus | {duration} | HIGH | [VISUAL] {description} |
|
|
762
843
|
|
|
763
|
-
## Step
|
|
844
|
+
## Step 7: Verdict
|
|
764
845
|
|
|
765
846
|
Count results: '{MATCH_COUNT}/{TOTAL} elements match at {breakpoints} breakpoints'
|
|
766
847
|
|
package/commands/gsd-t-quick.md
CHANGED
|
@@ -277,9 +277,28 @@ cannot be redeemed by visual polish.
|
|
|
277
277
|
6. Produce structured comparison table:
|
|
278
278
|
| # | Section | Element | Design (specific) | Implementation (specific) | Verdict |
|
|
279
279
|
Only valid verdicts: ✅ MATCH or ❌ DEVIATION (never 'appears to match')
|
|
280
|
-
7.
|
|
281
|
-
|
|
282
|
-
|
|
280
|
+
7. SVG Structural Overlay Comparison:
|
|
281
|
+
a. Export Figma frame as SVG (or ask user for SVG path if export unavailable)
|
|
282
|
+
b. Parse SVG DOM: extract positions, dimensions, fills, text for every element
|
|
283
|
+
c. Screenshot built page at same viewport width via Playwright
|
|
284
|
+
d. Map SVG elements → built DOM elements by text content + position proximity
|
|
285
|
+
e. Compare: position (≤2px=MATCH, 3-5px=REVIEW, >5px=DEVIATION),
|
|
286
|
+
dimensions, colors (exact hex), text (exact match)
|
|
287
|
+
f. Produce SVG structural diff table:
|
|
288
|
+
| # | SVG Element | SVG Position | Built Position | Δ px | Verdict |
|
|
289
|
+
g. Flag unmapped SVG elements as MISSING, unmapped DOM elements as EXTRA
|
|
290
|
+
This catches aggregate visual drift that property-level checks miss.
|
|
291
|
+
8. DOM Box Model Inspection (for fixed-height containers):
|
|
292
|
+
a. For each card body child, evaluate: offsetHeight, scrollHeight, flex-grow
|
|
293
|
+
b. Flag elements where offsetHeight > scrollHeight * 1.5 as INFLATED
|
|
294
|
+
(element using flex:1 when it shouldn't — box larger than content)
|
|
295
|
+
c. Verify layout arithmetic: sum of child heights + gaps = body height
|
|
296
|
+
d. Produce box model table:
|
|
297
|
+
| Element | offsetHeight | scrollHeight | flex-grow | Verdict |
|
|
298
|
+
9. Write results (property table + SVG diff + box model) to .gsd-t/contracts/design-contract.md
|
|
299
|
+
under '## Verification Status'
|
|
300
|
+
9. Any ❌ → append to .gsd-t/qa-issues.md with [VISUAL] tag
|
|
301
|
+
10. Report: DESIGN VERIFIED | DESIGN DEVIATIONS FOUND ({count})"
|
|
283
302
|
```
|
|
284
303
|
|
|
285
304
|
After subagent returns — run observability Bash and append to token-log.md.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.70.11",
|
|
4
4
|
"description": "GSD-T: Contract-Driven Development for Claude Code — 54 slash commands with headless CI/CD mode, graph-powered code analysis, real-time agent dashboard, execution intelligence, task telemetry, doc-ripple enforcement, backlog management, impact analysis, test sync, milestone archival, and PRD generation",
|
|
5
5
|
"author": "Tekyz, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,43 @@ A widget that uses `chart-donut` cannot change `chart-donut`'s bar-gap, colors,
|
|
|
35
35
|
|
|
36
36
|
---
|
|
37
37
|
|
|
38
|
-
## 1. Design
|
|
38
|
+
## 1. Design System Detection
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
MANDATORY:
|
|
42
|
+
├── BEFORE any extraction or implementation, check for a design system:
|
|
43
|
+
│ Ask user: "Is a design system or component library being used
|
|
44
|
+
│ (e.g., shadcn-vue, Vuetify, Radix, MUI, Ant Design, Chakra)?
|
|
45
|
+
│ If so, provide the URL."
|
|
46
|
+
├── If YES:
|
|
47
|
+
│ Fetch the library's docs landing page
|
|
48
|
+
│ Catalog available components (cards, tables, tabs, charts, buttons,
|
|
49
|
+
│ inputs, dialogs, dropdowns, etc.)
|
|
50
|
+
│ Identify the theming system (CSS variables, Tailwind config, theme object)
|
|
51
|
+
│ Determine customization model:
|
|
52
|
+
│ Copy-paste (shadcn) → full control, edit component source directly
|
|
53
|
+
│ Config-based (MUI theme) → customize via theme overrides
|
|
54
|
+
│ Utility-first (Tailwind + headless) → style via utility classes
|
|
55
|
+
│ Map design elements to library primitives — use library components
|
|
56
|
+
│ instead of building custom whenever a match exists
|
|
57
|
+
│ Record in the design contract: library name, URL, version,
|
|
58
|
+
│ components used, theming approach
|
|
59
|
+
├── If NO:
|
|
60
|
+
│ Proceed with fully custom implementation
|
|
61
|
+
│ Note in design contract: "No design system — all components custom"
|
|
62
|
+
└── WHY: Design system components provide battle-tested accessibility,
|
|
63
|
+
interactive states, and responsive behavior out of the box.
|
|
64
|
+
Building custom when a library component exists wastes effort
|
|
65
|
+
and produces inferior results (missing focus states, ARIA, etc.)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**BAD** — Building a custom card component, dropdown, and table from scratch when shadcn-vue already provides them with full accessibility and Tailwind theming.
|
|
69
|
+
|
|
70
|
+
**GOOD** — Detecting shadcn-vue, mapping 60% of the design's UI elements to library components, customizing via Tailwind theme tokens, and only building custom for elements the library doesn't cover (specialized charts, domain-specific widgets).
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 2. Design Source Setup
|
|
39
75
|
|
|
40
76
|
```
|
|
41
77
|
MANDATORY:
|
|
@@ -62,7 +98,7 @@ MANDATORY:
|
|
|
62
98
|
|
|
63
99
|
---
|
|
64
100
|
|
|
65
|
-
##
|
|
101
|
+
## 3. MCP & Tool Detection
|
|
66
102
|
|
|
67
103
|
```
|
|
68
104
|
MANDATORY:
|
|
@@ -95,7 +131,7 @@ MANDATORY:
|
|
|
95
131
|
|
|
96
132
|
---
|
|
97
133
|
|
|
98
|
-
##
|
|
134
|
+
## 4. Stack Capability Evaluation
|
|
99
135
|
|
|
100
136
|
```
|
|
101
137
|
MANDATORY:
|
|
@@ -147,7 +183,7 @@ MANDATORY:
|
|
|
147
183
|
|
|
148
184
|
---
|
|
149
185
|
|
|
150
|
-
##
|
|
186
|
+
## 5. Design Token Extraction Protocol
|
|
151
187
|
|
|
152
188
|
```
|
|
153
189
|
MANDATORY:
|
|
@@ -172,7 +208,7 @@ MANDATORY:
|
|
|
172
208
|
|
|
173
209
|
---
|
|
174
210
|
|
|
175
|
-
##
|
|
211
|
+
## 6. Design Contract Generation
|
|
176
212
|
|
|
177
213
|
```
|
|
178
214
|
MANDATORY:
|
|
@@ -188,7 +224,7 @@ The design contract serves the same purpose as API contracts in GSD-T: it define
|
|
|
188
224
|
|
|
189
225
|
---
|
|
190
226
|
|
|
191
|
-
##
|
|
227
|
+
## 7. Component Decomposition
|
|
192
228
|
|
|
193
229
|
```
|
|
194
230
|
MANDATORY:
|
|
@@ -226,7 +262,7 @@ Page
|
|
|
226
262
|
|
|
227
263
|
---
|
|
228
264
|
|
|
229
|
-
##
|
|
265
|
+
## 8. Layout Analysis
|
|
230
266
|
|
|
231
267
|
```
|
|
232
268
|
MANDATORY:
|
|
@@ -245,9 +281,50 @@ MANDATORY:
|
|
|
245
281
|
|
|
246
282
|
**GOOD** — Extracting gap as exactly `24px` from the design, then: `display: flex; gap: 1.5rem; /* 24px — design contract: section-gap */`
|
|
247
283
|
|
|
284
|
+
### Flex Centering Anti-Pattern (MANDATORY)
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
NEVER use flex: 1 on a content element to center its text/content.
|
|
288
|
+
flex: 1 makes the ELEMENT GROW to fill available space — the content
|
|
289
|
+
centers within an oversized box, but the box itself displaces siblings.
|
|
290
|
+
|
|
291
|
+
WRONG — content element grows, inflated box shifts layout:
|
|
292
|
+
.kpi { flex: 1; display: flex; justify-content: center; }
|
|
293
|
+
|
|
294
|
+
RIGHT — parent grows, children keep natural size:
|
|
295
|
+
.body { flex: 1; display: flex; flex-direction: column;
|
|
296
|
+
justify-content: center; }
|
|
297
|
+
.kpi { /* no flex: 1 — natural height only */ }
|
|
298
|
+
|
|
299
|
+
RULE: flex: 1 belongs on CONTAINERS, not on CONTENT elements.
|
|
300
|
+
To center content vertically, apply justify-content: center
|
|
301
|
+
on the parent — never flex: 1 on the child.
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Fixed-Height Container Arithmetic (MANDATORY)
|
|
305
|
+
|
|
306
|
+
```
|
|
307
|
+
When a card or container has a fixed height, BEFORE writing any CSS:
|
|
308
|
+
1. Compute the total available body height:
|
|
309
|
+
body_available = card_height - padding_top - padding_bottom
|
|
310
|
+
- header_height - header_to_body_gap
|
|
311
|
+
2. List every child element's height (from the design contract)
|
|
312
|
+
3. List every gap between children
|
|
313
|
+
4. SUM them: total_content = child1 + gap1 + child2 + gap2 + ...
|
|
314
|
+
5. Compare: total_content MUST ≤ body_available
|
|
315
|
+
6. If total_content < body_available:
|
|
316
|
+
Document the centering strategy (justify-content: center on parent)
|
|
317
|
+
7. If total_content > body_available:
|
|
318
|
+
The design extraction is wrong — go back to Figma
|
|
319
|
+
|
|
320
|
+
This arithmetic goes in the widget contract's Internal Layout
|
|
321
|
+
Arithmetic section. The implementation MUST match the arithmetic.
|
|
322
|
+
If gap: 12px makes the math exceed body_available, use gap: 8px.
|
|
323
|
+
```
|
|
324
|
+
|
|
248
325
|
---
|
|
249
326
|
|
|
250
|
-
##
|
|
327
|
+
## 9. Responsive Breakpoint Strategy
|
|
251
328
|
|
|
252
329
|
```
|
|
253
330
|
MANDATORY:
|
|
@@ -280,7 +357,7 @@ MANDATORY:
|
|
|
280
357
|
|
|
281
358
|
---
|
|
282
359
|
|
|
283
|
-
##
|
|
360
|
+
## 10. Semantic HTML Structure
|
|
284
361
|
|
|
285
362
|
```
|
|
286
363
|
MANDATORY:
|
|
@@ -300,7 +377,7 @@ MANDATORY:
|
|
|
300
377
|
|
|
301
378
|
---
|
|
302
379
|
|
|
303
|
-
##
|
|
380
|
+
## 11. Naming Conventions (Classes, IDs, Data Attributes)
|
|
304
381
|
|
|
305
382
|
```
|
|
306
383
|
MANDATORY:
|
|
@@ -339,7 +416,7 @@ MANDATORY:
|
|
|
339
416
|
|
|
340
417
|
---
|
|
341
418
|
|
|
342
|
-
##
|
|
419
|
+
## 12. CSS Precision Rules
|
|
343
420
|
|
|
344
421
|
```
|
|
345
422
|
MANDATORY:
|
|
@@ -370,7 +447,7 @@ MANDATORY:
|
|
|
370
447
|
|
|
371
448
|
---
|
|
372
449
|
|
|
373
|
-
##
|
|
450
|
+
## 13. Typography Rendering
|
|
374
451
|
|
|
375
452
|
```
|
|
376
453
|
MANDATORY:
|
|
@@ -403,7 +480,7 @@ MANDATORY:
|
|
|
403
480
|
|
|
404
481
|
---
|
|
405
482
|
|
|
406
|
-
##
|
|
483
|
+
## 14. Color Accuracy
|
|
407
484
|
|
|
408
485
|
```
|
|
409
486
|
MANDATORY:
|
|
@@ -437,7 +514,7 @@ MANDATORY:
|
|
|
437
514
|
|
|
438
515
|
---
|
|
439
516
|
|
|
440
|
-
##
|
|
517
|
+
## 15. Interactive States
|
|
441
518
|
|
|
442
519
|
```
|
|
443
520
|
MANDATORY:
|
|
@@ -474,7 +551,7 @@ MANDATORY:
|
|
|
474
551
|
|
|
475
552
|
---
|
|
476
553
|
|
|
477
|
-
##
|
|
554
|
+
## 16. Visual Verification — Against FIGMA, Not Just Contracts
|
|
478
555
|
|
|
479
556
|
**Visual verification is handled by a dedicated Design Verification Agent**, spawned automatically by `gsd-t-execute` (Step 5.25) after all domain tasks complete.
|
|
480
557
|
|
|
@@ -488,20 +565,26 @@ VERIFICATION TARGETS:
|
|
|
488
565
|
│ Does the code match the contract's claimed values?
|
|
489
566
|
│ (This is what the 13-task validation proved works — airtight.)
|
|
490
567
|
│
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
568
|
+
├── TARGET 2: Built screen vs FIGMA DESIGN (MANDATORY)
|
|
569
|
+
│ Does the BUILT SCREEN match the ORIGINAL FIGMA STRUCTURED DATA?
|
|
570
|
+
│ This catches: contracts that were wrong to begin with,
|
|
571
|
+
│ chart type misclassification, hallucinated data, missing elements.
|
|
572
|
+
│
|
|
573
|
+
└── TARGET 3: SVG STRUCTURAL OVERLAY (MANDATORY)
|
|
574
|
+
Export Figma frame as SVG → parse element positions/dimensions/colors
|
|
575
|
+
→ compare geometrically against built DOM bounding boxes.
|
|
576
|
+
This catches: aggregate spacing drift, alignment issues, proportion
|
|
577
|
+
errors that pass property-level checks but look wrong visually.
|
|
578
|
+
Mechanical, non-interpretive — no agent reasoning, just geometry.
|
|
496
579
|
```
|
|
497
580
|
|
|
498
|
-
**
|
|
581
|
+
**Targets 2 and 3 are complementary.** Target 2 catches wrong values (property-level). Target 3 catches wrong placement (geometry-level). Together they cover both "is each value correct?" and "does the whole page look right?"
|
|
499
582
|
|
|
500
583
|
### Verification agent workflow
|
|
501
584
|
|
|
502
585
|
```
|
|
503
586
|
SEPARATION OF CONCERNS:
|
|
504
|
-
├── CODING AGENT (you — Sections 1-
|
|
587
|
+
├── CODING AGENT (you — Sections 1-15 above):
|
|
505
588
|
│ Extract tokens → write precise CSS → trace every value to design contract
|
|
506
589
|
│ Do NOT open a browser or attempt visual comparison yourself
|
|
507
590
|
│
|
|
@@ -524,7 +607,16 @@ SEPARATION OF CONCERNS:
|
|
|
524
607
|
`get_design_context` response?
|
|
525
608
|
6. Produce structured comparison table (30+ rows):
|
|
526
609
|
| Element | Figma (get_design_context) | Built | MATCH/DEVIATION |
|
|
527
|
-
7.
|
|
610
|
+
7. SVG STRUCTURAL OVERLAY — mechanical geometry comparison:
|
|
611
|
+
a. Export Figma frame as SVG (API/MCP or user-provided)
|
|
612
|
+
b. Parse SVG DOM: positions, dimensions, fills, text per element
|
|
613
|
+
c. Map SVG elements → built DOM elements by text + position proximity
|
|
614
|
+
d. Compare geometry: position (≤2px=MATCH), dimensions, colors, text
|
|
615
|
+
e. Produce SVG diff table:
|
|
616
|
+
| SVG Element | SVG Position | Built Position | Δ px | Verdict |
|
|
617
|
+
f. Flag unmapped elements (MISSING IN BUILD / EXTRA IN BUILD)
|
|
618
|
+
This catches aggregate spacing/alignment drift the property table misses.
|
|
619
|
+
8. Fix deviations → re-verify → artifact gate enforces completion
|
|
528
620
|
```
|
|
529
621
|
|
|
530
622
|
The verification agent enforces the **FAIL-BY-DEFAULT** rule: every visual element starts as UNVERIFIED. The only valid verdicts are MATCH (with proof) or DEVIATION (with specifics). "Looks close" and "appears to match" are not verdicts. An artifact gate in the orchestrator blocks completion if the comparison table is missing or empty.
|
|
@@ -533,7 +625,7 @@ The verification agent enforces the **FAIL-BY-DEFAULT** rule: every visual eleme
|
|
|
533
625
|
|
|
534
626
|
---
|
|
535
627
|
|
|
536
|
-
##
|
|
628
|
+
## 17. Anti-Patterns
|
|
537
629
|
|
|
538
630
|
```
|
|
539
631
|
NEVER DO THESE:
|
|
@@ -553,10 +645,12 @@ NEVER DO THESE:
|
|
|
553
645
|
|
|
554
646
|
---
|
|
555
647
|
|
|
556
|
-
##
|
|
648
|
+
## 18. Design-to-Code Verification Checklist
|
|
557
649
|
|
|
558
650
|
Before marking any design implementation task as complete:
|
|
559
651
|
|
|
652
|
+
- [ ] Design system / component library identified (or confirmed none) and documented in design contract
|
|
653
|
+
- [ ] Library components mapped to design elements — custom build only where no library match exists
|
|
560
654
|
- [ ] Design source identified and documented in design contract
|
|
561
655
|
- [ ] Stack capability evaluated — all design requirements achievable (or alternatives approved)
|
|
562
656
|
- [ ] All design tokens extracted (colors, typography, spacing, borders, shadows)
|
|
@@ -574,4 +668,8 @@ Before marking any design implementation task as complete:
|
|
|
574
668
|
- [ ] Spacing exact: every padding, margin, gap matches design values
|
|
575
669
|
- [ ] Accessibility: focus indicators, alt text, ARIA where needed, 44px touch targets
|
|
576
670
|
- [ ] No magic numbers — every value is documented or uses a design token
|
|
671
|
+
- [ ] SVG structural overlay comparison completed — geometry diff ≤2px per element
|
|
672
|
+
- [ ] DOM box model inspection passed — no inflated elements (offsetHeight >> scrollHeight)
|
|
673
|
+
- [ ] Layout arithmetic verified — child heights + gaps = body available height (fixed-height cards)
|
|
674
|
+
- [ ] No content element uses `flex: 1` for centering — only parent containers
|
|
577
675
|
- [ ] Verification results logged in design contract Verification Status table
|
|
@@ -95,6 +95,41 @@ This section specifies how elements are sized, spaced, and aligned WITHIN the ca
|
|
|
95
95
|
- `body_layout` + `body_justify` + `body_align` together define whether the chart is centered in its card, left-aligned, or stretched. Get this wrong and every widget "looks off."
|
|
96
96
|
- These values are WIDGET-OWNED — they describe how the widget positions its elements, not the elements' internal specs (which live in element contracts).
|
|
97
97
|
|
|
98
|
+
### Internal Layout Arithmetic (MANDATORY for fixed-height cards)
|
|
99
|
+
|
|
100
|
+
When `container_height` is fixed (not `auto`), you MUST compute and document the internal height budget. The math must add up exactly — no approximation.
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
card_height: {e.g., 334px}
|
|
104
|
+
card_padding_top: {e.g., 16px}
|
|
105
|
+
card_padding_bottom: {e.g., 16px}
|
|
106
|
+
header_height: {title + subtitle + gap} = {e.g., 48px}
|
|
107
|
+
header_to_body_gap: {e.g., 16px}
|
|
108
|
+
─────────────────────────────────────────────────
|
|
109
|
+
body_available: {card_height - padding_top - padding_bottom
|
|
110
|
+
- header_height - header_to_body_gap}
|
|
111
|
+
= {e.g., 334 - 16 - 16 - 48 - 16 = 238px}
|
|
112
|
+
|
|
113
|
+
body_breakdown:
|
|
114
|
+
kpi_height: {natural content height, e.g., 40px — NOT flex:1}
|
|
115
|
+
kpi_to_chart_gap: {e.g., 16px}
|
|
116
|
+
chart_section: {bar + gap + labels + gap + legend}
|
|
117
|
+
= {e.g., 30 + 8 + 12 + 8 + 16 = 74px}
|
|
118
|
+
────────────────────
|
|
119
|
+
total_body_content: {40 + 16 + 74 = 130px}
|
|
120
|
+
remaining_space: {238 - 130 = 108px}
|
|
121
|
+
|
|
122
|
+
centering_strategy: {e.g., body uses flex-column + justify-content: center
|
|
123
|
+
to vertically center the content group (KPI + chart)
|
|
124
|
+
in the 238px body area. KPI keeps natural height.}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Rules:**
|
|
128
|
+
- Every row must be an exact pixel value extracted from the Figma design
|
|
129
|
+
- The sum of all body content MUST equal `body_available` OR explicitly document how remaining space is distributed (centering, padding, etc.)
|
|
130
|
+
- **NEVER use `flex: 1` on a content element (KPI, label, text) to center it.** `flex: 1` makes the element grow to fill available space, inflating its box model. Use `flex: 1` + `justify-content: center` on the PARENT container instead. The parent grows; children keep natural size.
|
|
131
|
+
- If the math doesn't add up, the design extraction is incomplete — go back to Figma
|
|
132
|
+
|
|
98
133
|
## Data Binding
|
|
99
134
|
|
|
100
135
|
**Widget input shape:**
|
|
@@ -189,6 +224,9 @@ Widget-level verification runs AFTER all referenced elements pass their own veri
|
|
|
189
224
|
- [ ] Element sizing matches design (chart_width, chart_height, legend_width)
|
|
190
225
|
- [ ] Legend alignment matches design (footer_legend_justify: center vs left)
|
|
191
226
|
- [ ] Card container values match design (padding, border, radius, shadow)
|
|
227
|
+
- [ ] Layout arithmetic adds up: sum of child heights + gaps = body_available (fixed-height cards only)
|
|
228
|
+
- [ ] No content element uses `flex: 1` for centering — only parent containers may use `flex: 1`
|
|
229
|
+
- [ ] DOM box model check: no element's offsetHeight >> its content height (inflated box = wrong flex)
|
|
192
230
|
- [ ] Responsive breakpoints adapt as specified
|
|
193
231
|
- [ ] Data binding produces correct element inputs (spot-check with sample data)
|
|
194
232
|
- [ ] Inter-element interactions fire (hover sync, click propagation)
|