@getcredify/credify-insurance-widget 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,289 @@
1
+ # Credify Insurance Widget
2
+
3
+ A React-based insurance quote widget that can be embedded via script tag or iframe.
4
+
5
+ ## Installation
6
+
7
+ ### As an npm Package
8
+
9
+ ```bash
10
+ npm install @getcredify/credify-insurance-widget
11
+ ```
12
+
13
+ ### Peer Dependencies
14
+
15
+ This package requires React 19+ as a peer dependency:
16
+
17
+ ```bash
18
+ npm install react@^19.0.0 react-dom@^19.0.0
19
+ ```
20
+
21
+ ### For Local Development
22
+
23
+ ```bash
24
+ npm install
25
+ ```
26
+
27
+ ## Development
28
+
29
+ ### Library Mode (Script Tag)
30
+
31
+ ```bash
32
+ npm run dev
33
+ ```
34
+
35
+ ### Iframe Mode
36
+
37
+ ```bash
38
+ npm run dev:iframe
39
+ ```
40
+
41
+ ## Building
42
+
43
+ Build both library and iframe versions:
44
+
45
+ ```bash
46
+ npm run build
47
+ ```
48
+
49
+ Build only library version:
50
+
51
+ ```bash
52
+ npm run build:lib
53
+ ```
54
+
55
+ Build only iframe version:
56
+
57
+ ```bash
58
+ npm run build:iframe
59
+ ```
60
+
61
+ ## Embedding Methods
62
+
63
+ ### Method 1: npm Package (Recommended)
64
+
65
+ Install and import the widget in your React application:
66
+
67
+ ```tsx
68
+ import { CredifyInsuranceWidget } from '@getcredify/credify-insurance-widget';
69
+ import '@getcredify/credify-insurance-widget/widget.css';
70
+
71
+ function App() {
72
+ useEffect(() => {
73
+ // Initialize the widget
74
+ CredifyInsuranceWidget.init({ autoOpen: false });
75
+ }, []);
76
+
77
+ return (
78
+ <div>
79
+ <button onClick={() => CredifyInsuranceWidget.open()}>Open Widget</button>
80
+ <button onClick={() => CredifyInsuranceWidget.close()}>Close Widget</button>
81
+ </div>
82
+ );
83
+ }
84
+ ```
85
+
86
+ **Note:** Make sure to import the CSS file for proper styling.
87
+
88
+ ### Method 2: Script Tag Embedding (UMD)
89
+
90
+ Include the widget as a script tag on your page:
91
+
92
+ ```html
93
+ <!DOCTYPE html>
94
+ <html>
95
+ <head>
96
+ <script src="https://your-cdn.com/widget/index.umd.js"></script>
97
+ <!-- Also include React and ReactDOM if not already present -->
98
+ <script src="https://unpkg.com/react@19/umd/react.production.min.js"></script>
99
+ <script src="https://unpkg.com/react-dom@19/umd/react-dom.production.min.js"></script>
100
+ </head>
101
+ <body>
102
+ <button onclick="window.CredifyInsuranceWidget.open()">Open Widget</button>
103
+
104
+ <script>
105
+ // Initialize the widget
106
+ window.CredifyInsuranceWidget.init({ autoOpen: false });
107
+
108
+ // Open the widget
109
+ function openWidget() {
110
+ window.CredifyInsuranceWidget.open();
111
+ }
112
+
113
+ // Close the widget
114
+ function closeWidget() {
115
+ window.CredifyInsuranceWidget.close();
116
+ }
117
+ </script>
118
+ </body>
119
+ </html>
120
+ ```
121
+
122
+ See `examples/umd.html` for a complete example.
123
+
124
+ **CDN Usage:**
125
+
126
+ The package is also available via CDN:
127
+
128
+ ```html
129
+ <script src="https://unpkg.com/@getcredify/credify-insurance-widget/dist/index.umd.js"></script>
130
+ ```
131
+
132
+ ### Method 3: Iframe Embedding (Cross-Origin)
133
+
134
+ The widget can be embedded as an iframe on different origins. This is useful for:
135
+
136
+ - Isolating the widget from your site's CSS/JavaScript
137
+ - Serving the widget from a different domain
138
+ - Better security and performance isolation
139
+
140
+ #### Step 1: Deploy the Widget
141
+
142
+ After building with `npm run build:iframe`, deploy the contents of `dist/iframe/` to your server.
143
+
144
+ **Note:** The iframe HTML is available at `@getcredify/credify-insurance-widget/iframe` after installation, but typically you'll want to deploy it to your own server.
145
+
146
+ #### Step 2: Embed the Iframe
147
+
148
+ ```html
149
+ <!DOCTYPE html>
150
+ <html>
151
+ <head>
152
+ <title>My Page</title>
153
+ </head>
154
+ <body>
155
+ <button id="open-btn">Open Widget</button>
156
+ <button id="close-btn">Close Widget</button>
157
+
158
+ <iframe
159
+ id="widget-iframe"
160
+ src="https://your-widget-domain.com/iframe.html"
161
+ width="100%"
162
+ height="700"
163
+ style="border: none;"
164
+ allow="clipboard-read; clipboard-write"
165
+ sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox"
166
+ ></iframe>
167
+
168
+ <script>
169
+ const iframe = document.getElementById('widget-iframe');
170
+
171
+ // Open the widget
172
+ document.getElementById('open-btn').addEventListener('click', () => {
173
+ iframe.contentWindow.postMessage(
174
+ {
175
+ type: 'open',
176
+ source: 'credify-insurance-widget'
177
+ },
178
+ 'https://your-widget-domain.com'
179
+ );
180
+ });
181
+
182
+ // Close the widget
183
+ document.getElementById('close-btn').addEventListener('click', () => {
184
+ iframe.contentWindow.postMessage(
185
+ {
186
+ type: 'close',
187
+ source: 'credify-insurance-widget'
188
+ },
189
+ 'https://your-widget-domain.com'
190
+ );
191
+ });
192
+
193
+ // Listen for events from the widget
194
+ window.addEventListener('message', (event) => {
195
+ // Verify origin for security
196
+ if (event.origin !== 'https://your-widget-domain.com') return;
197
+
198
+ if (event.data?.source === 'credify-insurance-widget') {
199
+ switch (event.data.type) {
200
+ case 'ready':
201
+ console.log('Widget is ready');
202
+ break;
203
+ case 'opened':
204
+ console.log('Widget opened');
205
+ break;
206
+ case 'closed':
207
+ console.log('Widget closed');
208
+ break;
209
+ }
210
+ }
211
+ });
212
+ </script>
213
+ </body>
214
+ </html>
215
+ ```
216
+
217
+ See `examples/iframe.html` for a complete example.
218
+
219
+ ## PostMessage API
220
+
221
+ When using iframe embedding, the widget communicates via the [postMessage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage).
222
+
223
+ ### Commands (Parent → Widget)
224
+
225
+ Send these messages to the widget:
226
+
227
+ - `{ type: 'open', source: 'credify-insurance-widget' }` - Opens the widget
228
+ - `{ type: 'close', source: 'credify-insurance-widget' }` - Closes the widget
229
+ - `{ type: 'init', source: 'credify-insurance-widget' }` - Initializes the widget (sent automatically)
230
+
231
+ ### Events (Widget → Parent)
232
+
233
+ Listen for these events from the widget:
234
+
235
+ - `{ type: 'ready', source: 'credify-insurance-widget' }` - Widget is ready
236
+ - `{ type: 'opened', source: 'credify-insurance-widget' }` - Widget has opened
237
+ - `{ type: 'closed', source: 'credify-insurance-widget' }` - Widget has closed
238
+
239
+ ## Server Configuration
240
+
241
+ When serving the widget for iframe embedding, ensure your server:
242
+
243
+ 1. **Allows iframe embedding** - Do NOT set `X-Frame-Options: DENY` or `X-Frame-Options: SAMEORIGIN` headers. To allow embedding from specific origins, use Content Security Policy:
244
+
245
+ ```
246
+ Content-Security-Policy: frame-ancestors 'self' https://example.com https://another-domain.com;
247
+ ```
248
+
249
+ 2. **Sets CORS headers** (if needed for API calls):
250
+
251
+ ```
252
+ Access-Control-Allow-Origin: *
253
+ Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
254
+ Access-Control-Allow-Headers: Content-Type, Authorization
255
+ ```
256
+
257
+ 3. **Serves the iframe HTML** from the `dist/iframe/` directory after building
258
+
259
+ ## Security Considerations
260
+
261
+ - **Origin Verification**: In production, always verify `event.origin` when receiving postMessage events to prevent XSS attacks
262
+ - **Specific Origins**: Replace `'*'` with specific origins in postMessage calls for better security
263
+ - **HTTPS**: Always serve the widget over HTTPS in production
264
+ - **CSP**: Consider implementing Content Security Policy headers for additional protection
265
+
266
+ ## API Reference
267
+
268
+ ### Script Tag API
269
+
270
+ ```typescript
271
+ interface CredifyInsuranceWidgetAPI {
272
+ init(options?: { autoOpen?: boolean }): void;
273
+ open(): void;
274
+ close(): void;
275
+ destroy(): void;
276
+ }
277
+ ```
278
+
279
+ - `init(options?)` - Initialize the widget. Set `autoOpen: true` to open immediately.
280
+ - `open()` - Open the widget
281
+ - `close()` - Close the widget
282
+ - `destroy()` - Remove the widget from the DOM
283
+
284
+ ## Examples
285
+
286
+ See the `examples/` directory for complete working examples:
287
+
288
+ - `umd.html` - Script tag embedding
289
+ - `iframe.html` - Iframe embedding with postMessage communication
@@ -0,0 +1 @@
1
+ @import"https://fonts.googleapis.com/css2?family=Spline+Sans:wght@400;500;700&display=swap";/*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */@layer properties,theme,base,components,utilities;@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-600:oklch(57.7% .245 27.325);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-900:oklch(20.8% .042 265.755);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-300:oklch(87.2% .01 258.338);--color-white:#fff;--spacing:.25rem;--container-lg:32rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing)*0)}.top-4{top:calc(var(--spacing)*4)}.right-4{right:calc(var(--spacing)*4)}.z-\[9999\]{z-index:9999}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-auto{margin-top:auto}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.ml-1{margin-left:calc(var(--spacing)*1)}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-12{height:calc(var(--spacing)*12)}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-screen{min-height:100vh}.w-12{width:calc(var(--spacing)*12)}.w-auto{width:auto}.w-full{width:100%}.max-w-lg{max-width:var(--container-lg)}.flex-1{flex:1}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-blue-600{border-color:var(--color-blue-600)}.border-gray-300{border-color:var(--color-gray-300)}.border-slate-200{border-color:var(--color-slate-200)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-300{background-color:var(--color-gray-300)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-white{background-color:var(--color-white)}.object-contain{object-fit:contain}.p-3{padding:calc(var(--spacing)*3)}.p-6{padding:calc(var(--spacing)*6)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-1{padding-block:calc(var(--spacing)*1)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.pt-4{padding-top:calc(var(--spacing)*4)}.text-center{text-align:center}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-emerald-600{color:var(--color-emerald-600)}.text-red-600{color:var(--color-red-600)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-900{color:var(--color-slate-900)}.text-white{color:var(--color-white)}.underline{text-decoration-line:underline}.opacity-75{opacity:.75}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,visibility,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.hover\:bg-blue-600\/90:hover{background-color:#155dfce6}@supports (color:color-mix(in lab,red,red)){.hover\:bg-blue-600\/90:hover{background-color:color-mix(in oklab,var(--color-blue-600)90%,transparent)}}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:text-slate-600:hover{color:var(--color-slate-600)}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-blue-600\/40:focus-visible{--tw-ring-color:#155dfc66}@supports (color:color-mix(in lab,red,red)){.focus-visible\:ring-blue-600\/40:focus-visible{--tw-ring-color:color-mix(in oklab,var(--color-blue-600)40%,transparent)}}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-slate-300:disabled{background-color:var(--color-slate-300)}.disabled\:text-slate-500:disabled{color:var(--color-slate-500)}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:64rem){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}}:root{--primary-color:#006aff;--secondary-color:#f0f4ff;--background-color:#fff;--text-primary:#1a202c;--text-secondary:#718096;--accent-color:#e2e8f0;--radius-sm:.25rem;--radius-md:.5rem;--radius-lg:.75rem;--radius-xl:1rem;--radius-2xl:1.25rem;--radius-3xl:1.75rem;--radius-full:9999px;--radio-dot-svg:url("data:image/svg+xml,%3csvg viewBox=%270 0 16 16%27 fill=%27%23006aff%27 xmlns=%27http://www.w3.org/2000/svg%27%3e%3ccircle cx=%278%27 cy=%278%27 r=%274%27/%3e%3c/svg%3e");--select-button-svg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24px' height='24px' fill='%23718096' viewBox='0 0 256 256'%3e%3cpath d='m215.39 92.94-80 80a8 8 0 0 1-11.32 0l-80-80a8 8 0 1 1 11.32-11.32L128 154.06l74.07-72.44a8 8 0 0 1 11.32 11.32Z'/%3e%3c/svg%3e")}html,body{background-color:var(--background-color);color:var(--text-primary);font-family:Spline Sans,ui-sans-serif,system-ui,sans-serif}.backdrop{background:#00000080;position:fixed;inset:0}.modal-panel{border-radius:var(--radius-2xl);background:#fff;padding:1.5rem;box-shadow:0 24px 64px -20px #00000059}@media (min-width:640px){.modal-panel{padding:2rem}}@media (min-width:768px){.modal-panel{padding:2.5rem}}.h1-title{letter-spacing:-.01em;color:var(--text-primary);font-size:1.875rem;font-weight:700;line-height:2.25rem}@media (min-width:640px){.h1-title{font-size:2.25rem;line-height:2.5rem}}.p-subtitle{color:var(--text-secondary);margin-top:.5rem}.form-label{color:var(--text-secondary);margin-bottom:.5rem;font-size:.875rem;font-weight:500;display:block}.form-input{border-radius:var(--radius-lg);border:1px solid var(--accent-color);width:100%;color:var(--text-primary);background:#fff;outline:none;padding:.75rem 1rem;font-size:1rem;transition:box-shadow .15s,border-color .15s}.form-input::placeholder{color:#94a3b8}.form-input:focus{border-color:var(--primary-color);box-shadow:0 0 0 1px var(--primary-color)}.select-caret{background-image:var(--select-button-svg);appearance:none;background-position:right .75rem center;background-repeat:no-repeat;background-size:1.25rem 1.25rem;padding-right:2.5rem}.radio-card{border-radius:var(--radius-md);border:2px solid var(--accent-color);cursor:pointer;background:#fff;align-items:center;gap:.75rem;padding:1rem;transition:all .15s;display:flex}.radio-card:hover{border-color:#cfd8e3}.radio-input{border:2px solid var(--accent-color);appearance:none;background:0 0;border-radius:9999px;outline:none;width:1.25rem;height:1.25rem}.radio-input:checked{border-color:var(--primary-color);background-image:var(--radio-dot-svg);background-position:50%;background-repeat:no-repeat}.radio-card:has(.radio-input:checked){border-color:var(--primary-color);box-shadow:0 0 0 2px var(--primary-color)}@supports (color:color-mix(in lab,red,red)){.radio-card:has(.radio-input:checked){box-shadow:0 0 0 2px color-mix(in oklab,var(--primary-color)20%,transparent)}}.radio-label{color:var(--text-primary);font-size:1rem;font-weight:600}.btn-primary{border-radius:var(--radius-full);background:var(--primary-color);color:#fff;letter-spacing:.02em;justify-content:center;align-items:center;width:100%;height:3rem;font-weight:700;transition:opacity .15s;display:flex}.btn-primary:hover{opacity:.9}.btn-outline{border-radius:var(--radius-full);width:100%;height:3rem;color:var(--text-primary);border:1px solid var(--accent-color);letter-spacing:.02em;background:#fff;justify-content:center;align-items:center;font-weight:700;transition:background .15s,color .15s,border-color .15s,opacity .15s;display:flex}.btn-outline:hover{border-color:#cfd8e3}.btn-primary,.btn-outline{cursor:pointer}.btn-primary:disabled,.btn-outline:disabled{opacity:.5;cursor:not-allowed;filter:grayscale(20%)}.btn-primary:not(:disabled):hover{opacity:.95}.btn-outline:not(:disabled):hover{border-color:#cfd8e3}.quote-btn{background-color:var(--color-blue-600);padding-inline:calc(var(--spacing)*6);padding-block:calc(var(--spacing)*3);--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--color-white);--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,visibility,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-radius:3.40282e38px}@media (hover:hover){.quote-btn:hover{background-color:var(--color-blue-700)}}.input-error{border-color:#dc2626!important;box-shadow:0 0 0 1px #dc2626!important}.checkbox-card{border-radius:var(--radius-md);border:2px solid var(--accent-color);cursor:pointer;background:#fff;align-items:center;gap:.75rem;padding:1rem;transition:all .15s;display:flex}.checkbox-card:hover{border-color:#cfd8e3}.checkbox-input{border:2px solid var(--accent-color);appearance:none;background:#fff;border-radius:.375rem;outline:none;place-items:center;width:1.25rem;height:1.25rem;display:grid}.checkbox-input:checked{border-color:var(--primary-color);background-color:var(--primary-color);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' viewBox='0 0 24 24'%3e%3cpath d='M20.285 6.709a1 1 0 0 1 0 1.414l-9.192 9.193a1 1 0 0 1-1.414 0L3.715 11.55a1 1 0 1 1 1.414-1.414l5.05 5.05 8.485-8.478a1 1 0 0 1 1.621.001z'/%3e%3c/svg%3e");background-position:50%;background-repeat:no-repeat}.checkbox-card:has(.checkbox-input:checked){border-color:var(--primary-color);box-shadow:0 0 0 2px var(--primary-color)}@supports (color:color-mix(in lab,red,red)){.checkbox-card:has(.checkbox-input:checked){box-shadow:0 0 0 2px color-mix(in oklab,var(--primary-color)20%,transparent)}}.checkbox-label{color:var(--text-primary);font-size:1rem;font-weight:600}.modal-scroll{overscroll-behavior:contain;-webkit-overflow-scrolling:touch;max-height:min(90dvh,800px);overflow-y:auto}.modal-scroll .h1-title{z-index:1;background:#fff;padding-top:.25rem;padding-bottom:.75rem;position:sticky;top:0}.form-label:has(+input[aria-required=true]):after,.form-label:has(+select[aria-required=true]):after,.form-label:has(+textarea[aria-required=true]):after,.legend-required:after{content:" *";color:#dc2626;margin-left:.25rem}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}