@thewhatmatters/wmds 0.4.34 → 0.4.35

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 (191) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/components/molecules/CalEmbed/CalEmbed.d.ts +6 -6
  3. package/dist/components/molecules/CalEmbed/CalEmbed.d.ts.map +1 -1
  4. package/dist/components/molecules/CalEmbed/CalEmbed.js +20 -15
  5. package/dist/components/molecules/IntakeForm/IntakeHoneypot.d.ts +17 -0
  6. package/dist/components/molecules/IntakeForm/IntakeHoneypot.d.ts.map +1 -0
  7. package/dist/components/molecules/IntakeForm/IntakeHoneypot.js +29 -0
  8. package/dist/components/organisms/IntakeConfirmation/IntakeConfirmation.d.ts +14 -2
  9. package/dist/components/organisms/IntakeConfirmation/IntakeConfirmation.d.ts.map +1 -1
  10. package/dist/components/organisms/IntakeConfirmation/IntakeConfirmation.js +38 -33
  11. package/dist/components/organisms/IntakeConfirmation/intakeConfirmationStyles.d.ts +5 -1
  12. package/dist/components/organisms/IntakeConfirmation/intakeConfirmationStyles.d.ts.map +1 -1
  13. package/dist/components/organisms/IntakeConfirmation/intakeConfirmationStyles.js +3 -3
  14. package/dist/components/organisms/IntakeModal/IntakeModal.d.ts +11 -2
  15. package/dist/components/organisms/IntakeModal/IntakeModal.d.ts.map +1 -1
  16. package/dist/components/organisms/IntakeModal/IntakeModal.js +91 -59
  17. package/dist/components/organisms/IntakeModal/intakeModalStyles.d.ts +3 -3
  18. package/dist/components/organisms/IntakeModal/intakeModalStyles.d.ts.map +1 -1
  19. package/dist/components/organisms/IntakeModal/intakeModalStyles.js +1 -1
  20. package/dist/components/organisms/IntakeModal/useIntakeUrlState.d.ts +12 -0
  21. package/dist/components/organisms/IntakeModal/useIntakeUrlState.d.ts.map +1 -0
  22. package/dist/components/organisms/IntakeModal/useIntakeUrlState.js +16 -0
  23. package/dist/index.d.ts +3 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +82 -80
  26. package/dist/styles.css +1 -1
  27. package/docs/components.md +1 -1
  28. package/docs/exports.json +2 -2
  29. package/docs/patterns/components-accordion--flush.tsx +1 -1
  30. package/docs/patterns/components-appshell--portal-dashboard-pattern.tsx +1 -1
  31. package/docs/patterns/components-avatar--dropdown-row.tsx +1 -1
  32. package/docs/patterns/components-badge--outline-tags.tsx +1 -1
  33. package/docs/patterns/components-badge--status-pill.tsx +1 -1
  34. package/docs/patterns/components-badge--with-avatar.tsx +1 -1
  35. package/docs/patterns/components-band--page-in-bands.tsx +1 -1
  36. package/docs/patterns/components-breadcrumb--editorial.tsx +1 -1
  37. package/docs/patterns/components-breadcrumb--long-path.tsx +1 -1
  38. package/docs/patterns/components-breadcrumb--path.tsx +1 -1
  39. package/docs/patterns/components-breadcrumb--router-links.tsx +1 -1
  40. package/docs/patterns/components-button-button--copy-button.tsx +1 -1
  41. package/docs/patterns/components-button-button--destructive-action.tsx +1 -1
  42. package/docs/patterns/components-button-button--external-link.tsx +1 -1
  43. package/docs/patterns/components-button-button--ghost-action.tsx +1 -1
  44. package/docs/patterns/components-button-button--inverse-action.tsx +1 -1
  45. package/docs/patterns/components-button-button--link-render.tsx +1 -1
  46. package/docs/patterns/components-button-button--multi-state-badge.tsx +1 -1
  47. package/docs/patterns/components-button-button--outline-mono.tsx +1 -1
  48. package/docs/patterns/components-button-button--primary-action.tsx +1 -1
  49. package/docs/patterns/components-button-button--row-hug.tsx +1 -1
  50. package/docs/patterns/components-button-button--row-layout.tsx +1 -1
  51. package/docs/patterns/components-button-button--secondary-action.tsx +1 -1
  52. package/docs/patterns/components-button-button--suggestion-pills.tsx +1 -1
  53. package/docs/patterns/components-button-button--with-count.tsx +1 -1
  54. package/docs/patterns/components-button-button--with-icon.tsx +1 -1
  55. package/docs/patterns/components-button-floatingactionbutton--vertical-actions.tsx +1 -1
  56. package/docs/patterns/components-calembed--pattern-skip-above.tsx +16 -0
  57. package/docs/patterns/components-card-card--body-slot-occupancy-history.tsx +1 -1
  58. package/docs/patterns/components-card-card--headerless-media.tsx +1 -1
  59. package/docs/patterns/components-card-card--outlined-layout.tsx +1 -1
  60. package/docs/patterns/components-card-card--pinned-height.tsx +1 -1
  61. package/docs/patterns/components-card-card--terminal-frame.tsx +1 -1
  62. package/docs/patterns/components-card-selectablecard--selectable-cards-pattern.tsx +1 -1
  63. package/docs/patterns/components-carousel--image-carousel.tsx +1 -1
  64. package/docs/patterns/components-chart--audience-activity-heatmap.tsx +1 -1
  65. package/docs/patterns/components-chart--cartesian-no-data-gaps.tsx +1 -1
  66. package/docs/patterns/components-chart--occupancy-history-in-card.tsx +1 -1
  67. package/docs/patterns/components-chart--occupancy-in-card.tsx +1 -1
  68. package/docs/patterns/components-chart--post-reach-distribution.tsx +1 -1
  69. package/docs/patterns/components-chart--ranked-audience-breakdown.tsx +1 -1
  70. package/docs/patterns/components-chart--revenue-by-line.tsx +1 -1
  71. package/docs/patterns/components-chart--segmented-ring-pattern.tsx +1 -1
  72. package/docs/patterns/components-chart--unit-grid-composition.tsx +1 -1
  73. package/docs/patterns/components-chatdock--pattern-chat-dock.tsx +1 -1
  74. package/docs/patterns/components-chatdock--pattern-start-project-gate.tsx +1 -1
  75. package/docs/patterns/components-chatqa--pattern-qa-with-reply.tsx +1 -1
  76. package/docs/patterns/components-checkbox-checkbox--default.tsx +1 -1
  77. package/docs/patterns/components-checkbox-checkbox--with-count.tsx +1 -1
  78. package/docs/patterns/components-checkbox-checkbox--with-description.tsx +1 -1
  79. package/docs/patterns/components-checkbox-checkboxgroup--default.tsx +1 -1
  80. package/docs/patterns/components-checkbox-checkboxgroup--option-counts.tsx +1 -1
  81. package/docs/patterns/components-copyfield--clipboard-blocked.tsx +1 -1
  82. package/docs/patterns/components-copyfield--copied.tsx +1 -1
  83. package/docs/patterns/components-copyfield--copy-key.tsx +1 -1
  84. package/docs/patterns/components-copyfield--on-navy.tsx +1 -1
  85. package/docs/patterns/components-descriptionlist--details.tsx +1 -1
  86. package/docs/patterns/components-descriptionlist--post-metadata.tsx +1 -1
  87. package/docs/patterns/components-dialog--alert-dialog-destructive.tsx +1 -1
  88. package/docs/patterns/components-dialog--alert-dialog-typed-confirmation.tsx +1 -1
  89. package/docs/patterns/components-dialog--default-dialog.tsx +1 -1
  90. package/docs/patterns/components-dialog--form-dialog.tsx +1 -1
  91. package/docs/patterns/components-displaycontrols--page-utilities.tsx +1 -1
  92. package/docs/patterns/components-displaycontrols--theme-switch.tsx +1 -1
  93. package/docs/patterns/components-errorsummary--contact-form.tsx +1 -1
  94. package/docs/patterns/components-field--horizontal-input.tsx +1 -1
  95. package/docs/patterns/components-field--horizontal-text-area.tsx +1 -1
  96. package/docs/patterns/components-field--multi-control.tsx +1 -1
  97. package/docs/patterns/components-filterpanel--panel.tsx +1 -1
  98. package/docs/patterns/components-footerreveal--marketing-hero-pattern.tsx +1 -1
  99. package/docs/patterns/components-footerreveal--marketing-hero-ruled-pattern.tsx +1 -1
  100. package/docs/patterns/components-footerreveal--marketing-hero-with-gallery-intro.tsx +1 -1
  101. package/docs/patterns/components-footerreveal--marketing-page-pattern.tsx +1 -1
  102. package/docs/patterns/components-footerreveal--ruled-grid-footer-pattern.tsx +1 -1
  103. package/docs/patterns/components-footerreveal--sequenced-marketing-hero.tsx +1 -1
  104. package/docs/patterns/components-herointro--two-line-intro.tsx +1 -1
  105. package/docs/patterns/components-herointro--with-actions.tsx +1 -1
  106. package/docs/patterns/components-herotilestack--marketing-hero-pattern.tsx +1 -1
  107. package/docs/patterns/components-herotilestack--marketing-hero-text-sequence.tsx +1 -1
  108. package/docs/patterns/components-herotilestack--marketing-hero-with-gallery-intro.tsx +1 -1
  109. package/docs/patterns/components-indexlist--post-index.tsx +1 -1
  110. package/docs/patterns/components-intakeconfirmation--booked-pattern.tsx +1 -1
  111. package/docs/patterns/components-intakeconfirmation--emailed-pattern.tsx +8 -2
  112. package/docs/patterns/components-intakeform--about-you-pattern.tsx +1 -1
  113. package/docs/patterns/components-intakeform--short-form-pattern.tsx +1 -1
  114. package/docs/patterns/components-intakemodal--intake-modal-pattern.tsx +2 -2
  115. package/docs/patterns/components-kbd--command-row.tsx +1 -1
  116. package/docs/patterns/components-kbd--numbered-choices.tsx +1 -1
  117. package/docs/patterns/components-kbd--shortcut.tsx +1 -1
  118. package/docs/patterns/components-linktile--resource-tile.tsx +1 -1
  119. package/docs/patterns/components-linktile--router-link.tsx +1 -1
  120. package/docs/patterns/components-logview--detail-pane.tsx +1 -1
  121. package/docs/patterns/components-logview--log-viewer.tsx +1 -1
  122. package/docs/patterns/components-moremenu--action-menu.tsx +1 -1
  123. package/docs/patterns/components-moremenu--in-card-header.tsx +1 -1
  124. package/docs/patterns/components-navlist--app-sidebar.tsx +1 -1
  125. package/docs/patterns/components-navlist--side-nav-settings.tsx +1 -1
  126. package/docs/patterns/components-pageheader--app-header-pattern.tsx +1 -1
  127. package/docs/patterns/components-pageheader--page-section-header.tsx +1 -1
  128. package/docs/patterns/components-pageheader--toolbar-header.tsx +1 -1
  129. package/docs/patterns/components-panel--end-detail-rail.tsx +1 -1
  130. package/docs/patterns/components-pillgroup--pill-group-pattern.tsx +1 -1
  131. package/docs/patterns/components-promptbar--pattern-prompt-bar.tsx +1 -1
  132. package/docs/patterns/components-prose--article-body.tsx +1 -1
  133. package/docs/patterns/components-radio-radiogroup--default.tsx +1 -1
  134. package/docs/patterns/components-scrollhorizontal--project-gallery-pattern.tsx +1 -1
  135. package/docs/patterns/components-scrollhorizontal--with-intro.tsx +1 -1
  136. package/docs/patterns/components-sectioncaption--column-caption.tsx +1 -1
  137. package/docs/patterns/components-sectioncaption--with-action.tsx +1 -1
  138. package/docs/patterns/components-sheet--bottom-sheet.tsx +1 -1
  139. package/docs/patterns/components-sheet--end-sheet.tsx +1 -1
  140. package/docs/patterns/components-sheet--side-sheet-header-actions.tsx +1 -1
  141. package/docs/patterns/components-sheet--side-sheet-url-deep-link.tsx +1 -1
  142. package/docs/patterns/components-sheet--side-sheet.tsx +1 -1
  143. package/docs/patterns/components-sitenav--brand-and-cta.tsx +1 -1
  144. package/docs/patterns/components-sitenav--centered-links.tsx +1 -1
  145. package/docs/patterns/components-sitenav--compact.tsx +1 -1
  146. package/docs/patterns/components-sitenav--marketing-header.tsx +1 -1
  147. package/docs/patterns/components-sitenav--mega-menu.tsx +1 -1
  148. package/docs/patterns/components-stat--hero-stat.tsx +1 -1
  149. package/docs/patterns/components-stat--insights-row.tsx +1 -1
  150. package/docs/patterns/components-stepprogress--step-progress-pattern.tsx +1 -1
  151. package/docs/patterns/components-switch--default.tsx +1 -1
  152. package/docs/patterns/components-switch--settings-row.tsx +1 -1
  153. package/docs/patterns/components-tab--settings-pages.tsx +1 -1
  154. package/docs/patterns/components-table--approvals-with-sheet.tsx +1 -1
  155. package/docs/patterns/components-table--approvals.tsx +1 -1
  156. package/docs/patterns/components-table--basic.tsx +1 -1
  157. package/docs/patterns/components-taskrows--action-details.tsx +1 -1
  158. package/docs/patterns/components-taskrows--capsules.tsx +1 -1
  159. package/docs/patterns/components-taskrows--card-with-status-rows.tsx +1 -1
  160. package/docs/patterns/components-taskrows--controlled-expand.tsx +1 -1
  161. package/docs/patterns/components-taskrows--custom-slots.tsx +1 -1
  162. package/docs/patterns/components-taskrows--needs-you-table.tsx +1 -1
  163. package/docs/patterns/components-taskrows--status-list.tsx +1 -1
  164. package/docs/patterns/components-taskrows--tag-chips.tsx +1 -1
  165. package/docs/patterns/components-textarea--save-status.tsx +1 -1
  166. package/docs/patterns/components-textlink--external-destination.tsx +1 -1
  167. package/docs/patterns/components-textlink--inline-prose.tsx +1 -1
  168. package/docs/patterns/components-textlink--quiet-title.tsx +1 -1
  169. package/docs/patterns/components-textlink--supporting-copy.tsx +1 -1
  170. package/docs/patterns/components-textsequence--default.tsx +1 -1
  171. package/docs/patterns/components-textsequence--reduced-motion.tsx +1 -1
  172. package/docs/patterns/components-textsequence--shapes.tsx +1 -1
  173. package/docs/patterns/components-tilegrid--masonry.tsx +1 -1
  174. package/docs/patterns/components-toast--stacked-notifications.tsx +1 -1
  175. package/docs/patterns/components-tooltip--controlled.tsx +1 -1
  176. package/docs/patterns/components-tooltip--disabled-control.tsx +1 -1
  177. package/docs/patterns/components-tooltip--icon-action.tsx +1 -1
  178. package/docs/patterns/components-tooltip--keyboard-shortcut.tsx +1 -1
  179. package/docs/patterns/components-tooltip--placement.tsx +1 -1
  180. package/docs/patterns/foundations-scroll-fade--horizontal-rail.tsx +1 -1
  181. package/docs/patterns/foundations-scroll-fade--overflowing-list.tsx +1 -1
  182. package/docs/patterns/guides-chart-explorations--comparison-gallery.tsx +1 -1
  183. package/docs/patterns/guides-filter-panel--filtered-grid.tsx +1 -1
  184. package/docs/patterns/guides-filter-panel--filtered-index.tsx +1 -1
  185. package/docs/patterns/guides-overlay-flows--notification-preferences.tsx +1 -1
  186. package/docs/patterns/guides-post-page--post-page.tsx +1 -1
  187. package/docs/patterns/guides-profile-typography--editorial-profile.tsx +1 -1
  188. package/docs/patterns/guides-resource-detail--detail.tsx +1 -1
  189. package/docs/patterns/index.json +5 -5
  190. package/package.json +1 -1
  191. package/docs/patterns/components-calembed--pattern-skip-in-footer.tsx +0 -25
package/CHANGELOG.md CHANGED
@@ -7,6 +7,30 @@ Every release of `@thewhatmatters/wmds` is listed here, newest first.
7
7
  - **Pasted patterns:** when a release changes a **Pattern — …** story's Show code, it is named under Consumer actions so apps re-copy it.
8
8
  - **How to add an entry** (contributors): add your change to the top entry. If that version is already on npm (`npm view @thewhatmatters/wmds versions`), start a new entry above it and bump `version` in `package.json` to match. `npm run check:changelog` enforces the format.
9
9
 
10
+ ## 0.4.35
11
+
12
+ **Contact and booking forms: two steps, booking after the request, a way out above the calendar, and nothing lost on close.**
13
+
14
+ - **IntakeModal** (Contact and booking forms T7, T9):
15
+ - Two steps by default (`steps` was 4): details, then the optional booking. The confirmation isn't counted.
16
+ - New `hasAnswers`: with typed answers, Close and Escape ask "Discard your answers?" (Keep editing, focused / Discard).
17
+ - New **useIntakeUrlState**: keeps `?sketch` in the URL while the modal is open. The link can be shared, a refresh reopens it, and Back closes it.
18
+ - **CalEmbed** (T8): the "Skip, just email me" link sits **above** the calendar, so on a phone it's visible without scrolling past the month. With no embed (not set up, or it failed), the email route shows inside the empty state straight away.
19
+ - **CalEmbed stories:** "Pattern — skip in footer" is replaced by **Pattern — skip above the calendar** (`CalEmbed.Skip` in `Card.Header`). The pasted pattern id changes, so `wmds-check` reports `pattern-removed` for copies of the old one: move the skip above the calendar.
20
+ - **IntakeConfirmation** (T2, T3): one "what happens next and when" sentence: `email` and `replyWithin` (default "within one business day") give "We'll email you at {email} within one business day with a few times that fit."; the booked variant names `bookingTime` in it. `summary` shows as "You told us: “…”". Then `contact`, then Done. New export `intakeConfirmationReplyWithin`.
21
+ - **IntakeModal**: no Back on step 1; the WM mark and wordmark take the ink in dark mode (navy on near-black failed 3:1).
22
+ - **IntakeHoneypot** and `isIntakeHoneypotFilled` (new, T4): a spam trap people never see or reach (`aria-hidden`, `tabindex="-1"`, no autofill). Drop requests where it's filled, on the server, with rate limits. No CAPTCHA.
23
+ - Stories **Components/IntakeModal → Pattern — sketch request** (details → optional booking → confirmation; "Send my request"; reply time under the form; contact details on the confirmation) and **Pattern — send failed** (answers kept, Try again, email route; T5, T6). Interaction tests cover the URL, the discard question, both steps, Back keeping answers, the skip above the calendar, the failure and the honeypot.
24
+
25
+ ### Consumer actions
26
+
27
+ - Pass `steps={2}` or drop `steps`, and move the booking after the details are sent.
28
+ - Pass `hasAnswers` while the visitor has typed something, and keep answers in your state.
29
+ - Open the modal with `useIntakeUrlState`, and give the form its own page too (see wmds-patterns Contact — Sketch Page).
30
+ - Add **IntakeHoneypot** and check it on the server.
31
+ - On the confirmation, pass `summary` and `contact`. Pass `email` so the sentence names it, and change `replyWithin` if one business day isn't true for you.
32
+ - If you placed `CalEmbed.Skip` after the calendar (for example in `Card.Footer`), move it to `Card.Header`, above the calendar.
33
+
10
34
  ## 0.4.34
11
35
 
12
36
  **Required and optional fields: mark the exception, read the badge with the field, never on autofill. Field width and form layout: widths that hint at the answer, a State select, side labels only on wide screens, and counters that don't cut text. Dropdowns, radios and checkboxes: a native Select for forms, bigger boxes with visible borders, and errors on Continue.**
@@ -4,7 +4,7 @@ export type CalEmbedLayoutClassName = string;
4
4
  export declare const calEmbedSkipHref = "#email";
5
5
  export declare const calEmbedSkipLabel = "Skip, just email me";
6
6
  export declare const calEmbedEmptyTitle = "Booking isn\u2019t available right now";
7
- export declare const calEmbedEmptyDescription = "Skip this step and we\u2019ll follow up by email.";
7
+ export declare const calEmbedEmptyDescription = "We\u2019ll follow up by email with a few times instead.";
8
8
  export interface CalEmbedSkipProps {
9
9
  /** Skip destination. Default `#email`. */
10
10
  skipHref?: string;
@@ -26,10 +26,10 @@ export interface CalEmbedProps {
26
26
  /** Empty-state supporting line. Default points visitors at the skip. */
27
27
  emptyDescription?: ReactNode;
28
28
  /**
29
- * Skip slot. Omit to render the default **TextLink** after the frame.
30
- * Pass `false` or **CalEmbed.Skip** when you place the skip yourself
31
- * (typically **Card.Footer**). CalEmbed does not render an in-body skip
32
- * when this slot is used.
29
+ * Skip slot. Omit to render the default **TextLink** above the frame (or inside the empty state).
30
+ * Pass `false` or **CalEmbed.Skip** when you place the skip yourself. Keep it visible without
31
+ * scrolling past the calendar at 390 (T8): above the frame or in a pinned footer, not after a month
32
+ * grid. CalEmbed does not render an in-body skip when this slot is used.
33
33
  */
34
34
  skip?: ReactNode | false;
35
35
  /** Skip destination when the in-body skip is shown. Default `#email`. */
@@ -41,7 +41,7 @@ export interface CalEmbedProps {
41
41
  className?: CalEmbedLayoutClassName;
42
42
  }
43
43
  /**
44
- * Same **TextLink** CalEmbed uses after the frame. Place it in **Card.Footer**
44
+ * Same **TextLink** CalEmbed uses above the frame. Place it in **Card.Header** (above the calendar, T8)
45
45
  * and pass `skip={false}` (or `skip={<CalEmbed.Skip />}`) so the in-body link is omitted.
46
46
  */
47
47
  export declare function CalEmbedSkip({ skipHref, skipLabel, onSkip, className, }: CalEmbedSkipProps): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"CalEmbed.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/CalEmbed/CalEmbed.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,OAAO,CAAC;AAUnD,qCAAqC;AACrC,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE7C,eAAO,MAAM,gBAAgB,WAAW,CAAC;AACzC,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AACvD,eAAO,MAAM,kBAAkB,2CAAsC,CAAC;AACtE,eAAO,MAAM,wBAAwB,sDAAiD,CAAC;AAEvF,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,uBAAuB,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iGAAiG;IACjG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,uBAAuB,CAAC;CACrC;AAcD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAA2B,EAC3B,SAA6B,EAC7B,MAAM,EACN,SAAS,GACV,EAAE,iBAAiB,+BAWnB;AAED;;;;GAIG;AACH,iBAAS,YAAY,CAAC,EACpB,QAAQ,EACR,UAA+B,EAC/B,gBAA2C,EAC3C,IAAI,EACJ,QAA2B,EAC3B,SAA6B,EAC7B,MAAM,EACN,SAAS,GACV,EAAE,aAAa,+BAkBf;AAED,eAAO,MAAM,QAAQ;;CAEnB,CAAC"}
1
+ {"version":3,"file":"CalEmbed.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/CalEmbed/CalEmbed.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,OAAO,CAAC;AAUnD,qCAAqC;AACrC,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE7C,eAAO,MAAM,gBAAgB,WAAW,CAAC;AACzC,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AACvD,eAAO,MAAM,kBAAkB,2CAAsC,CAAC;AACtE,eAAO,MAAM,wBAAwB,4DAAuD,CAAC;AAE7F,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,uBAAuB,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iGAAiG;IACjG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,uBAAuB,CAAC;CACrC;AAcD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAA2B,EAC3B,SAA6B,EAC7B,MAAM,EACN,SAAS,GACV,EAAE,iBAAiB,+BAWnB;AAED;;;;GAIG;AACH,iBAAS,YAAY,CAAC,EACpB,QAAQ,EACR,UAA+B,EAC/B,gBAA2C,EAC3C,IAAI,EACJ,QAA2B,EAC3B,SAA6B,EAC7B,MAAM,EACN,SAAS,GACV,EAAE,aAAa,+BAsBf;AAED,eAAO,MAAM,QAAQ;;CAEnB,CAAC"}
@@ -5,7 +5,7 @@ import { TextLink as n } from "../../atoms/TextLink/TextLink.js";
5
5
  import { calEmbedClasses as r, calEmbedEmptyClasses as i, calEmbedFrameClasses as a } from "./calEmbedStyles.js";
6
6
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
7
7
  //#region src/components/molecules/CalEmbed/CalEmbed.tsx
8
- var c = "#email", l = "Skip, just email me", u = "Booking isn’t available right now", d = "Skip this step and we’ll follow up by email.";
8
+ var c = "#email", l = "Skip, just email me", u = "Booking isn’t available right now", d = "We’ll follow up by email with a few times instead.";
9
9
  function f(e) {
10
10
  return e != null && e !== !1 && e !== "";
11
11
  }
@@ -22,27 +22,32 @@ function m({ skipHref: e = c, skipLabel: t = l, onSkip: r, className: i }) {
22
22
  });
23
23
  }
24
24
  function h({ children: n, emptyTitle: p = u, emptyDescription: h = d, skip: g, skipHref: _ = c, skipLabel: v = l, onSkip: y, className: b }) {
25
+ let x = f(n), S = g === void 0 ? /* @__PURE__ */ o(m, {
26
+ skipHref: _,
27
+ skipLabel: v,
28
+ onSkip: y
29
+ }) : null;
25
30
  return /* @__PURE__ */ s("div", {
26
31
  className: e(r, b),
27
32
  "data-cal-embed": "",
28
- children: [/* @__PURE__ */ o("div", {
33
+ children: [x ? S : null, /* @__PURE__ */ o("div", {
29
34
  className: a,
30
- children: f(n) ? n : /* @__PURE__ */ s("div", {
35
+ children: x ? n : /* @__PURE__ */ s("div", {
31
36
  className: i,
32
37
  "data-cal-embed-empty": "",
33
- children: [/* @__PURE__ */ o("p", {
34
- className: t("subheading"),
35
- children: p
36
- }), /* @__PURE__ */ o("p", {
37
- className: e(t("caption"), "text-muted"),
38
- children: h
39
- })]
38
+ children: [
39
+ /* @__PURE__ */ o("p", {
40
+ className: t("subheading"),
41
+ children: p
42
+ }),
43
+ /* @__PURE__ */ o("p", {
44
+ className: e(t("caption"), "text-muted"),
45
+ children: h
46
+ }),
47
+ S
48
+ ]
40
49
  })
41
- }), g === void 0 ? /* @__PURE__ */ o(m, {
42
- skipHref: _,
43
- skipLabel: v,
44
- onSkip: y
45
- }) : null]
50
+ })]
46
51
  });
47
52
  }
48
53
  var g = Object.assign(h, { Skip: m });
@@ -0,0 +1,17 @@
1
+ /** Props for **IntakeHoneypot**. */
2
+ export interface IntakeHoneypotProps {
3
+ /** Field name the server checks. Default `fax`: plausible to a bot, never a real question here. */
4
+ name?: string;
5
+ value: string;
6
+ onChange: (value: string) => void;
7
+ }
8
+ /**
9
+ * Contact and booking forms T4: spam checks without a puzzle. A field people never see or reach, hidden
10
+ * from screen readers too (`aria-hidden`, `tabindex="-1"`, no autofill), that bots fill in. Drop any
11
+ * request where it has a value, on the server, alongside rate limits and a time-to-submit check. Never
12
+ * a CAPTCHA.
13
+ */
14
+ export declare function IntakeHoneypot({ name, value, onChange }: IntakeHoneypotProps): import("react").JSX.Element;
15
+ /** True when the honeypot was filled: treat the request as spam (check this on the server too). */
16
+ export declare function isIntakeHoneypotFilled(value: string | null | undefined): boolean;
17
+ //# sourceMappingURL=IntakeHoneypot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IntakeHoneypot.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/IntakeForm/IntakeHoneypot.tsx"],"names":[],"mappings":"AAEA,oCAAoC;AACpC,MAAM,WAAW,mBAAmB;IAClC,mGAAmG;IACnG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,mBAAmB,+BAgBpF;AAED,mGAAmG;AACnG,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEhF"}
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { useId as e } from "react";
3
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
4
+ //#region src/components/molecules/IntakeForm/IntakeHoneypot.tsx
5
+ function r({ name: r = "fax", value: i, onChange: a }) {
6
+ let o = e();
7
+ return /* @__PURE__ */ n("div", {
8
+ "aria-hidden": "true",
9
+ className: "absolute -left-[9999px] size-px overflow-hidden",
10
+ "data-intake-honeypot": "",
11
+ children: [/* @__PURE__ */ t("label", {
12
+ htmlFor: o,
13
+ children: "Leave this empty"
14
+ }), /* @__PURE__ */ t("input", {
15
+ id: o,
16
+ name: r,
17
+ type: "text",
18
+ tabIndex: -1,
19
+ autoComplete: "off",
20
+ value: i,
21
+ onChange: (e) => a(e.target.value)
22
+ })]
23
+ });
24
+ }
25
+ function i(e) {
26
+ return (e ?? "").trim().length > 0;
27
+ }
28
+ //#endregion
29
+ export { r as IntakeHoneypot, i as isIntakeHoneypotFilled };
@@ -1,5 +1,6 @@
1
+ import type { ReactNode } from "react";
1
2
  import { type IntakeConfirmationVariant } from "./intakeConfirmationStyles";
2
- export { intakeConfirmationCopy, intakeConfirmationVariants, intakeConfettiColors, type IntakeConfirmationVariant, } from "./intakeConfirmationStyles";
3
+ export { intakeConfirmationCopy, intakeConfirmationReplyWithin, intakeConfirmationVariants, intakeConfettiColors, type IntakeConfirmationVariant, } from "./intakeConfirmationStyles";
3
4
  /** Layout-only — width or margin. */
4
5
  export type IntakeConfirmationLayoutClassName = string;
5
6
  export interface IntakeConfirmationProps {
@@ -21,6 +22,17 @@ export interface IntakeConfirmationProps {
21
22
  icsHref?: string;
22
23
  /** Label for the `.ics` action. Default `Download .ics`. */
23
24
  icsLabel?: string;
25
+ /** Where we'll reply (`emailed`): "We'll email you at {email} …". */
26
+ email?: string;
27
+ /**
28
+ * When we'll reply (Contact and booking forms T3), part of the one "what happens next" sentence. Default
29
+ * "within one business day". Never promise what you don't keep.
30
+ */
31
+ replyWithin?: string;
32
+ /** What we got: a short recap of their request, shown as "You told us: “…”" (e.g. "A new site before spring"). */
33
+ summary?: ReactNode;
34
+ /** How to reach us meanwhile: phone, email, hours (T1, T3). */
35
+ contact?: ReactNode;
24
36
  className?: IntakeConfirmationLayoutClassName;
25
37
  }
26
38
  /**
@@ -29,5 +41,5 @@ export interface IntakeConfirmationProps {
29
41
  * Optional booking actions reuse **TextLink** and **Button** — no new confirmation style.
30
42
  * Mount **ConfettiProvider** above this component.
31
43
  */
32
- export declare function IntakeConfirmation({ variant, onDone, bookingTime, videoHref, videoLabel, googleCalendarHref, googleCalendarLabel, icsHref, icsLabel, className, }: IntakeConfirmationProps): import("react").JSX.Element;
44
+ export declare function IntakeConfirmation({ variant, onDone, bookingTime, videoHref, videoLabel, googleCalendarHref, googleCalendarLabel, icsHref, icsLabel, email, replyWithin, summary, contact, className, }: IntakeConfirmationProps): import("react").JSX.Element;
33
45
  //# sourceMappingURL=IntakeConfirmation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IntakeConfirmation.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeConfirmation/IntakeConfirmation.tsx"],"names":[],"mappings":"AAOA,OAAO,EAQL,KAAK,yBAAyB,EAC/B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,sBAAsB,EACtB,0BAA0B,EAC1B,oBAAoB,EACpB,KAAK,yBAAyB,GAC/B,MAAM,4BAA4B,CAAC;AAEpC,qCAAqC;AACrC,MAAM,MAAM,iCAAiC,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,uBAAuB;IACtC,wEAAwE;IACxE,OAAO,EAAE,yBAAyB,CAAC;IACnC,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,iCAAiC,CAAC;CAC/C;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,MAAM,EACN,WAAW,EACX,SAAS,EACT,UAA8B,EAC9B,kBAAkB,EAClB,mBAA8C,EAC9C,OAAO,EACP,QAA0B,EAC1B,SAAS,GACV,EAAE,uBAAuB,+BA0DzB"}
1
+ {"version":3,"file":"IntakeConfirmation.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeConfirmation/IntakeConfirmation.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,OAAO,EASL,KAAK,yBAAyB,EAC/B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,0BAA0B,EAC1B,oBAAoB,EACpB,KAAK,yBAAyB,GAC/B,MAAM,4BAA4B,CAAC;AAEpC,qCAAqC;AACrC,MAAM,MAAM,iCAAiC,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,uBAAuB;IACtC,wEAAwE;IACxE,OAAO,EAAE,yBAAyB,CAAC;IACnC,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kHAAkH;IAClH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,iCAAiC,CAAC;CAC/C;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,MAAM,EACN,WAAW,EACX,SAAS,EACT,UAA8B,EAC9B,kBAAkB,EAClB,mBAA8C,EAC9C,OAAO,EACP,QAA0B,EAC1B,KAAK,EACL,WAA2C,EAC3C,OAAO,EACP,OAAO,EACP,SAAS,GACV,EAAE,uBAAuB,+BAmEzB"}
@@ -5,11 +5,11 @@ import { Badge as t } from "../../atoms/Badge/Badge.js";
5
5
  import { Button as n } from "../../atoms/Button/Button.js";
6
6
  import { TextLink as r } from "../../atoms/TextLink/TextLink.js";
7
7
  import { useConfettiOnMount as i } from "../Confetti/Confetti.js";
8
- import { intakeConfettiColors as a, intakeConfirmationActionsClasses as o, intakeConfirmationBodyClasses as s, intakeConfirmationClasses as c, intakeConfirmationCopy as l, intakeConfirmationMetaClasses as u, intakeConfirmationTitleClasses as d, intakeConfirmationVariants as f } from "./intakeConfirmationStyles.js";
9
- import { jsx as p, jsxs as m } from "react/jsx-runtime";
8
+ import { intakeConfettiColors as a, intakeConfirmationActionsClasses as o, intakeConfirmationBodyClasses as s, intakeConfirmationClasses as c, intakeConfirmationCopy as l, intakeConfirmationMetaClasses as u, intakeConfirmationReplyWithin as d, intakeConfirmationTitleClasses as f, intakeConfirmationVariants as p } from "./intakeConfirmationStyles.js";
9
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
10
10
  //#region src/components/organisms/IntakeConfirmation/IntakeConfirmation.tsx
11
- function h({ variant: f, onDone: h, bookingTime: g, videoHref: _, videoLabel: v = "Join video call", googleCalendarHref: y, googleCalendarLabel: b = "Add to Google Calendar", icsHref: x, icsLabel: S = "Download .ics", className: C }) {
12
- let w = l[f], T = g != null || _ != null || y != null || x != null;
11
+ function g({ variant: p, onDone: g, bookingTime: _, videoHref: v, videoLabel: y = "Join video call", googleCalendarHref: b, googleCalendarLabel: x = "Add to Google Calendar", icsHref: S, icsLabel: C = "Download .ics", email: w, replyWithin: T = d, summary: E, contact: D, className: O }) {
12
+ let k = l[p], A = p === "emailed" ? `We'll email you${w ? ` at ${w}` : ""} ${T} with a few times that fit.` : _ == null ? k.body : `We'll see you on ${_}, and we'll email a short note before so you know what to bring.`, j = v != null || b != null || S != null;
13
13
  return i({
14
14
  particleCount: 90,
15
15
  spread: 180,
@@ -19,59 +19,64 @@ function h({ variant: f, onDone: h, bookingTime: g, videoHref: _, videoLabel: v
19
19
  x: typeof window > "u" ? 0 : window.innerWidth / 2,
20
20
  y: 0
21
21
  }
22
- }), /* @__PURE__ */ m("div", {
23
- className: e(c, C),
24
- "data-intake-confirmation": f,
22
+ }), /* @__PURE__ */ h("div", {
23
+ className: e(c, O),
24
+ "data-intake-confirmation": p,
25
25
  children: [
26
- /* @__PURE__ */ p(t, {
27
- variant: f === "booked" ? "neutral" : "info",
26
+ /* @__PURE__ */ m(t, {
27
+ variant: p === "booked" ? "neutral" : "info",
28
28
  emphasis: "muted",
29
- children: w.badge
29
+ children: k.badge
30
30
  }),
31
- /* @__PURE__ */ p("h2", {
32
- className: d,
33
- children: w.title
31
+ /* @__PURE__ */ m("h2", {
32
+ className: f,
33
+ children: k.title
34
34
  }),
35
- /* @__PURE__ */ p("p", {
35
+ /* @__PURE__ */ m("p", {
36
36
  className: s,
37
- children: w.body
37
+ children: A
38
38
  }),
39
- T ? /* @__PURE__ */ m("div", {
39
+ E == null ? null : /* @__PURE__ */ h("p", {
40
+ className: u,
41
+ "data-intake-summary": "",
42
+ children: ["You told us: ", /* @__PURE__ */ m("q", { children: E })]
43
+ }),
44
+ j ? /* @__PURE__ */ h("div", {
40
45
  className: o,
41
46
  children: [
42
- g == null ? null : /* @__PURE__ */ p("p", {
43
- className: u,
44
- children: g
45
- }),
46
- _ == null ? null : /* @__PURE__ */ p(r, {
47
- href: _,
47
+ v == null ? null : /* @__PURE__ */ m(r, {
48
+ href: v,
48
49
  external: !0,
49
- children: v
50
+ children: y
50
51
  }),
51
- y == null ? null : /* @__PURE__ */ p(r, {
52
- href: y,
52
+ b == null ? null : /* @__PURE__ */ m(r, {
53
+ href: b,
53
54
  external: !0,
54
- children: b
55
+ children: x
55
56
  }),
56
- x == null ? null : /* @__PURE__ */ p(n, {
57
+ S == null ? null : /* @__PURE__ */ m(n, {
57
58
  role: "secondary",
58
59
  size: "md",
59
- render: /* @__PURE__ */ p("a", {
60
- href: x,
60
+ render: /* @__PURE__ */ m("a", {
61
+ href: S,
61
62
  download: !0
62
63
  }),
63
- children: S
64
+ children: C
64
65
  })
65
66
  ]
66
67
  }) : null,
67
- h == null ? null : /* @__PURE__ */ p(n, {
68
+ D == null ? null : /* @__PURE__ */ m("div", {
69
+ className: u,
70
+ children: D
71
+ }),
72
+ g == null ? null : /* @__PURE__ */ m(n, {
68
73
  role: "primary",
69
74
  type: "button",
70
- onClick: h,
75
+ onClick: g,
71
76
  children: "Done"
72
77
  })
73
78
  ]
74
79
  });
75
80
  }
76
81
  //#endregion
77
- export { h as IntakeConfirmation, a as intakeConfettiColors, l as intakeConfirmationCopy, f as intakeConfirmationVariants };
82
+ export { g as IntakeConfirmation, a as intakeConfettiColors, l as intakeConfirmationCopy, d as intakeConfirmationReplyWithin, p as intakeConfirmationVariants };
@@ -5,11 +5,15 @@
5
5
  export declare const intakeConfettiColors: readonly ["var(--color-brand)", "var(--color-brand-soft)", "var(--color-primary)", "var(--color-info-muted)", "var(--color-accent)", "var(--color-chart-categorical-1)", "var(--color-chart-categorical-4)"];
6
6
  export declare const intakeConfirmationVariants: readonly ["booked", "emailed"];
7
7
  export type IntakeConfirmationVariant = (typeof intakeConfirmationVariants)[number];
8
+ /** T2, T3: when the reply comes. Keep it true for your team. */
9
+ /** When we reply, inside the confirmation's one "what happens next" sentence (T3). */
10
+ export declare const intakeConfirmationReplyWithin = "within one business day";
8
11
  export declare const intakeConfirmationCopy: Record<IntakeConfirmationVariant, {
9
12
  badge: string;
10
13
  title: string;
11
14
  body: string;
12
15
  }>;
16
+ /** Left on phones, where the next-step sentence with an email runs 3 lines; centred from md (Headings H8). */
13
17
  export declare const intakeConfirmationClasses: string;
14
18
  /** Existing display-2 — the confirmation headline, larger than the step titles. */
15
19
  export declare const intakeConfirmationTitleClasses = "type-display-2 text-balance text-fg";
@@ -19,5 +23,5 @@ export declare const intakeConfirmationBodyClasses = "type-large max-w-2xl text-
19
23
  /** Booked time under the body — supporting muted type. */
20
24
  export declare const intakeConfirmationMetaClasses = "type-body text-balance text-muted";
21
25
  /** Optional booking actions — **TextLink** / **Button** stack, same center column. */
22
- export declare const intakeConfirmationActionsClasses = "flex w-full max-w-md flex-col items-center gap-3";
26
+ export declare const intakeConfirmationActionsClasses = "flex w-full max-w-md flex-col items-start gap-3 md:items-center";
23
27
  //# sourceMappingURL=intakeConfirmationStyles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"intakeConfirmationStyles.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeConfirmation/intakeConfirmationStyles.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,8MAQvB,CAAC;AAEX,eAAO,MAAM,0BAA0B,gCAAiC,CAAC;AAEzE,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpF,eAAO,MAAM,sBAAsB,EAAE,MAAM,CACzC,yBAAyB,EACzB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAY/C,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAErC,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,8BAA8B,wCAAwC,CAAC;AAEpF,yEAAyE;AACzE,6EAA6E;AAC7E,eAAO,MAAM,6BAA6B,8CAA8C,CAAC;AAEzF,0DAA0D;AAC1D,eAAO,MAAM,6BAA6B,sCAAsC,CAAC;AAEjF,sFAAsF;AACtF,eAAO,MAAM,gCAAgC,qDACO,CAAC"}
1
+ {"version":3,"file":"intakeConfirmationStyles.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeConfirmation/intakeConfirmationStyles.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,8MAQvB,CAAC;AAEX,eAAO,MAAM,0BAA0B,gCAAiC,CAAC;AAEzE,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpF,gEAAgE;AAChE,sFAAsF;AACtF,eAAO,MAAM,6BAA6B,4BAA4B,CAAC;AAEvE,eAAO,MAAM,sBAAsB,EAAE,MAAM,CACzC,yBAAyB,EACzB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAY/C,CAAC;AAEF,8GAA8G;AAC9G,eAAO,MAAM,yBAAyB,QAErC,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,8BAA8B,wCAAwC,CAAC;AAEpF,yEAAyE;AACzE,6EAA6E;AAC7E,eAAO,MAAM,6BAA6B,8CAA8C,CAAC;AAEzF,0DAA0D;AAC1D,eAAO,MAAM,6BAA6B,sCAAsC,CAAC;AAEjF,sFAAsF;AACtF,eAAO,MAAM,gCAAgC,oEACsB,CAAC"}
@@ -9,7 +9,7 @@ var t = [
9
9
  "var(--color-accent)",
10
10
  "var(--color-chart-categorical-1)",
11
11
  "var(--color-chart-categorical-4)"
12
- ], n = ["booked", "emailed"], r = {
12
+ ], n = ["booked", "emailed"], r = "within one business day", i = {
13
13
  booked: {
14
14
  badge: "Booked",
15
15
  title: "You're booked",
@@ -20,6 +20,6 @@ var t = [
20
20
  title: "We'll be in touch",
21
21
  body: "No calendar needed. We'll reply by email with a few times that fit."
22
22
  }
23
- }, i = e("flex w-full max-w-3xl flex-col items-center gap-8 text-center"), a = "type-display-2 text-balance text-fg", o = "type-large max-w-2xl text-balance text-fg", s = "type-body text-balance text-muted", c = "flex w-full max-w-md flex-col items-center gap-3";
23
+ }, a = e("flex w-full max-w-3xl flex-col items-start gap-8 text-left md:items-center md:text-center"), o = "type-display-2 text-balance text-fg", s = "type-large max-w-2xl text-balance text-fg", c = "type-body text-balance text-muted", l = "flex w-full max-w-md flex-col items-start gap-3 md:items-center";
24
24
  //#endregion
25
- export { t as intakeConfettiColors, c as intakeConfirmationActionsClasses, o as intakeConfirmationBodyClasses, i as intakeConfirmationClasses, r as intakeConfirmationCopy, s as intakeConfirmationMetaClasses, a as intakeConfirmationTitleClasses, n as intakeConfirmationVariants };
25
+ export { t as intakeConfettiColors, l as intakeConfirmationActionsClasses, s as intakeConfirmationBodyClasses, a as intakeConfirmationClasses, i as intakeConfirmationCopy, c as intakeConfirmationMetaClasses, r as intakeConfirmationReplyWithin, o as intakeConfirmationTitleClasses, n as intakeConfirmationVariants };
@@ -6,7 +6,10 @@ export interface IntakeModalProps {
6
6
  onOpenChange: (open: boolean) => void;
7
7
  /** Current step, 1-based. Shown when `showProgress` is set. */
8
8
  step?: number;
9
- /** Segment count. Default 4. */
9
+ /**
10
+ * Segment count. Default 2: details, then the optional booking; the confirmation isn't counted
11
+ * (Contact and booking forms T7: at most 3 steps, and only when a later step depends on earlier ones).
12
+ */
10
13
  steps?: number;
11
14
  /** Accessible name. Default `Start a project`. */
12
15
  title?: string;
@@ -29,6 +32,12 @@ export interface IntakeModalProps {
29
32
  * (the Close button still closes). Default `true`.
30
33
  */
31
34
  dismissOnEscape?: boolean;
35
+ /**
36
+ * The visitor has typed answers. Close and Escape then ask "Discard your answers?" before closing
37
+ * (Contact and booking forms T9). Keep the answers in the caller's state, so an accidental close
38
+ * that's undone, or reopening, finds them still there.
39
+ */
40
+ hasAnswers?: boolean;
32
41
  children?: ReactNode;
33
42
  className?: IntakeModalLayoutClassName;
34
43
  }
@@ -37,5 +46,5 @@ export interface IntakeModalProps {
37
46
  * Wordmark, close, step progress, and a pinned footer.
38
47
  * Focus trap, Escape, scroll lock, and `aria-modal`.
39
48
  */
40
- export declare function IntakeModal({ open, onOpenChange, step, steps, title, showProgress, hideFooter, hideContinue, onBack, onContinue, backDisabled, continueDisabled, continueLabel, dismissOnEscape, children, className, }: IntakeModalProps): import("react").ReactPortal | null;
49
+ export declare function IntakeModal({ open, onOpenChange, step, steps, title, showProgress, hideFooter, hideContinue, onBack, onContinue, backDisabled, continueDisabled, continueLabel, dismissOnEscape, hasAnswers, children, className, }: IntakeModalProps): import("react").ReactPortal | null;
41
50
  //# sourceMappingURL=IntakeModal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IntakeModal.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeModal/IntakeModal.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAuBnE,wDAAwD;AACxD,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qFAAqF;IACrF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,0BAA0B,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,YAAY,EACZ,IAAQ,EACR,KAAS,EACT,KAAyB,EACzB,YAAmB,EACnB,UAAkB,EAClB,YAAoB,EACpB,MAAM,EACN,UAAU,EACV,YAAoB,EACpB,gBAAwB,EACxB,aAA0B,EAC1B,eAAsB,EACtB,QAAQ,EACR,SAAS,GACV,EAAE,gBAAgB,sCA8FlB"}
1
+ {"version":3,"file":"IntakeModal.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeModal/IntakeModal.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAwBxF,wDAAwD;AACxD,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qFAAqF;IACrF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,0BAA0B,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,YAAY,EACZ,IAAQ,EACR,KAAS,EACT,KAAyB,EACzB,YAAmB,EACnB,UAAkB,EAClB,YAAoB,EACpB,MAAM,EACN,UAAU,EACV,YAAoB,EACpB,gBAAwB,EACxB,aAA0B,EAC1B,eAAsB,EACtB,UAAkB,EAClB,QAAQ,EACR,SAAS,GACV,EAAE,gBAAgB,sCAqIlB"}
@@ -1,96 +1,128 @@
1
1
  "use client";
2
2
  "use client";
3
3
  import { cn as e } from "../../../lib/cn.js";
4
- import { motionTransitionProp as t } from "../../../lib/motion.js";
5
- import { Button as n } from "../../atoms/Button/Button.js";
6
- import { IconButton as r } from "../../atoms/IconButton/IconButton.js";
7
- import { StepProgress as i } from "../../molecules/StepProgress/StepProgress.js";
8
- import { useOverlayLifecycle as a } from "../../../lib/dialogOverlay.js";
9
- import { intakeModalBodyClasses as o, intakeModalBrandClasses as s, intakeModalCenteredContentClasses as c, intakeModalContentClasses as l, intakeModalFooterClasses as u, intakeModalHeaderClasses as d, intakeModalMarkClasses as f, intakeModalProgressClasses as p, intakeModalRootClasses as m, intakeModalWordmarkClasses as h } from "./intakeModalStyles.js";
10
- import { useCallback as g, useId as _, useRef as v } from "react";
11
- import { X as y } from "lucide-react";
12
- import { jsx as b, jsxs as x } from "react/jsx-runtime";
13
- import { AnimatePresence as S, motion as C } from "motion/react";
14
- import { createPortal as w } from "react-dom";
4
+ import { typographyClass as t } from "../../../lib/typography.js";
5
+ import { motionTransitionProp as n } from "../../../lib/motion.js";
6
+ import { Button as r } from "../../atoms/Button/Button.js";
7
+ import { IconButton as i } from "../../atoms/IconButton/IconButton.js";
8
+ import { StepProgress as a } from "../../molecules/StepProgress/StepProgress.js";
9
+ import { useOverlayLifecycle as o } from "../../../lib/dialogOverlay.js";
10
+ import { intakeModalBodyClasses as s, intakeModalBrandClasses as c, intakeModalCenteredContentClasses as l, intakeModalContentClasses as u, intakeModalFooterClasses as d, intakeModalHeaderClasses as f, intakeModalMarkClasses as p, intakeModalProgressClasses as m, intakeModalRootClasses as h, intakeModalWordmarkClasses as g } from "./intakeModalStyles.js";
11
+ import { useCallback as _, useEffect as v, useId as y, useRef as b, useState as x } from "react";
12
+ import { X as S } from "lucide-react";
13
+ import { jsx as C, jsxs as w } from "react/jsx-runtime";
14
+ import { AnimatePresence as T, motion as E } from "motion/react";
15
+ import { createPortal as D } from "react-dom";
15
16
  //#region src/components/organisms/IntakeModal/IntakeModal.tsx
16
- function T({ open: T, onOpenChange: E, step: D = 1, steps: O = 4, title: k = "Start a project", showProgress: A = !0, hideFooter: j = !1, hideContinue: M = !1, onBack: N, onContinue: P, backDisabled: F = !1, continueDisabled: I = !1, continueLabel: L = "Continue", dismissOnEscape: R = !0, children: z, className: B }) {
17
- let V = _(), H = v(null), U = g(() => {
18
- E(!1);
19
- }, [E]);
20
- return a(H, {
21
- open: T,
22
- onClose: U,
23
- closeOnEscape: R,
17
+ function O({ open: O, onOpenChange: k, step: A = 1, steps: j = 2, title: M = "Start a project", showProgress: N = !0, hideFooter: P = !1, hideContinue: F = !1, onBack: I, onContinue: L, backDisabled: R = !1, continueDisabled: z = !1, continueLabel: B = "Continue", dismissOnEscape: V = !0, hasAnswers: H = !1, children: U, className: W }) {
18
+ let G = y(), K = b(null), q = y(), J = b(null), [Y, X] = x(!1), Z = _(() => {
19
+ X(!1), k(!1);
20
+ }, [k]), Q = _(() => {
21
+ H ? X(!0) : Z();
22
+ }, [H, Z]);
23
+ return v(() => {
24
+ Y && J.current?.focus();
25
+ }, [Y]), v(() => {
26
+ O || X(!1);
27
+ }, [O]), o(K, {
28
+ open: O,
29
+ onClose: Q,
30
+ closeOnEscape: V,
24
31
  initialFocus: "[aria-label=\"Close\"]"
25
- }), typeof document > "u" ? null : w(/* @__PURE__ */ b(S, { children: T ? /* @__PURE__ */ x(C.div, {
26
- ref: H,
27
- className: e(m, B),
32
+ }), typeof document > "u" ? null : D(/* @__PURE__ */ C(T, { children: O ? /* @__PURE__ */ w(E.div, {
33
+ ref: K,
34
+ className: e(h, W),
28
35
  role: "dialog",
29
36
  "aria-modal": "true",
30
- "aria-labelledby": V,
37
+ "aria-labelledby": G,
31
38
  "data-intake-modal": "",
32
39
  initial: { opacity: 0 },
33
40
  animate: { opacity: 1 },
34
41
  exit: { opacity: 0 },
35
- transition: t("medium"),
42
+ transition: n("medium"),
36
43
  children: [
37
- /* @__PURE__ */ b("h1", {
38
- id: V,
44
+ /* @__PURE__ */ C("h1", {
45
+ id: G,
39
46
  className: "sr-only",
40
- children: k
47
+ children: M
41
48
  }),
42
- /* @__PURE__ */ x("header", {
43
- className: d,
44
- children: [/* @__PURE__ */ x("div", {
45
- className: s,
46
- children: [/* @__PURE__ */ b("span", {
47
- className: f,
49
+ /* @__PURE__ */ w("header", {
50
+ className: f,
51
+ children: [/* @__PURE__ */ w("div", {
52
+ className: c,
53
+ children: [/* @__PURE__ */ C("span", {
54
+ className: p,
48
55
  "aria-hidden": !0,
49
56
  children: "WM"
50
- }), /* @__PURE__ */ b("span", {
51
- className: h,
57
+ }), /* @__PURE__ */ C("span", {
58
+ className: g,
52
59
  children: "WhatMatters"
53
60
  })]
54
- }), /* @__PURE__ */ b(r, {
55
- icon: /* @__PURE__ */ b(y, { strokeWidth: 2 }),
61
+ }), /* @__PURE__ */ C(i, {
62
+ icon: /* @__PURE__ */ C(S, { strokeWidth: 2 }),
56
63
  "aria-label": "Close",
57
64
  role: "ghost",
58
65
  size: "md",
59
- onClick: U
66
+ onClick: Q
60
67
  })]
61
68
  }),
62
- A ? /* @__PURE__ */ b("div", {
63
- className: p,
64
- children: /* @__PURE__ */ b(i, {
65
- step: D,
66
- steps: O
69
+ N ? /* @__PURE__ */ C("div", {
70
+ className: m,
71
+ children: /* @__PURE__ */ C(a, {
72
+ step: A,
73
+ steps: j
67
74
  })
68
75
  }) : null,
69
- /* @__PURE__ */ b("div", {
70
- className: o,
71
- children: /* @__PURE__ */ b("div", {
72
- className: j ? c : l,
73
- children: z
76
+ /* @__PURE__ */ C("div", {
77
+ className: s,
78
+ children: /* @__PURE__ */ C("div", {
79
+ className: P ? l : u,
80
+ children: U
74
81
  })
75
82
  }),
76
- j ? null : /* @__PURE__ */ x("footer", {
77
- className: u,
78
- children: [M ? null : /* @__PURE__ */ b(n, {
83
+ Y ? /* @__PURE__ */ w("footer", {
84
+ className: e(d, "flex-wrap"),
85
+ role: "alertdialog",
86
+ "aria-labelledby": q,
87
+ "data-intake-discard": "",
88
+ children: [
89
+ /* @__PURE__ */ C("p", {
90
+ id: q,
91
+ className: e(t("ui-label"), "basis-full text-fg md:basis-auto"),
92
+ children: "Discard your answers?"
93
+ }),
94
+ /* @__PURE__ */ C(r, {
95
+ ref: J,
96
+ role: "primary",
97
+ type: "button",
98
+ onClick: () => X(!1),
99
+ children: "Keep editing"
100
+ }),
101
+ /* @__PURE__ */ C(r, {
102
+ role: "ghost",
103
+ type: "button",
104
+ onClick: Z,
105
+ children: "Discard"
106
+ })
107
+ ]
108
+ }) : P ? null : /* @__PURE__ */ w("footer", {
109
+ className: d,
110
+ children: [F ? null : /* @__PURE__ */ C(r, {
79
111
  role: "primary",
80
112
  type: "button",
81
- disabled: I,
82
- onClick: P,
83
- children: L
84
- }), /* @__PURE__ */ b(n, {
113
+ disabled: z,
114
+ onClick: L,
115
+ children: B
116
+ }), A > 1 ? /* @__PURE__ */ C(r, {
85
117
  role: "ghost",
86
118
  type: "button",
87
- disabled: F,
88
- onClick: N,
119
+ disabled: R,
120
+ onClick: I,
89
121
  children: "Back"
90
- })]
122
+ }) : null]
91
123
  })
92
124
  ]
93
125
  }) : null }), document.body);
94
126
  }
95
127
  //#endregion
96
- export { T as IntakeModal };
128
+ export { O as IntakeModal };