For Launch.pad Clients · Add-On Packages

Your website is live. Now let's make it work harder.

You've got the foundation — a fast, credible one-page site built to convert. These add-ons give it traffic, visibility, and follow-up so it keeps generating leads long after launch day.

Select what you need  ·  See your running total  ·  Submit your order in minutes

Already included in your core package
One-page website, all sections Mobile-first responsive design SEO foundation Contact form & click-to-call 72-hr delivery + updates
Optional Add-Ons

Build the marketing system around your site

A website alone doesn't generate leads — it needs traffic, follow-up, and visibility. Each add-on below solves one specific piece of that system. Click any card to add it to your order.

Content & SEO Blog
Blog Add-On · $600

Turns your website into a content engine that keeps attracting traffic and building search authority long after launch day.

What's included
  • Blog page design and full setup
  • SEO-friendly blog template
  • Category and tag structure
  • 10 initial posts written around your services and customer questions
  • Posting schedule setup
  • Internal linking from posts to your service sections
  • Optional repurposing into social posts and email topics
Why it matters: A one-page site stops getting new search traffic once it's indexed. A blog gives Google fresh reasons to rank you for the questions your customers are actually typing.
Email Marketing Setup
Lead Nurture Add-On · $550

Turns website visitors into repeat contacts and returning customers with a professional, branded email presence.

What's included
  • Email platform setup (Constant Contact or preferred)
  • Branded templates for newsletters, promos, and announcements
  • Welcome email sequence for new subscribers
  • List setup and segmentation structure
  • Signup form integration on your website
  • Campaign schedule setup
  • Optional lead magnet or welcome offer
Why it matters: Most visitors aren't ready to buy on the first visit. Email is how you stay in front of them until they are — without paying for ads to bring them back.
Social Content Launch Kit
Social Media Add-On · $500

Launches a consistent, recognizable brand presence across social media without you starting from a blank screen.

What's included
  • Profile setup or optimization on selected platforms
  • Branded post and carousel templates
  • Bio, header, and profile image alignment
  • First 30 days of post planning
  • Content themes and CTA guidance
  • Cross-promotion plan tied to website, email, and blog
Why it matters: An inconsistent or outdated social profile undermines the trust your new website just built. This keeps every touchpoint looking like the same credible business.
Google Business Profile
Local Visibility Add-On · $250

Gets you showing up in local Google searches and Maps when potential customers are actively looking for what you offer, right now.

What's included
  • Full Google Business Profile setup or optimization
  • Category selection and keyword targeting
  • Photo upload and complete profile build-out
  • Review response strategy
  • Local schema markup integration with your website
  • First 4 posts written and scheduled
Why it matters: For most local businesses, Google Maps drives more calls than the website itself. A neglected or unclaimed profile means competitors win that search for free.
Analytics & Tracking
Data Add-On · $200

Tells you exactly how visitors find you, what they do on your site, and which actions actually convert them into leads.

What's included
  • Google Analytics 4 setup and configuration
  • Goal and conversion event tracking
  • Google Search Console setup and connection
  • Traffic dashboard ready on day one
  • First insights report after 30 days
Why it matters: Without tracking, you're guessing whether your marketing is working. This turns your website into a source of real numbers you can make decisions from.
Appointment Booking
Booking Add-On · $300

Lets customers book appointments, consultations, or services directly from your site — no phone tag, no back-and-forth.

What's included
  • Booking system selection and full setup
  • Calendar integration and availability configuration
  • Automated confirmation and reminder emails
  • Embedded seamlessly into your website
  • Custom booking form fields for your service type
Why it matters: Every extra step between "interested" and "booked" loses leads. Direct booking captures the customer at the exact moment they're ready to commit.
6 add-ons
Each one solving a specific gap in your marketing system — pick only what your business actually needs
$200–$600
Per add-on, one-time investment — vs. agencies charging $1,000–$3,000+ for the same services
No retainer
Pay once, keep it forever — no monthly fees, no lock-in, no surprises on your next invoice
Your Add-On Order

Review your selections & send your order

Select the add-ons above to build your order — your choices and total will appear here automatically.

No add-ons selected yet — scroll up and click Add to order on any package to get started.

Complete your payment

Secured by Stripe · Your card details are never stored on our servers

Payment confirmed!

Your add-ons are booked and paid. We'll follow up at your email address within one business day to get your work scheduled.

Make changes to my order
Order Summary

Your add-on package

Select add-ons above to see your order summary here.
0 add-ons selected
Add-on total
$0
Launch.pad
launchpad website services
Add-On Order Form
${today}
REF: LP-AO-${Date.now().toString(36).toUpperCase().slice(-6)}
About this order
This order covers optional add-on packages to be added to an existing Launch.pad core website package. All prices are one-time investments with no recurring fees unless otherwise noted. Work begins within one business day of order confirmation.
${rows}
# Add-On Package — Description of Services Price
Subtotal $${subtotal.toLocaleString()}
Sales Tax (6%) $${tax.toLocaleString()}
Total Due (one-time investment) $${grandTotal.toLocaleString()}
Client name
Business name
Core package tier
Email address
Phone number
Signature & date
`; const win = window.open('', '_blank'); if (win) { win.document.write(html); win.document.close(); } else { alert('Please allow pop-ups for this site to preview the order PDF.'); } } function scrollToOrderForm() { document.getElementById('order-form').scrollIntoView({ behavior: 'smooth', block: 'start' }); } // ── STRIPE SETUP ────────────────────────────────────────────────── // Replace the value below with your Stripe publishable key. // Find it at: https://dashboard.stripe.com/apikeys const STRIPE_PUBLISHABLE_KEY = 'pk_live_51SqFwtGgpx3yRqz0Ha2p8zaWrgzJhSTPf55EnxnCGx6ASuDtL6TwihSbqMM4UHa2KKicz0cyO9C3ylMN1ZcvzjqV009dhv6G2K'; let stripe, stripeElements, orderPayload; function showPaymentMessage(msg, type = 'error') { const el = document.getElementById('payment-message'); el.textContent = msg; el.className = type; el.style.display = msg ? 'block' : 'none'; } function fmt(dollars) { return '$' + dollars.toLocaleString('en-US', { minimumFractionDigits: 2 }); } function buildRecapHTML(items, subtotal, tax, total) { const rows = items.map(i => `
${i.name}${fmt(i.price)}
` ).join(''); return rows + `
Subtotal${fmt(subtotal)}
` + `
Tax (6%)${fmt(tax)}
` + `
Total due${fmt(total)}
`; } function showStep(step) { document.getElementById('order-form-el').style.display = step === 'form' ? '' : 'none'; document.getElementById('payment-step').style.display = step === 'payment' ? 'block' : 'none'; document.getElementById('form-empty-state').style.display = step === 'empty' ? '' : 'none'; if (step === 'success') { document.getElementById('form-success').classList.add('visible'); document.getElementById('order-bar').classList.remove('visible'); } } // Back button: return to order form document.getElementById('payment-back-btn').addEventListener('click', function() { showStep('form'); showPaymentMessage(''); const submitBtn = document.getElementById('submit-btn'); submitBtn.textContent = 'Proceed to Payment →'; submitBtn.disabled = false; }); // Form submission → validate → call backend → mount Stripe Payment Element document.getElementById('order-form-el').addEventListener('submit', async function(e) { e.preventDefault(); const fname = document.getElementById('fname').value.trim(); const lname = document.getElementById('lname').value.trim(); const email = document.getElementById('email').value.trim(); if (!fname || !lname || !email || selected.size === 0) { const missing = []; if (!fname) missing.push('first name'); if (!lname) missing.push('last name'); if (!email) missing.push('email'); if (selected.size === 0) missing.push('at least one add-on'); alert('Please fill in your ' + missing.join(', ') + ' before submitting.'); return; } const submitBtn = document.getElementById('submit-btn'); submitBtn.textContent = 'Loading payment…'; submitBtn.disabled = true; // Prices in dollars (matching data-price attributes and backend expectation) const selectedItems = [...selected].map(id => ({ id, name: ADDONS[id].name, price: ADDONS[id].price })); const subtotal = selectedItems.reduce((s, a) => s + a.price, 0); const tax = Math.round(subtotal * 0.06 * 100) / 100; // 2 decimal places const total = Math.round((subtotal + tax) * 100) / 100; orderPayload = { cart: { addons: selectedItems, subtotal, tax, total, }, account: { email, firstName: fname, lastName: lname, businessName: document.getElementById('biz').value.trim() || '', notes: document.getElementById('notes').value.trim() || '', }, }; try { const resp = await fetch('https://cmtghodlffrrugmrhndr.supabase.co/functions/v1/create-payment-intent', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(orderPayload), }); const data = await resp.json(); if (!resp.ok) throw new Error(data.error || 'Request failed'); // ── Path A: backend returns clientSecret → embedded Payment Element ── if (data.clientSecret) { stripe = Stripe(STRIPE_PUBLISHABLE_KEY); stripeElements = stripe.elements({ clientSecret: data.clientSecret, appearance: { theme: 'flat', variables: { colorPrimary: '#FF33CE', colorBackground: '#f9f7f2', colorText: '#111009', colorDanger: '#dc2626', fontFamily: 'Geist, Helvetica Neue, sans-serif', borderRadius: '8px', spacingUnit: '4px', }, }, }); const paymentElement = stripeElements.create('payment', { layout: 'tabs', }); document.getElementById('stripe-payment-element').innerHTML = ''; paymentElement.mount('#stripe-payment-element'); // Populate recap document.getElementById('payment-order-recap').innerHTML = buildRecapHTML(selectedItems, subtotal, tax, total); document.getElementById('payment-btn-amount').textContent = fmt(total); showStep('payment'); // ── Path B: backend returns checkout_url → redirect to Stripe Checkout ── } else if (data.checkout_url) { window.location.href = data.checkout_url; } else { throw new Error('No payment session returned from server.'); } } catch (err) { console.error('Payment init error:', err); submitBtn.textContent = 'Proceed to Payment →'; submitBtn.disabled = false; showPaymentMessage(err.message || 'Something went wrong starting payment. Please try again.', 'error'); showStep('payment'); } }); // Pay button → confirm payment document.getElementById('payment-submit-btn').addEventListener('click', async function() { if (!stripe || !stripeElements) return; const payBtn = document.getElementById('payment-submit-btn'); payBtn.disabled = true; payBtn.textContent = 'Processing…'; showPaymentMessage(''); const { error } = await stripe.confirmPayment({ elements: stripeElements, confirmParams: { return_url: window.location.href.split('?')[0] + '?payment=success', receipt_email: orderPayload ? orderPayload.email : undefined, }, redirect: 'if_required', // stay on page when no redirect needed (most cards) }); if (error) { // Show error without leaving the page showPaymentMessage( error.type === 'card_error' || error.type === 'validation_error' ? error.message : 'An unexpected error occurred. Please try again.', 'error' ); payBtn.disabled = false; payBtn.innerHTML = 'Pay ' + document.getElementById('payment-btn-amount').textContent + ' →'; } else { // Payment succeeded without redirect (redirect handled by return_url if 3DS needed) showStep('success'); } }); // Scroll-reveal const revealEls = document.querySelectorAll('.reveal'); const io = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('in'); io.unobserve(e.target); } }); }, { threshold: 0.1 }); revealEls.forEach(el => io.observe(el)); // Payment return state detection (function() { const params = new URLSearchParams(window.location.search); const payment = params.get('payment'); if (payment === 'success') { // Clean up URL history.replaceState({}, '', window.location.pathname); // Show success state const orderSection = document.getElementById('order-form'); if (orderSection) { orderSection.scrollIntoView({ behavior: 'smooth', block: 'start' }); } document.getElementById('order-form-el').style.display = 'none'; document.getElementById('form-empty-state').style.display = 'none'; document.getElementById('form-success').classList.add('visible'); document.getElementById('order-bar').classList.remove('visible'); } else if (payment === 'cancelled') { // Clean up URL history.replaceState({}, '', window.location.pathname); // Scroll to form and show cancellation notice const orderSection = document.getElementById('order-form'); if (orderSection) { setTimeout(() => orderSection.scrollIntoView({ behavior: 'smooth', block: 'start' }), 300); } const submitBtn = document.getElementById('submit-btn'); if (submitBtn) { submitBtn.textContent = 'Proceed to Payment →'; submitBtn.disabled = false; } // Show a dismissible notice above the form const notice = document.createElement('div'); notice.style.cssText = 'background:rgba(255,51,206,0.12);border:1px solid var(--g);border-radius:8px;padding:1rem 1.25rem;margin-bottom:1.5rem;color:var(--cream);font-size:0.9rem;'; notice.innerHTML = 'Payment cancelled. Your selections are still here — complete your order whenever you\'re ready.'; const formEl = document.getElementById('order-form-el'); if (formEl) formEl.insertAdjacentElement('beforebegin', notice); } })(); // Initial render render();