zsty.us

Before / After · Case Study

Balboa Psychic — a near-empty page turned into a calendar that sells its own slots

  • Local Pro Services
  • Beauty & Wellness

Doreen's psychic-reading business runs entirely on appointments, but her old site-builder page had almost nothing on it — every booking happened by phone tag, and a no-show cost the whole slot. Now clients pick a reading, pick in-person, phone, or video, pick a time in their own timezone, and put down a deposit — and the confirmation, the video meeting, and the reminders all happen on their own.

A psychic's calendar is her inventory. The site's job is to sell slots without ever selling the same one twice.
🔒balboa-psychic.vercel.app
jackiej.events — modern site

At a glance

What this rebuild covers.

  • Selling & payments

    A deposit confirms every booking, with an honest reserve-and-pay-later option for clients who won't pay online — either way, a slot is never held by an empty promise.

  • Design

    The booking flow narrows fast — choose a reading, choose how to meet, choose a time — because the site's one job is selling a slot, not showing off pages.

  • Theme & color

    A deep-night celestial look — a drifting starfield that follows the cursor over a soft aurora glow — reads 'mystic' without a single cliché tarot stock photo, and calms down for visitors who prefer reduced motion.

  • Agents

    Background jobs run the calendar while Doreen reads: abandoned checkouts give their slot back within ten minutes, and paid video readings get their meeting link created with zero clicks from her.

  • Customer notifications

    Every confirmed reading lands in the client's own calendar automatically, and reminder emails go out hourly for upcoming appointments — fewer no-shows without anyone managing a calendar app.

  • Security

    The owner's admin area sits behind a password and includes a one-tap button to ask a happy client for a review right after a good reading.

Receipts — measured

Numbers that moved.

0
Booking modes offered
was 0
1440 min
Minutes an abandoned checkout can block a slot
was 1440 min
4
Manual steps from payment to a scheduled Zoom reading
was 4
  • 0 → 3 ways to book a reading
  • Abandoned checkout blocks a slot: 24 hrs → 10 min
  • 4 → 0 manual steps from payment to a scheduled reading
  • Every slot backed by a deposit or a bounded hold

The pixel diff

Overview, then the walkthrough.

Left: everything the legacy site shipped — frozen in place. Right: an auto-scrolling tour of the rebuild, from hero to booking. No slider to fight with.

Before — the overview
🔒balboapsychic.com
Before — the overview

This is everything the legacy site had to offer above the fold. No pricing, no calendar, no booking — the funnel ended at a mailto.

After — scroll through what shipped
🔒balboa-psychic.vercel.app
After — scroll through what shipped

Auto-scrolls through the modern site so you can see the booking surface, the package grid, the pricing table, and the calendar inline — without leaving this page.

The four beats

Problem · Insight · Build · Outcome.

Scroll past the legacy frame. The four beats land in order. At the end, the modern site fades into the same window.

🔒balboapsychic.com
Legacy
01 · Problem

An appointment business with no appointment machinery.

The GoDaddy page had nearly nothing on it — no services, no times, no way to book. Every reading was arranged by phone tag, every slot was unprotected against no-shows, and remote readings meant manually creating and sharing a meeting link.

02 · Insight

Sell the slot, not the page.

The site's one conversion is a booked, deposit-backed slot. Everything in the build serves that: the multi-step flow narrows to a time fast, the deposit makes the booking real, and fulfillment (Zoom + .ics + reminders) happens without Doreen touching a dashboard.

03 · Build

Booking engine first, brand surface around it.

Next.js 15 + Neon. Multi-step /book (service → mode → timezone-aware slots), Stripe Checkout deposits with reserve-and-pay-later, webhook fulfillment (payment state, Zoom S2S meeting create, .ics email), hold-expiry + hourly reminder crons, and a password-gated admin with a review-ask button. The constellation hero and aurora styling wrap it in a brand that fits the business.

04 · Outcome

A calendar that defends itself, awaiting content + DNS.

The platform is live at balboa-psychic.vercel.app. Remaining before cutover: Doreen's real photos and pricing, and pointing balboapsychic.com — the legacy GoDaddy page still answers there today, which is exactly what the before-captures show.

🔒balboa-psychic.vercel.app
Modern
For the technically curiousHow it was done
  1. 01

    Where it started

    balboapsychic.com was a GoDaddy site-builder page with almost nothing on it — no services, no times, no way to book. Every reading was arranged by phone tag, every slot was unprotected against no-shows, and a remote reading meant manually creating and sharing a meeting link.

  2. 02

    The real problem

    A psychic's calendar is her inventory, and the old page didn't touch it. The site's one conversion is a booked, deposit-backed slot — so the build is a booking engine first, with the brand surface wrapped around it.

  3. 03

    The rebuild

    A multi-step booking flow on our hosting platform with a managed database behind it: choose a reading, choose in-person, phone, or video, then pick from timezone-aware slots — a phone reading booked from Chicago shows Chicago times. A hosted deposit checkout confirms the slot, with a reserve-and-pay-later fallback that holds it for a bounded window instead of forever. A database-level guard means two clients can't land on the same slot — the second writer loses cleanly, not silently.

  4. 04

    Fulfillment without hands

    When a deposit clears, a webhook flips the booking to paid, auto-creates the video meeting for remote modes with no user token dance, and emails a calendar-file confirmation the client's own calendar understands — zero manual steps between payment and a scheduled reading.

  5. 05

    What runs now

    Scheduled jobs defend the calendar around the clock: a hold-expiry job reclaims slots from abandoned checkouts every ten minutes, and an hourly job sends reminders for approaching readings. A password-gated admin adds a one-tap review-ask button — the retention loop for a reputation business.

  6. 06

    What's left before cutover

    The platform is live on a preview address. Remaining: Doreen's real photos and pricing, and pointing balboapsychic.com at the new site — the legacy GoDaddy page still answers there today, which is exactly what the before-captures show.

Architecture

Old stack
  • GoDaddy builder
  • Phone-tag booking
  • No deposits
  • No calendar
New stack
  • modern web framework
  • Multi-step /book flow
  • Timezone-aware slot picker
  • Stripe deposits + pay-later fallback
  • Zoom S2S + .ics fulfillment
  • Hold-expiry + reminder crons

What changed, with evidence

Design

A hero that sets the mood without a stock tarot photo

Canvas-2D particle constellation with mouse parallax over a CSS aurora — an atmospheric, performance-cheap hero that reads 'mystic' without a single cliché stock image, and degrades gracefully under reduced-motion.

Before
A default site-builder template with placeholder sections.
After
A bespoke celestial hero rendered in canvas, no heavy assets.
Retention

Deposits kill the no-show problem — with an honest fallback

The /book flow takes a Stripe Checkout deposit to confirm a slot. Clients who won't pay online can reserve-and-pay-later — the slot holds for a bounded window instead of forever. Webhook fulfillment marks the booking paid, creates the Zoom meeting via S2S OAuth when the mode is remote, and emails an .ics the client's calendar understands.

Before
A booked reading was a verbal promise; no-shows cost the whole slot.
After
A slot is only confirmed by a deposit or a bounded hold — and fulfillment is automatic.
  • Stripe Checkout session per booking; webhook flips the booking state
  • Zoom meeting auto-created on paid remote bookings (S2S OAuth, no user token dance)
  • .ics confirmation attached so the appointment lands in the client's calendar
Agent backbone

Timezone-aware slots with a double-booking guard

Slot generation is luxon-based and timezone-aware (a phone reading booked from Chicago shows Chicago times), and the booking transaction guards against two clients landing on the same slot — the second writer loses cleanly, not silently.

  • luxon slot math keyed to the client's timezone
  • DB-level double-booking guard on the slot claim
  • 10-minute hold expiry cron releases abandoned checkouts
Real-time push

Crons that run the calendar while Doreen reads

An hourly reminder cron nudges upcoming appointments; the hold-expiry cron reclaims slots from abandoned checkouts every 10 minutes; and the password-gated admin includes a one-tap review-ask button for after a good reading — the retention loop for a reputation business.

While the owner sleeps.

Autonomous surfaces

The agent backbone keeps the brand earning after hours. The owner approves; the system runs.

  • Releases abandoned holds before they cost a slot

    every 10 min

    The hold-expiry cron reclaims any slot whose checkout was abandoned past the 10-minute window, returning it to inventory automatically.

  • Reminds upcoming appointments

    hourly

    An hourly cron emails reminders for approaching readings — fewer no-shows without Doreen managing a calendar app.

  • Fulfills paid bookings end-to-end

    on each paid booking

    The Stripe webhook marks the booking paid, creates the Zoom meeting for remote modes, and sends the .ics confirmation — zero manual steps between payment and a scheduled reading.

← All rebuilds

Balboa Psychic — a near-empty page turned into a calendar that sells its own slots — zsty.us