Find your coffee

How do you take your coffee?

Find your coffee

What kind of coffee drinker are you?

Find your coffee

Do you have a coffee grinder?

One more thing

How do you brew?

Finding your perfect coffee…
'; var key = state.q1 + '-' + state.q2; var match = RESULTS[key] || { primary: 'il_caramello', secondary: 'png' }; var pKey = match.primary; var sKey = match.secondary; /* LE substitution */ if (LE_LIVE && pKey === 'guatemalan') { sKey = 'guatemalan'; pKey = 'limited'; } var primary = PRODUCTS[pKey]; var secondary = PRODUCTS[sKey]; var decaf = PRODUCTS.decaf; var fetchProduct = function(handle) { return fetch('/products/' + handle + '.js') .then(function(r) { return r.json(); }) .catch(function() { return null; }); }; /* Fetch rating from product page HTML — jdgm data attributes are server-rendered */ var fetchRating = fetch('/products/' + primary.handle) .then(function(r) { return r.text(); }) .then(function(html) { var doc = new DOMParser().parseFromString(html, 'text/html'); var el = doc.querySelector('[data-average-rating]'); return el ? { rating: parseFloat(el.dataset.averageRating), count: parseInt(el.dataset.numberOfReviews, 10), } : null; }) .catch(function() { return null; }); /* Fetch primary, secondary, decaf, and rating simultaneously */ var needsDecaf = primary.handle !== decaf.handle && secondary.handle !== decaf.handle; Promise.all([ fetchProduct(primary.handle), fetchProduct(secondary.handle), needsDecaf ? fetchProduct(decaf.handle) : Promise.resolve(null), fetchRating, ]).then(function(results) { renderResults(primary, secondary, results[0], results[1], results[2], results[3]); }); } /* Build a suggestion product card */ function buildCard(product, shopifyProduct) { var imgSrc = ''; if (shopifyProduct && shopifyProduct.media && shopifyProduct.media[0]) { imgSrc = shopifyProduct.media[0].src; } else if (shopifyProduct && shopifyProduct.featured_image) { imgSrc = String(shopifyProduct.featured_image); if (imgSrc.indexOf('//') === 0) imgSrc = 'https:' + imgSrc; } var imgHTML = imgSrc ? '' + esc(product.name) + '' : '
'; return '' + imgHTML + '
' + '

' + esc(product.name) + '

' + '

' + esc(product.tagline) + '

' + 'View →' + '
' + '
'; } function renderResults(primary, secondary, sp, secondarySp, decafSp, ratingData) { var ga = grindAnswer(); /* ── Options from live product data ── */ var sizeIdx = sp ? sp.options.findIndex(function(o) { return o.name.toLowerCase().includes('size'); }) : -1; var grindIdx = sp ? sp.options.findIndex(function(o) { return o.name.toLowerCase().includes('grind'); }) : -1; var allSizes = (sp && sizeIdx >= 0) ? sp.options[sizeIdx].values : []; var allGrinds = (sp && grindIdx >= 0) ? sp.options[grindIdx].values : []; var defaultSize = sp ? defaultSizeFor(sp) : null; var grindSearch = GRIND_SEARCH[ga] || 'whole'; var defaultGrind = allGrinds.find(function(g) { return norm(g).includes(norm(grindSearch)); }) || allGrinds[0]; /* Initial variant */ var initVariant = sp ? findVariantByAnswer(sp, defaultSize, ga) : null; var variantId = initVariant ? initVariant.id : null; /* ── Product image ── */ var imgSrc = null; if (sp && sp.media && sp.media[0] && sp.media[0].src) { imgSrc = sp.media[0].src; } else if (sp && sp.featured_image) { imgSrc = String(sp.featured_image); if (imgSrc.indexOf('//') === 0) imgSrc = 'https:' + imgSrc; } var imageHTML = imgSrc ? '
' + esc(primary.name) + '
' : ''; /* ── Selectors — hide size if only one option ── */ var sizePills = allSizes.map(function(s) { var active = norm(s) === norm(defaultSize) ? 'goo-quiz__pill--active' : ''; return ''; }).join(''); var grindPills = allGrinds.map(function(g) { var active = g === defaultGrind ? 'goo-quiz__pill--active' : ''; return ''; }).join(''); var selectorsHTML = ''; if (sp) { if (allSizes.length > 1) { selectorsHTML += '

Size

' + sizePills + '
'; } if (allGrinds.length > 0) { selectorsHTML += '

Grind

' + grindPills + '
'; } } /* ── Subscription price from selling plan ── */ var subPrice = null; if (sp && sp.selling_plan_groups && sp.selling_plan_groups[0] && initVariant) { var plan = sp.selling_plan_groups[0].selling_plans[0]; if (plan && plan.price_adjustments && plan.price_adjustments[0]) { var adj = plan.price_adjustments[0]; if (adj.value_type === 'price') { subPrice = adj.value; } else if (adj.value_type === 'percentage') { subPrice = Math.round(initVariant.price * (1 - adj.value / 100)); } else if (adj.value_type === 'fixed_amount') { subPrice = initVariant.price - adj.value; } } } /* ── Star rating ── */ var ratingHTML = ''; if (ratingData && ratingData.rating && ratingData.count) { var starsHTML = ''; for (var i = 1; i <= 5; i++) { var cls = i <= Math.round(ratingData.rating) ? '' : ' goo-quiz__star--off'; starsHTML += '★'; } ratingHTML = '
' + '
' + starsHTML + '
' + '' + ratingData.rating.toFixed(1) + ' (' + ratingData.count + ' reviews)' + '
'; } /* ── Blind Date badge ── */ var bdBadgeHTML = primary.handle === PRODUCTS.blinddate.handle ? 'Subscription only — every 6 weeks' : ''; /* ── Price display ── */ var priceHTML = ''; if (initVariant && initVariant.price) { var fullPrice = initVariant.price; var fullFmt = '$' + (fullPrice / 100).toFixed(2); if (primary.handle === PRODUCTS.blinddate.handle && subPrice && subPrice !== fullPrice) { priceHTML = '
' + '$' + (subPrice / 100).toFixed(2) + '' + '' + fullFmt + '' + '
' + '

Delivered every 6 weeks

'; } else if (primary.subscription && subPrice && subPrice !== fullPrice) { var subFmt = '$' + (subPrice / 100).toFixed(2); var saveFmt = '$' + ((fullPrice - subPrice) / 100).toFixed(2); priceHTML = '
' + '

' + subFmt + ' on subscription (Save ' + saveFmt + ')

' + '

' + fullFmt + ' one-time

' + '
'; } else { priceHTML = '

' + fullFmt + '

'; } } /* ── Track result shown ── */ trackEvent('quiz_result', { quiz_name: 'coffee_finder', product_name: primary.name, product_handle: primary.handle, q1: state.q1, q2: state.q2, q3: state.q3, q4: state.q4 || null, }); /* ── CTAs — all link to product page with UTM attribution ── */ var variantParam = variantId ? '?variant=' + variantId + '&utm_source=quiz&utm_medium=onsite' : '?utm_source=quiz&utm_medium=onsite'; var baseUrl = '/products/' + primary.handle; var ctaLabel = primary.handle === PRODUCTS.blinddate.handle ? 'Subscribe Now →' : 'Shop Now →'; var ctaHTML = '
' + '' + ctaLabel + '' + '
'; /* ── Suggestion cards ── */ var showDecaf = primary.handle !== PRODUCTS.decaf.handle && secondary.handle !== PRODUCTS.decaf.handle; var suggestionsHTML = '
' + '

Also worth exploring

' + '
' + buildCard(secondary, secondarySp) + (showDecaf ? buildCard(PRODUCTS.decaf, decafSp) : '') + '
' + '
'; /* ── Render ── */ resultCard.innerHTML = imageHTML + '

Here\'s what we\'d suggest

' + '

' + esc(primary.name) + '

' + ratingHTML + bdBadgeHTML + '

' + esc(primary.tagline) + '

' + '

' + esc(primary.desc) + '

' + selectorsHTML + priceHTML + ctaHTML + suggestionsHTML + '
'; if (sp) attachPills(sp, primary, defaultGrind); /* Track CTA click */ var shopBtn = document.getElementById('gooShopBtn'); if (shopBtn) { shopBtn.addEventListener('click', function() { trackEvent('quiz_cta_click', { quiz_name: 'coffee_finder', product_name: primary.name, product_handle: primary.handle, cta_label: this.textContent.trim(), }); }); } var restartBtn = document.getElementById('gooRestart'); if (restartBtn) restartBtn.addEventListener('click', restart); } /* ── PILL INTERACTION ─────────────────────────────────────────────── */ function attachPills(sp, primary, initGrind) { var currentSize = null; var currentGrind = initGrind || null; var activeSizePill = document.querySelector('#gooSizePills .goo-quiz__pill--active'); var activeGrindPill = document.querySelector('#gooGrindPills .goo-quiz__pill--active'); if (activeSizePill) currentSize = activeSizePill.dataset.val; if (activeGrindPill) currentGrind = activeGrindPill.dataset.val; function syncVariant() { var variant = findVariantByOptions(sp, currentSize, currentGrind) || sp.variants[0]; if (!variant) return; /* Update shop link */ var shopBtn = document.getElementById('gooShopBtn'); if (shopBtn) shopBtn.href='/products/' + primary.handle + '?variant=' + variant.id + '&utm_source=quiz&utm_medium=onsite'; /* Update prices */ var fullPrice = variant.price; var newSubPrice = null; if (sp.selling_plan_groups && sp.selling_plan_groups[0]) { var adj = sp.selling_plan_groups[0].selling_plans[0].price_adjustments[0]; newSubPrice = adj.value_type === 'price' ? adj.value : Math.round(fullPrice * (1 - adj.value / 100)); } var subPriceEl = document.getElementById('gooSubPrice'); var fullPriceEl = document.getElementById('gooFullPrice'); var saveAmtEl = document.getElementById('gooSaveAmt'); var simplePriceEl = document.getElementById('gooPrice'); if (subPriceEl && newSubPrice) subPriceEl.textContent = '$' + (newSubPrice / 100).toFixed(2); if (fullPriceEl) fullPriceEl.textContent = '$' + (fullPrice / 100).toFixed(2); if (saveAmtEl && newSubPrice) saveAmtEl.textContent = '(Save $' + ((fullPrice - newSubPrice) / 100).toFixed(2) + ')'; if (simplePriceEl) simplePriceEl.textContent = '$' + (fullPrice / 100).toFixed(2); } document.querySelectorAll('#gooResultCard .goo-quiz__pill').forEach(function(pill) { pill.addEventListener('click', function() { var type = this.dataset.type; var val = this.dataset.val; var containerId = type === 'size' ? 'gooSizePills' : 'gooGrindPills'; document.querySelectorAll('#' + containerId + ' .goo-quiz__pill') .forEach(function(p) { p.classList.remove('goo-quiz__pill--active'); }); this.classList.add('goo-quiz__pill--active'); if (type === 'size') currentSize = val; if (type === 'grind') currentGrind = val; syncVariant(); }); }); } /* ── RESTART ──────────────────────────────────────────────────────── */ function restart() { state = { q1: null, q2: null, q3: null, q4: null, step: 1 }; document.querySelectorAll('.goo-quiz__option') .forEach(function(b) { b.classList.remove('goo-quiz__option--selected'); }); if (dot4) dot4.style.display = 'none'; var progress = document.getElementById('gooProgress'); if (progress) progress.style.display = ''; document.getElementById('goo-coffee-quiz').classList.remove('goo-quiz--results'); showScreen(1); updateDots(1); } })();