Created
April 10, 2026 22:20
-
-
Save wesmith4/f22d8fbcc8fb2d7a2e18bba7b731160a to your computer and use it in GitHub Desktop.
Insurify In-House Survey Platform — Proof of Concept Demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Insurify Survey Platform — Proof of Concept</title> | |
| <link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&display=swap" rel="stylesheet"> | |
| <style> | |
| /* ============================================================ | |
| RESET & BASE | |
| ============================================================ */ | |
| *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } | |
| html { | |
| font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
| font-size: 16px; | |
| color: #191919; | |
| background: #f8f8f7; | |
| -webkit-font-smoothing: antialiased; | |
| } | |
| body { min-height: 100vh; } | |
| /* ============================================================ | |
| INSURIFY DESIGN TOKENS | |
| ============================================================ */ | |
| :root { | |
| --color-primary: #fb4d19; | |
| --color-primary-hover: #a53e03; | |
| --color-primary-pressed: #6b2802; | |
| --color-primary-light: #feebe1; | |
| --color-primary-lighter: #ffede8; | |
| --color-primary-bg: #ffede8; | |
| --color-primary-dark: #4b1708; | |
| --color-accent: #385fee; | |
| --color-accent-light: #e8ecfd; | |
| --color-success: #6bd425; | |
| --color-success-dark: #407f16; | |
| --color-success-bg: #eaf9e0; | |
| --color-warning: #ffc800; | |
| --color-text: #191919; | |
| --color-text-secondary: #7c7c7c; | |
| --color-text-muted: #959594; | |
| --color-border: #dfdfde; | |
| --color-border-light: #f8f8f7; | |
| --color-bg-white: #ffffff; | |
| --color-bg-page: #f8f8f7; | |
| --color-bg-card: #ffffff; | |
| --shadow-sm: 0px -1px 6px 0px rgba(25,25,25,0.01), 0px 3px 12px 0px rgba(25,25,25,0.08); | |
| --shadow-md: 0px 3px 16px 0px rgba(25,25,25,0.1), 0px -3px 6px 0px rgba(25,25,25,0.02), 0px 10px 16px 0px rgba(25,25,25,0.04); | |
| --shadow-lg: 0px 3px 20px 0px rgba(25,25,25,0.12), 0px -3px 6px 0px rgba(25,25,25,0.04), 0px 12px 32px 0px rgba(25,25,25,0.1); | |
| --shadow-action: 0px 3px 16px 0px rgba(251,77,25,0.24), 0px -3px 6px 0px rgba(251,77,25,0.1), 0px 10px 16px 0px rgba(251,77,25,0.04); | |
| --radius-sm: 8px; | |
| --radius-md: 12px; | |
| --radius-lg: 16px; | |
| --radius-xl: 20px; | |
| } | |
| /* ============================================================ | |
| LAYOUT | |
| ============================================================ */ | |
| .page-wrapper { | |
| max-width: 800px; | |
| margin: 0 auto; | |
| padding: 0 16px 80px; | |
| } | |
| /* ============================================================ | |
| HEADER | |
| ============================================================ */ | |
| .header { | |
| background: var(--color-primary-dark); | |
| padding: 16px 0; | |
| margin-bottom: 0; | |
| } | |
| .header-inner { | |
| max-width: 800px; | |
| margin: 0 auto; | |
| padding: 0 16px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| } | |
| .logo { | |
| font-size: 22px; | |
| font-weight: 700; | |
| color: #fff; | |
| letter-spacing: -0.5px; | |
| } | |
| .logo span { color: #fb4d19; } | |
| .header-nav { | |
| display: flex; | |
| gap: 20px; | |
| align-items: center; | |
| } | |
| .header-nav a { | |
| color: rgba(255,255,255,0.7); | |
| text-decoration: none; | |
| font-size: 14px; | |
| font-weight: 500; | |
| transition: color 0.2s; | |
| } | |
| .header-nav a:hover { color: #fff; } | |
| /* ============================================================ | |
| QUOTE LIST HEADER AREA | |
| ============================================================ */ | |
| .ql-hero { | |
| background: linear-gradient(180deg, var(--color-primary-dark) 0%, var(--color-primary-pressed) 100%); | |
| padding: 32px 0 48px; | |
| margin-bottom: -24px; | |
| } | |
| .ql-hero-inner { | |
| max-width: 800px; | |
| margin: 0 auto; | |
| padding: 0 16px; | |
| color: #fff; | |
| } | |
| .ql-hero h1 { | |
| font-size: 26px; | |
| font-weight: 700; | |
| margin-bottom: 6px; | |
| letter-spacing: -0.3px; | |
| } | |
| .ql-hero p { | |
| font-size: 15px; | |
| color: rgba(255,255,255,0.75); | |
| font-weight: 400; | |
| } | |
| .ql-meta { | |
| display: flex; | |
| gap: 24px; | |
| margin-top: 16px; | |
| } | |
| .ql-meta-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| font-size: 13px; | |
| color: rgba(255,255,255,0.6); | |
| } | |
| .ql-meta-item svg { opacity: 0.5; } | |
| /* ============================================================ | |
| SURVEY COMPONENT — THE STAR OF THE SHOW | |
| ============================================================ */ | |
| .survey-container { | |
| background: var(--color-bg-white); | |
| border-radius: var(--radius-lg); | |
| box-shadow: var(--shadow-lg); | |
| margin-bottom: 16px; | |
| overflow: hidden; | |
| transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1); | |
| border: 1px solid var(--color-border); | |
| } | |
| .survey-container.survey-hidden { | |
| max-height: 0; | |
| opacity: 0; | |
| margin-bottom: 0; | |
| border: none; | |
| box-shadow: none; | |
| } | |
| .survey-container.survey-visible { | |
| max-height: 600px; | |
| opacity: 1; | |
| } | |
| .survey-container.survey-completed { | |
| background: var(--color-success-bg); | |
| border-color: #b5e992; | |
| } | |
| .survey-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 16px 20px 0; | |
| } | |
| .survey-badge { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| font-size: 11px; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: 0.5px; | |
| color: var(--color-primary); | |
| background: var(--color-primary-lighter); | |
| padding: 4px 10px; | |
| border-radius: 100px; | |
| } | |
| .survey-badge svg { width: 12px; height: 12px; } | |
| .survey-close { | |
| width: 32px; | |
| height: 32px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| border: none; | |
| background: transparent; | |
| color: var(--color-text-muted); | |
| cursor: pointer; | |
| border-radius: 8px; | |
| transition: all 0.15s; | |
| flex-shrink: 0; | |
| } | |
| .survey-close:hover { | |
| background: var(--color-border-light); | |
| color: var(--color-text-secondary); | |
| } | |
| .survey-body { | |
| padding: 12px 20px 20px; | |
| } | |
| .survey-question { | |
| font-size: 17px; | |
| font-weight: 600; | |
| color: var(--color-text); | |
| margin-bottom: 4px; | |
| line-height: 1.4; | |
| letter-spacing: -0.2px; | |
| } | |
| .survey-subtitle { | |
| font-size: 13px; | |
| color: var(--color-text-secondary); | |
| margin-bottom: 16px; | |
| line-height: 1.5; | |
| } | |
| /* Progress bar */ | |
| .survey-progress { | |
| display: flex; | |
| gap: 4px; | |
| margin-bottom: 16px; | |
| } | |
| .survey-progress-step { | |
| height: 3px; | |
| flex: 1; | |
| border-radius: 2px; | |
| background: var(--color-border); | |
| transition: background 0.3s ease; | |
| } | |
| .survey-progress-step.active { | |
| background: var(--color-primary); | |
| } | |
| .survey-progress-step.completed { | |
| background: var(--color-success); | |
| } | |
| /* Option buttons */ | |
| .survey-options { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| } | |
| .survey-option { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| padding: 12px 16px; | |
| border: 1.5px solid var(--color-border); | |
| border-radius: var(--radius-sm); | |
| background: var(--color-bg-white); | |
| cursor: pointer; | |
| transition: all 0.15s ease; | |
| font-size: 15px; | |
| color: var(--color-text); | |
| text-align: left; | |
| width: 100%; | |
| font-family: inherit; | |
| line-height: 1.4; | |
| } | |
| .survey-option:hover { | |
| border-color: #f9ad81; | |
| background: var(--color-primary-lighter); | |
| } | |
| .survey-option.selected { | |
| border-color: var(--color-primary); | |
| background: var(--color-primary-light); | |
| } | |
| .survey-option-radio { | |
| width: 18px; | |
| height: 18px; | |
| border-radius: 50%; | |
| border: 2px solid var(--color-border); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| flex-shrink: 0; | |
| transition: all 0.15s; | |
| } | |
| .survey-option:hover .survey-option-radio { | |
| border-color: #f9ad81; | |
| } | |
| .survey-option.selected .survey-option-radio { | |
| border-color: var(--color-primary); | |
| background: var(--color-primary); | |
| } | |
| .survey-option.selected .survey-option-radio::after { | |
| content: ''; | |
| width: 6px; | |
| height: 6px; | |
| border-radius: 50%; | |
| background: white; | |
| } | |
| /* Text input */ | |
| .survey-input { | |
| width: 100%; | |
| padding: 12px 16px; | |
| border: 1.5px solid var(--color-border); | |
| border-radius: var(--radius-sm); | |
| font-family: inherit; | |
| font-size: 15px; | |
| color: var(--color-text); | |
| transition: border-color 0.15s; | |
| outline: none; | |
| } | |
| .survey-input:focus { | |
| border-color: var(--color-primary); | |
| box-shadow: 0 0 0 3px rgba(251,77,25,0.1); | |
| } | |
| .survey-input::placeholder { | |
| color: var(--color-text-muted); | |
| } | |
| /* Action buttons */ | |
| .survey-actions { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-top: 16px; | |
| gap: 12px; | |
| } | |
| .survey-btn-primary { | |
| padding: 10px 24px; | |
| background: var(--color-primary); | |
| color: white; | |
| border: none; | |
| border-radius: var(--radius-sm); | |
| font-family: inherit; | |
| font-size: 14px; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: all 0.15s; | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| } | |
| .survey-btn-primary:hover { | |
| background: var(--color-primary-hover); | |
| transform: translateY(-1px); | |
| box-shadow: var(--shadow-action); | |
| } | |
| .survey-btn-primary:disabled { | |
| background: #f9ad81; | |
| color: #ffffff; | |
| cursor: not-allowed; | |
| transform: none; | |
| box-shadow: none; | |
| opacity: 0.6; | |
| } | |
| .survey-btn-skip { | |
| padding: 10px 16px; | |
| background: transparent; | |
| color: var(--color-text-muted); | |
| border: none; | |
| font-family: inherit; | |
| font-size: 13px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: color 0.15s; | |
| } | |
| .survey-btn-skip:hover { | |
| color: var(--color-text-secondary); | |
| } | |
| /* Completion state */ | |
| .survey-complete-content { | |
| text-align: center; | |
| padding: 8px 0; | |
| } | |
| .survey-complete-icon { | |
| width: 48px; | |
| height: 48px; | |
| background: var(--color-success); | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| margin: 0 auto 12px; | |
| } | |
| .survey-complete-title { | |
| font-size: 17px; | |
| font-weight: 600; | |
| color: var(--color-text); | |
| margin-bottom: 4px; | |
| } | |
| .survey-complete-text { | |
| font-size: 14px; | |
| color: var(--color-text-secondary); | |
| line-height: 1.5; | |
| } | |
| /* Step transitions */ | |
| .survey-step { | |
| display: none; | |
| animation: fadeSlideIn 0.3s ease forwards; | |
| } | |
| .survey-step.active { | |
| display: block; | |
| } | |
| @keyframes fadeSlideIn { | |
| from { opacity: 0; transform: translateY(8px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| /* ============================================================ | |
| QUOTE CARDS | |
| ============================================================ */ | |
| .quote-card { | |
| background: var(--color-bg-card); | |
| border: 1px solid var(--color-border); | |
| border-radius: var(--radius-md); | |
| padding: 20px; | |
| margin-bottom: 12px; | |
| box-shadow: var(--shadow-sm); | |
| transition: all 0.2s; | |
| display: flex; | |
| align-items: center; | |
| gap: 16px; | |
| } | |
| .quote-card:hover { | |
| box-shadow: var(--shadow-md); | |
| border-color: #cbd5e1; | |
| } | |
| .quote-carrier-logo { | |
| width: 56px; | |
| height: 56px; | |
| border-radius: var(--radius-sm); | |
| background: var(--color-border-light); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| flex-shrink: 0; | |
| font-weight: 700; | |
| font-size: 11px; | |
| color: var(--color-text-secondary); | |
| text-align: center; | |
| line-height: 1.2; | |
| } | |
| .quote-info { | |
| flex: 1; | |
| min-width: 0; | |
| } | |
| .quote-carrier-name { | |
| font-size: 16px; | |
| font-weight: 600; | |
| color: var(--color-text); | |
| margin-bottom: 2px; | |
| } | |
| .quote-coverage { | |
| font-size: 13px; | |
| color: var(--color-text-secondary); | |
| } | |
| .quote-price-area { | |
| text-align: right; | |
| flex-shrink: 0; | |
| } | |
| .quote-price { | |
| font-size: 24px; | |
| font-weight: 700; | |
| color: var(--color-primary); | |
| letter-spacing: -0.5px; | |
| } | |
| .quote-price-period { | |
| font-size: 12px; | |
| color: var(--color-text-muted); | |
| font-weight: 400; | |
| } | |
| .quote-cta { | |
| margin-top: 6px; | |
| padding: 6px 16px; | |
| background: var(--color-primary); | |
| color: white; | |
| border: none; | |
| border-radius: 6px; | |
| font-family: inherit; | |
| font-size: 13px; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: all 0.15s; | |
| } | |
| .quote-cta:hover { | |
| background: var(--color-primary-hover); | |
| } | |
| .quote-savings-badge { | |
| display: inline-block; | |
| background: var(--color-success-bg); | |
| color: #2b550f; | |
| font-size: 11px; | |
| font-weight: 600; | |
| padding: 2px 8px; | |
| border-radius: 100px; | |
| margin-top: 4px; | |
| } | |
| /* ============================================================ | |
| DEMO BANNER | |
| ============================================================ */ | |
| .demo-banner { | |
| background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); | |
| border: 1px solid #f59e0b; | |
| border-radius: var(--radius-md); | |
| padding: 16px 20px; | |
| margin-bottom: 20px; | |
| display: flex; | |
| align-items: flex-start; | |
| gap: 12px; | |
| } | |
| .demo-banner-icon { | |
| width: 24px; | |
| height: 24px; | |
| flex-shrink: 0; | |
| margin-top: 1px; | |
| } | |
| .demo-banner h3 { | |
| font-size: 14px; | |
| font-weight: 600; | |
| color: #92400e; | |
| margin-bottom: 4px; | |
| } | |
| .demo-banner p { | |
| font-size: 13px; | |
| color: #a16207; | |
| line-height: 1.5; | |
| } | |
| .demo-banner code { | |
| background: rgba(0,0,0,0.08); | |
| padding: 1px 5px; | |
| border-radius: 4px; | |
| font-size: 12px; | |
| } | |
| /* ============================================================ | |
| CONFIG PANEL (collapsible) | |
| ============================================================ */ | |
| .config-panel { | |
| background: #1e1e2e; | |
| border-radius: var(--radius-md); | |
| margin-bottom: 20px; | |
| overflow: hidden; | |
| box-shadow: var(--shadow-lg); | |
| } | |
| .config-toggle { | |
| width: 100%; | |
| padding: 14px 20px; | |
| background: #1e1e2e; | |
| border: none; | |
| color: #a6adc8; | |
| font-family: inherit; | |
| font-size: 13px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| text-align: left; | |
| transition: background 0.15s; | |
| } | |
| .config-toggle:hover { background: #262637; } | |
| .config-toggle-label { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .config-toggle-dot { | |
| width: 8px; | |
| height: 8px; | |
| border-radius: 50%; | |
| background: var(--color-success); | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0%, 100% { opacity: 1; } | |
| 50% { opacity: 0.4; } | |
| } | |
| .config-toggle-arrow { | |
| transition: transform 0.2s; | |
| font-size: 11px; | |
| } | |
| .config-toggle.open .config-toggle-arrow { | |
| transform: rotate(180deg); | |
| } | |
| .config-content { | |
| max-height: 0; | |
| overflow: hidden; | |
| transition: max-height 0.3s ease; | |
| } | |
| .config-content.open { | |
| max-height: 800px; | |
| } | |
| .config-code { | |
| padding: 0 20px 16px; | |
| overflow-x: auto; | |
| } | |
| .config-code pre { | |
| font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace; | |
| font-size: 12px; | |
| line-height: 1.6; | |
| color: #cdd6f4; | |
| white-space: pre; | |
| margin: 0; | |
| } | |
| .config-code .key { color: #89b4fa; } | |
| .config-code .str { color: #a6e3a1; } | |
| .config-code .num { color: #fab387; } | |
| .config-code .bool { color: #f38ba8; } | |
| .config-code .comment { color: #585b70; font-style: italic; } | |
| .config-code .bracket { color: #9399b2; } | |
| .config-code .label { color: #cba6f7; } | |
| /* ============================================================ | |
| RESPONSIVE | |
| ============================================================ */ | |
| @media (max-width: 600px) { | |
| .ql-hero h1 { font-size: 22px; } | |
| .quote-card { flex-wrap: wrap; gap: 12px; } | |
| .quote-price-area { | |
| width: 100%; | |
| text-align: left; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| } | |
| .ql-meta { flex-wrap: wrap; gap: 12px; } | |
| .survey-question { font-size: 16px; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- ============================================================ | |
| HEADER | |
| ============================================================ --> | |
| <header class="header"> | |
| <div class="header-inner"> | |
| <div class="logo">insurify<span>.</span></div> | |
| <nav class="header-nav"> | |
| <a href="#">Auto</a> | |
| <a href="#">Home</a> | |
| <a href="#">Life</a> | |
| </nav> | |
| </div> | |
| </header> | |
| <!-- ============================================================ | |
| QUOTE LIST HERO | |
| ============================================================ --> | |
| <div class="ql-hero"> | |
| <div class="ql-hero-inner"> | |
| <h1>Your Auto Insurance Quotes</h1> | |
| <p>We found 8 quotes from top carriers for your 2022 Honda Civic</p> | |
| <div class="ql-meta"> | |
| <div class="ql-meta-item"> | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg> | |
| Sarah M., 34 | |
| </div> | |
| <div class="ql-meta-item"> | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg> | |
| Austin, TX | |
| </div> | |
| <div class="ql-meta-item"> | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg> | |
| Updated today | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ============================================================ | |
| MAIN CONTENT | |
| ============================================================ --> | |
| <div class="page-wrapper"> | |
| <!-- DEMO CONTEXT BANNER --> | |
| <div class="demo-banner"> | |
| <svg class="demo-banner-icon" viewBox="0 0 24 24" fill="none" stroke="#92400e" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg> | |
| <div> | |
| <h3>Proof of Concept — In-House Survey Platform</h3> | |
| <p>This demo shows a multi-step conditional survey rendered <strong>inline</strong> on a mock quote list page. The survey is entirely defined by a JSON config — no vendor SDK, no external scripts. Toggle the config below to see the survey definition.</p> | |
| </div> | |
| </div> | |
| <!-- CONFIG PANEL --> | |
| <div class="config-panel"> | |
| <button class="config-toggle" onclick="toggleConfig()" id="configToggle"> | |
| <span class="config-toggle-label"> | |
| <span class="config-toggle-dot"></span> | |
| survey-config.json — the entire survey definition | |
| </span> | |
| <span class="config-toggle-arrow">▼</span> | |
| </button> | |
| <div class="config-content" id="configContent"> | |
| <div class="config-code"> | |
| <pre><span class="bracket">{</span> | |
| <span class="key">"id"</span>: <span class="str">"survey_post_clickout_return_q2"</span>, | |
| <span class="key">"name"</span>: <span class="str">"Post-Clickout Return Survey"</span>, | |
| <span class="key">"status"</span>: <span class="str">"active"</span>, | |
| <span class="key">"eppo_flag"</span>: <span class="str">"survey_clickout_return_q2_2026"</span>, | |
| <span class="key">"targeting"</span>: <span class="bracket">{</span> | |
| <span class="key">"user_type"</span>: <span class="str">"returning"</span>, | |
| <span class="key">"event_trigger"</span>: <span class="str">"ad_click:*"</span>, <span class="comment">// any prior ad clickout</span> | |
| <span class="key">"page"</span>: <span class="str">"quote_list"</span>, | |
| <span class="key">"traffic_pct"</span>: <span class="num">15</span>, <span class="comment">// 15% of eligible users</span> | |
| <span class="key">"frequency_cap"</span>: <span class="str">"1 per user per week"</span> | |
| <span class="bracket">}</span>, | |
| <span class="key">"display"</span>: <span class="bracket">{</span> | |
| <span class="key">"mode"</span>: <span class="str">"inline"</span>, <span class="comment">// renders in-flow, not overlay</span> | |
| <span class="key">"position"</span>: <span class="str">"before_results"</span>, | |
| <span class="key">"auto_dismiss_seconds"</span>: <span class="num">60</span> | |
| <span class="bracket">}</span>, | |
| <span class="key">"questions"</span>: <span class="bracket">[</span> | |
| <span class="bracket">{</span> | |
| <span class="key">"id"</span>: <span class="str">"q_purchase_status"</span>, | |
| <span class="key">"type"</span>: <span class="str">"single_choice"</span>, | |
| <span class="key">"text"</span>: <span class="str">"Welcome back! Since your last visit, have you purchased a policy?"</span>, | |
| <span class="key">"options"</span>: <span class="bracket">[</span> | |
| <span class="bracket">{</span> <span class="key">"value"</span>: <span class="str">"purchased"</span>, <span class="key">"label"</span>: <span class="str">"Yes, I purchased a policy"</span>, <span class="key">"next"</span>: <span class="str">"q_which_carrier"</span> <span class="bracket">}</span>, | |
| <span class="bracket">{</span> <span class="key">"value"</span>: <span class="str">"still_shopping"</span>, <span class="key">"label"</span>: <span class="str">"Not yet — still comparing"</span>, <span class="key">"next"</span>: <span class="str">"q_whats_missing"</span> <span class="bracket">}</span>, | |
| <span class="bracket">{</span> <span class="key">"value"</span>: <span class="str">"not_ready"</span>, <span class="key">"label"</span>: <span class="str">"No, I'm not ready to switch yet"</span>, <span class="key">"next"</span>: <span class="str">"q_whats_missing"</span> <span class="bracket">}</span> | |
| <span class="bracket">]</span>, | |
| <span class="label">// persist "purchased" → update user.policy_status</span> | |
| <span class="key">"write_back"</span>: <span class="bracket">{</span> <span class="key">"field"</span>: <span class="str">"user.shopping_status"</span>, <span class="key">"map"</span>: <span class="bracket">{</span> <span class="str">"purchased"</span>: <span class="str">"converted"</span> <span class="bracket">}</span> <span class="bracket">}</span> | |
| <span class="bracket">}</span>, | |
| <span class="bracket">{</span> | |
| <span class="key">"id"</span>: <span class="str">"q_which_carrier"</span>, | |
| <span class="key">"type"</span>: <span class="str">"single_choice"</span>, | |
| <span class="key">"text"</span>: <span class="str">"Great! Which carrier did you go with?"</span>, | |
| <span class="key">"options"</span>: <span class="bracket">[</span> | |
| <span class="bracket">{</span> <span class="key">"value"</span>: <span class="str">"from_insurify"</span>, <span class="key">"label"</span>: <span class="str">"One I found on Insurify"</span>, <span class="key">"next"</span>: <span class="str">"q_rate_satisfaction"</span> <span class="bracket">}</span>, | |
| <span class="bracket">{</span> <span class="key">"value"</span>: <span class="str">"elsewhere"</span>, <span class="key">"label"</span>: <span class="str">"A carrier I found somewhere else"</span>, <span class="key">"next"</span>: <span class="str">"q_why_elsewhere"</span> <span class="bracket">}</span>, | |
| <span class="bracket">{</span> <span class="key">"value"</span>: <span class="str">"stayed"</span>, <span class="key">"label"</span>: <span class="str">"I stayed with my current carrier"</span>, <span class="key">"next"</span>: <span class="str">"q_why_stayed"</span> <span class="bracket">}</span> | |
| <span class="bracket">]</span>, | |
| <span class="key">"write_back"</span>: <span class="bracket">{</span> <span class="key">"field"</span>: <span class="str">"user.purchase_source"</span> <span class="bracket">}</span> | |
| <span class="bracket">}</span>, | |
| <span class="bracket">{</span> | |
| <span class="key">"id"</span>: <span class="str">"q_whats_missing"</span>, | |
| <span class="key">"type"</span>: <span class="str">"single_choice"</span>, | |
| <span class="key">"text"</span>: <span class="str">"What would help you make a decision?"</span>, | |
| <span class="key">"options"</span>: <span class="bracket">[</span> | |
| <span class="bracket">{</span> <span class="key">"value"</span>: <span class="str">"cheaper"</span>, <span class="key">"label"</span>: <span class="str">"I need to see cheaper rates"</span> <span class="bracket">}</span>, | |
| <span class="bracket">{</span> <span class="key">"value"</span>: <span class="str">"compare"</span>, <span class="key">"label"</span>: <span class="str">"I want to compare against my current policy"</span> <span class="bracket">}</span>, | |
| <span class="bracket">{</span> <span class="key">"value"</span>: <span class="str">"understand"</span>, <span class="key">"label"</span>: <span class="str">"I don't understand the coverage differences"</span> <span class="bracket">}</span>, | |
| <span class="bracket">{</span> <span class="key">"value"</span>: <span class="str">"talk"</span>, <span class="key">"label"</span>: <span class="str">"I want to talk to someone first"</span> <span class="bracket">}</span> | |
| <span class="bracket">]</span>, | |
| <span class="key">"write_back"</span>: <span class="bracket">{</span> <span class="key">"field"</span>: <span class="str">"user.shopping_blocker"</span> <span class="bracket">}</span> | |
| <span class="bracket">}</span>, | |
| <span class="comment">// ... additional branch questions omitted for brevity</span> | |
| <span class="bracket">]</span> | |
| <span class="bracket">}</span></pre> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ============================================================ | |
| SURVEY (inline, before results) | |
| ============================================================ --> | |
| <div class="survey-container survey-visible" id="surveyContainer"> | |
| <!-- Step 1: Purchase status --> | |
| <div class="survey-step active" id="step1"> | |
| <div class="survey-header"> | |
| <div class="survey-badge"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg> | |
| Quick question | |
| </div> | |
| <button class="survey-close" onclick="dismissSurvey()" aria-label="Close survey"> | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> | |
| </button> | |
| </div> | |
| <div class="survey-body"> | |
| <div class="survey-progress"> | |
| <div class="survey-progress-step active"></div> | |
| <div class="survey-progress-step"></div> | |
| <div class="survey-progress-step"></div> | |
| </div> | |
| <div class="survey-question">Welcome back! Since your last visit, have you purchased a policy?</div> | |
| <div class="survey-subtitle">This helps us show you more relevant information.</div> | |
| <div class="survey-options"> | |
| <button class="survey-option" onclick="selectOption(this, 'step1', 'purchased')"> | |
| <div class="survey-option-radio"></div> | |
| Yes, I purchased a policy | |
| </button> | |
| <button class="survey-option" onclick="selectOption(this, 'step1', 'still_shopping')"> | |
| <div class="survey-option-radio"></div> | |
| Not yet — still comparing | |
| </button> | |
| <button class="survey-option" onclick="selectOption(this, 'step1', 'not_ready')"> | |
| <div class="survey-option-radio"></div> | |
| No, I'm not ready to switch yet | |
| </button> | |
| </div> | |
| <div class="survey-actions"> | |
| <button class="survey-btn-skip" onclick="dismissSurvey()">Not now</button> | |
| <button class="survey-btn-primary" id="step1Next" disabled onclick="goToStep2()"> | |
| Continue | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="9 18 15 12 9 6"/></svg> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Step 2a: Which carrier (shown if purchased) --> | |
| <div class="survey-step" id="step2a"> | |
| <div class="survey-header"> | |
| <div class="survey-badge"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg> | |
| Quick question | |
| </div> | |
| <button class="survey-close" onclick="dismissSurvey()" aria-label="Close survey"> | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> | |
| </button> | |
| </div> | |
| <div class="survey-body"> | |
| <div class="survey-progress"> | |
| <div class="survey-progress-step completed"></div> | |
| <div class="survey-progress-step active"></div> | |
| <div class="survey-progress-step"></div> | |
| </div> | |
| <div class="survey-question">Great! Which carrier did you go with?</div> | |
| <div class="survey-subtitle">We'd love to know where you ended up.</div> | |
| <div class="survey-options"> | |
| <button class="survey-option" onclick="selectOption(this, 'step2a', 'from_insurify')"> | |
| <div class="survey-option-radio"></div> | |
| One I found on Insurify | |
| </button> | |
| <button class="survey-option" onclick="selectOption(this, 'step2a', 'elsewhere')"> | |
| <div class="survey-option-radio"></div> | |
| A carrier I found somewhere else | |
| </button> | |
| <button class="survey-option" onclick="selectOption(this, 'step2a', 'stayed')"> | |
| <div class="survey-option-radio"></div> | |
| I stayed with my current carrier | |
| </button> | |
| </div> | |
| <div class="survey-actions"> | |
| <button class="survey-btn-skip" onclick="dismissSurvey()">Skip</button> | |
| <button class="survey-btn-primary" id="step2aNext" disabled onclick="goToStep3('purchased')"> | |
| Continue | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="9 18 15 12 9 6"/></svg> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Step 2b: What's missing (shown if not purchased) --> | |
| <div class="survey-step" id="step2b"> | |
| <div class="survey-header"> | |
| <div class="survey-badge"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg> | |
| Quick question | |
| </div> | |
| <button class="survey-close" onclick="dismissSurvey()" aria-label="Close survey"> | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> | |
| </button> | |
| </div> | |
| <div class="survey-body"> | |
| <div class="survey-progress"> | |
| <div class="survey-progress-step completed"></div> | |
| <div class="survey-progress-step active"></div> | |
| <div class="survey-progress-step"></div> | |
| </div> | |
| <div class="survey-question">What would help you make a decision?</div> | |
| <div class="survey-subtitle">Your feedback shapes what we build next.</div> | |
| <div class="survey-options"> | |
| <button class="survey-option" onclick="selectOption(this, 'step2b', 'cheaper')"> | |
| <div class="survey-option-radio"></div> | |
| I need to see cheaper rates | |
| </button> | |
| <button class="survey-option" onclick="selectOption(this, 'step2b', 'compare')"> | |
| <div class="survey-option-radio"></div> | |
| I want to compare against my current policy | |
| </button> | |
| <button class="survey-option" onclick="selectOption(this, 'step2b', 'understand')"> | |
| <div class="survey-option-radio"></div> | |
| I don't understand the coverage differences | |
| </button> | |
| <button class="survey-option" onclick="selectOption(this, 'step2b', 'talk')"> | |
| <div class="survey-option-radio"></div> | |
| I want to talk to someone first | |
| </button> | |
| </div> | |
| <div class="survey-actions"> | |
| <button class="survey-btn-skip" onclick="dismissSurvey()">Skip</button> | |
| <button class="survey-btn-primary" id="step2bNext" disabled onclick="goToStep3('not_purchased')"> | |
| Continue | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="9 18 15 12 9 6"/></svg> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Step 3a: Rate satisfaction (purchased path) --> | |
| <div class="survey-step" id="step3a"> | |
| <div class="survey-header"> | |
| <div class="survey-badge"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg> | |
| Quick question | |
| </div> | |
| <button class="survey-close" onclick="dismissSurvey()" aria-label="Close survey"> | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> | |
| </button> | |
| </div> | |
| <div class="survey-body"> | |
| <div class="survey-progress"> | |
| <div class="survey-progress-step completed"></div> | |
| <div class="survey-progress-step completed"></div> | |
| <div class="survey-progress-step active"></div> | |
| </div> | |
| <div class="survey-question">How does your new rate compare to what you expected?</div> | |
| <div class="survey-subtitle">Last question — thank you for your time.</div> | |
| <div class="survey-options"> | |
| <button class="survey-option" onclick="selectOption(this, 'step3a', 'better')"> | |
| <div class="survey-option-radio"></div> | |
| Better than I expected | |
| </button> | |
| <button class="survey-option" onclick="selectOption(this, 'step3a', 'expected')"> | |
| <div class="survey-option-radio"></div> | |
| About what I expected | |
| </button> | |
| <button class="survey-option" onclick="selectOption(this, 'step3a', 'worse')"> | |
| <div class="survey-option-radio"></div> | |
| More expensive than I hoped | |
| </button> | |
| </div> | |
| <div class="survey-actions"> | |
| <button class="survey-btn-skip" onclick="dismissSurvey()">Skip</button> | |
| <button class="survey-btn-primary" id="step3aNext" disabled onclick="completeSurvey()"> | |
| Submit | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Step 3b: Current premium (not purchased path) --> | |
| <div class="survey-step" id="step3b"> | |
| <div class="survey-header"> | |
| <div class="survey-badge"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg> | |
| Quick question | |
| </div> | |
| <button class="survey-close" onclick="dismissSurvey()" aria-label="Close survey"> | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> | |
| </button> | |
| </div> | |
| <div class="survey-body"> | |
| <div class="survey-progress"> | |
| <div class="survey-progress-step completed"></div> | |
| <div class="survey-progress-step completed"></div> | |
| <div class="survey-progress-step active"></div> | |
| </div> | |
| <div class="survey-question">What do you currently pay per month for auto insurance?</div> | |
| <div class="survey-subtitle">This helps us highlight quotes that could save you money.</div> | |
| <div style="display: flex; align-items: center; gap: 8px;"> | |
| <span style="font-size: 20px; font-weight: 600; color: var(--color-text);">$</span> | |
| <input type="number" class="survey-input" id="premiumInput" placeholder="e.g. 150" min="0" max="2000" oninput="validatePremium()"> | |
| <span style="font-size: 14px; color: var(--color-text-secondary);">/mo</span> | |
| </div> | |
| <div class="survey-actions"> | |
| <button class="survey-btn-skip" onclick="completeSurvey()">Skip</button> | |
| <button class="survey-btn-primary" id="step3bNext" disabled onclick="completeSurvey()"> | |
| Submit | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Completion --> | |
| <div class="survey-step" id="stepComplete"> | |
| <div class="survey-body" style="padding: 24px 20px;"> | |
| <div class="survey-complete-content"> | |
| <div class="survey-complete-icon"> | |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg> | |
| </div> | |
| <div class="survey-complete-title">Thanks for sharing!</div> | |
| <div class="survey-complete-text">Your feedback helps us build a better experience for you.</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ============================================================ | |
| QUOTE CARDS | |
| ============================================================ --> | |
| <div class="quote-card"> | |
| <div class="quote-carrier-logo" style="background: #e8f5e9; color: #2e7d32;">GEICO</div> | |
| <div class="quote-info"> | |
| <div class="quote-carrier-name">GEICO</div> | |
| <div class="quote-coverage">Full Coverage · 100/300/100 · $500 deductible</div> | |
| <div class="quote-savings-badge">Saves $47/mo vs. avg</div> | |
| </div> | |
| <div class="quote-price-area"> | |
| <div class="quote-price">$89<span class="quote-price-period">/mo</span></div> | |
| <button class="quote-cta">View Details</button> | |
| </div> | |
| </div> | |
| <div class="quote-card"> | |
| <div class="quote-carrier-logo" style="background: #e3f2fd; color: #1565c0;">State Farm</div> | |
| <div class="quote-info"> | |
| <div class="quote-carrier-name">State Farm</div> | |
| <div class="quote-coverage">Full Coverage · 100/300/100 · $500 deductible</div> | |
| </div> | |
| <div class="quote-price-area"> | |
| <div class="quote-price">$102<span class="quote-price-period">/mo</span></div> | |
| <button class="quote-cta">View Details</button> | |
| </div> | |
| </div> | |
| <div class="quote-card"> | |
| <div class="quote-carrier-logo" style="background: #fff3e0; color: #e65100;">Progres-<br>sive</div> | |
| <div class="quote-info"> | |
| <div class="quote-carrier-name">Progressive</div> | |
| <div class="quote-coverage">Full Coverage · 100/300/100 · $500 deductible</div> | |
| </div> | |
| <div class="quote-price-area"> | |
| <div class="quote-price">$118<span class="quote-price-period">/mo</span></div> | |
| <button class="quote-cta">View Details</button> | |
| </div> | |
| </div> | |
| <div class="quote-card"> | |
| <div class="quote-carrier-logo" style="background: #fce4ec; color: #c62828;">Liberty Mutual</div> | |
| <div class="quote-info"> | |
| <div class="quote-carrier-name">Liberty Mutual</div> | |
| <div class="quote-coverage">Full Coverage · 100/300/100 · $1000 deductible</div> | |
| </div> | |
| <div class="quote-price-area"> | |
| <div class="quote-price">$124<span class="quote-price-period">/mo</span></div> | |
| <button class="quote-cta">View Details</button> | |
| </div> | |
| </div> | |
| <div class="quote-card"> | |
| <div class="quote-carrier-logo" style="background: #f3e5f5; color: #6a1b9a;">Allstate</div> | |
| <div class="quote-info"> | |
| <div class="quote-carrier-name">Allstate</div> | |
| <div class="quote-coverage">Full Coverage · 50/100/50 · $500 deductible</div> | |
| </div> | |
| <div class="quote-price-area"> | |
| <div class="quote-price">$131<span class="quote-price-period">/mo</span></div> | |
| <button class="quote-cta">View Details</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ============================================================ | |
| JAVASCRIPT | |
| ============================================================ --> | |
| <script> | |
| // State | |
| let selectedValues = {}; | |
| let currentBranch = null; | |
| function selectOption(el, stepId, value) { | |
| // Deselect siblings | |
| el.parentElement.querySelectorAll('.survey-option').forEach(opt => opt.classList.remove('selected')); | |
| // Select this one | |
| el.classList.add('selected'); | |
| // Store value | |
| selectedValues[stepId] = value; | |
| // Enable the next button | |
| const nextBtn = document.getElementById(stepId + 'Next'); | |
| if (nextBtn) nextBtn.disabled = false; | |
| } | |
| function goToStep2() { | |
| const v = selectedValues['step1']; | |
| document.getElementById('step1').classList.remove('active'); | |
| if (v === 'purchased') { | |
| currentBranch = 'purchased'; | |
| document.getElementById('step2a').classList.add('active'); | |
| } else { | |
| currentBranch = 'not_purchased'; | |
| document.getElementById('step2b').classList.add('active'); | |
| } | |
| scrollToSurvey(); | |
| } | |
| function goToStep3(branch) { | |
| document.getElementById('step2a').classList.remove('active'); | |
| document.getElementById('step2b').classList.remove('active'); | |
| if (branch === 'purchased') { | |
| document.getElementById('step3a').classList.add('active'); | |
| } else { | |
| document.getElementById('step3b').classList.add('active'); | |
| } | |
| scrollToSurvey(); | |
| } | |
| function validatePremium() { | |
| const input = document.getElementById('premiumInput'); | |
| const btn = document.getElementById('step3bNext'); | |
| btn.disabled = !input.value || input.value <= 0; | |
| } | |
| function completeSurvey() { | |
| // Hide all steps | |
| document.querySelectorAll('.survey-step').forEach(s => s.classList.remove('active')); | |
| // Show completion | |
| const container = document.getElementById('surveyContainer'); | |
| container.classList.add('survey-completed'); | |
| document.getElementById('stepComplete').classList.add('active'); | |
| // Auto-collapse after 3 seconds | |
| setTimeout(() => { | |
| container.classList.remove('survey-visible'); | |
| container.classList.add('survey-hidden'); | |
| }, 3000); | |
| scrollToSurvey(); | |
| } | |
| function dismissSurvey() { | |
| const container = document.getElementById('surveyContainer'); | |
| container.classList.remove('survey-visible'); | |
| container.classList.add('survey-hidden'); | |
| } | |
| function scrollToSurvey() { | |
| document.getElementById('surveyContainer').scrollIntoView({ behavior: 'smooth', block: 'nearest' }); | |
| } | |
| // Config panel toggle | |
| function toggleConfig() { | |
| const toggle = document.getElementById('configToggle'); | |
| const content = document.getElementById('configContent'); | |
| toggle.classList.toggle('open'); | |
| content.classList.toggle('open'); | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment