@explorer02/cfm-survey-sdk 0.2.3 → 0.2.5

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 (100) hide show
  1. package/dist/cli/index.js +141 -33
  2. package/dist/cli/index.mjs +141 -33
  3. package/dist/index.js +1 -1
  4. package/dist/index.mjs +1 -1
  5. package/package.json +3 -1
  6. package/postinstall.js +9 -5
  7. package/templates/AGENT.md +60 -19
  8. package/templates/deploy-wizard-to-s3.sh +52 -0
  9. package/templates/docs/00-integration/agent-execution-flow.md +293 -0
  10. package/templates/docs/00-integration/agent-operating-contract.md +268 -0
  11. package/templates/docs/00-integration/apply-ui-config.md +390 -0
  12. package/templates/docs/00-integration/aws-deploy.md +117 -3
  13. package/templates/docs/00-integration/canonical-survey-fixtures.md +94 -0
  14. package/templates/docs/00-integration/client-integration-guide.md +9 -7
  15. package/templates/docs/00-integration/client-lib-folder.md +115 -0
  16. package/templates/docs/00-integration/component-checklist.md +90 -62
  17. package/templates/docs/00-integration/constraints.md +14 -5
  18. package/templates/docs/00-integration/custom-field-logic-and-navigation.md +56 -0
  19. package/templates/docs/00-integration/mockup-ui-extraction.md +113 -0
  20. package/templates/docs/00-integration/placeholders-and-custom-fields-wiring.md +192 -0
  21. package/templates/docs/00-integration/placeholders-and-tokens.md +2 -1
  22. package/templates/docs/00-integration/progress.md +4 -2
  23. package/templates/docs/00-integration/setup.md +12 -0
  24. package/templates/docs/00-integration/ui-customization-wizard.md +123 -0
  25. package/templates/docs/00-integration/useSurveySDK.md +35 -1
  26. package/templates/docs/00-integration/wizard-api.md +126 -0
  27. package/templates/docs/00-integration/wizard-config-handoff.md +292 -0
  28. package/templates/docs/00-integration/wizard-preview-build-guide.md +405 -0
  29. package/templates/docs/00-integration/wizard-question-type-styling.md +197 -0
  30. package/templates/docs/00-integration/wizard-troubleshooting.md +80 -0
  31. package/templates/docs/01-components/01-survey-page.md +18 -8
  32. package/templates/docs/01-components/02-question.md +2 -2
  33. package/templates/docs/01-components/03-rating-scale.md +12 -18
  34. package/templates/docs/01-components/05-csat-matrix-scale.md +18 -26
  35. package/templates/docs/01-components/06-likert-matrix-scale.md +19 -39
  36. package/templates/docs/01-components/07-slider-matrix-scale.md +48 -33
  37. package/templates/docs/01-components/09-custom-slider-track.md +15 -25
  38. package/templates/docs/01-components/10-header-footer.md +23 -4
  39. package/templates/docs/01-components/11-progress-bar.md +14 -6
  40. package/templates/docs/01-components/19-survey-sticky-chrome.md +79 -0
  41. package/templates/docs/01-components/README.md +2 -2
  42. package/templates/docs/02-reference/question-types/10-slider-matrix.md +38 -26
  43. package/templates/docs/02-reference/routing-table.md +1 -0
  44. package/templates/docs/02-reference/value-derivation.md +1 -1
  45. package/templates/docs/03-ui-specs/00-question-shell.md +10 -0
  46. package/templates/docs/03-ui-specs/01-rating.md +18 -0
  47. package/templates/docs/03-ui-specs/02-radio.md +16 -1
  48. package/templates/docs/03-ui-specs/03-text.md +12 -1
  49. package/templates/docs/03-ui-specs/04-csat.md +84 -50
  50. package/templates/docs/03-ui-specs/06-slider.md +3 -1
  51. package/templates/docs/03-ui-specs/07-matrix-cfm.md +71 -48
  52. package/templates/docs/03-ui-specs/08-matrix-csat-rating.md +48 -18
  53. package/templates/docs/03-ui-specs/09-slider-matrix.md +59 -32
  54. package/templates/docs/03-ui-specs/10-file-upload.md +11 -0
  55. package/templates/docs/03-ui-specs/11-text-and-media.md +4 -0
  56. package/templates/docs/03-ui-specs/12-survey-chrome.md +54 -5
  57. package/templates/docs/03-ui-specs/13-heatmap.md +12 -1
  58. package/templates/docs/03-ui-specs/14-rank-order.md +11 -0
  59. package/templates/docs/03-ui-specs/README.md +4 -2
  60. package/templates/docs/03-ui-specs/shared/matrix-dropdown.md +1 -1
  61. package/templates/docs/MANIFEST.json +180 -7
  62. package/templates/docs/index.md +114 -117
  63. package/templates/docs/templates/CsatMatrixScale.tsx +637 -0
  64. package/templates/docs/templates/FileUploadScale.tsx +262 -0
  65. package/templates/docs/templates/HeatmapScale.tsx +114 -0
  66. package/templates/docs/templates/LikertMatrixScale.tsx +414 -0
  67. package/templates/docs/templates/Question.tsx +3 -0
  68. package/templates/docs/templates/RatingScale.tsx +129 -0
  69. package/templates/docs/templates/SliderMatrixScale.tsx +248 -0
  70. package/templates/docs/templates/SurveyStickyChrome.tsx +24 -0
  71. package/templates/docs/templates/customFieldValues.ts +36 -0
  72. package/templates/docs/templates/deploy-to-aws.sh +74 -0
  73. package/templates/docs/templates/implementation_plan.md +64 -10
  74. package/templates/docs/templates/labelStyles.ts +33 -0
  75. package/templates/docs/templates/selectionStyles.ts +100 -0
  76. package/templates/docs/templates/surveyUiIcons.tsx +11 -0
  77. package/templates/docs/templates/surveyUiScaleUtils.ts +51 -0
  78. package/templates/docs/templates/verify-agent-build.sh +119 -0
  79. package/templates/preview-harness/preview-bridge.inline.js +201 -0
  80. package/templates/preview-harness/previewPages.js +108 -0
  81. package/templates/preview-harness/previewPages.ts +298 -0
  82. package/templates/preview-harness/vite-app/src/PreviewConfigContext.tsx +67 -0
  83. package/templates/preview-harness/vite-app/src/QuestionPreview.tsx +122 -0
  84. package/templates/preview-harness/vite-app/src/SurveyPagePreview.tsx +75 -0
  85. package/templates/preview-harness/vite-app/src/fixtures/questions.ts +311 -0
  86. package/templates/preview-harness/vite-app/src/globals.css +16 -0
  87. package/templates/preview-harness/vite-app/src/mount.tsx +9 -0
  88. package/templates/preview-harness/vite-app/src/preview-live-overrides.css +101 -0
  89. package/templates/preview-harness/vite-app/stubs/next-dynamic.tsx +25 -0
  90. package/templates/preview-harness/vite-app/stubs/next-image.tsx +29 -0
  91. package/templates/previewBridge.ts +153 -0
  92. package/templates/survey-theme.css +295 -0
  93. package/templates/survey-ui-config.schema.json +213 -0
  94. package/templates/wizard-dist/assets/PreviewMock-AoZdAEPZ.js +1 -0
  95. package/templates/wizard-dist/assets/TypePanel-39FnbtvG.js +1 -0
  96. package/templates/wizard-dist/assets/index-BhWM50Yu.css +1 -0
  97. package/templates/wizard-dist/assets/index-CWKdsJOp.js +34 -0
  98. package/templates/wizard-dist/assets/vendor-BwkXDkd3.js +17 -0
  99. package/templates/wizard-dist/index.html +20 -0
  100. package/templates/wizard.html +13 -1129
@@ -0,0 +1,405 @@
1
+ # Wizard Live Preview — Client Build Guide
2
+
3
+ > **Read during Phase 5 (BUILD) — mandatory.** Wizard **run** (Phase 6b) is optional; this contract is required for every agent build.
4
+ > Pipeline: [`agent-execution-flow.md`](agent-execution-flow.md).
5
+
6
+ Related docs:
7
+
8
+ - [`ui-customization-wizard.md`](ui-customization-wizard.md) — wizard flow and CLI
9
+ - [`apply-ui-config.md`](apply-ui-config.md) — applying final `survey-ui-config.json` after wizard
10
+ - [`wizard-api.md`](wizard-api.md) — EC2 `/wizard/*` API
11
+ - [`03-ui-specs/12-survey-chrome.md`](../03-ui-specs/12-survey-chrome.md) — chrome layout spec
12
+
13
+ ---
14
+
15
+ ## Why client code matters for live preview
16
+
17
+ The wizard does **not** re-render your React app. It loads **static preview pages** built from your real `src/components/` (`npx cfm-sdk export-previews`), then sends token updates into each preview iframe via `postMessage`.
18
+
19
+ ```mermaid
20
+ sequenceDiagram
21
+ participant Agent as Agent_build
22
+ participant CLI as export_previews
23
+ participant Disk as EC2_or_agent_disk
24
+ participant Wizard as Wizard_SPA
25
+ participant Iframe as Preview_iframe
26
+
27
+ Agent->>Agent: Build components with token contract
28
+ Agent->>CLI: customize (default) / customize-ui (remote)
29
+ CLI->>Disk: Upload HTML + JS + CSS (local-server)
30
+ Wizard->>Iframe: Load chrome / MCQ_single / etc.
31
+ Wizard->>Iframe: postMessage SNAPSHOT + DELTA
32
+ Iframe->>Iframe: Apply --cfm-* vars + content patches
33
+ ```
34
+
35
+ If components use **hardcoded** colors (`bg-[#e20074]`) with no `var(--cfm-*)` hooks, the preview **looks correct initially** but **does not change** when the client drags color pickers or edits identity fields (unless a harness override happens to match your class names).
36
+
37
+ **The same token contract is used after the wizard** when you apply `survey-ui-config.json` to production (Phase 6c). Building for live preview = building for accurate customization end-to-end.
38
+
39
+ ---
40
+
41
+ ## Two preview modes (know which you get)
42
+
43
+ | Mode | CLI | Preview source | Live updates | Fidelity |
44
+ |------|-----|----------------|--------------|----------|
45
+ | **Agent components** (default) | `export-previews` | Copies your `src/components/` + Vite build | Full **only if** token contract below is followed | Matches real survey UI |
46
+ | **Template harness only** | `export-previews --use-templates-only` | SDK static HTML harness | Always live | Generic SDK chrome — not your implementation |
47
+
48
+ **Default for production wizard:** agent components. Use templates-only for SDK smoke tests, not client delivery.
49
+
50
+ ---
51
+
52
+ ## Required project artifacts (Phase 5)
53
+
54
+ Create these **before** the client opens the wizard:
55
+
56
+ | File | Purpose |
57
+ |------|---------|
58
+ | `src/styles/survey-theme.css` | All `--cfm-*` CSS custom properties (defaults from mockup) |
59
+ | `survey-ui-config.json` (draft) | Seeds wizard form fields from agent branding |
60
+ | `src/lib/previewBridge.ts` | Live bridge in **local dev** (`npx cfm-sdk customize`) — copy from `templates/previewBridge.ts` |
61
+ | `src/components/PreviewBridgeInit.tsx` | Mount bridge once in `layout.tsx` (local dev only) |
62
+
63
+ Import theme in `globals.css`:
64
+
65
+ ```css
66
+ @import "tailwindcss";
67
+ @import "../styles/survey-theme.css";
68
+ ```
69
+
70
+ Wire bridge in root layout (client app only — not uploaded to wizard):
71
+
72
+ ```tsx
73
+ import { PreviewBridgeInit } from '@/components/PreviewBridgeInit';
74
+
75
+ export default function RootLayout({ children }) {
76
+ return (
77
+ <html lang="en">
78
+ <body>
79
+ <PreviewBridgeInit />
80
+ {children}
81
+ </body>
82
+ </html>
83
+ );
84
+ }
85
+ ```
86
+
87
+ **Wizard iframes** embed `preview-bridge.inline.js` at export time — you do not ship `previewBridge.ts` inside preview HTML.
88
+
89
+ ---
90
+
91
+ ## The token contract (two layers)
92
+
93
+ ### Layer 1 — CSS variables (`--cfm-*`)
94
+
95
+ Wizard sends CSS custom properties on `:root` (SNAPSHOT on tab load, DELTA during drag).
96
+
97
+ **Rule:** Any brand color, radius, spacing, or chrome dimension the client can edit in the wizard must be consumed via `var(--cfm-…)` in components or shared CSS — **not** hardcoded hex in Tailwind arbitrary values.
98
+
99
+ Copy the full default set from [`templates/survey-theme.css`](../../survey-theme.css) and extend with per-type vars your survey uses.
100
+
101
+ **Good — responds to wizard color changes:**
102
+
103
+ ```tsx
104
+ <div
105
+ className="h-3 rounded-full transition-all"
106
+ style={{
107
+ width: `${progress}%`,
108
+ backgroundColor: 'var(--cfm-progress-fill, var(--cfm-primary))',
109
+ }}
110
+ />
111
+ ```
112
+
113
+ **Avoid for wizard-controlled colors:**
114
+
115
+ ```tsx
116
+ <div className="bg-[#e20074] h-3 rounded-full" />
117
+ ```
118
+
119
+ **Tailwind + tokens pattern** (when you prefer classes):
120
+
121
+ ```tsx
122
+ <button
123
+ className="rounded-md px-6 py-2 text-sm font-semibold hover:opacity-90"
124
+ style={{
125
+ backgroundColor: 'var(--cfm-primary)',
126
+ color: 'var(--cfm-button-text)',
127
+ borderRadius: 'var(--cfm-border-radius)',
128
+ }}
129
+ >
130
+ {nextLabel}
131
+ </button>
132
+ ```
133
+
134
+ Or define utilities in `survey-theme.css`:
135
+
136
+ ```css
137
+ .cfm-btn-primary {
138
+ background-color: var(--cfm-primary);
139
+ color: var(--cfm-button-text);
140
+ border-radius: var(--cfm-border-radius);
141
+ }
142
+ ```
143
+
144
+ ### Layer 2 — Content hooks (`data-cfm-*`)
145
+
146
+ Wizard sends a **content patch** for text, logo URL, layout toggles, and footer links. The preview bridge updates DOM nodes matching these attributes.
147
+
148
+ | Attribute | Wizard source | Apply to |
149
+ |-----------|---------------|----------|
150
+ | `data-cfm-logo` | Logo step / `global.logo` | `<img>` in Header, Footer — **image logo mode** |
151
+ | `data-cfm-logo-text` | Identity → company name (when no image) | Text fallback inside logo slot — **text logo mode** |
152
+ | `data-cfm-company` | Identity → company name | Header company text (separate from logo slot) |
153
+ | `data-cfm-survey-title` | Identity → survey title | Main heading, chrome preview |
154
+ | `data-cfm-thank-you` | Identity → thank-you message | End page message |
155
+ | `data-cfm-copyright` | Footer step | Footer copyright line |
156
+ | `data-cfm-footer-links` | Footer step | Footer `<nav>` container (links injected) |
157
+ | `data-cfm-btn-next` | Layout → button labels | Next / Submit button |
158
+ | `data-cfm-btn-back` | Layout → button labels | Back button |
159
+ | `data-cfm-progress` | Layout → show progress bar | Wrapper around `ProgressBar` |
160
+
161
+ **Image logo (file in `public/`):**
162
+
163
+ ```tsx
164
+ <div className="cfm-header-logo-slot flex shrink-0 items-center justify-center">
165
+ <img
166
+ data-cfm-logo
167
+ src="/telekom-logo.svg"
168
+ alt="Company"
169
+ className="object-contain"
170
+ style={{
171
+ padding: 'var(--cfm-header-logo-padding)',
172
+ width: '100%',
173
+ height: '100%',
174
+ }}
175
+ />
176
+ {/* Hidden until wizard has no uploaded image — bridge toggles visibility */}
177
+ <span data-cfm-logo-text className="hidden font-semibold">
178
+ Company Name
179
+ </span>
180
+ </div>
181
+ ```
182
+
183
+ **Text-only logo (CSS-built brand, no `public/` image):**
184
+
185
+ ```tsx
186
+ <div className="cfm-header-logo-slot flex shrink-0 items-center justify-center">
187
+ <span
188
+ data-cfm-logo-text
189
+ className="font-semibold"
190
+ style={{
191
+ color: 'var(--cfm-header-company-color)',
192
+ fontSize: 'var(--cfm-header-company-size)',
193
+ fontWeight: 'var(--cfm-header-company-weight)',
194
+ }}
195
+ >
196
+ Company Name
197
+ </span>
198
+ </div>
199
+ ```
200
+
201
+ Do **not** add unrelated `public/logo_*` files during agent build — the CLI seeds the wizard from `Header.tsx` (`data-cfm-logo` src) or `data-cfm-logo-text`, not the newest file in `public/`. After the client uploads a logo in the wizard, `survey-ui-config.json` stores `global.logo.fileName`; the next wizard session uses **only that saved file**.
202
+
203
+ **Example SurveyPage nav buttons:**
204
+
205
+ ```tsx
206
+ <button data-cfm-btn-back type="button" onClick={onBack}>
207
+ Back
208
+ </button>
209
+ <button
210
+ data-cfm-btn-next
211
+ type="button"
212
+ style={{ backgroundColor: 'var(--cfm-primary)', color: 'var(--cfm-button-text)' }}
213
+ onClick={onNext}
214
+ >
215
+ Next
216
+ </button>
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Per-component checklist
222
+
223
+ ### Chrome (always)
224
+
225
+ | Component | CSS vars | data-cfm-* |
226
+ |-----------|----------|------------|
227
+ | `Header.tsx` | `--cfm-header-*`, `--cfm-primary` (logo box) | `data-cfm-logo`, `data-cfm-company` |
228
+ | `Footer.tsx` | `--cfm-footer-*` | `data-cfm-logo`, `data-cfm-copyright`, `data-cfm-footer-links` |
229
+ | `ProgressBar.tsx` | `--cfm-progress-*` | wrap parent with `data-cfm-progress` |
230
+ | `SurveyStickyChrome.tsx` | header + progress vars | same as Header / progress |
231
+ | `IntroPage.tsx` | page bg, card, primary button | `data-cfm-survey-title` on main heading |
232
+ | `EndPage.tsx` | same | `data-cfm-thank-you` on thank-you copy |
233
+ | `SurveyPage.tsx` | `--cfm-max-width`, layout toggles | `data-cfm-btn-next`, `data-cfm-btn-back`; conditional render for `showHeader`, `showFooter`, `showProgressBar` from config at apply time |
234
+
235
+ ### Question scales (per type in survey)
236
+
237
+ Full per-type wizard control mapping: [`wizard-question-type-styling.md`](wizard-question-type-styling.md).
238
+
239
+ Use vars from `survey-theme.css` for cosmetic tokens the wizard exposes per type. See [`apply-ui-config.md`](apply-ui-config.md) token → file mapping.
240
+
241
+ | Type | Key vars | Component |
242
+ |------|----------|-----------|
243
+ | MCQ | `--cfm-mcq-*` | `Question.tsx` MCQ branch / `OptionItem` |
244
+ | NPS_SCALE | `--cfm-nps-*` | `RatingScale.tsx` |
245
+ | CFM_MATRIX | `--cfm-matrix-*` | `LikertMatrixScale.tsx` |
246
+ | CSAT_MATRIX | `--cfm-csat-*` | `CsatMatrixScale.tsx` |
247
+ | RATING_MATRIX | `--cfm-star-*`, `--cfm-badge-*` | `RatingScale.tsx` / `CsatMatrixScale.tsx` |
248
+ | SLIDER_MATRIX | `--cfm-slider-*` | `SliderMatrixScale.tsx`, `CustomSliderTrack.tsx` |
249
+ | FILE_UPLOAD | `--cfm-upload-*` | `FileUploadScale.tsx` |
250
+ | HEATMAP | `--cfm-heatmap-*` | `HeatmapScale.tsx` |
251
+ | RANK_ORDER | `--cfm-rank-*` | `RankOrderScale.tsx` |
252
+
253
+ **Do not change** dispatch logic, answer shapes, or SDK visibility helpers for wizard compatibility.
254
+
255
+ ---
256
+
257
+ ## Draft `survey-ui-config.json` (wizard seed)
258
+
259
+ After branding from the client prompt, write a **draft** `survey-ui-config.json` at project root so `customize-ui` seeds the wizard with your build — not generic Sprinklr defaults.
260
+
261
+ CLI resolution order:
262
+
263
+ 1. `./survey-ui-config.json` — including wizard-saved `global.logo.fileName` (re-open uses uploaded logo only)
264
+ 2. Parsed `src/styles/survey-theme.css`
265
+ 3. `implementation_plan.md` branding hints
266
+ 4. `Header.tsx` — `data-cfm-logo` image `src` (e.g. `/telekom-logo.svg`) or `data-cfm-logo-text` for text-only builds
267
+ 5. SDK defaults
268
+
269
+ **Logo seed rules for agents:**
270
+
271
+ - **Image logo:** put file in `public/`, reference exact path on `<img data-cfm-logo src="/your-logo.svg" />`. CLI base64-encodes that file for the wizard preview.
272
+ - **Text logo:** use `<span data-cfm-logo-text>` in the logo slot (CSS shapes optional). Omit `data-cfm-logo` img. Wizard shows company text until client uploads an image.
273
+ - **After wizard upload:** `global.logo.fileName` in saved config takes precedence — do not fall back to `Header.tsx` or scan `public/logo_*`.
274
+ - **AWS deploy:** logo file must be in `out/{fileName}` with `data-cfm-logo src="./{fileName}"` — wizard preview memory is not uploaded. See [`aws-deploy.md`](aws-deploy.md) § Logos & local assets.
275
+
276
+ Debug without opening wizard:
277
+
278
+ ```bash
279
+ npx cfm-sdk resolve-ui-config --write
280
+ ```
281
+
282
+ Keep draft JSON and `survey-theme.css` **in sync** (same primary color, title, company name).
283
+
284
+ ---
285
+
286
+ ## How `export-previews` uses your code
287
+
288
+ When the client opts in, **`npx cfm-sdk customize`** (default) or `customize-ui` (remote) runs `export-previews`:
289
+
290
+ 1. Copies `src/components/`, `src/lib/`, `public/`, `survey-theme.css` into a temp Vite harness
291
+ 2. Stubs `next/image` and `next/dynamic` for static build
292
+ 3. Builds one HTML page per preview key (`header`, `chrome`, `MCQ_single`, …) with canonical fixtures
293
+ 4. Injects `preview-bridge.inline.js` into each `index.html`
294
+ 5. Uploads each preview page to **EC2 disk** via `PUT /wizard/session/:id/preview-file` (local-server model)
295
+ 6. Prints the **deployed wizard link** for the client:
296
+
297
+ ```
298
+ http://43.204.26.213:3000/wizard-app/index.html?session=<uuid>&secret=<hex>
299
+ ```
300
+
301
+ 7. Wizard iframes load previews from `/previews/{sessionId}/{component}/…` on the same EC2 host (`GET /api/inventory` + local-server API)
302
+
303
+ **Agent handoff:** after step 5–6, copy the printed link and send it to the client. The client customizes on EC2 only — not localhost.
304
+
305
+ Preview keys match wizard steps — see [`ui-customization-wizard.md`](ui-customization-wizard.md) step table.
306
+
307
+ **Implication:** Wizard previews are a **snapshot of your component source at export time**. Re-run `customize-ui` (or `export-previews` + re-upload) after you change component structure.
308
+
309
+ ---
310
+
311
+ ## Live update protocol (wizard ↔ iframe)
312
+
313
+ | Message | When | Payload |
314
+ |---------|------|---------|
315
+ | `CFM_UI_CONFIG_SNAPSHOT` | Iframe load, tab change, text debounce | Full `cssVars` + `contentPatch` |
316
+ | `CFM_UI_CONFIG_DELTA` | Color sliders, drag (~60fps) | Partial `cssVars` only |
317
+
318
+ Content patches apply to `[data-cfm-*]` nodes. CSS vars apply to `:root`. Components must **read** those vars (Layer 1) for visual updates.
319
+
320
+ ---
321
+
322
+ ## Agent build checklist (blocking for full live preview)
323
+
324
+ Add to `implementation_plan.md` §5 and verify before Phase 6b:
325
+
326
+ - [ ] `src/styles/survey-theme.css` exists with full `--cfm-*` set for types in survey
327
+ - [ ] Draft `survey-ui-config.json` matches theme + identity from mockup
328
+ - [ ] `previewBridge.ts` + `PreviewBridgeInit` wired for local `customize` dev
329
+ - [ ] **No hardcoded brand hex** in chrome or scale components for wizard-controlled tokens
330
+ - [ ] Header: `data-cfm-logo`, `data-cfm-company` + header CSS vars
331
+ - [ ] Footer: `data-cfm-copyright`, `data-cfm-footer-links`, footer CSS vars
332
+ - [ ] ProgressBar: `--cfm-progress-fill` / `--cfm-progress-track`; parent `data-cfm-progress`
333
+ - [ ] SurveyPage buttons: `data-cfm-btn-next`, `data-cfm-btn-back`
334
+ - [ ] Intro/End: `data-cfm-survey-title`, `data-cfm-thank-you` where applicable
335
+ - [ ] Per-type scale vars wired per `apply-ui-config.md` mapping
336
+ - [ ] `npx cfm-sdk export-previews` succeeds from project root
337
+ - [ ] Grep: no `not yet implemented` stubs
338
+
339
+ Quick self-test (local):
340
+
341
+ ```bash
342
+ npx cfm-sdk export-previews
343
+ # Open out/previews/chrome/index.html in browser; in devtools console:
344
+ # postMessage({ type: 'CFM_UI_CONFIG_SNAPSHOT', cssVars: { '--cfm-primary': '#0066cc' }, contentPatch: { surveyTitle: 'Test Title' }}, '*')
345
+ # Title and primary-colored surfaces should update
346
+ ```
347
+
348
+ ---
349
+
350
+ ## Common mistakes
351
+
352
+ | Mistake | Symptom in wizard | Fix |
353
+ |---------|-------------------|-----|
354
+ | Hardcoded `bg-[#brand]` everywhere | Preview frozen on theme step | Use `var(--cfm-primary)` or `.cfm-btn-primary` |
355
+ | `survey-theme.css` missing or minimal | Seed config wrong; few vars update | Copy full template `survey-theme.css` |
356
+ | No `data-cfm-survey-title` | Identity edits don't change preview text | Add attribute to visible headings |
357
+ | Logo `<Image>` without `data-cfm-logo` | Logo step doesn't update preview | Add `data-cfm-logo` to img |
358
+ | Only Phase 6c tokenization | Worked after wizard, not during | Tokenize in Phase 5 (this guide) |
359
+ | Skipped `export-previews` after component edits | Wizard shows old UI | Re-run `customize-ui` |
360
+ | Used `customize-ui` when client is on same machine | Unnecessary complexity | Use **`customize`** (default) |
361
+ | `surveyTypes` only lists fetched survey types | Wizard shows one question type (e.g. NPS only) | `customize-ui` exports all 11 types; mockup image ≠ wizard inventory |
362
+ | Missing `data-cfm-progress` / `data-cfm-question-number` | Layout toggles don't work | Wire hooks per § Layer 2 table |
363
+ | Hardcoded brand hex in scales | Only NPS-like paths look correct | Use `--cfm-*` + `selectionStyles.ts` |
364
+
365
+ ---
366
+
367
+ ## Phase flow summary
368
+
369
+ | Phase | Agent action |
370
+ |-------|----------------|
371
+ | **5 BUILD** | Implement components per this guide + UI specs; draft config + theme |
372
+ | **6 VERIFY** | `npm run build`, verify script, localhost preview |
373
+ | **6b WIZARD** (optional) | Client says yes → **`npx cfm-sdk customize`** → wait for save → apply config |
374
+ | **6c APPLY** | Apply **all** paths from `survey-ui-config.final.json` per [`wizard-config-handoff.md`](wizard-config-handoff.md) + [`apply-ui-config.md`](apply-ui-config.md) → `confirm-ui-config` |
375
+ | **7 DEPLOY** | Full static build upload (separate from wizard preview files) |
376
+
377
+ ---
378
+
379
+ ## Copy-from-template shortcut
380
+
381
+ Fastest path to full live preview: start from SDK portable templates in `templates/docs/templates/`, then customize branding using **tokens from day one** rather than hardcoded mockup hex. Extend tokens as you deviate from defaults.
382
+
383
+ Templates to prioritize for token wiring:
384
+
385
+ - `Header.tsx`, `Footer.tsx`, `ProgressBar.tsx`, `SurveyStickyChrome.tsx`
386
+ - Scale components listed in [`component-checklist.md`](component-checklist.md)
387
+
388
+ ---
389
+
390
+ ## CLI reference
391
+
392
+ ```bash
393
+ # Build preview pages only (from project root)
394
+ npx cfm-sdk export-previews
395
+
396
+ # Template harness smoke test (not client UI)
397
+ npx cfm-sdk export-previews --use-templates-only
398
+
399
+ # Full AWS wizard session
400
+ export CFM_INSTANCE_ID="..." CFM_DEPLOY_API_BASE="http://your-ec2:3000"
401
+ npx cfm-sdk customize-ui
402
+
403
+ # Inspect seed config
404
+ npx cfm-sdk resolve-ui-config --write
405
+ ```
@@ -0,0 +1,197 @@
1
+ # Wizard Question-Type Styling
2
+
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
+ > Pipeline: [`agent-execution-flow.md`](agent-execution-flow.md).
5
+
6
+ **Do not change** `Question.tsx` dispatch logic, answer shapes, SDK visibility helpers, or matrix routing algorithms — styling only.
7
+
8
+ ---
9
+
10
+ ## Shared selection pattern (Question card theme)
11
+
12
+ Wizard **Theme & Colors → Question card** exposes two tokens used across radio/scale selections:
13
+
14
+ | Wizard field | CSS variable | Visual role |
15
+ |--------------|--------------|-------------|
16
+ | **Cell selected color** | `--cfm-matrix-selected` | Fill **between** outer ring and inner dot (annulus); also solid numbered/star cell background when selected |
17
+ | **Focus ring** | `--cfm-input-focus-ring` | Outer circle **border** + inner **dot** color |
18
+
19
+ Also mapped (for MCQ compatibility): `--cfm-mcq-selected-accent` ← cell selected color.
20
+
21
+ Copy [`templates/selectionStyles.ts`](../templates/selectionStyles.ts) → `src/lib/surveyUi/selectionStyles.ts` and use in scale components:
22
+
23
+ ```tsx
24
+ import {
25
+ scaleRadioRingStyle,
26
+ scaleRadioDotStyle,
27
+ matrixRadioRingStyle,
28
+ matrixRadioDotStyle,
29
+ cellSelectedVar,
30
+ focusRingVar,
31
+ } from '@/lib/surveyUi/selectionStyles';
32
+ ```
33
+
34
+ **Selected radio cell structure:**
35
+
36
+ ```
37
+ ┌─ focus ring (border) ─────────┐
38
+ │ cell selected (annulus) │
39
+ │ ● focus ring (dot) │
40
+ └─────────────────────────────┘
41
+ ```
42
+
43
+ **Numbered badge when selected:** border = focus ring, background = cell selected, text = white.
44
+ **Unselected numbered badges:** keep traffic-light / per-number colors from `--cfm-number-*` vars (do not override with theme tokens).
45
+
46
+ ---
47
+
48
+ ## Shared label helpers
49
+
50
+ Copy [`templates/labelStyles.ts`](../templates/labelStyles.ts) → `src/lib/surveyUi/labelStyles.ts`.
51
+
52
+ | Helper | CSS vars | Wizard control |
53
+ |--------|----------|----------------|
54
+ | `hintLabelStyle()` | `--cfm-hint-label-color`, `--cfm-hint-label-bg` | Hint labels (min/max anchors) |
55
+ | `matrixColumnLabelStyle()` | `--cfm-matrix-column-label-*` | CFM matrix column header items |
56
+ | `csatColumnLabelStyle()` | `--cfm-csat-column-label-*` | CSAT/Rating column header items |
57
+ | `sliderTickLabelStyle()` | `--cfm-slider-tick-label-*` | Slider matrix tick label items |
58
+
59
+ **CFM matrix:** column headers are **label items** only — not hint labels, not number labels.
60
+ **CSAT/Rating:** per-format controls differ — see per-type table below.
61
+
62
+ ---
63
+
64
+ ## Per-type wizard controls → CSS vars → components
65
+
66
+ ### MCQ (`MCQ_single`, `MCQ_multiple`)
67
+
68
+ | Wizard section | Config path | CSS vars | Apply in |
69
+ |----------------|-------------|----------|----------|
70
+ | Option style | `questionTypes.MCQ.optionStyle` | `data-cfm-mcq-style` on `:root` | `Question.tsx` MCQ branch |
71
+ | Option gap / radius / padding | `questionTypes.MCQ.*` | `--cfm-mcq-option-gap`, `--cfm-mcq-border-radius`, `--cfm-mcq-card-padding` | MCQ option cards |
72
+ | Selection | Theme → Question card | `--cfm-input-focus-ring`, `--cfm-matrix-selected`, `--cfm-mcq-selected-bg` | Radio: ring border + annulus + dot; checkbox: ring border + fill |
73
+
74
+ Single-select radio: outer border = focus ring, annulus = cell selected, inner dot = focus ring.
75
+
76
+ ### TEXTFIELD (`TEXTFIELD_short`, `TEXTFIELD_long`)
77
+
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 |
82
+
83
+ ### NPS_SCALE (`NPS_SCALE`)
84
+
85
+ | Wizard section | Config path | CSS vars | Apply in |
86
+ |----------------|-------------|----------|----------|
87
+ | Button style | `questionTypes.NPS_SCALE.buttonStyle` | `data-cfm-nps-button-style` | `RatingScale.tsx` |
88
+ | Track | `selectedFill`, `trackBar`, `trackHighlight` | `--cfm-nps-selected-fill`, `--cfm-nps-track-bar`, `--cfm-nps-track-highlight` | Track bar background |
89
+ | Hint labels | `hintMinText`, `hintMaxText` + hint colors | `--cfm-hint-label-*` | Min/max anchor row |
90
+ | Number labels | `numberLabelMode`, per-index colors | `--cfm-number-label-mode`, `--cfm-number-mono-color`, `--cfm-number-color-{n}` | Badge row above radios |
91
+ | Selection | Theme → Question card | `--cfm-matrix-selected`, `--cfm-input-focus-ring` | `scaleRadioRingStyle` + `scaleRadioDotStyle` |
92
+
93
+ ### CFM_MATRIX (`CFM_matrix`, `CFM_dropdown`, `CFM_transpose`, `CFM_likert`, `CFM_bipolar`)
94
+
95
+ | Wizard section | CSS vars | Apply in |
96
+ |----------------|----------|----------|
97
+ | Row label width | `--cfm-matrix-row-width` | `LikertMatrixScale.tsx` |
98
+ | Bipolar column width | `--cfm-matrix-bipolar-width` | Bipolar anchor column |
99
+ | Label items | `--cfm-matrix-column-label-color`, `--cfm-matrix-column-label-bg` | Column header row only |
100
+ | Selection | `--cfm-matrix-selected`, `--cfm-input-focus-ring` | `matrixRadioRingStyle` / custom cells; dropdown option ring |
101
+
102
+ **No** per-type accent/ring overrides in CFM — use Question card tokens only.
103
+
104
+ ### CSAT_MATRIX (`CSAT_carousel`, `CSAT_dropdown`, `CSAT_emoji`, `CSAT_graphics`, `CSAT_numbered`, `CSAT_star`)
105
+
106
+ | Format | Wizard sections | Key styling |
107
+ |--------|-----------------|-------------|
108
+ | **emoji** | Emoji size, unselected opacity, label items | `emojiSizeStyle()`, `unselectedOpacityStyle()`, emoji ring = focus ring on select |
109
+ | **star** | Emoji size, unselected opacity, label items | Stars: selected color = `cellSelectedVar` |
110
+ | **numbered** | Number labels, label items | Selected cell: border focus ring, fill cell selected |
111
+ | **radio** (grid) | Label items | Horizontal radio grid; `matrixRadioRingStyle` |
112
+ | **graphics** (slider) | Label items, tick labels | `CustomSliderTrack` thumb: ring + annulus + dot pattern |
113
+ | **carousel** | Label items | Dot indicators: cell selected when active |
114
+ | **dropdown / selectbox** | Label items | `MatrixDropdown` + list radio pattern |
115
+
116
+ **Removed from wizard UI (do not wire):** per-type accent, selected ring, badge color, hint labels section on CSAT formats that use label items only.
117
+
118
+ ### RATING_MATRIX (`RATING_radio`, `RATING_emoji`, `RATING_graphics`, `RATING_slider`, `RATING_star`, `RATING_numbered`)
119
+
120
+ Same CSAT patterns where formats overlap. **Radio format:** horizontal grid (not vertical list). Use CSAT matrix component paths with star/numbered/emoji/graphics variants.
121
+
122
+ ### SLIDER_MATRIX (`SLIDER_matrix`)
123
+
124
+ | Wizard section | CSS vars | Apply in |
125
+ |----------------|----------|----------|
126
+ | Track / thumb / tick | `--cfm-slider-track`, `--cfm-slider-thumb`, `--cfm-slider-tick` | `SliderMatrixScale`, `CustomSliderTrack` |
127
+ | Row band | `--cfm-slider-row-band` | Statement row background |
128
+ | Tick label items | `--cfm-slider-tick-label-*` | Header tick labels |
129
+ | Tick number labels | `--cfm-number-*` | Colored number badges |
130
+ | Thumb selection | `--cfm-matrix-selected`, `--cfm-input-focus-ring` | Knob: border + annulus + center dot |
131
+
132
+ **No** hint labels section in wizard for slider matrix — use tick label items.
133
+
134
+ ### FILE_UPLOAD (`FILE_UPLOAD`)
135
+
136
+ | Wizard section | CSS vars | Apply in |
137
+ |----------------|----------|----------|
138
+ | Dropzone border style | `--cfm-upload-border-style`, `data-cfm-dropzone-style` | `FileUploadScale.tsx` |
139
+ | Border color | `--cfm-upload-border-color` | Dropzone border (not hardcoded `#d1d5db`) |
140
+ | Fill / padding | `--cfm-upload-fill`, `--cfm-upload-padding` | Dropzone background |
141
+ | Focus/hover | `--cfm-input-focus-ring`, `--cfm-mcq-selected-bg` | Focus border + drag-active bg |
142
+
143
+ ### HEATMAP (`HEATMAP`)
144
+
145
+ | Wizard section | CSS vars |
146
+ |----------------|----------|
147
+ | Pin color / border / size | `--cfm-heatmap-pin`, pin border config, `--cfm-heatmap-pin-size` |
148
+
149
+ ### RANK_ORDER (`RANK_drag`, `RANK_dropdown`)
150
+
151
+ | Variant | Wizard controls | CSS vars |
152
+ |---------|-----------------|----------|
153
+ | Drag | Item bg, handle, badge, gap, padding | `--cfm-rank-item-bg`, `--cfm-rank-handle`, `--cfm-rank-badge`, `--cfm-rank-item-gap`, `--cfm-rank-item-padding` |
154
+ | Dropdown | Item bg, select border, badge | `--cfm-rank-select-border`, etc. |
155
+ | Focus on inputs | Theme focus ring | `--cfm-input-focus-ring` on focus |
156
+
157
+ **Rank drag:** ensure `interactionMode: 'dragAndDrop'` in fixture/survey — do not change dispatch.
158
+
159
+ ### TEXT_AND_MEDIA
160
+
161
+ Use `--cfm-media-max-width`, `--cfm-media-radius` from theme.
162
+
163
+ ---
164
+
165
+ ## Live preview re-render (export-previews harness)
166
+
167
+ Components that read CSS vars at render time should import `useLiveThemeTick` from preview harness or bump state when wizard sends `CFM_UI_CONFIG_SNAPSHOT` / `DELTA`. The **export-previews** Vite harness includes this; production client apps only need it if running local `npx cfm-sdk customize`.
168
+
169
+ For production builds after wizard: syncing `survey-theme.css` is sufficient — no `previewLiveTick` required.
170
+
171
+ ---
172
+
173
+ ## Agent checklist (per survey type)
174
+
175
+ **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
+
177
+ For each type in **wizard export** (all 11):
178
+
179
+ - [ ] Scale component uses `var(--cfm-*)` for every wizard-exposed token (no hardcoded brand hex)
180
+ - [ ] Radio/scale selections use `selectionStyles.ts` pattern (focus ring + cell selected)
181
+ - [ ] Matrix column headers use `labelStyles.ts` (label items — not conflated with hint/number labels)
182
+ - [ ] NPS/numbered formats use `resolveNumberLabelColor` from `surveyUiScaleUtils.ts` for **unselected** badges only
183
+ - [ ] File upload dropzone uses `--cfm-upload-border-color`
184
+ - [ ] `Question.tsx` dispatch unchanged; cosmetic inline styles only
185
+ - [ ] `npx cfm-sdk export-previews` succeeds after styling wiring
186
+
187
+ ---
188
+
189
+ ## Related files
190
+
191
+ | File | Purpose |
192
+ |------|---------|
193
+ | [`templates/selectionStyles.ts`](../templates/selectionStyles.ts) | Copy to client `src/lib/surveyUi/` |
194
+ | [`templates/labelStyles.ts`](../templates/labelStyles.ts) | Copy to client `src/lib/surveyUi/` |
195
+ | [`templates/survey-theme.css`](../../survey-theme.css) | Full `--cfm-*` defaults |
196
+ | [`wizard-troubleshooting.md`](wizard-troubleshooting.md) | Mock preview, local vs EC2, toggle/logo fixes |
197
+ | [`apply-ui-config.md`](apply-ui-config.md) | Post-wizard apply workflow |
@@ -0,0 +1,80 @@
1
+ # Wizard Troubleshooting — Agent Guide
2
+
3
+ > Companion: [`ui-customization-wizard.md`](ui-customization-wizard.md), [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md).
4
+
5
+ ## Default command
6
+
7
+ **When client says yes → run `npx cfm-sdk customize`** (not `customize-ui` unless client is on another device).
8
+
9
+ | | `customize` **(default)** | `customize-ui` **(fallback)** |
10
+ |--|---------------------------|--------------------------------|
11
+ | **When** | Client on same machine as agent | Client on different device |
12
+ | **URL** | `localhost:4200` | EC2 link with `session` + `secret` |
13
+ | **Previews** | `out/previews/` on agent disk | EC2 disk |
14
+ | **Save** | `survey-ui-config.json` immediately | Poll → `.final.json` + `.diff.md` |
15
+ | **GC** | CLI stops → no orphans | Session cleanup on EC2 |
16
+
17
+ ---
18
+
19
+ ## Mock preview instead of live components
20
+
21
+ ### Symptom
22
+
23
+ Footer: **"Mock preview — run customize or customize-ui…"**
24
+
25
+ ### Fix
26
+
27
+ 1. Run `npx cfm-sdk customize` — auto-runs `export-previews` if needed
28
+ 2. Ensure `src/components/Question.tsx` exists (Phase 5 build complete)
29
+ 3. Re-run if you changed components after last export
30
+
31
+ ---
32
+
33
+ ## Client on another device opened localhost
34
+
35
+ ### Symptom
36
+
37
+ Client cannot open `http://localhost:4200`
38
+
39
+ ### Fix
40
+
41
+ Use EC2 fallback:
42
+
43
+ ```bash
44
+ export CFM_INSTANCE_ID="<JWT>"
45
+ export CFM_DEPLOY_API_BASE="http://43.204.26.213:3000"
46
+ npx cfm-sdk customize-ui
47
+ ```
48
+
49
+ Send **only the EC2 link** from CLI output.
50
+
51
+ ---
52
+
53
+ ## Storage service unavailable (EC2 only)
54
+
55
+ Only applies to **`customize-ui`** on submit — S3 denied when saving final config/logo. Previews on EC2 disk do not need S3.
56
+
57
+ Fix: EC2 IAM + `HOSTING_BUCKET` on deploy-api.
58
+
59
+ For same-machine clients, use **`customize`** — no S3 during wizard at all.
60
+
61
+ ---
62
+
63
+ ## Logo / toggles / layout not updating
64
+
65
+ Wire `data-cfm-*` hooks and `--cfm-*` CSS vars per [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md).
66
+
67
+ ---
68
+
69
+ ## Only one question type showing
70
+
71
+ `customize` exports **all 11** types. Mockup may show NPS only — wizard still customizes all types.
72
+
73
+ ---
74
+
75
+ ## Checklist
76
+
77
+ - [ ] Used **`customize`** as default when client said yes
78
+ - [ ] Waited for `✅ UI configuration saved`
79
+ - [ ] Phase 5 preview bridge + `data-cfm-*` wired
80
+ - [ ] EC2 only if client on remote device