@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 +289 -0
- package/dist/credify-insurance-widget.css +1 -0
- package/dist/iframe/assets/iframe-C4lVsnfn.js +50 -0
- package/dist/iframe/assets/iframe-C4lVsnfn.js.map +1 -0
- package/dist/iframe/assets/iframe-ohWV1j6m.css +1 -0
- package/dist/iframe/iframe.html +24 -0
- package/dist/iframe/vite.svg +1 -0
- package/dist/index.es.js +26610 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +272 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/vite.svg +1 -0
- package/package.json +64 -0
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}}}
|