@axos-web-dev/shared-components 2.0.0-dev.13-stepForm.3 → 2.0.0-dev.13-stepForm.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/dist/ATMLocator/ATMLocator.js +2 -1
  2. package/dist/Accordion/Accordion.js +2 -1
  3. package/dist/AlertBanner/index.js +2 -1
  4. package/dist/Auth/ErrorAlert.js +2 -1
  5. package/dist/BulletItem/BulletItem.js +2 -1
  6. package/dist/Button/Button.js +2 -1
  7. package/dist/Calculators/AxosOneCalculator/index.js +2 -1
  8. package/dist/Calculators/BalanceAPYCalculator/index.js +2 -1
  9. package/dist/Calculators/Calculator.js +2 -1
  10. package/dist/Calculators/MarginTradingCalculator/index.js +2 -1
  11. package/dist/Calculators/SummitApyCalculator/index.js +2 -1
  12. package/dist/Carousel/index.js +2 -1
  13. package/dist/Chatbot/ChatWindow.js +24 -18
  14. package/dist/Chatbot/Chatbot.js +19 -17
  15. package/dist/Chevron/index.js +2 -1
  16. package/dist/CollectInformationAlert/index.js +2 -1
  17. package/dist/Comparison/Comparison.css.js +2 -1
  18. package/dist/Comparison/Comparison.js +2 -1
  19. package/dist/DownloadTile/index.js +1 -0
  20. package/dist/ExecutiveBio/ExecutiveBio.js +2 -1
  21. package/dist/FaqAccordion/index.js +2 -1
  22. package/dist/FooterDisclosure/LVF/LaVictorieFooter.js +2 -1
  23. package/dist/FooterSiteMap/AxosBank/FooterSiteMap.js +20 -1
  24. package/dist/Forms/ApplicationStart.js +2 -1
  25. package/dist/Forms/ApplyNow.js +2 -1
  26. package/dist/Forms/BoatMooringLocation.d.ts +4 -1
  27. package/dist/Forms/BoatMooringLocation.js +136 -54
  28. package/dist/Forms/ClearingForm.js +2 -1
  29. package/dist/Forms/CommercialDeposits.js +2 -1
  30. package/dist/Forms/CommercialDepositsNoLendingOption.js +2 -1
  31. package/dist/Forms/CommercialLending.js +2 -1
  32. package/dist/Forms/CommercialPremiumFinance.js +2 -1
  33. package/dist/Forms/ConstructionLendingDynamic.js +2 -1
  34. package/dist/Forms/ContactCompany.js +2 -1
  35. package/dist/Forms/ContactCompanyTitle.js +2 -1
  36. package/dist/Forms/ContactUs.js +2 -1
  37. package/dist/Forms/ContactUsAAS.js +2 -1
  38. package/dist/Forms/ContactUsBusiness.js +2 -1
  39. package/dist/Forms/ContactUsBusinessNameEmail.js +2 -1
  40. package/dist/Forms/ContactUsLVF.js +2 -1
  41. package/dist/Forms/ContactUsNMLSId.js +2 -1
  42. package/dist/Forms/CpraRequest.js +2 -1
  43. package/dist/Forms/CraPublicFile.js +2 -1
  44. package/dist/Forms/DealerServices.js +2 -1
  45. package/dist/Forms/EmailOnly.js +2 -1
  46. package/dist/Forms/EmailUs.js +2 -1
  47. package/dist/Forms/FormEnums.js +2 -2
  48. package/dist/Forms/MortgageRate/MortgageRateForm.js +2 -1
  49. package/dist/Forms/MortgageRate/MortgageRateStep.css.d.ts +12 -0
  50. package/dist/Forms/MortgageRate/MortgageRateStep.css.js +33 -9
  51. package/dist/Forms/MortgageRate/MortgageRateStep.js +801 -356
  52. package/dist/Forms/MortgageRate/MortgageRateWatch.js +2 -1
  53. package/dist/Forms/MortgageRate/mortgageLeadForm.config.d.ts +28 -11
  54. package/dist/Forms/MortgageRate/mortgageLeadForm.config.js +18 -7
  55. package/dist/Forms/MortgageRate/mortgageLeadForm.types.d.ts +6 -2
  56. package/dist/Forms/MortgageWarehouseLending.js +2 -1
  57. package/dist/Forms/QuickPricer/QuickPricerForm.js +2 -1
  58. package/dist/Forms/ScheduleCall.js +2 -1
  59. package/dist/Forms/ScheduleCallPremier.js +2 -1
  60. package/dist/Forms/SuccesForm.js +2 -1
  61. package/dist/Forms/WcplSurvey.js +2 -1
  62. package/dist/HeroBanner/HeroBanner.js +2 -1
  63. package/dist/HeroBanner/LargeHeroBanner.js +2 -1
  64. package/dist/Hyperlink/index.js +2 -1
  65. package/dist/ImageBillboard/ImageBillboard.js +2 -1
  66. package/dist/ImageBillboard/ImageBillboardSet.js +2 -1
  67. package/dist/ImageLink/ImageLink.js +2 -1
  68. package/dist/ImageLink/ImageLinkSet.js +2 -1
  69. package/dist/ImageLink/index.js +2 -1
  70. package/dist/Insight/Featured/CategorySelector.js +2 -1
  71. package/dist/Insight/Featured/Featured.js +2 -1
  72. package/dist/Insight/Featured/Header.js +2 -1
  73. package/dist/LandingPageHeader/LandingPageHeader.js +2 -1
  74. package/dist/Modal/Modal.js +2 -1
  75. package/dist/NavigationMenu/AxosALTS/index.js +2 -1
  76. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileMenu.js +2 -1
  77. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileMenu.module.js +27 -27
  78. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileNavData.d.ts +5 -2
  79. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileNavData.js +9 -4
  80. package/dist/NavigationMenu/AxosBank/NavBar.module.js +39 -39
  81. package/dist/NavigationMenu/AxosBank/SubNavBar.js +11 -1
  82. package/dist/NavigationMenu/AxosBank/index.js +29 -18
  83. package/dist/NavigationMenu/LaVictoire/index.js +2 -1
  84. package/dist/NavigationMenu/Navbar.js +2 -1
  85. package/dist/NavigationMenu/SignInNavButton.js +2 -1
  86. package/dist/Pagination/Pagination.js +2 -1
  87. package/dist/SetContainer/SetContainer.js +2 -1
  88. package/dist/SocialMediaBar/iconsRepository.js +2 -1
  89. package/dist/Table/Table.js +2 -1
  90. package/dist/VideoTile/VideoTile.js +2 -1
  91. package/dist/VideoWrapper/index.js +2 -1
  92. package/dist/assets/Forms/MortgageRate/MortgageRateStep.css +156 -19
  93. package/dist/assets/NavigationMenu/AxosBank/MobileMenu/MobileMenu.css +49 -49
  94. package/dist/assets/NavigationMenu/AxosBank/NavBar.css +88 -88
  95. package/dist/assets/icons/AlertBell/AlertBellIcon.css +6 -0
  96. package/dist/icons/AlertBell/AlertBellIcon.css.d.ts +1 -0
  97. package/dist/icons/AlertBell/AlertBellIcon.css.js +5 -0
  98. package/dist/icons/AlertBell/index.d.ts +1 -0
  99. package/dist/icons/AlertBell/index.js +57 -0
  100. package/dist/icons/index.d.ts +1 -0
  101. package/dist/icons/index.js +2 -0
  102. package/dist/main.js +2 -0
  103. package/package.json +148 -148
@@ -1,17 +1,27 @@
1
1
  "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
3
3
  import { useState, useRef, useMemo, useEffect } from "react";
4
4
  import { AnimatePresence, motion } from "framer-motion";
5
- import { Button, Field, Label, Input, RadioGroup, Radio } from "@headlessui/react";
6
- import { section, formShell, successWrap, successTitle, successText, disclosure, disclosureTitle, disclosureText, mainTitle, mainDescription, progressWrap, progressRow, progressLabel, progressTrack, progressFill, stepPanel, title, description, actions, secondaryButton, primaryButton, overlayOpacity, inputGrid, inputRowTwo, fieldBlock, fieldLabel, input, errorText, optionalText, radioOption, radioOptionChecked, radioText, autoAdvanceHint, sliderWrap, sliderHeader, sliderValue, slider, helperText, amountPreview, amountPreviewLabel, amountPreviewValue, radioGrid, autoAdvanceStatus, autoAdvanceText, autoAdvanceTrack, autoAdvanceBar } from "./MortgageRateStep.css.js";
7
- import { fixedLoanTermOptions, armLoanTermOptions, fixedLoanTypeOptions, amortizationTypeOptions, creditScoreOptions, propertyUseOptions, propertyTypeOptions, mortgageTypeOptions } from "./mortgageLeadForm.config.js";
8
- import { parseCurrencyInput, formatCurrency, formatPhoneInput, formatPercentInput, formatCurrencyInput, calculatePercentAmount, validateZipCode, validateEmail, validatePhone } from "./mortgageLeadForm.utils.js";
5
+ import { Button, Field, Label, Input, Listbox, ListboxButton, ListboxOptions, ListboxOption, Fieldset, Legend, RadioGroup, Radio } from "@headlessui/react";
6
+ import { section, formShell, successWrap, successTitle, successText, disclosure, disclosureTitle, disclosureText, mainTitle, mainDescription, progressWrap, progressRow, progressLabel, progressTrack, progressFill, stepPanel, title, description, actions, secondaryButton, primaryButton, disclosureTextSm, overlayOpacity, inputGrid, fieldBlock, fieldLabel, input, errorText, selectWrap, selectButton, selectButtonPlaceholder, selectChevron, selectOptions, selectOption, autoAdvanceHint, fieldSet, subStepLabel, inputRowTwo, radioOption, radioOptionChecked, radioText, conditionalField, conditionalFieldWrap, selectLabel, sliderWrap, sliderHeader, sliderValue, slider, helperText, amountPreview, amountPreviewLabel, amountPreviewValue, optionalText, radioGrid, autoAdvanceStatus, autoAdvanceText, autoAdvanceTrack, autoAdvanceBar } from "./MortgageRateStep.css.js";
7
+ import { updateFrequencyOptions, fixedLoanTermOptions, armLoanTermOptions, amortizationTypeOptions, creditScoreOptions, propertyTypeOptions, unitCountOptions, propertyUseOptions, mortgageTypeOptions } from "./mortgageLeadForm.config.js";
8
+ import { parseCurrencyInput, formatCurrency, formatPercentInput, formatCurrencyInput, formatPhoneInput, calculatePercentAmount, validateEmail, validatePhone, validateZipCode } from "./mortgageLeadForm.utils.js";
9
+ import "../../icons/ArrowIcon/ArrowIcon.css.js";
10
+ import "../../icons/CheckIcon/CheckIcon.css.js";
11
+ import '../../assets/icons/FollowIcon/FollowIcon.css';import '../../assets/icons/DownloadIcon/DownloadIcon.css';import '../../assets/themes/victorie.css';import '../../assets/themes/ufb.css';import '../../assets/themes/premier.css';import '../../assets/themes/axos.css';/* empty css */
12
+ /* empty css */
13
+ /* empty css */
14
+ /* empty css */
15
+ /* empty css */
16
+ /* empty css */
17
+ import { AlertBellIcon } from "../../icons/AlertBell/index.js";
9
18
  import { Overlay } from "../../ExecutiveBio/Overlay.js";
10
19
  import { overlay } from "../../ExecutiveBio/ExecutiveBio.css.js";
11
- const AUTO_ADVANCE_DELAY = 1200;
20
+ const AUTO_ADVANCE_DELAY = 1e3;
12
21
  const initialValues = {
13
22
  mortgageType: "",
14
23
  propertyType: "",
24
+ unitCount: "",
15
25
  propertyUse: "",
16
26
  creditScore: "",
17
27
  purchasePrice: "",
@@ -22,14 +32,15 @@ const initialValues = {
22
32
  cashOutAmount: "",
23
33
  zipCode: "",
24
34
  amortizationType: "",
25
- fixedLoanType: "",
35
+ fixedLoanType: "conforming",
26
36
  loanTerm: "",
27
37
  desiredRate: "",
28
- discountPoints: "",
38
+ discountPoints: "0",
29
39
  firstName: "",
30
40
  lastName: "",
31
41
  email: "",
32
- phoneNumber: ""
42
+ phoneNumber: "",
43
+ updateFrequency: ""
33
44
  };
34
45
  function MortgageRateStep() {
35
46
  const [currentStepIndex, setCurrentStepIndex] = useState(0);
@@ -42,22 +53,18 @@ function MortgageRateStep() {
42
53
  const autoAdvanceTimeout = useRef(null);
43
54
  const isPurchase = values.mortgageType === "purchase-rates";
44
55
  const isRefinance = values.mortgageType === "refinance-rates";
45
- const showFixedLoanTypeStep = values.amortizationType === "fixed";
56
+ const isMultiUnit = values.propertyType === "2-4-unit";
46
57
  const steps = useMemo(() => {
47
- const base = [
58
+ return [
59
+ "contact",
48
60
  "mortgageType",
49
- "propertyType",
50
- "propertyUse",
61
+ "propertyTypeUse",
51
62
  "creditScore",
52
63
  "propertyDetails",
53
- "amortizationType"
64
+ "amortizationLoanTerm",
65
+ "finalDetails"
54
66
  ];
55
- if (showFixedLoanTypeStep) {
56
- base.push("fixedLoanType");
57
- }
58
- base.push("loanTerm", "finalDetails", "contact");
59
- return base;
60
- }, [showFixedLoanTypeStep]);
67
+ }, []);
61
68
  const totalSteps = steps.length;
62
69
  const stepKey = steps[currentStepIndex];
63
70
  const progress = (currentStepIndex + 1) / totalSteps * 100;
@@ -90,8 +97,18 @@ function MortgageRateStep() {
90
97
  Number(value)
91
98
  );
92
99
  }
100
+ if (key === "mortgageType") {
101
+ next.purchasePrice = "";
102
+ next.downPaymentAmount = "";
103
+ next.downPaymentPercent = 10;
104
+ next.estimatedHomeValue = "";
105
+ next.currentLoanBalance = "";
106
+ next.cashOutAmount = "";
107
+ }
108
+ if (key === "propertyType" && value !== "2-4-unit") {
109
+ next.unitCount = "";
110
+ }
93
111
  if (key === "amortizationType") {
94
- next.fixedLoanType = "";
95
112
  next.loanTerm = "";
96
113
  }
97
114
  return next;
@@ -104,14 +121,37 @@ function MortgageRateStep() {
104
121
  };
105
122
  const validateStep = (step) => {
106
123
  const nextErrors = {};
124
+ if (step === "contact") {
125
+ if (!values.firstName.trim()) {
126
+ nextErrors.firstName = "Please enter your first name.";
127
+ }
128
+ if (!values.lastName.trim()) {
129
+ nextErrors.lastName = "Please enter your last name.";
130
+ }
131
+ if (!values.email.trim()) {
132
+ nextErrors.email = "Please enter your email address.";
133
+ } else if (!validateEmail(values.email)) {
134
+ nextErrors.email = "Please enter a valid email address.";
135
+ }
136
+ if (!values.phoneNumber.trim()) {
137
+ nextErrors.phoneNumber = "Please enter your phone number.";
138
+ } else if (!validatePhone(values.phoneNumber)) {
139
+ nextErrors.phoneNumber = "Please enter a valid 10-digit phone number.";
140
+ }
141
+ }
107
142
  if (step === "mortgageType" && !values.mortgageType) {
108
143
  nextErrors.mortgageType = "Please select a mortgage type.";
109
144
  }
110
- if (step === "propertyType" && !values.propertyType) {
111
- nextErrors.propertyType = "Please select a property type.";
112
- }
113
- if (step === "propertyUse" && !values.propertyUse) {
114
- nextErrors.propertyUse = "Please select how the property will be used.";
145
+ if (step === "propertyTypeUse") {
146
+ if (!values.propertyType) {
147
+ nextErrors.propertyType = "Please select a property type.";
148
+ }
149
+ if (values.propertyType === "2-4-unit" && !values.unitCount) {
150
+ nextErrors.unitCount = "Please select the number of units.";
151
+ }
152
+ if (!values.propertyUse) {
153
+ nextErrors.propertyUse = "Please select how the property will be used.";
154
+ }
115
155
  }
116
156
  if (step === "creditScore" && !values.creditScore) {
117
157
  nextErrors.creditScore = "Please select your estimated credit score.";
@@ -141,36 +181,22 @@ function MortgageRateStep() {
141
181
  }
142
182
  }
143
183
  }
144
- if (step === "amortizationType" && !values.amortizationType) {
145
- nextErrors.amortizationType = "Please select an amortization type.";
146
- }
147
- if (step === "fixedLoanType" && !values.fixedLoanType) {
148
- nextErrors.fixedLoanType = "Please select a loan type.";
149
- }
150
- if (step === "loanTerm" && !values.loanTerm) {
151
- nextErrors.loanTerm = "Please select a desired loan term.";
184
+ if (step === "amortizationLoanTerm") {
185
+ if (!values.amortizationType) {
186
+ nextErrors.amortizationType = "Please select an amortization type.";
187
+ }
188
+ if (!values.loanTerm) {
189
+ nextErrors.loanTerm = "Please select a desired loan term.";
190
+ }
152
191
  }
153
192
  if (step === "finalDetails") {
154
193
  if (!values.desiredRate.trim()) {
155
194
  nextErrors.desiredRate = "Please enter your desired rate.";
195
+ } else if (Number(values.desiredRate) < 2 || Number(values.desiredRate) > 10) {
196
+ nextErrors.desiredRate = "Please enter a rate between 2% and 10%.";
156
197
  }
157
- }
158
- if (step === "contact") {
159
- if (!values.firstName.trim()) {
160
- nextErrors.firstName = "Please enter your first name.";
161
- }
162
- if (!values.lastName.trim()) {
163
- nextErrors.lastName = "Please enter your last name.";
164
- }
165
- if (!values.email.trim()) {
166
- nextErrors.email = "Please enter your email address.";
167
- } else if (!validateEmail(values.email)) {
168
- nextErrors.email = "Please enter a valid email address.";
169
- }
170
- if (!values.phoneNumber.trim()) {
171
- nextErrors.phoneNumber = "Please enter your phone number.";
172
- } else if (!validatePhone(values.phoneNumber)) {
173
- nextErrors.phoneNumber = "Please enter a valid 10-digit phone number.";
198
+ if (!values.updateFrequency) {
199
+ nextErrors.updateFrequency = "Please select how often you'd like to receive rate updates.";
174
200
  }
175
201
  }
176
202
  setErrors(nextErrors);
@@ -194,37 +220,31 @@ function MortgageRateStep() {
194
220
  setLastInteractedRadioStep(null);
195
221
  setCurrentStepIndex((prev) => Math.max(0, prev - 1));
196
222
  };
197
- const getAutoAdvanceValue = () => {
198
- switch (stepKey) {
199
- case "mortgageType":
200
- return values.mortgageType;
201
- case "propertyType":
202
- return values.propertyType;
203
- case "propertyUse":
204
- return values.propertyUse;
205
- case "creditScore":
206
- return values.creditScore;
207
- case "amortizationType":
208
- return values.amortizationType;
209
- case "fixedLoanType":
210
- return values.fixedLoanType;
211
- case "loanTerm":
212
- return values.loanTerm;
213
- default:
214
- return "";
215
- }
216
- };
217
223
  const isAutoAdvanceStep = (key) => {
218
224
  return [
219
225
  "mortgageType",
220
- "propertyType",
221
- "propertyUse",
226
+ "propertyTypeUse",
222
227
  "creditScore",
223
- "amortizationType",
224
- "fixedLoanType",
225
- "loanTerm"
228
+ "amortizationLoanTerm"
226
229
  ].includes(key);
227
230
  };
231
+ const isAutoAdvanceReady = (key) => {
232
+ switch (key) {
233
+ case "mortgageType":
234
+ return !!values.mortgageType;
235
+ case "propertyTypeUse":
236
+ if (!values.propertyType || !values.propertyUse) return false;
237
+ if (values.propertyType === "2-4-unit" && !values.unitCount)
238
+ return false;
239
+ return true;
240
+ case "creditScore":
241
+ return !!values.creditScore;
242
+ case "amortizationLoanTerm":
243
+ return !!values.amortizationType && !!values.loanTerm;
244
+ default:
245
+ return false;
246
+ }
247
+ };
228
248
  const registerRadioInteraction = (step) => {
229
249
  setLastInteractedRadioStep(step);
230
250
  setRadioSelectionVersion((prev) => prev + 1);
@@ -232,13 +252,16 @@ function MortgageRateStep() {
232
252
  useEffect(() => {
233
253
  clearAutoAdvance();
234
254
  if (!isAutoAdvanceStep(stepKey)) return;
235
- const selectedValue = getAutoAdvanceValue();
236
- if (!selectedValue) return;
255
+ if (!isAutoAdvanceReady(stepKey)) return;
237
256
  if (lastInteractedRadioStep !== stepKey) return;
238
257
  setIsAutoAdvancing(true);
258
+ const stepAtSchedule = currentStepIndex;
239
259
  autoAdvanceTimeout.current = setTimeout(() => {
240
- if (currentStepIndex === totalSteps - 1) return;
241
- setCurrentStepIndex((prev) => prev + 1);
260
+ setCurrentStepIndex((prev) => {
261
+ if (prev !== stepAtSchedule) return prev;
262
+ if (prev === totalSteps - 1) return prev;
263
+ return prev + 1;
264
+ });
242
265
  setIsAutoAdvancing(false);
243
266
  }, AUTO_ADVANCE_DELAY);
244
267
  return () => clearAutoAdvance();
@@ -250,54 +273,46 @@ function MortgageRateStep() {
250
273
  radioSelectionVersion,
251
274
  values.mortgageType,
252
275
  values.propertyType,
276
+ values.unitCount,
253
277
  values.propertyUse,
254
278
  values.creditScore,
255
279
  values.amortizationType,
256
- values.fixedLoanType,
257
280
  values.loanTerm
258
281
  ]);
259
282
  const getStepTitle = () => {
260
283
  switch (stepKey) {
284
+ case "contact":
285
+ return "Let's start with how we can reach you.";
261
286
  case "mortgageType":
262
287
  return "What type of mortgage are you interested in?";
263
- case "propertyType":
264
- return "What kind of property type are you looking to finance?";
265
- case "propertyUse":
266
- return "How will you use this property?";
288
+ case "propertyTypeUse":
289
+ return "Tell us about the property.";
267
290
  case "creditScore":
268
- return "What's your estimated credit score?";
291
+ return "What is your estimated credit score?";
269
292
  case "propertyDetails":
270
- return "Let us know more about the property";
271
- case "amortizationType":
272
- return "What is your preferred amortization type on the loan?";
273
- case "fixedLoanType":
274
- return "Which loan type are interested in?";
275
- case "loanTerm":
276
- return "What is your desired loan term?";
293
+ return "Please share more details about the property.";
294
+ case "amortizationLoanTerm":
295
+ return "Choose your loan structure.";
277
296
  case "finalDetails":
278
297
  return "Some final details...";
279
- case "contact":
280
- return "Let us know how we can reach you";
281
298
  default:
282
299
  return "";
283
300
  }
284
301
  };
285
302
  const getStepDescription = () => {
286
303
  switch (stepKey) {
304
+ case "contact":
305
+ return "Share your contact details so we can send you personalized rate alerts that match your goals.";
287
306
  case "mortgageType":
288
307
  return "Select the option that best matches your needs.";
289
- case "propertyUse":
290
- return "Describe how you plan to use the property to help us find the best mortgage options for you.";
308
+ case "propertyTypeUse":
309
+ return "Tell us a bit about the property type and how you plan to use it so we can match you with the most suitable mortgage options.";
291
310
  case "propertyDetails":
292
- return "Please provide these additional details to better understand your mortgage needs.";
293
- case "amortizationType":
294
- return "Selecting an amortization type helps us tailor loan options that fit your financial goals and preferences.";
295
- case "fixedLoanType":
296
- return "Choose the loan type that best describes the mortgage you are seeking.";
297
- case "loanTerm":
298
- return "Select the length of time (in years) for your loan term.";
311
+ return "Kindly share these extra details so we can better grasp your mortgage requirements.";
312
+ case "amortizationLoanTerm":
313
+ return "Pick the amortization style that fits your goals, then select your preferred loan term.";
299
314
  case "finalDetails":
300
- return "Almost there! Please provide these final details to help us find the best rates for you.";
315
+ return "You're almost done! Just share these last details so we can help you discover the best rates available.";
301
316
  default:
302
317
  return "";
303
318
  }
@@ -311,6 +326,105 @@ function MortgageRateStep() {
311
326
  };
312
327
  const renderStep = () => {
313
328
  switch (stepKey) {
329
+ case "contact":
330
+ return /* @__PURE__ */ jsxs(Fieldset, { className: `${inputGrid} ${fieldSet}`, children: [
331
+ /* @__PURE__ */ jsx(Legend, { className: fieldLabel, style: { fontSize: "1rem" }, children: "Contact Information" }),
332
+ /* @__PURE__ */ jsxs("div", { className: inputRowTwo, children: [
333
+ /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
334
+ /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "First Name" }),
335
+ /* @__PURE__ */ jsx(
336
+ Input,
337
+ {
338
+ className: input,
339
+ type: "text",
340
+ placeholder: "Enter your first name",
341
+ value: values.firstName,
342
+ onChange: (e) => updateValue("firstName", e.target.value),
343
+ "aria-describedby": errors.firstName ? "firstName-error" : void 0,
344
+ "aria-invalid": !!errors.firstName,
345
+ autoComplete: "given-name"
346
+ }
347
+ ),
348
+ errors.firstName ? /* @__PURE__ */ jsx(
349
+ "p",
350
+ {
351
+ id: "firstName-error",
352
+ className: errorText,
353
+ role: "alert",
354
+ children: errors.firstName
355
+ }
356
+ ) : null
357
+ ] }),
358
+ /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
359
+ /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Last Name" }),
360
+ /* @__PURE__ */ jsx(
361
+ Input,
362
+ {
363
+ className: input,
364
+ type: "text",
365
+ placeholder: "Enter your last name",
366
+ value: values.lastName,
367
+ onChange: (e) => updateValue("lastName", e.target.value),
368
+ "aria-describedby": errors.lastName ? "lastName-error" : void 0,
369
+ "aria-invalid": !!errors.lastName,
370
+ autoComplete: "family-name"
371
+ }
372
+ ),
373
+ errors.lastName ? /* @__PURE__ */ jsx(
374
+ "p",
375
+ {
376
+ id: "lastName-error",
377
+ className: errorText,
378
+ role: "alert",
379
+ children: errors.lastName
380
+ }
381
+ ) : null
382
+ ] })
383
+ ] }),
384
+ /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
385
+ /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Email" }),
386
+ /* @__PURE__ */ jsx(
387
+ Input,
388
+ {
389
+ className: input,
390
+ type: "email",
391
+ placeholder: "Enter your email",
392
+ value: values.email,
393
+ onChange: (e) => updateValue("email", e.target.value),
394
+ "aria-describedby": errors.email ? "email-error" : void 0,
395
+ "aria-invalid": !!errors.email,
396
+ autoComplete: "email"
397
+ }
398
+ ),
399
+ errors.email ? /* @__PURE__ */ jsx("p", { id: "email-error", className: errorText, role: "alert", children: errors.email }) : null
400
+ ] }),
401
+ /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
402
+ /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Phone Number" }),
403
+ /* @__PURE__ */ jsx(
404
+ Input,
405
+ {
406
+ className: input,
407
+ type: "tel",
408
+ inputMode: "tel",
409
+ placeholder: "(XXX) XXX-XXXX",
410
+ value: values.phoneNumber,
411
+ onChange: (e) => updateValue("phoneNumber", formatPhoneInput(e.target.value)),
412
+ "aria-describedby": errors.phoneNumber ? "phoneNumber-error" : void 0,
413
+ "aria-invalid": !!errors.phoneNumber,
414
+ autoComplete: "tel"
415
+ }
416
+ ),
417
+ errors.phoneNumber ? /* @__PURE__ */ jsx(
418
+ "p",
419
+ {
420
+ id: "phoneNumber-error",
421
+ className: errorText,
422
+ role: "alert",
423
+ children: errors.phoneNumber
424
+ }
425
+ ) : null
426
+ ] })
427
+ ] });
314
428
  case "mortgageType":
315
429
  return /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
316
430
  /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Choose one" }),
@@ -339,73 +453,191 @@ function MortgageRateStep() {
339
453
  ),
340
454
  /* @__PURE__ */ jsx("p", { className: autoAdvanceHint, children: "Your selection will continue automatically." }),
341
455
  renderAutoAdvanceStatus(),
342
- errors.mortgageType ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.mortgageType }) : null
343
- ] });
344
- case "propertyType":
345
- return /* @__PURE__ */ jsxs(Field, { className: fieldBlock, style: { marginTop: "24px" }, children: [
346
- /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Choose one" }),
347
- /* @__PURE__ */ jsx(
348
- RadioGroup,
456
+ errors.mortgageType ? /* @__PURE__ */ jsx(
457
+ "p",
349
458
  {
350
- value: values.propertyType,
351
- onChange: (value) => {
352
- updateValue("propertyType", value);
353
- registerRadioInteraction("propertyType");
354
- },
355
- className: radioGrid,
356
- style: {
357
- gridTemplateColumns: "repeat(auto-fit,minmax(258px,1fr))"
358
- },
359
- children: propertyTypeOptions.map((option) => {
360
- const checked = values.propertyType === option.value;
361
- return /* @__PURE__ */ jsx(
362
- Radio,
363
- {
364
- value: option.value,
365
- className: `${radioOption} ${checked ? radioOptionChecked : ""}`,
366
- children: /* @__PURE__ */ jsx("span", { className: radioText, children: option.label })
367
- },
368
- option.value
369
- );
370
- })
459
+ id: "mortgageType-error",
460
+ className: errorText,
461
+ role: "alert",
462
+ children: errors.mortgageType
371
463
  }
372
- ),
373
- /* @__PURE__ */ jsx("p", { className: autoAdvanceHint, children: "Your selection will continue automatically." }),
374
- renderAutoAdvanceStatus(),
375
- errors.propertyType ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.propertyType }) : null
464
+ ) : null
376
465
  ] });
377
- case "propertyUse":
378
- return /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
379
- /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Choose one" }),
380
- /* @__PURE__ */ jsx(
381
- RadioGroup,
382
- {
383
- value: values.propertyUse,
384
- onChange: (value) => {
385
- updateValue("propertyUse", value);
386
- registerRadioInteraction("propertyUse");
387
- },
388
- className: radioGrid,
389
- style: {
390
- gridTemplateColumns: "repeat(auto-fit,minmax(258px,1fr))"
466
+ case "propertyTypeUse":
467
+ return /* @__PURE__ */ jsxs(Fieldset, { className: fieldSet, children: [
468
+ /* @__PURE__ */ jsx(Legend, { className: fieldLabel, style: { fontSize: "1rem" }, children: "Property Details" }),
469
+ /* @__PURE__ */ jsxs(Field, { className: fieldBlock, style: { marginTop: "16px" }, children: [
470
+ /* @__PURE__ */ jsx(Label, { className: subStepLabel, children: "What type of property are you financing?" }),
471
+ /* @__PURE__ */ jsx(
472
+ RadioGroup,
473
+ {
474
+ value: values.propertyType,
475
+ onChange: (value) => {
476
+ updateValue("propertyType", value);
477
+ registerRadioInteraction("propertyTypeUse");
478
+ },
479
+ className: radioGrid,
480
+ style: {
481
+ gridTemplateColumns: "repeat(auto-fit,minmax(258px,1fr))"
482
+ },
483
+ children: propertyTypeOptions.map((option) => {
484
+ const checked = values.propertyType === option.value;
485
+ return /* @__PURE__ */ jsx(
486
+ Radio,
487
+ {
488
+ value: option.value,
489
+ className: `${radioOption} ${checked ? radioOptionChecked : ""}`,
490
+ children: /* @__PURE__ */ jsx("span", { className: radioText, children: option.label })
491
+ },
492
+ option.value
493
+ );
494
+ })
495
+ }
496
+ ),
497
+ errors.propertyType ? /* @__PURE__ */ jsx(
498
+ "p",
499
+ {
500
+ id: "propertyType-error",
501
+ className: errorText,
502
+ role: "alert",
503
+ children: errors.propertyType
504
+ }
505
+ ) : null,
506
+ /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: isMultiUnit && /* @__PURE__ */ jsx(
507
+ motion.div,
508
+ {
509
+ initial: { opacity: 0, height: 0, y: -8 },
510
+ animate: { opacity: 1, height: "auto", y: 0 },
511
+ exit: { opacity: 0, height: 0, y: -8 },
512
+ transition: { duration: 0.28, ease: "easeOut" },
513
+ className: conditionalField,
514
+ children: /* @__PURE__ */ jsxs("div", { className: conditionalFieldWrap, children: [
515
+ /* @__PURE__ */ jsxs(
516
+ Listbox,
517
+ {
518
+ value: values.unitCount,
519
+ onChange: (value) => {
520
+ updateValue("unitCount", value);
521
+ registerRadioInteraction("propertyTypeUse");
522
+ },
523
+ children: [
524
+ /* @__PURE__ */ jsx(Label, { className: selectLabel, children: "How many units?" }),
525
+ /* @__PURE__ */ jsxs("div", { className: selectWrap, children: [
526
+ /* @__PURE__ */ jsx(
527
+ ListboxButton,
528
+ {
529
+ className: selectButton,
530
+ "aria-describedby": errors.unitCount ? "unitCount-error" : void 0,
531
+ "aria-invalid": !!errors.unitCount,
532
+ children: ({ open }) => /* @__PURE__ */ jsxs(Fragment, { children: [
533
+ /* @__PURE__ */ jsx(
534
+ "span",
535
+ {
536
+ className: values.unitCount ? "" : selectButtonPlaceholder,
537
+ children: values.unitCount ? unitCountOptions.find(
538
+ (o) => o.value === values.unitCount
539
+ )?.label : "Select number of units"
540
+ }
541
+ ),
542
+ /* @__PURE__ */ jsx(
543
+ "svg",
544
+ {
545
+ className: selectChevron,
546
+ "data-open": open,
547
+ viewBox: "0 0 20 20",
548
+ fill: "none",
549
+ xmlns: "http://www.w3.org/2000/svg",
550
+ "aria-hidden": "true",
551
+ children: /* @__PURE__ */ jsx(
552
+ "path",
553
+ {
554
+ d: "M5 7.5L10 12.5L15 7.5",
555
+ stroke: "currentColor",
556
+ strokeWidth: "2",
557
+ strokeLinecap: "round",
558
+ strokeLinejoin: "round"
559
+ }
560
+ )
561
+ }
562
+ )
563
+ ] })
564
+ }
565
+ ),
566
+ /* @__PURE__ */ jsx(
567
+ ListboxOptions,
568
+ {
569
+ className: selectOptions,
570
+ modal: false,
571
+ children: unitCountOptions.map((option) => /* @__PURE__ */ jsx(
572
+ ListboxOption,
573
+ {
574
+ value: option.value,
575
+ className: selectOption,
576
+ children: option.label
577
+ },
578
+ option.value
579
+ ))
580
+ }
581
+ )
582
+ ] })
583
+ ]
584
+ }
585
+ ),
586
+ errors.unitCount ? /* @__PURE__ */ jsx(
587
+ "p",
588
+ {
589
+ id: "unitCount-error",
590
+ className: errorText,
591
+ role: "alert",
592
+ style: { marginTop: "8px" },
593
+ children: errors.unitCount
594
+ }
595
+ ) : null
596
+ ] })
391
597
  },
392
- children: propertyUseOptions.map((option) => {
393
- const checked = values.propertyUse === option.value;
394
- return /* @__PURE__ */ jsx(
395
- Radio,
396
- {
397
- value: option.value,
398
- className: `${radioOption} ${checked ? radioOptionChecked : ""}`,
399
- children: /* @__PURE__ */ jsx("span", { className: radioText, children: option.label })
400
- },
401
- option.value
402
- );
403
- })
404
- }
405
- ),
406
- /* @__PURE__ */ jsx("p", { className: autoAdvanceHint, children: "Your selection will continue automatically." }),
407
- renderAutoAdvanceStatus(),
408
- errors.propertyUse ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.propertyUse }) : null
598
+ "unit-count-wrap"
599
+ ) })
600
+ ] }),
601
+ /* @__PURE__ */ jsxs(Field, { className: fieldBlock, style: { marginTop: "12px" }, children: [
602
+ /* @__PURE__ */ jsx(Label, { className: subStepLabel, children: "How do you plan to use this property?" }),
603
+ /* @__PURE__ */ jsx(
604
+ RadioGroup,
605
+ {
606
+ value: values.propertyUse,
607
+ onChange: (value) => {
608
+ updateValue("propertyUse", value);
609
+ registerRadioInteraction("propertyTypeUse");
610
+ },
611
+ className: radioGrid,
612
+ style: {
613
+ gridTemplateColumns: "repeat(auto-fit,minmax(258px,1fr))"
614
+ },
615
+ children: propertyUseOptions.map((option) => {
616
+ const checked = values.propertyUse === option.value;
617
+ return /* @__PURE__ */ jsx(
618
+ Radio,
619
+ {
620
+ value: option.value,
621
+ className: `${radioOption} ${checked ? radioOptionChecked : ""}`,
622
+ children: /* @__PURE__ */ jsx("span", { className: radioText, children: option.label })
623
+ },
624
+ option.value
625
+ );
626
+ })
627
+ }
628
+ ),
629
+ errors.propertyUse ? /* @__PURE__ */ jsx(
630
+ "p",
631
+ {
632
+ id: "propertyUse-error",
633
+ className: errorText,
634
+ role: "alert",
635
+ children: errors.propertyUse
636
+ }
637
+ ) : null
638
+ ] }),
639
+ /* @__PURE__ */ jsx("p", { className: autoAdvanceHint, style: { marginTop: "12px" }, children: "Once all selections are made, you'll continue automatically." }),
640
+ renderAutoAdvanceStatus()
409
641
  ] });
410
642
  case "creditScore":
411
643
  return /* @__PURE__ */ jsxs(Field, { className: fieldBlock, style: { marginTop: "24px" }, children: [
@@ -435,7 +667,15 @@ function MortgageRateStep() {
435
667
  ),
436
668
  /* @__PURE__ */ jsx("p", { className: autoAdvanceHint, children: "Your selection will continue automatically." }),
437
669
  renderAutoAdvanceStatus(),
438
- errors.creditScore ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.creditScore }) : null
670
+ errors.creditScore ? /* @__PURE__ */ jsx(
671
+ "p",
672
+ {
673
+ id: "creditScore-error",
674
+ className: errorText,
675
+ role: "alert",
676
+ children: errors.creditScore
677
+ }
678
+ ) : null
439
679
  ] });
440
680
  case "propertyDetails":
441
681
  if (isPurchase) {
@@ -452,10 +692,20 @@ function MortgageRateStep() {
452
692
  onChange: (e) => updateValue(
453
693
  "purchasePrice",
454
694
  formatCurrencyInput(e.target.value)
455
- )
695
+ ),
696
+ "aria-describedby": errors.purchasePrice ? "purchasePrice-error" : void 0,
697
+ "aria-invalid": !!errors.purchasePrice
456
698
  }
457
699
  ),
458
- errors.purchasePrice ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.purchasePrice }) : null
700
+ errors.purchasePrice ? /* @__PURE__ */ jsx(
701
+ "p",
702
+ {
703
+ id: "purchasePrice-error",
704
+ className: errorText,
705
+ role: "alert",
706
+ children: errors.purchasePrice
707
+ }
708
+ ) : null
459
709
  ] }),
460
710
  /* @__PURE__ */ jsxs(Field, { className: sliderWrap, children: [
461
711
  /* @__PURE__ */ jsxs("div", { className: sliderHeader, children: [
@@ -475,7 +725,8 @@ function MortgageRateStep() {
475
725
  step: 1,
476
726
  value: values.downPaymentPercent,
477
727
  onChange: (e) => updateValue("downPaymentPercent", Number(e.target.value)),
478
- "aria-label": "Down payment percentage"
728
+ "aria-label": "Down payment percentage",
729
+ "aria-valuetext": `${values.downPaymentPercent}% down payment, estimated amount ${purchaseDownPaymentPreview}`
479
730
  }
480
731
  ),
481
732
  /* @__PURE__ */ jsx("p", { className: helperText, children: "Move the slider to estimate your down payment amount instantly." }),
@@ -496,10 +747,20 @@ function MortgageRateStep() {
496
747
  onChange: (e) => updateValue(
497
748
  "zipCode",
498
749
  e.target.value.replace(/[^\d]/g, "").slice(0, 5)
499
- )
750
+ ),
751
+ "aria-describedby": errors.zipCode ? "zipCode-error" : void 0,
752
+ "aria-invalid": !!errors.zipCode
500
753
  }
501
754
  ),
502
- errors.zipCode ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.zipCode }) : null
755
+ errors.zipCode ? /* @__PURE__ */ jsx(
756
+ "p",
757
+ {
758
+ id: "zipCode-error",
759
+ className: errorText,
760
+ role: "alert",
761
+ children: errors.zipCode
762
+ }
763
+ ) : null
503
764
  ] })
504
765
  ] });
505
766
  }
@@ -523,10 +784,20 @@ function MortgageRateStep() {
523
784
  onChange: (e) => updateValue(
524
785
  "estimatedHomeValue",
525
786
  formatCurrencyInput(e.target.value)
526
- )
787
+ ),
788
+ "aria-describedby": errors.estimatedHomeValue ? "estimatedHomeValue-error" : void 0,
789
+ "aria-invalid": !!errors.estimatedHomeValue
527
790
  }
528
791
  ),
529
- errors.estimatedHomeValue ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.estimatedHomeValue }) : null
792
+ errors.estimatedHomeValue ? /* @__PURE__ */ jsx(
793
+ "p",
794
+ {
795
+ id: "estimatedHomeValue-error",
796
+ className: errorText,
797
+ role: "alert",
798
+ children: errors.estimatedHomeValue
799
+ }
800
+ ) : null
530
801
  ] }),
531
802
  /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
532
803
  /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Current Loan Balance" }),
@@ -540,10 +811,20 @@ function MortgageRateStep() {
540
811
  onChange: (e) => updateValue(
541
812
  "currentLoanBalance",
542
813
  formatCurrencyInput(e.target.value)
543
- )
814
+ ),
815
+ "aria-describedby": errors.currentLoanBalance ? "currentLoanBalance-error" : void 0,
816
+ "aria-invalid": !!errors.currentLoanBalance
544
817
  }
545
818
  ),
546
- errors.currentLoanBalance ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.currentLoanBalance }) : null
819
+ errors.currentLoanBalance ? /* @__PURE__ */ jsx(
820
+ "p",
821
+ {
822
+ id: "currentLoanBalance-error",
823
+ className: errorText,
824
+ role: "alert",
825
+ children: errors.currentLoanBalance
826
+ }
827
+ ) : null
547
828
  ] }),
548
829
  /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
549
830
  /* @__PURE__ */ jsxs(Label, { className: fieldLabel, children: [
@@ -561,9 +842,20 @@ function MortgageRateStep() {
561
842
  onChange: (e) => updateValue(
562
843
  "cashOutAmount",
563
844
  formatCurrencyInput(e.target.value)
564
- )
845
+ ),
846
+ "aria-describedby": errors.cashOutAmount ? "cashOutAmount-error" : void 0,
847
+ "aria-invalid": !!errors.cashOutAmount
848
+ }
849
+ ),
850
+ errors.cashOutAmount ? /* @__PURE__ */ jsx(
851
+ "p",
852
+ {
853
+ id: "cashOutAmount-error",
854
+ className: errorText,
855
+ role: "alert",
856
+ children: errors.cashOutAmount
565
857
  }
566
- )
858
+ ) : null
567
859
  ] }),
568
860
  /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
569
861
  /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "ZIP Code" }),
@@ -577,128 +869,197 @@ function MortgageRateStep() {
577
869
  onChange: (e) => updateValue(
578
870
  "zipCode",
579
871
  e.target.value.replace(/[^\d]/g, "").slice(0, 5)
580
- )
872
+ ),
873
+ "aria-describedby": errors.zipCode ? "zipCode-error" : void 0,
874
+ "aria-invalid": !!errors.zipCode
581
875
  }
582
876
  ),
583
- errors.zipCode ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.zipCode }) : null
877
+ errors.zipCode ? /* @__PURE__ */ jsx("p", { id: "zipCode-error", className: errorText, role: "alert", children: errors.zipCode }) : null
584
878
  ] })
585
879
  ]
586
880
  }
587
881
  );
588
- case "amortizationType":
589
- return /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
590
- /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Choose one" }),
591
- /* @__PURE__ */ jsx(
592
- RadioGroup,
593
- {
594
- value: values.amortizationType,
595
- onChange: (value) => {
596
- updateValue("amortizationType", value);
597
- registerRadioInteraction("amortizationType");
598
- },
599
- className: inputRowTwo,
600
- children: amortizationTypeOptions.map((option) => {
601
- const checked = values.amortizationType === option.value;
602
- return /* @__PURE__ */ jsx(
603
- Radio,
604
- {
605
- value: option.value,
606
- className: `${radioOption} ${checked ? radioOptionChecked : ""}`,
607
- children: /* @__PURE__ */ jsx("span", { className: radioText, children: option.label })
608
- },
609
- option.value
610
- );
611
- })
612
- }
613
- ),
614
- /* @__PURE__ */ jsx("p", { className: autoAdvanceHint, children: "Your selection will continue automatically." }),
615
- renderAutoAdvanceStatus(),
616
- errors.amortizationType ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.amortizationType }) : null
617
- ] });
618
- case "fixedLoanType":
619
- return /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
620
- /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Choose one" }),
621
- /* @__PURE__ */ jsx(
622
- RadioGroup,
623
- {
624
- value: values.fixedLoanType,
625
- onChange: (value) => {
626
- updateValue("fixedLoanType", value);
627
- registerRadioInteraction("fixedLoanType");
628
- },
629
- className: inputRowTwo,
630
- children: fixedLoanTypeOptions.map((option) => {
631
- const checked = values.fixedLoanType === option.value;
632
- return /* @__PURE__ */ jsx(
633
- Radio,
634
- {
635
- value: option.value,
636
- className: `${radioOption} ${checked ? radioOptionChecked : ""}`,
637
- children: /* @__PURE__ */ jsx("span", { className: radioText, children: option.label })
638
- },
639
- option.value
640
- );
641
- })
642
- }
643
- ),
644
- /* @__PURE__ */ jsx("p", { className: autoAdvanceHint, children: "Your selection will continue automatically." }),
645
- renderAutoAdvanceStatus(),
646
- errors.fixedLoanType ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.fixedLoanType }) : null
647
- ] });
648
- case "loanTerm":
649
- const loanTermOptions = values.amortizationType === "fixed" ? fixedLoanTermOptions : armLoanTermOptions;
650
- return /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
651
- /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Choose one" }),
652
- /* @__PURE__ */ jsx(
653
- RadioGroup,
654
- {
655
- value: values.loanTerm,
656
- onChange: (value) => {
657
- updateValue("loanTerm", value);
658
- registerRadioInteraction("loanTerm");
882
+ case "amortizationLoanTerm": {
883
+ const loanTermOptions = values.amortizationType === "fixed" ? fixedLoanTermOptions : values.amortizationType === "arm" ? armLoanTermOptions : [];
884
+ const selectedTermLabel = loanTermOptions.find(
885
+ (o) => o.value === values.loanTerm
886
+ )?.label;
887
+ return /* @__PURE__ */ jsxs(Fieldset, { className: fieldSet, children: [
888
+ /* @__PURE__ */ jsx(Legend, { className: fieldLabel, style: { fontSize: "1rem" }, children: "Loan Structure" }),
889
+ /* @__PURE__ */ jsxs(Field, { className: fieldBlock, style: { marginTop: "16px" }, children: [
890
+ /* @__PURE__ */ jsx(Label, { className: subStepLabel, children: "Which amortization type do you prefer?" }),
891
+ /* @__PURE__ */ jsx(
892
+ RadioGroup,
893
+ {
894
+ value: values.amortizationType,
895
+ onChange: (value) => {
896
+ updateValue("amortizationType", value);
897
+ registerRadioInteraction("amortizationLoanTerm");
898
+ },
899
+ className: inputRowTwo,
900
+ children: amortizationTypeOptions.map((option) => {
901
+ const checked = values.amortizationType === option.value;
902
+ return /* @__PURE__ */ jsx(
903
+ Radio,
904
+ {
905
+ value: option.value,
906
+ className: `${radioOption} ${checked ? radioOptionChecked : ""}`,
907
+ title: option.value === "fixed" ? "Fixed Rate Mortgage" : "Adjustable Rate Mortgage",
908
+ children: /* @__PURE__ */ jsx("span", { className: radioText, children: option.label })
909
+ },
910
+ option.value
911
+ );
912
+ })
913
+ }
914
+ ),
915
+ errors.amortizationType ? /* @__PURE__ */ jsx(
916
+ "p",
917
+ {
918
+ id: "amortizationType-error",
919
+ className: errorText,
920
+ role: "alert",
921
+ children: errors.amortizationType
922
+ }
923
+ ) : null,
924
+ /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", initial: false, children: values.amortizationType && /* @__PURE__ */ jsxs(
925
+ motion.div,
926
+ {
927
+ initial: { opacity: 0, height: 0, y: -8 },
928
+ animate: { opacity: 1, height: "auto", y: 0 },
929
+ exit: { opacity: 0, height: 0, y: -8 },
930
+ transition: { duration: 0.32, ease: [0.22, 1, 0.36, 1] },
931
+ className: conditionalField,
932
+ style: { minHeight: "154px" },
933
+ children: [
934
+ /* @__PURE__ */ jsxs("div", { className: conditionalFieldWrap, children: [
935
+ /* @__PURE__ */ jsxs(
936
+ Listbox,
937
+ {
938
+ value: values.loanTerm,
939
+ onChange: (value) => {
940
+ updateValue("loanTerm", value);
941
+ registerRadioInteraction("amortizationLoanTerm");
942
+ },
943
+ children: [
944
+ /* @__PURE__ */ jsx(Label, { className: selectLabel, children: values.amortizationType === "fixed" ? "What is your desired loan term?" : "What is your desired ARM term?" }),
945
+ /* @__PURE__ */ jsxs("div", { className: selectWrap, children: [
946
+ /* @__PURE__ */ jsx(
947
+ ListboxButton,
948
+ {
949
+ className: selectButton,
950
+ "aria-describedby": errors.loanTerm ? "loanTerm-error" : void 0,
951
+ "aria-invalid": !!errors.loanTerm,
952
+ children: ({ open }) => /* @__PURE__ */ jsxs(Fragment, { children: [
953
+ /* @__PURE__ */ jsx(
954
+ "span",
955
+ {
956
+ className: values.loanTerm ? "" : selectButtonPlaceholder,
957
+ children: selectedTermLabel ?? "Select a loan term"
958
+ }
959
+ ),
960
+ /* @__PURE__ */ jsx(
961
+ "svg",
962
+ {
963
+ className: selectChevron,
964
+ "data-open": open,
965
+ viewBox: "0 0 20 20",
966
+ fill: "none",
967
+ xmlns: "http://www.w3.org/2000/svg",
968
+ "aria-hidden": "true",
969
+ children: /* @__PURE__ */ jsx(
970
+ "path",
971
+ {
972
+ d: "M5 7.5L10 12.5L15 7.5",
973
+ stroke: "currentColor",
974
+ strokeWidth: "2",
975
+ strokeLinecap: "round",
976
+ strokeLinejoin: "round"
977
+ }
978
+ )
979
+ }
980
+ )
981
+ ] })
982
+ }
983
+ ),
984
+ /* @__PURE__ */ jsx(
985
+ ListboxOptions,
986
+ {
987
+ className: selectOptions,
988
+ modal: false,
989
+ children: loanTermOptions.map((option) => /* @__PURE__ */ jsx(
990
+ ListboxOption,
991
+ {
992
+ value: option.value,
993
+ className: selectOption,
994
+ children: option.label
995
+ },
996
+ option.value
997
+ ))
998
+ }
999
+ )
1000
+ ] })
1001
+ ]
1002
+ }
1003
+ ),
1004
+ errors.loanTerm ? /* @__PURE__ */ jsx(
1005
+ "p",
1006
+ {
1007
+ id: "loanTerm-error",
1008
+ className: errorText,
1009
+ role: "alert",
1010
+ style: { marginTop: "8px" },
1011
+ children: errors.loanTerm
1012
+ }
1013
+ ) : null
1014
+ ] }),
1015
+ /* @__PURE__ */ jsx(
1016
+ "p",
1017
+ {
1018
+ className: autoAdvanceHint,
1019
+ style: { marginTop: "12px" },
1020
+ children: "Once both selections are made, you'll continue automatically."
1021
+ }
1022
+ )
1023
+ ]
659
1024
  },
660
- className: inputRowTwo,
661
- children: loanTermOptions.map((option) => {
662
- const checked = values.loanTerm === option.value;
663
- return /* @__PURE__ */ jsx(
664
- Radio,
665
- {
666
- value: option.value,
667
- className: `${radioOption} ${checked ? radioOptionChecked : ""}`,
668
- children: /* @__PURE__ */ jsx("span", { className: radioText, children: option.label })
669
- },
670
- option.value
671
- );
672
- })
673
- }
674
- ),
675
- /* @__PURE__ */ jsx("p", { className: autoAdvanceHint, children: "Your selection will continue automatically." }),
676
- renderAutoAdvanceStatus(),
677
- errors.loanTerm ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.loanTerm }) : null
1025
+ `loan-term-${values.amortizationType}`
1026
+ ) })
1027
+ ] }),
1028
+ renderAutoAdvanceStatus()
678
1029
  ] });
1030
+ }
679
1031
  case "finalDetails":
680
1032
  return /* @__PURE__ */ jsxs("div", { className: inputGrid, children: [
681
1033
  /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
682
- /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Desired Rate" }),
1034
+ /* @__PURE__ */ jsxs(Label, { className: fieldLabel, children: [
1035
+ "Desired Rate",
1036
+ /* @__PURE__ */ jsx("sup", { children: "*" })
1037
+ ] }),
683
1038
  /* @__PURE__ */ jsx(
684
1039
  Input,
685
1040
  {
686
1041
  className: input,
687
1042
  type: "text",
688
1043
  inputMode: "decimal",
689
- placeholder: "6.25%",
1044
+ placeholder: "Enter your desired rate",
690
1045
  value: values.desiredRate ? `${values.desiredRate}%` : "",
691
- onChange: (e) => updateValue("desiredRate", formatPercentInput(e.target.value))
1046
+ onChange: (e) => updateValue("desiredRate", formatPercentInput(e.target.value)),
1047
+ "aria-describedby": errors.desiredRate ? "desiredRate-error" : void 0,
1048
+ "aria-invalid": !!errors.desiredRate
692
1049
  }
693
1050
  ),
694
- errors.desiredRate ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.desiredRate }) : null
1051
+ errors.desiredRate ? /* @__PURE__ */ jsx(
1052
+ "p",
1053
+ {
1054
+ id: "desiredRate-error",
1055
+ className: errorText,
1056
+ role: "alert",
1057
+ children: errors.desiredRate
1058
+ }
1059
+ ) : null
695
1060
  ] }),
696
1061
  /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
697
- /* @__PURE__ */ jsxs(Label, { className: fieldLabel, children: [
698
- "Discount Points",
699
- " ",
700
- /* @__PURE__ */ jsx("span", { className: optionalText, children: "(Optional)" })
701
- ] }),
1062
+ /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Discount Points" }),
702
1063
  /* @__PURE__ */ jsx(
703
1064
  Input,
704
1065
  {
@@ -706,72 +1067,108 @@ function MortgageRateStep() {
706
1067
  type: "text",
707
1068
  inputMode: "decimal",
708
1069
  placeholder: "1.0",
709
- value: values.discountPoints,
710
- onChange: (e) => updateValue("discountPoints", e.target.value)
1070
+ value: values.discountPoints ? `${values.discountPoints}%` : "",
1071
+ onChange: (e) => updateValue(
1072
+ "discountPoints",
1073
+ formatPercentInput(e.target.value)
1074
+ ),
1075
+ "aria-describedby": errors.discountPoints ? "discountPoints-error" : void 0,
1076
+ "aria-invalid": !!errors.discountPoints
711
1077
  }
712
- )
713
- ] })
714
- ] });
715
- case "contact":
716
- return /* @__PURE__ */ jsxs("div", { className: inputGrid, style: { marginTop: "24px" }, children: [
717
- /* @__PURE__ */ jsxs("div", { className: inputRowTwo, children: [
718
- /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
719
- /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "First Name" }),
720
- /* @__PURE__ */ jsx(
721
- Input,
722
- {
723
- className: input,
724
- type: "text",
725
- placeholder: "Enter your first name",
726
- value: values.firstName,
727
- onChange: (e) => updateValue("firstName", e.target.value)
728
- }
729
- ),
730
- errors.firstName ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.firstName }) : null
731
- ] }),
732
- /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
733
- /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Last Name" }),
734
- /* @__PURE__ */ jsx(
735
- Input,
736
- {
737
- className: input,
738
- type: "text",
739
- placeholder: "Enter your last name",
740
- value: values.lastName,
741
- onChange: (e) => updateValue("lastName", e.target.value)
742
- }
743
- ),
744
- errors.lastName ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.lastName }) : null
745
- ] })
746
- ] }),
747
- /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
748
- /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Email" }),
749
- /* @__PURE__ */ jsx(
750
- Input,
1078
+ ),
1079
+ errors.discountPoints ? /* @__PURE__ */ jsx(
1080
+ "p",
751
1081
  {
752
- className: input,
753
- type: "email",
754
- placeholder: "Enter your email",
755
- value: values.email,
756
- onChange: (e) => updateValue("email", e.target.value)
1082
+ id: "discountPoints-error",
1083
+ className: errorText,
1084
+ role: "alert",
1085
+ children: errors.discountPoints
757
1086
  }
758
- ),
759
- errors.email ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.email }) : null
1087
+ ) : null
760
1088
  ] }),
761
1089
  /* @__PURE__ */ jsxs(Field, { className: fieldBlock, children: [
762
- /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "Phone Number" }),
763
- /* @__PURE__ */ jsx(
764
- Input,
1090
+ /* @__PURE__ */ jsxs(
1091
+ Listbox,
765
1092
  {
766
- className: input,
767
- type: "tel",
768
- inputMode: "tel",
769
- placeholder: "(XXX) XXX-XXXX",
770
- value: values.phoneNumber,
771
- onChange: (e) => updateValue("phoneNumber", formatPhoneInput(e.target.value))
1093
+ value: values.updateFrequency,
1094
+ onChange: (value) => updateValue("updateFrequency", value),
1095
+ children: [
1096
+ /* @__PURE__ */ jsx(Label, { className: fieldLabel, children: "How often would you like rate updates?" }),
1097
+ /* @__PURE__ */ jsxs("div", { className: selectWrap, style: { marginTop: "0px" }, children: [
1098
+ /* @__PURE__ */ jsx(
1099
+ ListboxButton,
1100
+ {
1101
+ className: selectButton,
1102
+ "aria-describedby": errors.updateFrequency ? "updateFrequency-error" : void 0,
1103
+ "aria-invalid": !!errors.updateFrequency,
1104
+ children: ({ open }) => /* @__PURE__ */ jsxs(Fragment, { children: [
1105
+ /* @__PURE__ */ jsx(
1106
+ "span",
1107
+ {
1108
+ className: values.updateFrequency ? "" : selectButtonPlaceholder,
1109
+ children: values.updateFrequency ? updateFrequencyOptions.find(
1110
+ (o) => o.value === values.updateFrequency
1111
+ )?.label : "Select update frequency"
1112
+ }
1113
+ ),
1114
+ /* @__PURE__ */ jsx(
1115
+ "svg",
1116
+ {
1117
+ className: selectChevron,
1118
+ "data-open": open,
1119
+ viewBox: "0 0 20 20",
1120
+ fill: "none",
1121
+ xmlns: "http://www.w3.org/2000/svg",
1122
+ "aria-hidden": "true",
1123
+ children: /* @__PURE__ */ jsx(
1124
+ "path",
1125
+ {
1126
+ d: "M5 7.5L10 12.5L15 7.5",
1127
+ stroke: "currentColor",
1128
+ strokeWidth: "2",
1129
+ strokeLinecap: "round",
1130
+ strokeLinejoin: "round"
1131
+ }
1132
+ )
1133
+ }
1134
+ )
1135
+ ] })
1136
+ }
1137
+ ),
1138
+ /* @__PURE__ */ jsx(
1139
+ ListboxOptions,
1140
+ {
1141
+ className: selectOptions,
1142
+ modal: false,
1143
+ children: updateFrequencyOptions.map((option) => /* @__PURE__ */ jsx(
1144
+ ListboxOption,
1145
+ {
1146
+ value: option.value,
1147
+ className: selectOption,
1148
+ children: option.label
1149
+ },
1150
+ option.value
1151
+ ))
1152
+ }
1153
+ )
1154
+ ] })
1155
+ ]
772
1156
  }
773
1157
  ),
774
- errors.phoneNumber ? /* @__PURE__ */ jsx("p", { className: errorText, children: errors.phoneNumber }) : null
1158
+ errors.updateFrequency ? /* @__PURE__ */ jsx(
1159
+ "p",
1160
+ {
1161
+ id: "updateFrequency-error",
1162
+ className: errorText,
1163
+ role: "alert",
1164
+ style: { marginTop: "8px" },
1165
+ children: errors.updateFrequency
1166
+ }
1167
+ ) : null
1168
+ ] }),
1169
+ /* @__PURE__ */ jsxs("p", { className: autoAdvanceHint, children: [
1170
+ /* @__PURE__ */ jsx("sup", { children: "*" }),
1171
+ "Minimum 2% and no more than 10%."
775
1172
  ] })
776
1173
  ] });
777
1174
  default:
@@ -791,42 +1188,64 @@ function MortgageRateStep() {
791
1188
  ] }) });
792
1189
  }
793
1190
  const isCurrentStepAutoAdvanceStep = isAutoAdvanceStep(stepKey);
794
- const continueButtonLabel = isCurrentStepAutoAdvanceStep && isAutoAdvancing ? "Continuing…" : currentStepIndex === totalSteps - 1 ? "Submit" : "Continue";
1191
+ const continueButtonLabel = isCurrentStepAutoAdvanceStep && isAutoAdvancing ? "Continuing…" : currentStepIndex === totalSteps - 1 ? "Start Watching Rates" : "Continue";
795
1192
  const continueButtonDisabled = isCurrentStepAutoAdvanceStep && isAutoAdvancing;
796
1193
  return /* @__PURE__ */ jsxs("section", { className: section, children: [
797
- stepKey === "mortgageType" && /* @__PURE__ */ jsxs("div", { className: "text_center", children: [
798
- /* @__PURE__ */ jsx("h1", { className: mainTitle, children: "Rate Watch" }),
799
- /* @__PURE__ */ jsx("p", { className: mainDescription, children: "Get a personalized rate based on your needs. It only takes a few minutes." })
1194
+ stepKey === "contact" && /* @__PURE__ */ jsxs("div", { className: "text_center", children: [
1195
+ /* @__PURE__ */ jsxs("div", { className: "flex middle center", style: { gap: "16px" }, children: [
1196
+ /* @__PURE__ */ jsx("h1", { className: mainTitle, children: "Rate Watch" }),
1197
+ /* @__PURE__ */ jsx(AlertBellIcon, {})
1198
+ ] }),
1199
+ /* @__PURE__ */ jsx("p", { className: mainDescription, children: "Receive alerts for a customized rate tailored to your requirements. It only takes a couple of minutes." })
800
1200
  ] }),
801
1201
  /* @__PURE__ */ jsxs("div", { className: formShell, children: [
802
1202
  /* @__PURE__ */ jsxs("div", { className: progressWrap, children: [
803
1203
  /* @__PURE__ */ jsxs("div", { className: progressRow, children: [
804
- /* @__PURE__ */ jsxs("span", { className: progressLabel, children: [
805
- "Step ",
806
- currentStepIndex + 1,
807
- " of ",
808
- totalSteps
809
- ] }),
1204
+ /* @__PURE__ */ jsxs(
1205
+ "span",
1206
+ {
1207
+ className: progressLabel,
1208
+ "aria-live": "polite",
1209
+ "aria-atomic": "true",
1210
+ children: [
1211
+ "Step ",
1212
+ currentStepIndex + 1,
1213
+ " of ",
1214
+ totalSteps
1215
+ ]
1216
+ }
1217
+ ),
810
1218
  /* @__PURE__ */ jsxs("span", { className: progressLabel, children: [
811
1219
  Math.round(progress),
812
1220
  "%"
813
1221
  ] })
814
1222
  ] }),
815
- /* @__PURE__ */ jsx("div", { className: progressTrack, children: /* @__PURE__ */ jsx(
1223
+ /* @__PURE__ */ jsx(
816
1224
  "div",
817
1225
  {
818
- className: progressFill,
819
- style: { width: `${progress}%` }
1226
+ className: progressTrack,
1227
+ role: "progressbar",
1228
+ "aria-valuenow": Math.round(progress),
1229
+ "aria-valuemin": 0,
1230
+ "aria-valuemax": 100,
1231
+ "aria-label": "Form completion progress",
1232
+ children: /* @__PURE__ */ jsx(
1233
+ "div",
1234
+ {
1235
+ className: progressFill,
1236
+ style: { width: `${progress}%` }
1237
+ }
1238
+ )
820
1239
  }
821
- ) })
1240
+ )
822
1241
  ] }),
823
1242
  /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxs(
824
1243
  motion.div,
825
1244
  {
826
1245
  className: stepPanel,
827
- initial: { opacity: 0, x: 28 },
1246
+ initial: { opacity: 0, x: 15 },
828
1247
  animate: { opacity: 1, x: 0 },
829
- exit: { opacity: 0, x: -28 },
1248
+ exit: { opacity: 0, x: -15 },
830
1249
  transition: { duration: 0.24, ease: "easeOut" },
831
1250
  children: [
832
1251
  /* @__PURE__ */ jsx("h2", { className: title, children: getStepTitle() }),
@@ -840,6 +1259,8 @@ function MortgageRateStep() {
840
1259
  className: secondaryButton,
841
1260
  onClick: goBack,
842
1261
  disabled: currentStepIndex === 0,
1262
+ "aria-disabled": currentStepIndex === 0,
1263
+ "aria-label": currentStepIndex === 0 ? "Back button, disabled, you are on the first step" : "Back button, go to previous step",
843
1264
  children: "Back"
844
1265
  }
845
1266
  ),
@@ -850,13 +1271,37 @@ function MortgageRateStep() {
850
1271
  className: primaryButton,
851
1272
  onClick: goNext,
852
1273
  disabled: continueButtonDisabled,
1274
+ "aria-disabled": continueButtonDisabled,
1275
+ "aria-label": continueButtonDisabled ? `${continueButtonLabel} button, disabled, processing selection` : `${continueButtonLabel} button, go to next step`,
853
1276
  children: continueButtonLabel
854
1277
  }
855
1278
  )
856
1279
  ] }),
857
- stepKey === "mortgageType" && /* @__PURE__ */ jsxs("div", { className: disclosure, children: [
1280
+ stepKey === "contact" && /* @__PURE__ */ jsxs("div", { className: disclosure, children: [
1281
+ /* @__PURE__ */ jsxs(
1282
+ "p",
1283
+ {
1284
+ className: `${disclosureText} ${disclosureTextSm}`,
1285
+ children: [
1286
+ "By continuing, you agree to these",
1287
+ " ",
1288
+ /* @__PURE__ */ jsx("a", { href: "https://assets.axos.com/o9ov1v03uwqk/6gQNHxCzLuaoCeivQk84N4/14ae33b36f550b3c776d2840be513fb9/SMS-and-MMS-Disclosure-Axos-Bank.pdf", children: "Terms and Conditions" }),
1289
+ ", and you have agreed to receive automated SMS text messages, calls, and emails for any purpose including but not limited to marketing of products and services by Axos Bank. You understand and agree that such messages may be sent via Automatic Telephone Dialing System and/or artificial or pre-recorded voice, and that such consent is not a condition of receipt of any good or service. Mobile carrier messages and data rates may apply. You may opt out at any time."
1290
+ ]
1291
+ }
1292
+ ),
1293
+ /* @__PURE__ */ jsx(
1294
+ "p",
1295
+ {
1296
+ className: `${disclosureText} ${disclosureTextSm}`,
1297
+ style: { marginTop: "8px" },
1298
+ children: "If you do not wish to receive your rate quote by email or SMS text, please call 888-546-2364 to speak with a mortgage expert to receive a rate quote."
1299
+ }
1300
+ )
1301
+ ] }),
1302
+ stepKey === "finalDetails" && /* @__PURE__ */ jsxs("div", { className: disclosure, children: [
858
1303
  /* @__PURE__ */ jsx("p", { className: disclosureTitle, children: "Important information" }),
859
- /* @__PURE__ */ jsx("p", { className: disclosureText, children: "By continuing, you agree to provide information so Axos can better understand your mortgage needs. Mortgage products are subject to underwriting and approval. Rates, terms, and product availability may vary based on credit profile, property type, occupancy, loan amount, and other factors. This form is for informational purposes only and is not a commitment to lend. NMLS #524995." })
1304
+ /* @__PURE__ */ jsx("p", { className: disclosureText, children: "Mortgage products are subject to underwriting and approval. Rates, terms, and product availability may vary based on credit profile, property type, occupancy, loan amount, and other factors. This form is for informational purposes only and is not a commitment to lend. NMLS #524995." })
860
1305
  ] })
861
1306
  ]
862
1307
  },