[{"data":1,"prerenderedAt":142},["ShallowReactive",2],{"work-flow-society-mx":3,"work-siblings-flow-society-mx":104},{"id":4,"title":5,"accent":6,"body":7,"completedAt":81,"cover":82,"coverAlt":83,"description":13,"extension":84,"external":85,"liveUrl":85,"meta":86,"navigation":87,"order":88,"path":89,"role":90,"seo":91,"stack":92,"status":99,"stem":100,"summary":101,"year":102,"__hash__":103},"work\u002Fwork\u002Fflow-society-mx.md","Flow Society MX","#166534",{"type":8,"value":9,"toc":74},"minimark",[10,14,19,22,41,45,48,54,57,63,71],[11,12,13],"p",{},"Flow Society runs small group e-bike rides in Bosque La Primavera, plus a membership and a two\nday camping trip. Before this build the bookings arrived through direct messages, and the person\nanswering them was also the person leading the ride.",[15,16,18],"h2",{"id":17},"the-problem-underneath-the-brief","The problem underneath the brief",[11,20,21],{},"A tour operator's real constraint is not the marketing page, it is the fact that a departure has\na fixed number of seats and a fixed number of bikes, and both are consumed by a booking that has\nnot been confirmed yet. Any form that ignores the held state will eventually sell the same seat\ntwice on a Saturday morning, and the person who finds out is standing in a car park.",[23,24,25,31,36],"metric-row",{},[26,27],"metric",{"label":28,"note":29,"value":30},"Steps in the booking flow","Date, trip basics, riders, equipment, logistics, review.","6",[26,32],{"label":33,"note":34,"value":35},"Fields captured","Including accessory rentals, which used to be a separate message thread.","12",[26,37],{"label":38,"note":39,"value":40},"Experiences seeded","Brunch rides, the hybrid couples format, membership, and the camping trip.","5",[15,42,44],{"id":43},"how-it-is-built","How it is built",[11,46,47],{},"Prisma over Postgres holds experiences, departures, bikes, and bookings. Availability is derived\nfrom the departure rather than stored on it, so a held booking and a confirmed one both reduce\nwhat the calendar offers without anyone remembering to decrement a counter. The form is React\nHook Form with Zod schemas shared between the client and the server action, which means the\nvalidation the visitor sees and the validation the database trusts are the same rules.",[49,50],"shot",{"alt":51,"caption":52,"src":53},"The booking flow at step three, showing rider details and a running summary of the trip.","The running summary on the right stays filled in across all six steps, so nobody reaches the review screen unsure what they picked.","\u002Fwork\u002Fflow-society-mx\u002Fshot-booking.png",[11,55,56],{},"Sold out and held departures stay on the calendar. Removing them makes the season look emptier\nthan it is and invites the question of whether the operator runs rides at all that month.",[58,59],"demo",{"component":60,"note":61,"origin":5,"title":62},"FilterDemo","Try the level filter. Unavailable departures stay visible, stay in the count, and refuse the click, which is what a paper calendar with a line through it has always done.","Departure picker with unavailable dates left in",[11,64,65,66,70],{},"The operator dashboard at ",[67,68,69],"code",{},"\u002Fadmin"," confirms or declines bookings and blocks dates. Email runs\nthrough Resend, with a console fallback so the whole flow can be developed and demonstrated\nwithout an account or an API key.",[11,72,73],{},"::callout{title=\"A note on the free tier\"\n}\nEvery service in the stack sits inside a free plan: Neon for Postgres, Resend for mail. That was\na requirement, not a shortcut. A small operator will abandon a system whose\nrunning cost arrives before its first booking does.\n::",{"title":75,"searchDepth":76,"depth":77,"links":78},"",2,3,[79,80],{"id":17,"depth":76,"text":18},{"id":43,"depth":76,"text":44},"2026-08","\u002Fwork\u002Fflow-society-mx\u002Fcover.png","The Flow Society MX booking page, showing a departure calendar beside a trail photograph.","md",null,{},true,9,"\u002Fwork\u002Fflow-society-mx","Product design and full stack build",{"title":5,"description":13},[93,94,95,96,97,98],"Next.js 15","React 19","Prisma 6","PostgreSQL","Radix UI","Resend","completed","work\u002Fflow-society-mx","An e-bike tour operator in Jalisco, with a six step booking flow, a per departure availability calendar, and an operator dashboard behind it.",2026,"5GP-xfidXkZW2hCaT2NG0xybqPRpGePuvtAMCksH9cg",[105,109,113,117,121,125,129,133,137,138],{"path":106,"title":107,"summary":108},"\u002Fwork\u002Fwayta-peru","Wayta Perú","A bilingual travel operator site where the marketing page, the blog, and the studio the client edits in are one deployment.",{"path":110,"title":111,"summary":112},"\u002Fwork\u002Fpersonae","Personae","A persona library built on IBM Carbon, where every profile links out to its research and every reader can flag a claim that no longer holds.",{"path":114,"title":115,"summary":116},"\u002Fwork\u002Farsonistai","ArsonistAI","An AI design consultancy with two audiences on one homepage, enterprises hiring for AI augmented product work, and individual designers buying tools off the shelf.",{"path":118,"title":119,"summary":120},"\u002Fwork\u002Fhcit","HCIT","A five vertical AI and infrastructure integrator whose site had to make enterprise grade credibility legible without turning into an alphabet soup of sub brands.",{"path":122,"title":123,"summary":124},"\u002Fwork\u002Flynne","Lynne","A lead capture first booking site for a solo telehealth counseling practice, sized to get one action in front of a visitor rather than a full site's worth of pages.",{"path":126,"title":127,"summary":128},"\u002Fwork\u002Fn-hub","N Brand Portal","An internal brand portal holding the logos, color tokens, and templates a small team actually needs, so the approved asset stops living in an eight month old Slack thread.",{"path":130,"title":131,"summary":132},"\u002Fwork\u002Freductivist","Reductivist","A minimalist goods brand selling a handful of well made objects, where the real commerce problem was resisting the urge to add a fourth product to the homepage.",{"path":134,"title":135,"summary":136},"\u002Fwork\u002Fpattern-library","Pattern Library","Four hundred and twenty two documented interaction patterns across web, mobile, and cross platform concerns, with the rationale that makes each one work.",{"path":89,"title":5,"summary":101},{"path":139,"title":140,"summary":141},"\u002Fwork\u002Fcytron-motorcycles","Cytron Motorcycles","A Tokyo motorcycle brand invented end to end, drawn as a working prototype and then built as the site that prototype had been arguing for.",1789230933991]