@explorer02/cfm-survey-sdk 0.2.4 → 0.2.6
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/dist/cli/index.js +45 -44
- package/dist/cli/index.mjs +43 -42
- package/package.json +1 -6
- package/postinstall.js +2 -1
- package/templates/AGENT.md +3 -3
- package/templates/docs/00-integration/agent-execution-flow.md +46 -27
- package/templates/docs/00-integration/agent-operating-contract.md +13 -5
- package/templates/docs/00-integration/apply-ui-config.md +35 -10
- package/templates/docs/00-integration/aws-deploy.md +117 -3
- package/templates/docs/00-integration/component-checklist.md +8 -4
- package/templates/docs/00-integration/constraints.md +3 -2
- package/templates/docs/00-integration/custom-field-logic-and-navigation.md +1 -1
- package/templates/docs/00-integration/mockup-ui-extraction.md +113 -0
- package/templates/docs/00-integration/placeholders-and-custom-fields-wiring.md +192 -0
- package/templates/docs/00-integration/placeholders-and-tokens.md +2 -1
- package/templates/docs/00-integration/ui-customization-wizard.md +83 -104
- package/templates/docs/00-integration/wizard-api.md +74 -82
- package/templates/docs/00-integration/wizard-chrome-contract.md +210 -0
- package/templates/docs/00-integration/wizard-config-handoff.md +57 -9
- package/templates/docs/00-integration/wizard-preview-build-guide.md +30 -11
- package/templates/docs/00-integration/wizard-question-type-styling.md +4 -2
- package/templates/docs/00-integration/wizard-troubleshooting.md +80 -0
- package/templates/docs/01-components/10-header-footer.md +3 -3
- package/templates/docs/01-components/19-survey-sticky-chrome.md +16 -55
- package/templates/docs/MANIFEST.json +34 -13
- package/templates/docs/index.md +9 -11
- package/templates/docs/templates/Footer.tsx +72 -0
- package/templates/docs/templates/Header.tsx +84 -0
- package/templates/docs/templates/LanguageSelector.tsx +40 -0
- package/templates/docs/templates/PreviewBridgeInit.tsx +13 -0
- package/templates/docs/templates/ProgressBar.tsx +33 -0
- package/templates/docs/templates/Question.tsx +50 -7
- package/templates/docs/templates/SurveyStickyChrome.tsx +19 -5
- package/templates/docs/templates/deploy-to-aws.sh +74 -0
- package/templates/docs/templates/implementation_plan.md +19 -12
- package/templates/docs/templates/verify-agent-build.sh +25 -1
- package/templates/preview-harness/preview-bridge.inline.js +1 -1
- package/templates/previewBridge.ts +131 -38
- package/templates/wizard-dist/assets/{PreviewMock-DgHfrVeb.js → PreviewMock-7peNZK-z.js} +1 -1
- package/templates/wizard-dist/assets/{TypePanel-CFVC3Ptn.js → TypePanel-BxHnE3cm.js} +1 -1
- package/templates/wizard-dist/assets/index-DtZhNwPS.js +34 -0
- package/templates/wizard-dist/index.html +1 -1
- package/templates/wizard-dist/assets/index-DYK3X1e5.js +0 -34
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Wizard Chrome Contract — Required DOM + CSS Hooks
|
|
2
|
+
|
|
3
|
+
> **Mandatory Phase 5.** If any hook is missing, wizard live preview fails for that control — even though the survey may look fine in localhost dev without the wizard open.
|
|
4
|
+
> **Copy-first templates:** [`templates/Header.tsx`](../templates/Header.tsx), [`Footer.tsx`](../templates/Footer.tsx), [`ProgressBar.tsx`](../templates/ProgressBar.tsx), [`SurveyStickyChrome.tsx`](../templates/SurveyStickyChrome.tsx), [`LanguageSelector.tsx`](../templates/LanguageSelector.tsx), [`PreviewBridgeInit.tsx`](../templates/PreviewBridgeInit.tsx), [`previewBridge.ts`](../../previewBridge.ts).
|
|
5
|
+
|
|
6
|
+
Pipeline: [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md) · [`apply-ui-config.md`](apply-ui-config.md)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Symptom → missing hook (quick fix)
|
|
11
|
+
|
|
12
|
+
| Wizard control / symptom | Required fix |
|
|
13
|
+
|--------------------------|--------------|
|
|
14
|
+
| Logo not updating in Branding / Header preview | `data-cfm-logo` img + `data-cfm-logo-text` fallback in `Header.tsx` |
|
|
15
|
+
| Company name not updating | `data-cfm-company` span in `Header.tsx` |
|
|
16
|
+
| Show header works but progress bar toggle does nothing | Progress bar needs `data-cfm-progress` + class `cfm-progress`; header needs class `cfm-header` only — **not** on sticky wrapper |
|
|
17
|
+
| Show footer toggle does nothing | `footer` + class `cfm-footer` |
|
|
18
|
+
| Question numbers / required asterisk toggles | `data-cfm-question-number` + `data-cfm-required` on every question title |
|
|
19
|
+
| Question card padding/shadow/colors not live-updating | Question wrapper uses `var(--cfm-card-*)` — not hardcoded `bg-white shadow-sm` |
|
|
20
|
+
| MCQ / NPS / dropzone style pickers | Root reads `html[data-cfm-mcq-style]`, `[data-cfm-nps-button-style]`, `[data-cfm-dropzone-style]` from bridge |
|
|
21
|
+
| Scale selection colors not updating | Import `selectionStyles.ts`; use `var(--cfm-matrix-selected)` / `var(--cfm-input-focus-ring)` |
|
|
22
|
+
| Nothing updates except static harness | Agent build missing token contract — re-copy templates above |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Copy order (agents — do this in Phase 5)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# From SDK templates folder (monorepo or node_modules)
|
|
30
|
+
cp templates/docs/templates/Header.tsx src/components/Header.tsx
|
|
31
|
+
cp templates/docs/templates/Footer.tsx src/components/Footer.tsx
|
|
32
|
+
cp templates/docs/templates/ProgressBar.tsx src/components/ProgressBar.tsx
|
|
33
|
+
cp templates/docs/templates/SurveyStickyChrome.tsx src/components/SurveyStickyChrome.tsx
|
|
34
|
+
cp templates/docs/templates/LanguageSelector.tsx src/components/LanguageSelector.tsx
|
|
35
|
+
cp templates/docs/templates/PreviewBridgeInit.tsx src/components/PreviewBridgeInit.tsx
|
|
36
|
+
cp templates/previewBridge.ts src/lib/previewBridge.ts
|
|
37
|
+
cp templates/survey-theme.css src/styles/survey-theme.css
|
|
38
|
+
cp templates/docs/templates/selectionStyles.ts src/lib/surveyUi/selectionStyles.ts
|
|
39
|
+
cp templates/docs/templates/labelStyles.ts src/lib/surveyUi/labelStyles.ts
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Wire `PreviewBridgeInit` in `layout.tsx` (local dev). Wizard iframes use injected `preview-bridge.inline.js` at export time.
|
|
43
|
+
|
|
44
|
+
Run verification:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
bash templates/verify-agent-build.sh
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Layer 1 — CSS variables (`--cfm-*`)
|
|
53
|
+
|
|
54
|
+
Wizard sends SNAPSHOT (full) + DELTA (partial) CSS vars to `:root`.
|
|
55
|
+
|
|
56
|
+
**Rule:** Every color, radius, spacing, or chrome dimension editable in the wizard must be consumed via `var(--cfm-…)` — not hardcoded `#e20074` / `bg-[#e20074]`.
|
|
57
|
+
|
|
58
|
+
Minimum files:
|
|
59
|
+
|
|
60
|
+
| File | Role |
|
|
61
|
+
|------|------|
|
|
62
|
+
| `src/styles/survey-theme.css` | All default `--cfm-*` vars |
|
|
63
|
+
| `globals.css` | `@import './styles/survey-theme.css'` |
|
|
64
|
+
| Scale components | `selectionStyles.ts` + `labelStyles.ts` |
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Layer 2 — Content patches (`data-cfm-*` + layout flags)
|
|
69
|
+
|
|
70
|
+
Wizard sends `contentPatch` on SNAPSHOT (not DELTA). Preview bridge applies patches to matching DOM nodes.
|
|
71
|
+
|
|
72
|
+
### Branding & header
|
|
73
|
+
|
|
74
|
+
| Patch field | DOM target | Template location |
|
|
75
|
+
|-------------|------------|-------------------|
|
|
76
|
+
| `logoUrl` | `[data-cfm-logo]` → sets `src`, shows img; hides `[data-cfm-logo-text]` | `Header.tsx` |
|
|
77
|
+
| `companyName` | `[data-cfm-company]` text; fills logo-text when img hidden | `Header.tsx` |
|
|
78
|
+
| `layoutFlags.showCompanyName` | `[data-cfm-company]` display | bridge |
|
|
79
|
+
|
|
80
|
+
### Layout toggles (independent — critical)
|
|
81
|
+
|
|
82
|
+
| `layoutFlags` key | Bridge selector | Component requirement |
|
|
83
|
+
|-------------------|-----------------|----------------------|
|
|
84
|
+
| `showHeader` | `.cfm-header`, `header.cfm-header` | Class on `<header>` only |
|
|
85
|
+
| `showProgressBar` | `.cfm-progress`, `[data-cfm-progress]` | **Separate** from header — `ProgressBar.tsx` |
|
|
86
|
+
| `showFooter` | `.cfm-footer`, `footer.cfm-footer` | Class on `<footer>` |
|
|
87
|
+
| `showLanguageSwitcher` | `[data-cfm-language]` | `LanguageSelector.tsx` |
|
|
88
|
+
| `showNextButton` | `[data-cfm-btn-next]` | `SurveyPage.tsx` nav |
|
|
89
|
+
| `showBackButton` | `[data-cfm-btn-back]` | `SurveyPage.tsx` nav |
|
|
90
|
+
| `showQuestionNumbers` | `[data-cfm-question-number]` | `Question.tsx` title |
|
|
91
|
+
| `showRequiredAsterisk` | `[data-cfm-required]` | `Question.tsx` title |
|
|
92
|
+
| `showFooterLogo` | `[data-cfm-footer-logo]` | `Footer.tsx` |
|
|
93
|
+
|
|
94
|
+
**Anti-pattern:** Putting `sticky top-0` on the same element as `cfm-header` — bridge used to hide progress when toggling header. Templates use `cfm-sticky-chrome` wrapper without using it for `showHeader`.
|
|
95
|
+
|
|
96
|
+
### Survey chrome content
|
|
97
|
+
|
|
98
|
+
| Patch field | DOM target |
|
|
99
|
+
|-------------|------------|
|
|
100
|
+
| `surveyTitle` | `[data-cfm-survey-title]` |
|
|
101
|
+
| `thankYouMessage` | `[data-cfm-thank-you]` |
|
|
102
|
+
| `buttonLabels.next` / `.back` | `[data-cfm-btn-next]` / `[data-cfm-btn-back]` |
|
|
103
|
+
| `copyrightText` | `[data-cfm-copyright]` |
|
|
104
|
+
| `footerLinks[]` | `[data-cfm-footer-links]` innerHTML |
|
|
105
|
+
|
|
106
|
+
### Question-type DOM attributes (on `<html>`)
|
|
107
|
+
|
|
108
|
+
Set via `contentPatch.domAttributes`:
|
|
109
|
+
|
|
110
|
+
| Attribute | Wizard source | Component reads |
|
|
111
|
+
|-----------|---------------|-----------------|
|
|
112
|
+
| `data-cfm-mcq-style` | `questionTypes.MCQ.optionStyle` | MCQ card classes / CSS |
|
|
113
|
+
| `data-cfm-nps-button-style` | `questionTypes.NPS_SCALE.buttonStyle` | `RatingScale.tsx` |
|
|
114
|
+
| `data-cfm-dropzone-style` | `questionTypes.FILE_UPLOAD.dropzoneStyle` | `FileUploadScale.tsx` |
|
|
115
|
+
|
|
116
|
+
Vite preview harness also applies `previewState` via `PreviewConfigContext` for placeholders, NPS hints, rank variant, etc.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Question card (Theme step)
|
|
121
|
+
|
|
122
|
+
Question outer wrapper **must** use theme vars:
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
<section
|
|
126
|
+
id={question.id}
|
|
127
|
+
className="cfm-question-card space-y-4"
|
|
128
|
+
style={{
|
|
129
|
+
background: 'var(--cfm-card-bg, #fff)',
|
|
130
|
+
borderColor: 'var(--cfm-card-border-color, #e5e7eb)',
|
|
131
|
+
padding: 'var(--cfm-card-padding, 24px)',
|
|
132
|
+
boxShadow: 'var(--cfm-card-shadow, 0 1px 3px rgba(0,0,0,0.1))',
|
|
133
|
+
borderRadius: 'var(--cfm-border-radius, 12px)',
|
|
134
|
+
borderWidth: 1,
|
|
135
|
+
borderStyle: 'solid',
|
|
136
|
+
}}
|
|
137
|
+
>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Question title hooks:
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
<h2>
|
|
144
|
+
{question.questionNumber != null && (
|
|
145
|
+
<span data-cfm-question-number className="mr-1 font-semibold">
|
|
146
|
+
{question.questionNumber}.
|
|
147
|
+
</span>
|
|
148
|
+
)}
|
|
149
|
+
<span dangerouslySetInnerHTML={{ __html: displayQuestionText }} />
|
|
150
|
+
{question.required && (
|
|
151
|
+
<span data-cfm-required className="ml-1 text-red-500">*</span>
|
|
152
|
+
)}
|
|
153
|
+
</h2>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
TEXTFIELD placeholder live preview: `data-cfm-textfield` on input/textarea.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## SurveyPage wiring (content phase)
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
<div className="flex min-h-screen flex-col" style={{ background: 'var(--cfm-background)' }}>
|
|
164
|
+
<SurveyStickyChrome progressPercentage={state.progressPercentage} />
|
|
165
|
+
<main style={{ maxWidth: 'var(--cfm-max-width)' }}>...</main>
|
|
166
|
+
<Footer />
|
|
167
|
+
</div>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Intro / end / paused: standalone `<Header />` (not sticky chrome). Footer still uses `cfm-footer`.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Local wizard quit — preview garbage collection
|
|
175
|
+
|
|
176
|
+
When the client **quits** local wizard (`npx cfm-sdk customize`) without saving:
|
|
177
|
+
|
|
178
|
+
1. Wizard SPA calls `POST /api/wizard-quit` on the customize server
|
|
179
|
+
2. CLI deletes `out/previews/` on agent disk
|
|
180
|
+
3. CLI exits; no orphan preview folders
|
|
181
|
+
|
|
182
|
+
When client **saves**: config written; previews remain until CLI exits (then server stops).
|
|
183
|
+
|
|
184
|
+
When CLI is **Ctrl+C**'d: customize server runs the same preview cleanup on shutdown.
|
|
185
|
+
|
|
186
|
+
EC2 `customize-ui`: quit calls `POST /wizard/session/quit` — disk session folder deleted (see [`wizard-config-handoff.md`](wizard-config-handoff.md)).
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Verification checklist (blocking before Phase 6b)
|
|
191
|
+
|
|
192
|
+
- [ ] Copied all templates from § Copy order
|
|
193
|
+
- [ ] `grep -r data-cfm-logo src/components/Header.tsx` — match
|
|
194
|
+
- [ ] `grep -r data-cfm-progress src/components/ProgressBar.tsx` — match
|
|
195
|
+
- [ ] `grep -r cfm-footer src/components/Footer.tsx` — match
|
|
196
|
+
- [ ] `grep -r data-cfm-question-number src/components/Question.tsx` — match
|
|
197
|
+
- [ ] `grep -rE 'var\\(--cfm-' src/components/` — no wizard colors as hardcoded hex only
|
|
198
|
+
- [ ] `bash templates/verify-agent-build.sh` exit 0
|
|
199
|
+
- [ ] `npx cfm-sdk export-previews` exit 0
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Related
|
|
204
|
+
|
|
205
|
+
| Doc | Role |
|
|
206
|
+
|-----|------|
|
|
207
|
+
| [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md) | Full build guide |
|
|
208
|
+
| [`wizard-question-type-styling.md`](wizard-question-type-styling.md) | Per-type CSS vars |
|
|
209
|
+
| [`10-header-footer.md`](../01-components/10-header-footer.md) | Branding patterns |
|
|
210
|
+
| [`12-survey-chrome.md`](../03-ui-specs/12-survey-chrome.md) | Chrome layout spec |
|
|
@@ -11,14 +11,53 @@ This doc tells the agent **exactly** how to wait for the client to finish the wi
|
|
|
11
11
|
|
|
12
12
|
**Do not apply wizard changes until the client has submitted the wizard.**
|
|
13
13
|
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
14
|
+
- **Default (`customize`):** CLI blocks until client saves — wait for `✅ UI configuration saved`.
|
|
15
|
+
- **Remote client (`customize-ui`):** CLI blocks and polls until status `ready`.
|
|
16
16
|
|
|
17
|
-
**Do not** guess final colors from memory
|
|
17
|
+
**Do not** guess final colors from memory or proceed to deploy before the wizard CLI exits 0.
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## Default flow — `npx cfm-sdk customize`
|
|
22
|
+
|
|
23
|
+
### Step 1 — Agent runs CLI (and waits)
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx cfm-sdk customize
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The CLI will:
|
|
30
|
+
|
|
31
|
+
1. Export all 11 component preview pages (`export-previews` if needed)
|
|
32
|
+
2. Start wizard at `http://localhost:4200`
|
|
33
|
+
3. Open browser on the **agent machine**
|
|
34
|
+
4. **Block** until client clicks **Review & Build**
|
|
35
|
+
5. Write `survey-ui-config.json` and exit 0
|
|
36
|
+
|
|
37
|
+
**Agent must:**
|
|
38
|
+
|
|
39
|
+
- [ ] Client is on the **same machine** (can see `localhost:4200`)
|
|
40
|
+
- [ ] Keep terminal open until `✅ UI configuration saved`
|
|
41
|
+
- [ ] Apply per Phase 6c from `survey-ui-config.json`
|
|
42
|
+
|
|
43
|
+
**Artifact:** `survey-ui-config.json` — apply source for local flow.
|
|
44
|
+
|
|
45
|
+
**Logo on local wizard (critical for AWS deploy):**
|
|
46
|
+
|
|
47
|
+
When the client uploads a logo in the local wizard:
|
|
48
|
+
|
|
49
|
+
1. CLI writes the file to `public/logo_{timestamp}_{name}.jpg` via `POST /api/upload-logo`.
|
|
50
|
+
2. Saved config has `global.logo.fileName` — preview `data:` URL is **not** persisted (stripped on save).
|
|
51
|
+
3. Agent **must** set `Header.tsx` `data-cfm-logo` to `src="./{fileName}"` during Phase 6c.
|
|
52
|
+
4. `yarn build` copies `public/` → `out/`; Phase 7 uploads `out/` to `sites/{surveyId}/{deployId}/`.
|
|
53
|
+
|
|
54
|
+
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
|
+
**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
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Remote client flow — `customize-ui` (fallback only)
|
|
22
61
|
|
|
23
62
|
### Step 1 — Agent runs CLI (and waits)
|
|
24
63
|
|
|
@@ -31,12 +70,12 @@ npx cfm-sdk customize-ui
|
|
|
31
70
|
**Default is review mode** (no flags). The CLI will:
|
|
32
71
|
|
|
33
72
|
1. Export component preview pages (`export-previews`)
|
|
34
|
-
2. Upload preview HTML to
|
|
73
|
+
2. Upload preview HTML to **EC2 disk** (local-server model — same as agent `customize`)
|
|
35
74
|
3. Print the **deployed EC2 wizard link** — agent **must share this URL with the client**
|
|
36
75
|
4. **Poll every ~3s** (`GET /wizard/config/:surveyId`) until the client submits
|
|
37
76
|
5. Print `✅ Configuration ready` when `status === 'ready'`
|
|
38
77
|
|
|
39
|
-
### Deployed wizard link (give to client after
|
|
78
|
+
### Deployed wizard link (give to client after preview upload)
|
|
40
79
|
|
|
41
80
|
The client does **not** use localhost. After previews are uploaded, the CLI prints:
|
|
42
81
|
|
|
@@ -45,8 +84,9 @@ The client does **not** use localhost. After previews are uploaded, the CLI prin
|
|
|
45
84
|
http://43.204.26.213:3000/wizard-app/index.html?session=<uuid>&secret=<hex>
|
|
46
85
|
```
|
|
47
86
|
|
|
48
|
-
- **Previews:** stored
|
|
49
|
-
- **Wizard UI:** served from EC2 at `/wizard-app
|
|
87
|
+
- **Previews:** stored on **EC2 disk** (`WIZARD_DATA_DIR/{sessionId}/previews/`); wizard iframes load via `GET /previews/{sessionId}/{component}/index.html` (local-server API — same model as `customize`)
|
|
88
|
+
- **Wizard UI:** served from EC2 at `/wizard-app/`; inventory via `GET /api/inventory`
|
|
89
|
+
- **On submit:** final config + permanent logo → S3 only
|
|
50
90
|
|
|
51
91
|
Set `CFM_DEPLOY_API_BASE=http://43.204.26.213:3000` (or your EC2 host). The link is built from that base + session credentials returned by `POST /wizard/session/start`.
|
|
52
92
|
|
|
@@ -71,13 +111,16 @@ Set `CFM_DEPLOY_API_BASE=http://43.204.26.213:3000` (or your EC2 host). The link
|
|
|
71
111
|
|
|
72
112
|
Poll response includes `logoUrl` and `logoKey` — CLI merges `logo.url` into final JSON.
|
|
73
113
|
|
|
114
|
+
**EC2 logo vs deploy bundle:** `logoUrl` points to `sites/{surveyId}/assets/{fileName}` on CloudFront. That path is for **wizard handoff** (download into `public/` via `confirm-ui-config`). The **live survey** loads the logo from `sites/{surveyId}/{deployId}/{fileName}` only after you rebuild and run Phase 7 deploy. Apply `data-cfm-logo src="./{fileName}"` then deploy — see [`aws-deploy.md`](aws-deploy.md) § Logos & local assets.
|
|
115
|
+
|
|
74
116
|
**If all diff counts are 0:** client submitted without changes — still verify; skip heavy apply.
|
|
75
117
|
|
|
76
118
|
### S3 garbage collection
|
|
77
119
|
|
|
78
120
|
| When | Deleted | Kept |
|
|
79
121
|
|------|---------|------|
|
|
80
|
-
| Client **Review & Build** | `wizard-sessions/{sessionId}/`
|
|
122
|
+
| Client **Review & Build** | EC2 session disk folder (`data/wizard-sessions/{sessionId}/`) | `sites/{surveyId}/assets/{logo}`, `wizard/config.json` |
|
|
123
|
+
| Client **Quit** (or tab close) | Same session prefix — `POST /wizard/session/quit` | N/A |
|
|
81
124
|
| Session **expires** (2h default) | Same session prefix — auto sweep every 5 min | N/A |
|
|
82
125
|
|
|
83
126
|
### Step 3 — Agent reads diff before touching code
|
|
@@ -216,6 +259,8 @@ npx cfm-sdk fetch-ui-config
|
|
|
216
259
|
- [ ] `src/styles/survey-theme.css` fully synced to final config
|
|
217
260
|
- [ ] All `data-cfm-*` content hooks updated
|
|
218
261
|
- [ ] Logo file exists in `public/` when config has `global.logo.fileName`
|
|
262
|
+
- [ ] `out/{fileName}` exists after build when logo configured (AWS deploy gate)
|
|
263
|
+
- [ ] `Header.tsx` uses `data-cfm-logo src="./{fileName}"` — not `data:` or `/assets/` URL
|
|
219
264
|
- [ ] `placeholders` / `customFields` / `debug` wired if present in final
|
|
220
265
|
- [ ] AWS: ran `npx cfm-sdk confirm-ui-config` after codebase apply
|
|
221
266
|
- [ ] `verify-agent-build.sh` + `npm run build` pass
|
|
@@ -228,11 +273,14 @@ npx cfm-sdk fetch-ui-config
|
|
|
228
273
|
| Mistake | Fix |
|
|
229
274
|
|---------|-----|
|
|
230
275
|
| Killed CLI during poll | Re-run `customize-ui`; client re-submits |
|
|
276
|
+
| Client quit wizard | CLI exits with abandon message; S3 GC done — re-run `customize-ui` for new session |
|
|
231
277
|
| Applied from `survey-ui-config.json` while still seed | Use `.final.json` or run `confirm-ui-config` after apply |
|
|
232
278
|
| Only changed primary color, ignored diff | Read **entire** `diff.md` — clients often change 20+ paths |
|
|
233
279
|
| Skipped `confirm-ui-config` | Active JSON stays seed; next wizard re-open is wrong |
|
|
234
280
|
| Changed `Question.tsx` dispatch during apply | UI tokens only — see `apply-ui-config.md` scope |
|
|
235
281
|
| Proceeded to deploy before apply | Complete Phase 6c first |
|
|
282
|
+
| Logo works in wizard but broken on CloudFront | Preview uses memory; deploy needs `public/` → `out/` → S3 — see `aws-deploy.md` § Logos |
|
|
283
|
+
| Used `global.logo.url` as Header src | Use `./{fileName}` only; download assets URL via `confirm-ui-config` |
|
|
236
284
|
|
|
237
285
|
---
|
|
238
286
|
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# Wizard Live Preview — Client Build Guide
|
|
2
2
|
|
|
3
3
|
> **Read during Phase 5 (BUILD) — mandatory.** Wizard **run** (Phase 6b) is optional; this contract is required for every agent build.
|
|
4
|
+
> **Authoritative hook list + copy commands:** [`wizard-chrome-contract.md`](wizard-chrome-contract.md) — fixes logo, layout toggles, question card, and per-type preview issues.
|
|
4
5
|
> Pipeline: [`agent-execution-flow.md`](agent-execution-flow.md).
|
|
5
6
|
|
|
6
7
|
Related docs:
|
|
7
8
|
|
|
9
|
+
- [`wizard-chrome-contract.md`](wizard-chrome-contract.md) — **copy-first templates** + symptom → fix table
|
|
10
|
+
|
|
8
11
|
- [`ui-customization-wizard.md`](ui-customization-wizard.md) — wizard flow and CLI
|
|
9
12
|
- [`apply-ui-config.md`](apply-ui-config.md) — applying final `survey-ui-config.json` after wizard
|
|
10
13
|
- [`wizard-api.md`](wizard-api.md) — EC2 `/wizard/*` API
|
|
@@ -20,13 +23,13 @@ The wizard does **not** re-render your React app. It loads **static preview page
|
|
|
20
23
|
sequenceDiagram
|
|
21
24
|
participant Agent as Agent_build
|
|
22
25
|
participant CLI as export_previews
|
|
23
|
-
participant
|
|
26
|
+
participant Disk as EC2_or_agent_disk
|
|
24
27
|
participant Wizard as Wizard_SPA
|
|
25
28
|
participant Iframe as Preview_iframe
|
|
26
29
|
|
|
27
30
|
Agent->>Agent: Build components with token contract
|
|
28
|
-
Agent->>CLI: customize
|
|
29
|
-
CLI->>
|
|
31
|
+
Agent->>CLI: customize (default) / customize-ui (remote)
|
|
32
|
+
CLI->>Disk: Upload HTML + JS + CSS (local-server)
|
|
30
33
|
Wizard->>Iframe: Load chrome / MCQ_single / etc.
|
|
31
34
|
Wizard->>Iframe: postMessage SNAPSHOT + DELTA
|
|
32
35
|
Iframe->>Iframe: Apply --cfm-* vars + content patches
|
|
@@ -51,14 +54,25 @@ If components use **hardcoded** colors (`bg-[#e20074]`) with no `var(--cfm-*)` h
|
|
|
51
54
|
|
|
52
55
|
## Required project artifacts (Phase 5)
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
**Copy wizard-ready templates first** (do not hand-write chrome from `apps/client`):
|
|
58
|
+
|
|
59
|
+
| Template (SDK) | Copy to |
|
|
60
|
+
|----------------|---------|
|
|
61
|
+
| `templates/docs/templates/Header.tsx` | `src/components/Header.tsx` |
|
|
62
|
+
| `templates/docs/templates/Footer.tsx` | `src/components/Footer.tsx` |
|
|
63
|
+
| `templates/docs/templates/ProgressBar.tsx` | `src/components/ProgressBar.tsx` |
|
|
64
|
+
| `templates/docs/templates/SurveyStickyChrome.tsx` | `src/components/SurveyStickyChrome.tsx` |
|
|
65
|
+
| `templates/docs/templates/LanguageSelector.tsx` | `src/components/LanguageSelector.tsx` |
|
|
66
|
+
| `templates/docs/templates/PreviewBridgeInit.tsx` | `src/components/PreviewBridgeInit.tsx` |
|
|
67
|
+
| `templates/previewBridge.ts` | `src/lib/previewBridge.ts` |
|
|
68
|
+
| `templates/survey-theme.css` | `src/styles/survey-theme.css` |
|
|
69
|
+
| `templates/docs/templates/Question.tsx` | `src/components/Question.tsx` (dispatcher base) |
|
|
70
|
+
|
|
71
|
+
Full symptom → fix table: [`wizard-chrome-contract.md`](wizard-chrome-contract.md).
|
|
55
72
|
|
|
56
73
|
| File | Purpose |
|
|
57
74
|
|------|---------|
|
|
58
|
-
| `src/styles/survey-theme.css` | All `--cfm-*` CSS custom properties (defaults from mockup) |
|
|
59
75
|
| `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
76
|
|
|
63
77
|
Import theme in `globals.css`:
|
|
64
78
|
|
|
@@ -271,6 +285,7 @@ CLI resolution order:
|
|
|
271
285
|
- **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
286
|
- **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
287
|
- **After wizard upload:** `global.logo.fileName` in saved config takes precedence — do not fall back to `Header.tsx` or scan `public/logo_*`.
|
|
288
|
+
- **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.
|
|
274
289
|
|
|
275
290
|
Debug without opening wizard:
|
|
276
291
|
|
|
@@ -284,20 +299,20 @@ Keep draft JSON and `survey-theme.css` **in sync** (same primary color, title, c
|
|
|
284
299
|
|
|
285
300
|
## How `export-previews` uses your code
|
|
286
301
|
|
|
287
|
-
When the client opts in, `customize-ui` runs `export-previews`:
|
|
302
|
+
When the client opts in, **`npx cfm-sdk customize`** (default) or `customize-ui` (remote) runs `export-previews`:
|
|
288
303
|
|
|
289
304
|
1. Copies `src/components/`, `src/lib/`, `public/`, `survey-theme.css` into a temp Vite harness
|
|
290
305
|
2. Stubs `next/image` and `next/dynamic` for static build
|
|
291
306
|
3. Builds one HTML page per preview key (`header`, `chrome`, `MCQ_single`, …) with canonical fixtures
|
|
292
307
|
4. Injects `preview-bridge.inline.js` into each `index.html`
|
|
293
|
-
5. Uploads each preview page to
|
|
308
|
+
5. Uploads each preview page to **EC2 disk** via `PUT /wizard/session/:id/preview-file` (local-server model)
|
|
294
309
|
6. Prints the **deployed wizard link** for the client:
|
|
295
310
|
|
|
296
311
|
```
|
|
297
312
|
http://43.204.26.213:3000/wizard-app/index.html?session=<uuid>&secret=<hex>
|
|
298
313
|
```
|
|
299
314
|
|
|
300
|
-
7. Wizard iframes load previews
|
|
315
|
+
7. Wizard iframes load previews from `/previews/{sessionId}/{component}/…` on the same EC2 host (`GET /api/inventory` + local-server API)
|
|
301
316
|
|
|
302
317
|
**Agent handoff:** after step 5–6, copy the printed link and send it to the client. The client customizes on EC2 only — not localhost.
|
|
303
318
|
|
|
@@ -356,6 +371,10 @@ npx cfm-sdk export-previews
|
|
|
356
371
|
| Logo `<Image>` without `data-cfm-logo` | Logo step doesn't update preview | Add `data-cfm-logo` to img |
|
|
357
372
|
| Only Phase 6c tokenization | Worked after wizard, not during | Tokenize in Phase 5 (this guide) |
|
|
358
373
|
| Skipped `export-previews` after component edits | Wizard shows old UI | Re-run `customize-ui` |
|
|
374
|
+
| Used `customize-ui` when client is on same machine | Unnecessary complexity | Use **`customize`** (default) |
|
|
375
|
+
| `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 |
|
|
376
|
+
| Missing `data-cfm-progress` / `data-cfm-question-number` | Layout toggles don't work | Wire hooks per § Layer 2 table |
|
|
377
|
+
| Hardcoded brand hex in scales | Only NPS-like paths look correct | Use `--cfm-*` + `selectionStyles.ts` |
|
|
359
378
|
|
|
360
379
|
---
|
|
361
380
|
|
|
@@ -365,7 +384,7 @@ npx cfm-sdk export-previews
|
|
|
365
384
|
|-------|----------------|
|
|
366
385
|
| **5 BUILD** | Implement components per this guide + UI specs; draft config + theme |
|
|
367
386
|
| **6 VERIFY** | `npm run build`, verify script, localhost preview |
|
|
368
|
-
| **6b WIZARD** (optional) | Client says yes →
|
|
387
|
+
| **6b WIZARD** (optional) | Client says yes → **`npx cfm-sdk customize`** → wait for save → apply config |
|
|
369
388
|
| **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` |
|
|
370
389
|
| **7 DEPLOY** | Full static build upload (separate from wizard preview files) |
|
|
371
390
|
|
|
@@ -172,7 +172,9 @@ For production builds after wizard: syncing `survey-theme.css` is sufficient —
|
|
|
172
172
|
|
|
173
173
|
## Agent checklist (per survey type)
|
|
174
174
|
|
|
175
|
-
|
|
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):
|
|
176
178
|
|
|
177
179
|
- [ ] Scale component uses `var(--cfm-*)` for every wizard-exposed token (no hardcoded brand hex)
|
|
178
180
|
- [ ] Radio/scale selections use `selectionStyles.ts` pattern (focus ring + cell selected)
|
|
@@ -191,5 +193,5 @@ For each type in survey inventory:
|
|
|
191
193
|
| [`templates/selectionStyles.ts`](../templates/selectionStyles.ts) | Copy to client `src/lib/surveyUi/` |
|
|
192
194
|
| [`templates/labelStyles.ts`](../templates/labelStyles.ts) | Copy to client `src/lib/surveyUi/` |
|
|
193
195
|
| [`templates/survey-theme.css`](../../survey-theme.css) | Full `--cfm-*` defaults |
|
|
194
|
-
| [`wizard-
|
|
196
|
+
| [`wizard-troubleshooting.md`](wizard-troubleshooting.md) | Mock preview, local vs EC2, toggle/logo fixes |
|
|
195
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
|
|
@@ -25,12 +25,12 @@ Agents must implement **one** of these wizard-compatible patterns in `Header.tsx
|
|
|
25
25
|
|
|
26
26
|
| Mode | When | Required markup |
|
|
27
27
|
|------|------|-----------------|
|
|
28
|
-
| **Image** | Brand asset in `public/` | `<img data-cfm-logo src="
|
|
28
|
+
| **Image** | Brand asset in `public/` | `<img data-cfm-logo src="./exact-file.svg" />` for AWS deploy (`assetPrefix: './'`). Use `/exact-file.svg` only for local dev. Include hidden `<span data-cfm-logo-text>` fallback. |
|
|
29
29
|
| **Text** | CSS-only logo from prompt (no image file) | `<span data-cfm-logo-text>Company</span>` in logo slot — no `data-cfm-logo` img |
|
|
30
30
|
|
|
31
|
-
- **NO EXTERNAL URLS** for logos (`https
|
|
31
|
+
- **NO EXTERNAL URLS** for logos (`https://…`, wizard `/assets/` URLs, or `data:image/…`).
|
|
32
32
|
- **CSS-only logos** use `data-cfm-logo-text` (and optional CSS shapes) — wizard shows text until client uploads an image.
|
|
33
|
-
- After wizard upload,
|
|
33
|
+
- After wizard upload, set `src="./{global.logo.fileName}"` from saved config — see [`aws-deploy.md`](../00-integration/aws-deploy.md) § Logos & local assets.
|
|
34
34
|
|
|
35
35
|
## Theme Engineering
|
|
36
36
|
- Map the primary brand color to the accent and border colors across the entire survey.
|
|
@@ -1,30 +1,28 @@
|
|
|
1
1
|
# Survey Sticky Chrome
|
|
2
2
|
|
|
3
|
-
> **UI spec (authoritative):** `03-ui-specs/12-survey-chrome.md`
|
|
4
|
-
> **
|
|
3
|
+
> **UI spec (authoritative):** `03-ui-specs/12-survey-chrome.md`
|
|
4
|
+
> **Wizard contract:** [`wizard-chrome-contract.md`](../00-integration/wizard-chrome-contract.md) — header and progress are **separate** toggle targets
|
|
5
5
|
> **Template:** [`templates/SurveyStickyChrome.tsx`](../templates/SurveyStickyChrome.tsx)
|
|
6
|
-
> **Component**: `SurveyStickyChrome`
|
|
7
6
|
|
|
8
7
|
## Purpose
|
|
9
8
|
|
|
10
|
-
Wrap **Header + ProgressBar** in a
|
|
9
|
+
Wrap **Header + ProgressBar** in a sticky container. The wizard toggles them **independently**:
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
| Toggle | Target |
|
|
12
|
+
|--------|--------|
|
|
13
|
+
| `showHeader` | `.cfm-header` on `<header>` only |
|
|
14
|
+
| `showProgressBar` | `[data-cfm-progress]` / `.cfm-progress` only |
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
type SurveyStickyChromeProps = {
|
|
16
|
-
progressPercentage: number; // from state.progressPercentage
|
|
17
|
-
};
|
|
18
|
-
```
|
|
16
|
+
Do **not** put class `cfm-header` on the sticky wrapper.
|
|
19
17
|
|
|
20
|
-
## Implementation
|
|
18
|
+
## Implementation (wizard-ready)
|
|
21
19
|
|
|
22
20
|
```tsx
|
|
23
21
|
export default function SurveyStickyChrome({ progressPercentage }: SurveyStickyChromeProps) {
|
|
24
22
|
return (
|
|
25
|
-
<div className="sticky top-0 z-30
|
|
23
|
+
<div className="cfm-sticky-chrome sticky top-0 z-30" style={{ background: 'var(--cfm-header-bg)' }}>
|
|
26
24
|
<Header embedded />
|
|
27
|
-
<div className="mx-auto w-full
|
|
25
|
+
<div className="mx-auto w-full px-4" style={{ maxWidth: 'var(--cfm-max-width)' }}>
|
|
28
26
|
<ProgressBar progressPercentage={progressPercentage} />
|
|
29
27
|
</div>
|
|
30
28
|
</div>
|
|
@@ -32,48 +30,11 @@ export default function SurveyStickyChrome({ progressPercentage }: SurveyStickyC
|
|
|
32
30
|
}
|
|
33
31
|
```
|
|
34
32
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Keep a visible gap between the logo block and the progress track — do **not** flush them together.
|
|
38
|
-
|
|
39
|
-
| Token | Tailwind | Purpose |
|
|
40
|
-
|-------|----------|---------|
|
|
41
|
-
| Top inset | `pt-4` | 16px gap below logo / header row |
|
|
42
|
-
| Bottom inset | `pb-5` | 20px gap above scrollable question content |
|
|
43
|
-
| Horizontal | `px-4 sm:px-6 lg:px-8` | Align track with `main` content column (`max-w-4xl`) |
|
|
44
|
-
|
|
45
|
-
## Header `embedded` prop
|
|
46
|
-
|
|
47
|
-
When `Header` is inside sticky chrome, pass `embedded` to avoid a double shadow:
|
|
48
|
-
|
|
49
|
-
```tsx
|
|
50
|
-
<header className={`relative h-[120px] w-full bg-white ${embedded ? '' : 'z-10 shadow-[0_2px_8px_rgba(0,0,0,0.06)]'}`}>
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Use the standalone `Header` (no `embedded`) on intro, end, loading, and terminal pages.
|
|
54
|
-
|
|
55
|
-
## SurveyPage wiring (content phase only)
|
|
56
|
-
|
|
57
|
-
```tsx
|
|
58
|
-
<div className="flex min-h-screen flex-col bg-white">
|
|
59
|
-
<SurveyStickyChrome progressPercentage={state.progressPercentage} />
|
|
60
|
-
|
|
61
|
-
<main className="mx-auto w-full max-w-4xl flex-1 px-4 py-10 sm:px-6 lg:px-8">
|
|
62
|
-
<LanguageSelector ... />
|
|
63
|
-
{/* questions + nav */}
|
|
64
|
-
</main>
|
|
65
|
-
|
|
66
|
-
<Footer />
|
|
67
|
-
</div>
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Do **not** render a separate `ProgressBar` inside `<main>` — it belongs in sticky chrome only.
|
|
33
|
+
Copy full file from [`templates/SurveyStickyChrome.tsx`](../templates/SurveyStickyChrome.tsx).
|
|
71
34
|
|
|
72
35
|
## Agent checklist
|
|
73
36
|
|
|
74
|
-
- [ ] `
|
|
75
|
-
- [ ] `ProgressBar`
|
|
76
|
-
- [ ]
|
|
77
|
-
- [ ] `pt
|
|
78
|
-
- [ ] Progress track aligned to same `max-w-4xl` as question content
|
|
79
|
-
- [ ] Standalone `Header` on intro / end / loading / terminal branches
|
|
37
|
+
- [ ] `Header.tsx` has class `cfm-header` + `data-cfm-logo` + `data-cfm-company`
|
|
38
|
+
- [ ] `ProgressBar.tsx` has `data-cfm-progress` + class `cfm-progress`
|
|
39
|
+
- [ ] Sticky wrapper uses `cfm-sticky-chrome` — not `cfm-header`
|
|
40
|
+
- [ ] `pt`/`pb` spacing via `--cfm-sticky-pt` / `--cfm-sticky-pb`
|