@explorer02/cfm-survey-sdk 0.2.6 → 0.2.8

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 (27) hide show
  1. package/dist/cli/index.js +25 -25
  2. package/dist/cli/index.mjs +24 -24
  3. package/package.json +1 -1
  4. package/templates/docs/00-integration/agent-execution-flow.md +8 -5
  5. package/templates/docs/00-integration/agent-operating-contract.md +2 -0
  6. package/templates/docs/00-integration/apply-ui-config.md +15 -2
  7. package/templates/docs/00-integration/wizard-chrome-contract.md +84 -11
  8. package/templates/docs/00-integration/wizard-config-handoff.md +6 -2
  9. package/templates/docs/00-integration/wizard-post-customize-build.md +405 -0
  10. package/templates/docs/00-integration/wizard-question-type-styling.md +25 -4
  11. package/templates/docs/MANIFEST.json +3 -1
  12. package/templates/docs/index.md +4 -3
  13. package/templates/docs/templates/Header.tsx +61 -35
  14. package/templates/docs/templates/Question.tsx +1 -0
  15. package/templates/docs/templates/RatingScale.tsx +66 -59
  16. package/templates/docs/templates/uiConfig.ts +33 -0
  17. package/templates/docs/templates/verify-agent-build.sh +6 -0
  18. package/templates/preview-harness/preview-bridge.inline.js +17 -3
  19. package/templates/preview-harness/vite-app/src/preview-live-overrides.css +7 -0
  20. package/templates/previewBridge.ts +16 -4
  21. package/templates/survey-theme.css +7 -0
  22. package/templates/wizard-dist/assets/{PreviewMock-7peNZK-z.js → PreviewMock-tTMvwuEy.js} +1 -1
  23. package/templates/wizard-dist/assets/{TypePanel-BxHnE3cm.js → TypePanel-B9Ls7BSq.js} +1 -1
  24. package/templates/wizard-dist/assets/index-CjkIlOUI.css +1 -0
  25. package/templates/wizard-dist/assets/{index-DtZhNwPS.js → index-CoCrnnxt.js} +6 -6
  26. package/templates/wizard-dist/index.html +2 -2
  27. package/templates/wizard-dist/assets/index-BhWM50Yu.css +0 -1
@@ -1,6 +1,7 @@
1
1
  # Wizard Config Handoff — Wait, Capture, Apply
2
2
 
3
3
  > **Phase 6b → 6c.** Read with [`ui-customization-wizard.md`](ui-customization-wizard.md) and [`apply-ui-config.md`](apply-ui-config.md).
4
+ > **Phase 6c runbook (all formats + build):** [`wizard-post-customize-build.md`](wizard-post-customize-build.md).
4
5
  > Pipeline: [`agent-execution-flow.md`](agent-execution-flow.md).
5
6
 
6
7
  This doc tells the agent **exactly** how to wait for the client to finish the wizard, capture the JSON output, and apply **every** change without omission.
@@ -53,7 +54,9 @@ When the client uploads a logo in the local wizard:
53
54
 
54
55
  The logo is **not** fetched from wizard memory on CloudFront — only from the deploy bundle. See [`aws-deploy.md`](aws-deploy.md) § Logos & local assets.
55
56
 
56
- **Local quit (preview GC):** If the client exits without saving, wizard calls `POST /api/wizard-quit` → CLI deletes `out/previews/` on agent disk. Ctrl+C on customize CLI runs the same cleanup.
57
+ **Local quit (preview GC):** If the client exits without saving, wizard calls `POST /api/wizard-quit` → CLI deletes `out/previews/`.
58
+
59
+ **After save:** `POST /api/save-config` also deletes `out/previews/` before CLI exits (preview garbage collection).
57
60
 
58
61
  ---
59
62
 
@@ -141,7 +144,7 @@ For **every** section in the diff (`Changed`, `Added`, `Removed`):
141
144
 
142
145
  ### Step 4 — Apply to codebase (Phase 6c)
143
146
 
144
- Follow [`apply-ui-config.md`](apply-ui-config.md) using **`survey-ui-config.final.json`** as input.
147
+ Follow [`wizard-post-customize-build.md`](wizard-post-customize-build.md) (ordered checklist + format matrix), then [`apply-ui-config.md`](apply-ui-config.md) path tables using **`survey-ui-config.final.json`** (EC2) or **`survey-ui-config.json`** (local) as input.
145
148
 
146
149
  Order:
147
150
 
@@ -288,6 +291,7 @@ npx cfm-sdk fetch-ui-config
288
291
 
289
292
  | Doc | Role |
290
293
  |-----|------|
294
+ | [`wizard-post-customize-build.md`](wizard-post-customize-build.md) | Phase 6c runbook — all question formats + verify/build |
291
295
  | [`apply-ui-config.md`](apply-ui-config.md) | Complete config path → file mapping |
292
296
  | [`wizard-api.md`](wizard-api.md) | Poll endpoint, complete payload |
293
297
  | [`wizard-question-type-styling.md`](wizard-question-type-styling.md) | Per-type CSS vars |
@@ -0,0 +1,405 @@
1
+ # Wizard Post-Customize Build — All Types, All Formats
2
+
3
+ > **Phase 6c runbook.** Read after the client clicks **Review & Build** and the CLI prints `✅ UI configuration saved`.
4
+ > Companion docs: [`wizard-config-handoff.md`](wizard-config-handoff.md) · [`apply-ui-config.md`](apply-ui-config.md) · [`wizard-question-type-styling.md`](wizard-question-type-styling.md) · [`wizard-chrome-contract.md`](wizard-chrome-contract.md)
5
+
6
+ This doc answers two agent questions:
7
+
8
+ 1. **What does the wizard expose** for every question type and format — and which component must honor it?
9
+ 2. **What is the exact build sequence** after the client confirms customization — without re-running the wizard or skipping tokens?
10
+
11
+ ---
12
+
13
+ ## End-to-end flow (confirmation → deploy)
14
+
15
+ ```mermaid
16
+ sequenceDiagram
17
+ participant Client
18
+ participant Wizard as Wizard SPA
19
+ participant CLI as cfm-sdk customize
20
+ participant Agent
21
+ participant Build as npm run build
22
+ participant Deploy as Phase 7
23
+
24
+ Client->>Wizard: Review and Build
25
+ Wizard->>CLI: POST /api/save-config
26
+ CLI->>CLI: Write survey-ui-config.json
27
+ CLI->>CLI: Delete out/previews/ (GC)
28
+ CLI->>Agent: Exit 0 — UI configuration saved
29
+ Agent->>Agent: Phase 6c apply (this doc)
30
+ Agent->>Build: verify-agent-build.sh
31
+ Build->>Agent: out/ + logo in out/
32
+ Agent->>Deploy: After INPUT 4 confirm
33
+ ```
34
+
35
+ **Agent must not** start Phase 6c until CLI exit 0. **Agent must not** proceed to Phase 7 until verify + build pass after apply.
36
+
37
+ ---
38
+
39
+ ## Phase 6c — ordered runbook (copy-paste checklist)
40
+
41
+ Run from project root after `✅ UI configuration saved`.
42
+
43
+ ### A. Capture
44
+
45
+ ```bash
46
+ # Local wizard (default)
47
+ test -f survey-ui-config.json && echo "OK: config captured"
48
+
49
+ # EC2 review mode only — also read diff before editing code
50
+ test -f survey-ui-config.final.json && cat survey-ui-config.diff.md
51
+ ```
52
+
53
+ ### B. Validate
54
+
55
+ - [ ] JSON parses; validate against `templates/survey-ui-config.schema.json`
56
+ - [ ] `surveyTypes[]` still matches fetched survey inventory (types in survey, not wizard tabs)
57
+ - [ ] EC2: every path in `survey-ui-config.diff.json` (`changed` + `added` + `removed`) has a planned apply target
58
+
59
+ ### C. Regenerate theme (full — never partial)
60
+
61
+ - [ ] Regenerate **entire** `src/styles/survey-theme.css` from final config (all `global.*` + all `questionTypes.*`)
62
+ - [ ] Confirm `@import` in `globals.css` (or equivalent)
63
+ - [ ] Theme → Question card tokens present: `--cfm-matrix-selected`, `--cfm-input-focus-ring`
64
+
65
+ ### D. Chrome + content hooks
66
+
67
+ Copy/sync if missing — see [`wizard-chrome-contract.md`](wizard-chrome-contract.md).
68
+
69
+ | Area | Config paths | Wire in |
70
+ |------|--------------|---------|
71
+ | Logo | `global.logo.fileName` | `Header.tsx` via `uiConfig.getLogoSrc()` → `src="./{fileName}"` |
72
+ | Company | `global.companyName`, `global.header.showCompanyName` | `data-cfm-company` in brand row after logo |
73
+ | Title / thank you | `global.surveyTitle`, `global.thankYouMessage` | `data-cfm-survey-title`, `data-cfm-thank-you` |
74
+ | Buttons | `global.buttons.*` | `data-cfm-btn-next`, `data-cfm-btn-back` |
75
+ | Footer | `global.footer.*` | `cfm-footer`, `data-cfm-copyright`, `data-cfm-footer-links` |
76
+ | Layout | `global.layout.*` | `SurveyPage` / `SurveyStickyChrome` conditionals |
77
+ | Progress | `global.theme.progress*` | `data-cfm-progress` + `.cfm-progress` (separate from header) |
78
+
79
+ **Logo rule:** never hand-edit `fileName` to a seed SVG. Use wizard value; file must exist in `public/{fileName}`.
80
+
81
+ ```bash
82
+ LOGO=$(python3 -c "import json; print(json.load(open('survey-ui-config.json')).get('global',{}).get('logo',{}).get('fileName') or '')")
83
+ test -z "$LOGO" || test -f "public/$LOGO" || echo "FAIL: logo file missing in public/"
84
+ ```
85
+
86
+ ### E. Per-type tokens (all wizard types — not only survey inventory)
87
+
88
+ The wizard **Question Types** step exposes **10 type families** (TEXT_AND_MEDIA uses theme vars only). Apply `questionTypes.{TYPE}` for **every** type block in saved JSON — even if the client's survey does not include that type. This keeps `survey-theme.css` complete and future-proof.
89
+
90
+ Use the format matrix below. Detailed token tables: [`wizard-question-type-styling.md`](wizard-question-type-styling.md) and [`apply-ui-config.md`](apply-ui-config.md).
91
+
92
+ ### F. Hook options
93
+
94
+ - [ ] `placeholders.*` → `useSurveySDK({ options: { placeholders } })` (stable ref)
95
+ - [ ] `customFields` → `customFieldValues.ts` + SurveyPage + Question prop
96
+ - [ ] `debug.enabled` → hook `debug: true`
97
+
98
+ ### G. EC2 promote (review mode only)
99
+
100
+ ```bash
101
+ npx cfm-sdk confirm-ui-config # downloads logo → public/
102
+ ```
103
+
104
+ ### H. Verify + build (blocking)
105
+
106
+ ```bash
107
+ bash templates/verify-agent-build.sh
108
+ ```
109
+
110
+ Script runs `npm run build`. Additionally confirm logo in static output:
111
+
112
+ ```bash
113
+ test -z "$LOGO" || test -f "out/$LOGO" || echo "FAIL: logo not in out/"
114
+ ```
115
+
116
+ ### I. Phase 7 gate
117
+
118
+ Only after H passes → ask deploy (INPUT 4). See [`aws-deploy.md`](aws-deploy.md) § Logos.
119
+
120
+ **Do not re-run** `npx cfm-sdk customize` unless the client explicitly requests another session.
121
+
122
+ **Do not re-run** `npx cfm-sdk export-previews` after wizard save — previews were deleted on purpose (GC). Export-previews is for **component structure changes** during Phase 5, not for applying saved config.
123
+
124
+ ---
125
+
126
+ ## Wizard steps → live preview keys
127
+
128
+ | Wizard step | Default preview | What updates live |
129
+ |-------------|-----------------|-------------------|
130
+ | **Branding & Header** | `header` | Logo upload, company name, header dimensions/colors |
131
+ | **Footer** | `footer` | Copyright, links, footer logo, colors |
132
+ | **Theme & Colors** | `survey_page` | Palette, header/footer/progress/language colors, **Question card** (cell selected + focus ring) |
133
+ | **Layout & Chrome** | `survey_page` | showHeader/Footer/Progress, nav buttons, question numbers, asterisk, width, font |
134
+ | **Question Types** | per format tab | Per-type panels (see matrix below) |
135
+ | **Testing & Tokens** | `survey_page` | Placeholders, custom fields, debug |
136
+ | **Deploy & Build** | `survey_page` | Deploy target metadata (informational) |
137
+
138
+ Chrome previews also exist: `intro`, `end`, `chrome` — used by harness; agent wires same hooks on Intro/End/SurveyPage.
139
+
140
+ ---
141
+
142
+ ## Question type format matrix (wizard → config → component)
143
+
144
+ ### How to read this table
145
+
146
+ | Column | Meaning |
147
+ |--------|---------|
148
+ | **Preview key** | Iframe loaded in wizard right panel |
149
+ | **Survey `question.type`** | Flat literal in `Question.tsx` dispatch |
150
+ | **Wizard controls** | Fields in Question Types step for that tab |
151
+ | **Config block** | `survey-ui-config.json` path (shared across formats of same type) |
152
+ | **Scale / branch** | Component that must use `var(--cfm-*)` + `selectionStyles` / `labelStyles` |
153
+ | **DOM attrs** | `data-cfm-*` set on `:root` or elements |
154
+
155
+ **Shared across almost all scale types:** Theme → Question card → `cellSelectedColor` → `--cfm-matrix-selected`; `focusRingColor` → `--cfm-input-focus-ring`. Use [`selectionStyles.ts`](../templates/selectionStyles.ts).
156
+
157
+ **Matrix multi-row:** Toggle **Preview multiple statements** on CFM, CSAT, Rating, Slider types. `LikertMatrixScale` / `CsatMatrixScale` must map **all** `statementRows` — not a single hardcoded row.
158
+
159
+ ---
160
+
161
+ ### MCQ — `questionTypes.MCQ`
162
+
163
+ | Preview key | Format | Wizard controls | Scale / branch |
164
+ |-------------|--------|-----------------|----------------|
165
+ | `MCQ_single` | Single select | Option style, gap, radius, padding | `Question.tsx` MCQ branch + radio ring/dot |
166
+ | `MCQ_multiple` | Multi select | Same | Checkbox: ring border + fill from theme |
167
+
168
+ | Config field | CSS / DOM |
169
+ |--------------|-----------|
170
+ | `optionStyle` | `data-cfm-mcq-style` on `:root` |
171
+ | `optionGap` | `--cfm-mcq-option-gap` |
172
+ | `borderRadius` | `--cfm-mcq-border-radius` |
173
+ | `optionPadding` | `--cfm-mcq-card-padding` |
174
+ | Selection | `--cfm-input-focus-ring`, `--cfm-matrix-selected`, `--cfm-mcq-selected-bg` |
175
+
176
+ ---
177
+
178
+ ### TEXTFIELD — `questionTypes.TEXTFIELD`
179
+
180
+ | Preview key | Format | Wizard controls | Scale / branch |
181
+ |-------------|--------|-----------------|----------------|
182
+ | `TEXTFIELD_short` | Short | Placeholder text, radius, border, placeholder color | `Question.tsx` + `data-cfm-textfield` |
183
+ | `TEXTFIELD_long` | Long | Same | `textarea` with same hooks |
184
+
185
+ | Config field | CSS / DOM |
186
+ |--------------|-----------|
187
+ | `inputRadius` | `--cfm-input-radius` |
188
+ | `borderColor` | `--cfm-input-border` |
189
+ | `placeholderColor` | `--cfm-input-placeholder` + `::placeholder` rule in theme CSS |
190
+ | `defaultPlaceholder` | Default placeholder string (cosmetic) |
191
+ | Focus | `--cfm-input-focus-ring` |
192
+
193
+ ---
194
+
195
+ ### NPS_SCALE — `questionTypes.NPS_SCALE`
196
+
197
+ | Preview key | Format | Wizard controls | Scale / branch |
198
+ |-------------|--------|-----------------|----------------|
199
+ | `NPS_SCALE` | Radio / numbered / pill | Button style, track colors, hint labels, number labels | `RatingScale.tsx` |
200
+
201
+ | Config field | CSS / DOM |
202
+ |--------------|-----------|
203
+ | `buttonStyle` | `data-cfm-nps-button-style` |
204
+ | `selectedFill`, `trackBarColor`, `trackHighlightColor` | `--cfm-nps-*` |
205
+ | `hintMinText`, `hintMaxText`, hint colors | `hintLabelStyle()` |
206
+ | `numberLabelMode`, per-index colors | `--cfm-number-*`, `resolveNumberLabelColor()` for **unselected** badges |
207
+ | Selection | `scaleRadioRingStyle`, `scaleRadioDotStyle` |
208
+
209
+ ---
210
+
211
+ ### CFM_MATRIX — `questionTypes.CFM_MATRIX`
212
+
213
+ Wizard tabs: **Likert**, **Bipolar**. Harness also ships `CFM_transpose`, `CFM_carousel`, `CFM_dropdown` — same config block.
214
+
215
+ | Preview key | Matrix variant | Wizard controls | Scale / branch |
216
+ |-------------|----------------|-----------------|----------------|
217
+ | `CFM_likert` | Likert grid | Row width, bipolar %, label items | `LikertMatrixScale.tsx` |
218
+ | `CFM_bipolar` | Bipolar anchors | Same + bipolar column width | Same |
219
+ | `CFM_transpose` | Transposed | *(no extra wizard fields)* | `LikertMatrixScale` / matrix utils |
220
+ | `CFM_carousel` | Carousel | Label items + theme selection | Matrix carousel branch |
221
+ | `CFM_dropdown` | Dropdown | Label items | `MatrixDropdown.tsx` |
222
+
223
+ | Config field | CSS / DOM |
224
+ |--------------|-----------|
225
+ | `rowLabelWidth` | `--cfm-matrix-row-width` |
226
+ | `bipolarColumnWidthPercent` | `--cfm-matrix-bipolar-width` |
227
+ | `columnLabelColor`, `columnLabelBgColor` | `matrixColumnLabelStyle()` |
228
+ | Selection | `matrixRadioRingStyle`, `matrixRadioDotStyle` |
229
+
230
+ **No** per-format accent overrides in wizard — Question card tokens only.
231
+
232
+ ---
233
+
234
+ ### CSAT_MATRIX — `questionTypes.CSAT_MATRIX`
235
+
236
+ | Preview key | Format | Wizard controls | Scale / branch |
237
+ |-------------|--------|-----------------|----------------|
238
+ | `CSAT_emoji` | Emoji | Emoji size, unselected opacity, label items | `CsatMatrixScale.tsx` emoji cells |
239
+ | `CSAT_star` | Star | Unselected opacity, label items | Star row; selected = `cellSelectedVar` |
240
+ | `CSAT_numbered` | Numbered | Opacity, label items, number labels | Number badges + selection pattern |
241
+ | `CSAT_graphics` | Graphics slider | Label items | `CustomSliderTrack.tsx` thumb pattern |
242
+ | `CSAT_carousel` | Carousel | Label items | Dot indicators = cell selected when active |
243
+ | `CSAT_dropdown` | Dropdown | Label items | `MatrixDropdown` + list radio |
244
+
245
+ | Config field | CSS / DOM |
246
+ |--------------|-----------|
247
+ | `emojiSize` | `--cfm-csat-emoji-size` |
248
+ | `unselectedOpacity` | `--cfm-csat-unselected-opacity` |
249
+ | `columnLabelColor`, `columnLabelBgColor` | `csatColumnLabelStyle()` |
250
+ | Number labels (numbered tab) | `--cfm-number-*` |
251
+ | Selection | theme Question card vars |
252
+
253
+ ---
254
+
255
+ ### RATING_MATRIX — `questionTypes.RATING_MATRIX`
256
+
257
+ | Preview key | Format | Wizard controls | Scale / branch |
258
+ |-------------|--------|-----------------|----------------|
259
+ | `RATING_star` | Star | Unselected star opacity, label items | `CsatMatrixScale.tsx` (shared path) |
260
+ | `RATING_numbered` | Numbered | Opacity, label items, number labels | Numbered badges |
261
+ | `RATING_radio` | Radio grid | Opacity, label items | Horizontal radio grid — `matrixRadioRingStyle` |
262
+ | `RATING_emoji` | Emoji | Emoji size, opacity, label items | Emoji cells |
263
+ | `RATING_graphics` | Graphics | Opacity, label items | `CustomSliderTrack` |
264
+ | `RATING_slider` | Slider | Label items | Slider thumb pattern |
265
+
266
+ Config block mirrors CSAT where formats overlap; uses `unselectedStarOpacity` instead of `unselectedOpacity` in JSON.
267
+
268
+ ---
269
+
270
+ ### SLIDER_MATRIX — `questionTypes.SLIDER_MATRIX`
271
+
272
+ | Preview key | Format | Wizard controls | Scale / branch |
273
+ |-------------|--------|-----------------|----------------|
274
+ | `SLIDER_matrix` | Slider matrix | Track, thumb, tick colors, row width, tick label items, tick number labels | `SliderMatrixScale.tsx`, `CustomSliderTrack.tsx` |
275
+
276
+ | Config field | CSS / DOM |
277
+ |--------------|-----------|
278
+ | `trackColor`, `thumbColor`, `tickColor` | `--cfm-slider-track`, `--cfm-slider-thumb`, `--cfm-slider-tick` |
279
+ | `rowLabelWidth` | `--cfm-matrix-row-width` |
280
+ | Tick label items | `sliderTickLabelStyle()` |
281
+ | Tick number labels | `--cfm-number-*` |
282
+ | Row band | `--cfm-slider-row-band` / `--cfm-row-band` from theme |
283
+ | Thumb selection | focus ring + cell selected on knob |
284
+
285
+ ---
286
+
287
+ ### FILE_UPLOAD — `questionTypes.FILE_UPLOAD`
288
+
289
+ | Preview key | Wizard controls | Scale / branch |
290
+ |-------------|-----------------|----------------|
291
+ | `FILE_UPLOAD` | Dropzone border style, border color, fill, padding | `FileUploadScale.tsx` |
292
+
293
+ | Config field | CSS / DOM |
294
+ |--------------|-----------|
295
+ | `dropzoneStyle` | `data-cfm-dropzone-style` |
296
+ | `borderColor` | `--cfm-upload-border-color` (not hardcoded gray) |
297
+ | `dropzoneFillColor`, `dropzonePadding` | `--cfm-upload-fill`, `--cfm-upload-padding` |
298
+ | Focus / drag | `--cfm-input-focus-ring`, `--cfm-mcq-selected-bg` |
299
+
300
+ Presigned upload flow unchanged — styling only.
301
+
302
+ ---
303
+
304
+ ### HEATMAP — `questionTypes.HEATMAP`
305
+
306
+ | Preview key | Wizard controls | Scale / branch |
307
+ |-------------|-----------------|----------------|
308
+ | `HEATMAP` | Pin color, border, size | `HeatmapScale.tsx` |
309
+
310
+ | Config field | CSS / DOM |
311
+ |--------------|-----------|
312
+ | `pinColor` | `--cfm-heatmap-pin` |
313
+ | `pinBorderColor` | `--cfm-heatmap-pin-border` |
314
+ | `pinSize` | `--cfm-heatmap-pin-size` |
315
+
316
+ ---
317
+
318
+ ### RANK_ORDER — `questionTypes.RANK_ORDER`
319
+
320
+ | Preview key | Variant | Wizard controls | Scale / branch |
321
+ |-------------|---------|-----------------|----------------|
322
+ | `RANK_drag` | Drag & drop | Item bg, handle, badge | `RankOrderScale.tsx` + `@dnd-kit` |
323
+ | `RANK_dropdown` | Dropdown | Item bg, select border, badge | Dropdown rank UI in same scale |
324
+
325
+ | Config path | CSS var |
326
+ |-------------|---------|
327
+ | `drag.itemBg` / `dropdown.itemBg` | `--cfm-rank-item-bg` |
328
+ | `drag.dragHandleColor` | `--cfm-rank-handle` |
329
+ | `*.rankBadgeColor` | `--cfm-rank-badge` |
330
+ | `drag.itemGap`, `itemPadding` | `--cfm-rank-item-gap`, `--cfm-rank-item-padding` |
331
+ | `dropdown.selectBorderColor` | `--cfm-rank-select-border` |
332
+
333
+ Do not change `interactionMode` or answer payload shapes.
334
+
335
+ ---
336
+
337
+ ### TEXT_AND_MEDIA — theme only
338
+
339
+ | Preview key | Wizard step | Tokens |
340
+ |-------------|-------------|--------|
341
+ | `TEXT_AND_MEDIA` | Theme (media) | `--cfm-media-max-width`, `--cfm-media-radius` |
342
+
343
+ No dedicated Question Types panel — wire in `Question.tsx` TEXT_AND_MEDIA branch.
344
+
345
+ ---
346
+
347
+ ## Phase 5 prerequisite — why post-customize apply works smoothly
348
+
349
+ If Phase 5 copied all wizard-ready artifacts **before** the wizard ran, Phase 6c is mostly **config sync** — not rewriting components:
350
+
351
+ | Artifact | Required before wizard |
352
+ |----------|------------------------|
353
+ | `survey-theme.css` | Full `--cfm-*` scaffold |
354
+ | `selectionStyles.ts`, `labelStyles.ts` | Selection + label helpers |
355
+ | `Header.tsx`, `Footer.tsx`, chrome templates | All `data-cfm-*` hooks |
356
+ | `uiConfig.ts` | No bare `UI_CONFIG` |
357
+ | Scale components per inventory | `var(--cfm-*)` not hardcoded hex |
358
+ | `previewBridge.ts` | `layoutFlags` handler (dev preview) |
359
+
360
+ If a wizard control does not live-update during Phase 6b, fix the **missing hook** in Phase 5 templates first — then re-run wizard. See symptom table in [`wizard-chrome-contract.md`](wizard-chrome-contract.md).
361
+
362
+ ---
363
+
364
+ ## Post-apply smoke checks (by type in survey)
365
+
366
+ For each `question.type` in the **fetched survey** (not all 11), spot-check in `npm run dev` after apply:
367
+
368
+ | Type | Check |
369
+ |------|-------|
370
+ | MCQ | Option gap/radius; selected ring uses theme focus + cell colors |
371
+ | TEXTFIELD | Placeholder color on focus/blur |
372
+ | NPS_SCALE | Number badge traffic colors when unselected; selected uses theme |
373
+ | CFM_MATRIX | Column label item colors; multi-row if multiple statements |
374
+ | CSAT / RATING | Format-specific opacity/size; carousel dots if used |
375
+ | SLIDER_MATRIX | Thumb ring+dot; tick label item colors |
376
+ | FILE_UPLOAD | Dropzone border color from config |
377
+ | HEATMAP | Pin size/color |
378
+ | RANK_ORDER | Drag handle + badge colors |
379
+ | TEXT_AND_MEDIA | Media max-width |
380
+
381
+ ---
382
+
383
+ ## Common mistakes after confirmation
384
+
385
+ | Mistake | Fix |
386
+ |---------|-----|
387
+ | Partial CSS update (only changed colors) | Full regen `survey-theme.css` from entire JSON |
388
+ | Changed `logo.fileName` manually | Use wizard `fileName`; keep `public/` file in sync |
389
+ | Re-ran `export-previews` after save | Unnecessary — previews GC'd; apply config to client app instead |
390
+ | Skipped types not in survey inventory | Still apply `questionTypes.*` blocks from saved JSON to CSS |
391
+ | Edited `Question.tsx` dispatch | Forbidden — cosmetic tokens only |
392
+ | Deploy before `out/{logo}` exists | Run build + logo preflight in Phase 6c H |
393
+
394
+ ---
395
+
396
+ ## Related
397
+
398
+ | Doc | When |
399
+ |-----|------|
400
+ | [`wizard-config-handoff.md`](wizard-config-handoff.md) | Wait protocol, GC, EC2 link |
401
+ | [`apply-ui-config.md`](apply-ui-config.md) | Full config path → CSS tables |
402
+ | [`wizard-question-type-styling.md`](wizard-question-type-styling.md) | Selection patterns, code snippets |
403
+ | [`wizard-chrome-contract.md`](wizard-chrome-contract.md) | Copy commands, symptom → fix |
404
+ | [`agent-execution-flow.md`](agent-execution-flow.md) | Full pipeline phases |
405
+ | [`verify-agent-build.sh`](../templates/verify-agent-build.sh) | Automated gate before deploy |
@@ -1,6 +1,7 @@
1
1
  # Wizard Question-Type Styling
2
2
 
3
3
  > **Read during Phase 5 (BUILD) — mandatory.** Alongside [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md) and [`apply-ui-config.md`](apply-ui-config.md).
4
+ > **After client saves wizard:** [`wizard-post-customize-build.md`](wizard-post-customize-build.md) — full format matrix + Phase 6c runbook.
4
5
  > Pipeline: [`agent-execution-flow.md`](agent-execution-flow.md).
5
6
 
6
7
  **Do not change** `Question.tsx` dispatch logic, answer shapes, SDK visibility helpers, or matrix routing algorithms — styling only.
@@ -75,10 +76,26 @@ Single-select radio: outer border = focus ring, annulus = cell selected, inner d
75
76
 
76
77
  ### TEXTFIELD (`TEXTFIELD_short`, `TEXTFIELD_long`)
77
78
 
78
- | Wizard section | CSS vars |
79
- |----------------|----------|
80
- | Input radius, border, placeholder | `--cfm-input-radius`, `--cfm-input-border`, `--cfm-input-placeholder` |
81
- | Focus | `--cfm-input-focus-ring` on focus outline |
79
+ | Wizard section | CSS vars | Apply in |
80
+ |----------------|----------|----------|
81
+ | Input radius, border, padding | `--cfm-input-radius`, `--cfm-input-border`, `--cfm-input-padding` | `Question.tsx` textarea |
82
+ | **Placeholder color** | `--cfm-input-placeholder` | `data-cfm-textfield` + CSS `::placeholder { color: var(--cfm-input-placeholder) }` |
83
+ | Focus | `--cfm-input-focus-ring` | focus outline |
84
+
85
+ ```tsx
86
+ <textarea
87
+ data-cfm-textfield
88
+ style={{ borderColor: 'var(--cfm-input-border)', ... }}
89
+ className="placeholder:cfm-input-ph"
90
+ />
91
+ ```
92
+
93
+ ```css
94
+ [data-cfm-textfield]::placeholder {
95
+ color: var(--cfm-input-placeholder);
96
+ opacity: 1;
97
+ }
98
+ ```
82
99
 
83
100
  ### NPS_SCALE (`NPS_SCALE`)
84
101
 
@@ -101,6 +118,8 @@ Single-select radio: outer border = focus ring, annulus = cell selected, inner d
101
118
 
102
119
  **No** per-type accent/ring overrides in CFM — use Question card tokens only.
103
120
 
121
+ **Matrix multi-row preview:** Wizard **Question Types → CFM** has a **multi-statement** toggle. Preview harness injects a second `statementRow` when enabled. `LikertMatrixScale.tsx` **must** map over `question.statementRows` — never hardcode a single row.
122
+
104
123
  ### CSAT_MATRIX (`CSAT_carousel`, `CSAT_dropdown`, `CSAT_emoji`, `CSAT_graphics`, `CSAT_numbered`, `CSAT_star`)
105
124
 
106
125
  | Format | Wizard sections | Key styling |
@@ -174,6 +193,8 @@ For production builds after wizard: syncing `survey-theme.css` is sufficient —
174
193
 
175
194
  **Wizard customization** exposes all **11** question types regardless of fetched survey inventory. Wire styling for every scale template you copy — not only types in the client's mockup image.
176
195
 
196
+ **Format-level matrix** (every preview tab → component): [`wizard-post-customize-build.md`](wizard-post-customize-build.md) § Question type format matrix.
197
+
177
198
  For each type in **wizard export** (all 11):
178
199
 
179
200
  - [ ] Scale component uses `var(--cfm-*)` for every wizard-exposed token (no hardcoded brand hex)
@@ -457,9 +457,11 @@
457
457
  "when": "wizardUsedOrSurveyUiConfigExists",
458
458
  "read": [
459
459
  "00-integration/wizard-config-handoff.md",
460
+ "00-integration/wizard-post-customize-build.md",
460
461
  "00-integration/apply-ui-config.md",
461
462
  "00-integration/wizard-preview-build-guide.md",
462
- "00-integration/wizard-question-type-styling.md"
463
+ "00-integration/wizard-question-type-styling.md",
464
+ "00-integration/wizard-chrome-contract.md"
463
465
  ],
464
466
  "inputFile": "survey-ui-config.final.json",
465
467
  "inputFileLocal": "survey-ui-config.json",
@@ -30,6 +30,7 @@ templates/docs/
30
30
  │ ├── agent-operating-contract.md ← Anti-hallucination — read FIRST
31
31
  │ ├── agent-execution-flow.md ← Pipeline, client questions, wizard-ready build
32
32
  │ ├── wizard-preview-build-guide.md
33
+ │ ├── wizard-post-customize-build.md ← Phase 6c — all formats + build gate
33
34
  │ ├── wizard-question-type-styling.md
34
35
  │ └── …
35
36
  ├── 01-components/ ← Wiring blueprints (per type from MANIFEST)
@@ -80,7 +81,7 @@ Full step-by-step: [`agent-execution-flow.md`](00-integration/agent-execution-fl
80
81
  | **5** Build | Wizard-ready UI | `wizard-chrome-contract.md`, `wizard-preview-build-guide.md`, `wizard-question-type-styling.md`, `03-ui-specs/*` |
81
82
  | **6** Verify | Build + dev server | `verify-agent-build.sh` — **ask wizard** |
82
83
  | **6b** Wizard | Optional customize | **`npx cfm-sdk customize`** (default) — EC2 `customize-ui` only if client on another device |
83
- | **6c** Apply | Sync final config | `apply-ui-config.md` |
84
+ | **6c** Apply | Sync final config | `wizard-post-customize-build.md`, `apply-ui-config.md` |
84
85
  | **7** Deploy | Production | **ask deploy** — `aws-deploy.md` or Vercel |
85
86
 
86
87
  **Auto-proceed:** Phase 4 → 5 and Phase 5 → 6 without waiting for approval.
@@ -135,7 +136,7 @@ npx cfm-sdk customize # DEFAULT — opens localhost:4200, WAITS until client s
135
136
 
136
137
  **Phase 6b:** Client on same machine → `customize` writes `survey-ui-config.json` directly. Remote client → `customize-ui` + EC2 link (see `wizard-troubleshooting.md`). Apply per `apply-ui-config.md`.
137
138
 
138
- **Phase 6c:** Apply from `survey-ui-config.final.json` per [`wizard-config-handoff.md`](00-integration/wizard-config-handoff.md) + [`apply-ui-config.md`](00-integration/apply-ui-config.md) **every** diff path. Then:
139
+ **Phase 6c:** Apply from `survey-ui-config.json` (local) or `.final.json` (EC2) per [`wizard-post-customize-build.md`](00-integration/wizard-post-customize-build.md) — all question types/formats + chrome — then [`apply-ui-config.md`](00-integration/apply-ui-config.md) for path tables. Then:
139
140
 
140
141
  ```bash
141
142
  npx cfm-sdk confirm-ui-config
@@ -154,7 +155,7 @@ Re-run verify script + build.
154
155
  | Phase 4 plan | `mockup-ui-extraction.md`, `placeholders-and-custom-fields-wiring.md`, `component-checklist.md`, per-type `03-ui-specs/*` |
155
156
  | Wizard build | `wizard-preview-build-guide.md`, `wizard-question-type-styling.md` |
156
157
  | Wizard run | `wizard-config-handoff.md`, `ui-customization-wizard.md`, `wizard-api.md`, `wizard-troubleshooting.md` |
157
- | After wizard (apply all paths) | `apply-ui-config.md` |
158
+ | After wizard (apply all paths) | `wizard-post-customize-build.md`, `apply-ui-config.md` |
158
159
  | Deploy | `aws-deploy.md` (§ Logos & local assets), `setup.md#nextjs-aws-static-export` |
159
160
  | Config audit | `02-reference/config-field-index.md` |
160
161