A guest experience system that turns a photo handoff into a complete post-visit touchpoint: reviews, tips, and return bookings built in.
Hidden Palms Ranch guides photograph every visit. After the ride, they'd airdrop photos to iPhone guests or email them to Android users. Both methods work. Both end the same way: photos received, relationship over.
There was no branded follow-up. No path to a review. No way for guests to tip their guide after they'd already separated. No prompt to book again before the memory faded. The ranch was delivering a great product and leaving every downstream outcome to chance.
The opportunity wasn't in the photo delivery. It was in everything that should happen after the last photo lands.
A guide-facing upload interface and a guest-facing landing page, connected by a QR code and followed by a personalized email.
What a guest sees after a Private Trail Ride.
Minutes after returning from the trail, the guide shows a QR code. The guest scans it. Everything below loads on their phone.
The email and tip cards are hidden on desktop using CSS :has(), targeting the inner component rather than adding a class. By the time a guest opens this on a laptop, both moments have passed. The desktop version serves the photos and the return path.
A guest who just rode a private trail for the first time needs a different next step than a returning member or a corporate group. The rebook section adapts to who's reading it.
| Visit Type | Immediate Rebook CTA ↗ links go direct to FareHarbor |
Downstream Offers | Reasoning |
|---|---|---|---|
| Private Trail Ride | Rebook same visit | NEIGHborhood Club Team Outing waitlist | They came alone or as a small group. They want to come back the same way, but the club and team offering expand the relationship. |
| Group Trail Ride | Rebook same visit | NEIGHborhood Club Team Outing waitlist | Same logic as private. Direct rebook link personalized to their exact visit type, not a generic booking page. |
| Horse Experience | No direct rebook link | Private Trail Ride Group Trail Ride | This is the ranch's loss-leader for younger guests. The natural next step is the trail: parents see their child's excitement and want to ride themselves. |
| NEIGHborhood Club | See you next month | Team Outing waitlist | Returning members already love the ranch. The Team Outing prompt is less a pitch and more a quiet aside to someone who is already on the inside: something they or someone they know might want. |
| Team Outing | No direct rebook link | Group Trail Ride Private Trail Ride | Corporate groups experienced the ranch as a team. Their individual next step is a personal trail visit. The tip card is hidden for this visit type (not the right context). |
The visit type is captured in the guide form, stored in Airtable, pulled at render time, and drives five separate rendering branches. No manual segmentation. The page just knows who it's talking to.
Built for a phone, on the trail.
A 30-day HMAC-signed cookie means guides log in once and the app opens every time. No friction at the end of a visit when guests are waiting.
A single appState variable drives everything: list, ready, uploading, complete, error. A horse emoji rides the progress bar. The QR code is hidden until every file succeeds. Partial failures go to a retry state: no starting over, just the failed files retry.
The guide must actively select yes or no. A guest's photos only enter the marketing library if permission was explicitly granted. Both client-side validation and server-side enforcement.
After each upload, a dashboard refreshes above the form. Party name, visit type, submission time, QR code and link, so guides can hand the QR to late arrivals without resubmitting.
Tested against hard Safari exits mid-upload, the guide switching to another app (a text message, a call), and full network loss from the phone being put in airplane mode. The upload resumes and the state is preserved. A stall indicator fires after 15 seconds of no progress so the guide knows the upload is still running on a slow connection.
Every guide's photo, name, Venmo handle, and Cash App handle lives in a single Airtable record. Adding a new guide or updating a link is a one-row edit with no code change required. The guest page pulls the current data on every load.
Every guest who approves marketing use has photos sitting in Cloudflare R2, tagged to their visit type and guide. Right now that library is unstructured. Phase 2 puts it in front of the right person.
The media dashboard was originally built for the Make.com / Dropbox pipeline. It has to be rebuilt for the current system. The schema, the R2 key structure, and the permission field are already in place. The dashboard itself just needs to be rewired.
In version 1.5, horses and other animals in the photos will be auto-tagged using a vision AI API so the social media team always gets the names right.
"The rehearsals, the arguments, the a/b tests, the last-minute fixes: that's the team's job. By the time the lights go down, none of it should be visible. The work disappears into the moment. That is how you know it was done right."
Nearly 15 years running audio operations at the Orlando Magic meant managing systems under load, coordinating across departments with competing priorities, and delivering for clients who all needed something different and none of them spoke the same language. Before that, 7 years at Northland Church in multi-site broadcast production. Before that, Walt Disney World dinner shows, where a five-piece band, Broadway-caliber performers, and the stage manager could all hear the same show completely differently.
What transferred: the understanding that the audience is there for the experience, not the backstage context. That framing has driven every product decision in this build.
The first version was an automation-stitched prototype: Fillout, Make.com, Dropbox, Twilio chained together. It worked in testing. Field testing revealed it crashed Safari on iPhone when a guide tried to upload a full ride's worth of photos. The automation chain couldn't handle it.
Rather than patch around the failure, the whole approach was rethought. The rebuild became a purpose-built application: more secure, capable of handling video, and no longer dependent on chained third-party automation. The state machine upload flow, the HMAC-signed proxy URLs, the retry logic: all of it came from testing against what actually happens in the field.
No traditional engineering background. AI as the development partner from the first line of code. Claude and Claude Code for architecture and implementation. The work is understanding the real problem, choosing the right tools and approach, testing against real conditions, and being willing to start over when the evidence requires it.
Custom Crew Gear: bulk apparel platform for production crews; architecture and brand kit complete, launching when AI-assisted print-file generation reaches production quality. Hidden Palms Ranch Website: originally built on Squarespace in 2015; being rebuilt using an AI-native development approach with a long-tail content strategy to capture guests who are not explicitly searching for "horseback riding" but discovering it through broader outdoor experience searches, and optimized for LLM-based discovery alongside traditional search.
Experience
Technical ownership of audio operations for a 20,000-seat NBA arena: systems, staff, vendors, and cross-departmental coordination across 200+ annual events.
FOH mix for a 3,330-seat facility; live broadcast to multi-site simulcast venues nationwide.
$150K systems installation from planning through completion; technical team built from scratch.
Stack
Education
Full Sail University
Associate Degree, Recording Arts · 1995
Community
PA of the Day
Founder. 350,000+ followers across Facebook and Instagram. Professional audio community, active since 2015.