The core observation behind Horizon was simple: couples don't agree on trips — they negotiate them. One person wants the beach resort, the other wants the city apartment. One wants to fly direct, the other wants the cheapest option.
Most travel apps optimize for a single decision-maker. Horizon was built for two. The swipe mechanic was the answer: show a card, swipe right or left, and generate a match the moment both users swipe right on the same item.
The first version of the match mechanic worked in under a day. The hard part wasn't the swipe — it was what happened after the match. A match in a list is just information. Getting from "we both liked this" to "this is booked" required building out checkout, status tracking, and partner-synchronized state across a Supabase backend.
Three architectural rewrites followed. First: group IDs. When a couple shares a vault, whose user ID owns the itinerary? The answer had to be canonical — a group_id derived from partner_id, falling back to the solo user's ID — otherwise one partner's vault wouldn't show the other's confirmed items.
Second: checkout status. "Liked" and "booked" are different states. The vault needed to distinguish them, and the checkout timeline needed to filter to only ACTIVE itineraries. Third: the entertainment gap — entertainment cards were being matched but not routed to the checkout flow.
The last fix shipped in June 2026. Now a match on any card — flight, stay, car, or experience — routes cleanly to a shared checkout. Both partners' swipe records update atomically. The swipe finally became a booking.