diff --git a/assets/images/oliver-arnold.jpg b/assets/images/oliver-arnold.jpg new file mode 100644 index 0000000..d5e2e38 Binary files /dev/null and b/assets/images/oliver-arnold.jpg differ diff --git a/index.html b/index.html index 49e16ef..0b0d1a6 100644 --- a/index.html +++ b/index.html @@ -975,6 +975,114 @@ .pricing-card.featured { transform: none; } } + /* ══════════════════════════════════════════════════════════ + PRICING SLIDER & ORDER FORM + ══════════════════════════════════════════════════════════ */ + .pricing-slider { + position: relative; + overflow: hidden; + max-width: 960px; + margin: 0 auto; + } + .pricing-slider-track { + display: flex; + transition: transform 0.5s cubic-bezier(.34,1.56,.64,1); + transform: translateX(0); + } + .pricing-slider-track.slide-left { + transform: translateX(-50%); + } + .pricing-panel, + .order-panel { + min-width: 100%; + box-sizing: border-box; + } + .order-panel { + background: var(--bg-card); + border: 1px solid var(--border-hi); + border-radius: var(--radius-card); + padding: 40px 36px; + box-shadow: var(--shadow); + text-align: center; + } + .order-panel h3 { + font-size: 1.3rem; + margin-bottom: 8px; + } + .order-panel .order-plan { + color: var(--accent); + font-weight: 600; + margin-bottom: 20px; + } + .order-email-row { + margin-bottom: 24px; + text-align: left; + } + .order-email-row label { + display: block; + font-size: 12px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--text-muted); + margin-bottom: 6px; + } + .order-email-row input { + width: 100%; + padding: 12px 16px; + background: var(--bg); + border: 1px solid var(--border); + border-radius: var(--radius); + color: var(--text); + font-size: 15px; + outline: none; + transition: border-color 0.2s; + box-sizing: border-box; + } + .order-email-row input:focus { + border-color: var(--accent); + } + .order-stripe-btn { + width: 100%; + padding: 14px 28px; + border: none; + border-radius: var(--radius); + background: linear-gradient(135deg, var(--accent), #5a7de0); + color: #fff; + font-size: 15px; + font-weight: 600; + cursor: pointer; + transition: opacity 0.2s, transform 0.15s; + } + .order-stripe-btn:hover { opacity: 0.9; transform: scale(1.02); } + .order-stripe-btn:active { transform: scale(0.97); } + .order-stripe-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; } + .order-back { + display: inline-block; + margin-top: 16px; + font-size: 13px; + color: var(--text-muted); + cursor: pointer; + text-decoration: none; + } + .order-back:hover { color: var(--accent); } + .order-status { + margin-top: 16px; + font-size: 13px; + color: var(--text-muted); + display: none; + } + .order-status.show { + display: block; + animation: msgSlide 0.25s cubic-bezier(.22,1,.36,1); + } + .order-status.success { color: #4ade80; } + .order-status.error { color: #f87171; } + + @media (max-width: 900px) { + .order-panel { padding: 32px 24px; } + } + /* ══════════════════════════════════════════════════════════ FAQ ══════════════════════════════════════════════════════════ */ @@ -1815,6 +1923,10 @@

+
+
+ +
Monthly
@@ -1916,7 +2028,7 @@ Higher API key credit allocation - Hire Junior +
@@ -1975,10 +2087,28 @@ Highest API key credit allocation - Hire Senior +
+ + +
+

Processing with Stripe

+

+
+ + +
+ +
+ ← Back to plans +
+ + + @@ -1989,7 +2119,7 @@
-
👤
+ Oliver Arnold
@@ -2348,12 +2478,103 @@ document.getElementById('period-senior').textContent = yearly ? '/ month ✦ yearly' : '/ month'; } + /* ── Pricing Slider / Order Form ──────────────────────────── */ + const ORDER_WEBHOOK = "https://n8n.derez.ai/webhook/5318a0d8-d064-42fb-95b7-aa5552cb3fa9"; + let selectedProduct = null; + + function hireAgent(product) { + selectedProduct = product; + + // Update order panel with plan info + const yearly = document.getElementById('billing-toggle').checked; + const period = yearly ? 'yearly' : 'monthly'; + const names = { trainee: 'Trainee', junior: 'Junior', senior: 'Senior' }; + document.getElementById('order-plan-display').textContent = names[product] + ' — ' + period; + + // Slide pricing out, order form in + document.getElementById('pricing-track').classList.add('slide-left'); + + // Reset status + document.getElementById('order-status').className = 'order-status'; + document.getElementById('order-status').style.display = 'none'; + document.getElementById('order-stripe-btn').disabled = false; + document.getElementById('order-stripe-btn').textContent = 'Proceed to Stripe'; + document.getElementById('order-email').focus(); + } + + function backToPricing() { + document.getElementById('pricing-track').classList.remove('slide-left'); + selectedProduct = null; + } + + async function processStripeOrder() { + const email = document.getElementById('order-email').value.trim(); + const statusEl = document.getElementById('order-status'); + const btn = document.getElementById('order-stripe-btn'); + + if (!email) { + statusEl.textContent = 'Please enter your email address.'; + statusEl.className = 'order-status show error'; + return; + } + + btn.disabled = true; + btn.textContent = 'Processing with Stripe…'; + statusEl.className = 'order-status show'; + statusEl.textContent = 'Connecting to Stripe…'; + + const yearly = document.getElementById('billing-toggle').checked; + const period = yearly ? 'yearly' : 'monthly'; + + try { + const res = await fetch(ORDER_WEBHOOK, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + email: email, + product: selectedProduct, + period: period, + }), + }); + + if (!res.ok) throw new Error('Webhook returned ' + res.status); + + // Try to parse the response — could be JSON or plain text + const ct = res.headers.get('content-type') || ''; + let data; + if (ct.indexOf('json') !== -1) { + data = await res.json(); + } else { + data = await res.text(); + } + + // If we get a Stripe checkout URL back, open it + const checkoutUrl = (data && typeof data === 'object') + ? (data.url || data.checkout_url || data.checkoutUrl || data.redirect) + : null; + if (checkoutUrl && checkoutUrl.startsWith('http')) { + window.open(checkoutUrl, '_blank'); + statusEl.textContent = '✓ Redirecting to Stripe checkout…'; + statusEl.className = 'order-status show success'; + } else { + statusEl.textContent = '✓ Request sent! Check your email for the Stripe payment link.'; + statusEl.className = 'order-status show success'; + } + } catch (err) { + statusEl.textContent = 'Error: ' + err.message + '. Please try again.'; + statusEl.className = 'order-status show error'; + btn.disabled = false; + btn.textContent = 'Proceed to Stripe'; + } + } + /* ── Chat Widget ──────────────────────────────────────────── */ const CHAT_URL = "https://n8n.derez.ai/webhook/a58d00c4-f0c9-40cd-bb50-4f45f0442ef0"; let chatId = null; let chatOpen = false; let chatBusy = false; let greeted = false; + let probeTimer = null; function chatToggle() { chatOpen = !chatOpen; @@ -2361,6 +2582,8 @@ document.getElementById('chat-fab').classList.toggle('open', chatOpen); document.getElementById('chat-widget').setAttribute('aria-hidden', !chatOpen); if (chatOpen) { + // User opened chat manually — cancel the auto-open probe + if (probeTimer) { clearTimeout(probeTimer); probeTimer = null; } if (!chatId) { chatId = String(Math.floor(100000 + Math.random() * 900000)); chatAppendMsg('bot', "Hi! I'm your Sales Agent. Ask me about plans, setup, pricing, integrations, or anything about your AI agent."); @@ -2442,7 +2665,7 @@ /* ── Visitor Probe — auto-open after 15s ────────────────── */ (function () { let fired = false; - setTimeout(function () { + probeTimer = setTimeout(function () { fetch("https://ipinfo.io/json") .then(function (r) { return r.json(); }) .then(function (geo) { fireProbe(geo); }) @@ -2509,7 +2732,7 @@ if (!chatId) chatId = cid; chatAppendMsg("bot", reply); greeted = true; - chatOpenSilent(); + if (!chatOpen) chatOpenSilent(); } }) .catch(function () {});