Skip to content

Instantly share code, notes, and snippets.

@wesmith4
Created April 10, 2026 22:20
Show Gist options
  • Select an option

  • Save wesmith4/f22d8fbcc8fb2d7a2e18bba7b731160a to your computer and use it in GitHub Desktop.

Select an option

Save wesmith4/f22d8fbcc8fb2d7a2e18bba7b731160a to your computer and use it in GitHub Desktop.
Insurify In-House Survey Platform — Proof of Concept Demo
<!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">&#9660;</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