widget.js hit the real /api/chat (real LLM replies) and wrote a real lead to the DB (draft tenant, fake visitor). The soft-data the visitor volunteers in chat — preferred time, occasion, note — is now captured via a new invisible [SOFTCTX:] tag the model emits, stashed to the session, and folded into the lead at form-submit. It shows on the card below and in the tenant notification email.Visitor lands on the med-spa site; the widget greets them.

Visitor asks to book Botox. The bot confirms the service and, in the same breath, invites timing and any occasion — conversationally, not as a form.

"Saturday afternoon… it's for my wedding next month, and I'd love something subtle." The model acknowledges warmly and silently emits [SOFTCTX: preferred_time=…, occasion=…, note=…] (stripped from what the visitor sees).

Just name, phone, optional email + consent. The hard contact data stays a validated field — the soft context was already captured in chat.

Name, phone, email entered.

The heart of Flow B — now fully populated from the real captured context: Preferred time: Saturday afternoon, Occasion: wedding next month, Note: wants something subtle. Casual buttons: Sounds good! / Make changes (never "Confirm"). The lead is already saved by this point — the card isn't a gate.

Tap "Sounds good!" → friendly close. Walking away here still keeps the lead; only an explicit "don't contact me" removes it.
