Case study, Roam, Side Project, 2026

Roam: Trip planning by AI, grounded in reality

Role

Solo designer and builder

Timeline

48-hour build, then refining

Stack

Figma · Claude · Cursor · Vercel

Status

Live and user-tested

The product

One designer. No engineers. Shipped.

Enter a destination, set your dates, travellers and budget, and Roam generates a real day by day itinerary with live places, hotel pricing and travel times between stops. Everything, from the first wireframe to the deployed app, was built by me. Roam is mobile-first by design, built for the phone people actually plan trips on.

This is not a prototype made to look real. It is real, and you can use it right here. →

A 0-to-1 AI trip planner I took from problem to production on my own in 48 hours, with no engineers. I designed the system and shipped the front end through an AI-assisted pipeline: Figma Make for wireframes, a component library I built with Figma Agent generating the variants, then Claude reading the live Figma spec through MCP to generate the React 19 front end, built with Vite, with Cursor and Vercel to deploy. It is live, and it runs on a cost model I re-architected to keep per-trip API spend sustainable.

Then I validated it. In unmoderated usability testing, six real users each planned a trip end to end and saved it with no help: a 100% task success rate, scoring 86% for ease and 83% for trust, with a median time of under four minutes from blank screen to finished plan. The sessions did not just prove the concept worked, they mapped exactly where a production version goes next.

Context

A trip to Albania that became a product question

Planning a group trip is still a surprisingly broken experience. You start in a WhatsApp thread, end up in a Google Doc, consult a few travel blogs, and somehow consolidate everything in a spreadsheet. There's no shortage of travel apps, but most of them search for things you already know you want. They don't help you figure out what you want in the first place.

After planning a trip to Ksamil, Albania with two couples, coordinating ferry timetables, accommodation, beach recommendations, restaurant reservations, and daily budgets across multiple tools, the question felt real: could a single AI-native interface replace all of that without feeling like yet another chatbot?

Roam was the attempt to find out. The constraint was deliberate: not a portfolio exercise, but a real thing, built from scratch, with a hard time budget of 48 hours.

Context

A trip to Albania that became a product question

Planning a group trip is still a surprisingly broken experience. You start in a WhatsApp thread, drift into a Google Doc, consult a few blogs and end up reconciling it all in a spreadsheet. There is no shortage of travel apps, but most of them search for things you already know you want. They do not help you work out what you want in the first place.

After planning a trip to Ksamil in Albania with two other couples, juggling ferry times, stays, beaches, restaurants and daily budgets across a handful of tools, the question felt real: could a single AI-native interface replace all of that without feeling like yet another chatbot?

Roam was the attempt to find out, built from scratch with a hard budget of 48 hours.

Discovery

I tried the tools people already use. Every one let the trip fall apart

Before designing anything, I planned the Albania trip with the tools that already exist, then went looking for whether my frustration was just mine or something the whole category gets wrong. It was the second one.

This was not a two-week research programme, and I want to be honest about that. It was a real trip planned end to end, a hands-on teardown of the main trip-planning tools, and a read through what reviewers were reporting about AI itineraries in 2026. Small and scrappy, but enough to turn a hunch into problems worth building against.

The tools people actually reach for

I planned the same Ksamil trip through each of these, plus the real incumbent nobody names: a group chat and a spreadsheet. They are good at organising a trip you have already worked out, and bad at the messy middle of deciding what to do.

Tool Good at Where it broke for me
Group chat Everyone can see it. No learning curve. No structure, no map, no costs. The plan lives in six people's heads and nobody owns the final version.
Wanderlog Nice map and drag to reorder. Suggested closed places and out-of-date events. It organises what you feed it; it does not check the world is still there.
AI chatbots Fast, flexible, answers any odd question. Invented addresses and hours, no map, no real prices, and you paste the whole thing into another tool to use it.
Google Travel Real place data behind it. Built around a place you have already chosen. It helps you book, not decide, and never hands you a day plan.

The pattern underneath: plans that look right and fall apart

The failure is shared and specific: AI itineraries read beautifully and quietly do not hold up. That is not just my experience. When InsureMyTrip had ChatGPT, Gemini and Google's AI plan a real week-long trip in 2026, the tools recommended restaurants that did not exist, underpriced a train by more than half, and laid out days with travel times that were not physically doable.

Independent testing

"The itineraries often looked polished and logical on the surface... closer inspection revealed that both big and small details were often inaccurate."

Sara Boisvert, InsureMyTrip, reported in Forbes, 2026

That became the thesis for the whole product. Anything can generate a plan. The design problem is guaranteeing the plan is real: places that exist, prices that are close, and a day whose stops you can actually get between before dinner. Trust, not text, is the job. Four failures showed up again and again, and each one became something Roam had to answer.

Problem

The four failures Roam had to answer

In the order they cost me the most time. Every one is answered in the shipped app.

01

Trip planning has no single home

A dozen tabs: a group chat, a doc nobody updates, blogs, a budget sheet. Roam turns one short brief into a full day by day plan with places, costs and a map.

02

AI bolted onto the wrong moment

Booking tools assume you already know where you are going, then add AI as an afterthought. Roam is AI-first from the first screen, built for "we want to go somewhere, help us decide."

03

Plans that look right but fall apart

Ask any chatbot and it reads well, then breaks: lunch across town from your morning, stops with no time between them. Roam checks each plan against real travel times and meal windows before you see it.

04

Change one stop, the plan breaks

Swap a museum for a market in most tools and the timings fall out of sync. In Roam, change any stop and the schedule recomputes itself around it automatically.

Tech stack

Six platforms. One pipeline.

The 48-hour budget was not just a timeline, it was a design constraint: every decision had to answer "does this justify the time?" Six platforms covered the full stack, each feeding the next. Design and engineering never really separated, because Claude read the node data straight from Figma, so spacing, component properties and type translated into code without a manual handoff. The code itself is a React 19 app, bundled with Vite.

Claude

Cowork

API

Code

Ideation

Itinerary & pricing

Component build

Figma

Make

Design

Agent

Token Studio

MCP

Wireframes

Design system

Design assistance

Design tokens

Design bridge

Google APIs

Places

Routes

Static Maps

Location data

Travel times

Map view

Cursor

Agent

Editor

Front-end build

Edge-case fixes

Vercel

Deploy

Functions

Edge CDN

KV

Production hosting

Serverless API

Photo caching

Place cache

UXtweak

Study

Recordings

Unmoderated tests

Screen replay

Claude

Cowork

API

Code

Ideation

Itinerary & pricing

Component build

Figma

Make

Design

Agent

Token Studio

MCP

Wireframes

Design system

Design assistance

Design tokens

Design bridge

Google APIs

Places

Routes

Static Maps

Location data

Travel times

Map view

Cursor

Agent

Editor

Front-end build

Edge-case fixes

Vercel

Deploy

Functions

Edge CDN

KV

Production hosting

Serverless API

Photo caching

Place cache

UXtweak

Study

Recordings

Unmoderated tests

Screen replay

Process

48 hours, phase by phase

Seven phases, each leaning on a different tool. When a phase ran long, scope was cut, not quality. The phase that mattered most was the sixth, where Claude read the live Figma spec through MCP and built each React component from it, so spacing came from the component and colour came from the tokens, not from eyeballing a screenshot.

Hours Tool Phase What happened
0–2 Claude Ideation Stress-tested the concept in a Claude session. The output was a set of decisions: three surfaces, two integrations, one hard time limit.
2–4 Figma Make Wireframes Nine screens from a plain-language brief. Several survived almost unchanged, which moved the real work to flow rather than layout.
4–20 Figma Agent Hi-fi design Agent populated the frames with real content, so the design went from placeholder boxes to something that felt like a product.
20–24 Token Studio Design tokens to CSS The whole visual system exported as CSS custom properties. Change a colour in Figma, it changes in the app.
24–28 Anthropic API API and system prompt Wired up the planning layer and wrote the system prompt, where the two-phase "ask, then generate" model was defined.
28–40 Figma MCP Design to code Components built in Cursor straight from the live spec. This is the phase that made handoff feel solved rather than tedious.
40–48 Vercel Build and deploy Tight iteration on edge cases and loading states, then a production deploy in under two minutes.

Wireframes

The structure, decided in wireframes

The first two hours went into wireframes, not visuals. Figma Make turned a plain-language brief, a travel app with a trip form, an AI planning flow and an itinerary view, into nine rough screens. Grey boxes, real structure, enough to react to.

The speed was the point. With working screens in hours rather than days, the real decisions moved to flow and interaction instead of layout, and several of these frames carried through, almost unchanged, into the shipped app. The originals are below, still clickable.

Click through the nine wireframes Figma Make generated from a plain-language brief. Several survived, almost untouched, into the final build.

Design foundation

A system before the screens

Before any screen went to high fidelity, I built the foundation everything else would inherit from: a set of tokens and a component library. Working solo under a 48-hour clock, a single source of truth was the only way to stay consistent, and AI let me build that foundation far faster than I could alone.

Design Tokens

Colour primitives were aliased to semantic tokens, each graded for AA or AAA contrast, so no component ever touched a raw hex. I worked that layer out with Claude, pressure-testing the naming and contrast before I committed it. Plugged into Token Studio in Figma, the tokens export to CSS custom properties, so one colour change flows through the whole file and into the app.

Design System

On top of the tokens sat the component library: buttons, tags, cards, inputs, confidence badges and meal pills, each designed once and reused everywhere. Figma Agent generated the variant matrix, so I could spend my time on the decisions that needed judgement. Every screen drew from that same set, so nothing drifted and a fix in one place appeared everywhere it was used.

The token reference on the left, and the component library it feeds on the right, from colour primitives through to finished buttons, cards and badges.

The token reference on top, and the component library it feeds below it, from colour primitives through to finished buttons, cards and badges.

Tokens and components, straight to code

The same pipeline, traced through two components. The meal tag follows a colour, the trending card follows shape and elevation. Each time, the value set in the design system is the exact token the shipped CSS renders from.

Figma · Design System
Dinner
MealTag · Property 1 = Dinner · selected
Fill #FFF1F2
Stroke #FDA4AF
Text #9F1239
Radius 9999

The Dinner meal tag, selected. Its colours live in the design system, not on the component.

tokens.css
/* Meal */
--meal-dinner-fg: #9F1239;
--meal-dinner-bg: #FFF1F2;
--meal-dinner-border: #FDA4AF;

Each colour is one named token, the only place the raw hex is written.

components.css
.meal-tag--dinner {
color: var(--meal-dinner-fg);
background: var(--meal-dinner-bg);
border-color: var(--meal-dinner-border);
}

The component asks for the token by name. It never touches a raw colour.

The meal tag's colours. Fill, border and text each come from a named token, so the colour set in the design is the exact colour the component renders, one of dozens wired this way.

Figma · Design System
Santorini, Greece
Whitewashed clifftop villages overlooking the Aegean
TrendingCard · selected
Fill #FFFFFF
Radius 16
Elevation sm

The trending card, selected. Its shape, surface and shadow all come from the system, not hard-coded values.

tokens.css
/* Elevation & shape */
--radius-lg: 16px;
--surface-default: #FFFFFF;
--shadow-sm:
0 1px 3px 0 rgba(15,23,42,0.08),
0 1px 2px 0 rgba(15,23,42,0.04);

Shape and elevation are tokens too. The shadow is one compound token carrying a whole two-layer elevation.

components.css
.trending-card {
border-radius: var(--radius-lg);
background: var(--surface-default);
box-shadow: var(--shadow-sm);
}

The card sets no pixels of its own. It reads its radius, surface and shadow from named tokens.

The trending card's structure. Radius, surface and a two-layer shadow each come from a named token, so the system carries shape and depth into code, not just colour.

Design

Three acts, and the prompt behind them

Roam's interface follows a three-act structure: tell it about your trip, let it plan, then explore and refine. The brief opens with a structured form rather than a blank chat box, because most people do not want to type an essay to start a trip, and the form doubles as the model's context, so it can generate straight away. The accommodation step offers three options filtered by budget, each with a short reason it was chosen, because a suggestion that just lists a price feels algorithmic.

Work in progress. Early passes at each surface, where the structure and flow got settled before the design system brought everything to final fidelity.

Figma's agent doing the repetitive build. A plain-language brief, and it duplicated and edited three detail screens in parallel while I stayed on direction.

Work in progress. Early passes at each surface, where the structure and flow got settled before the design system brought everything to final fidelity.

Figma's agent doing the repetitive build. A plain-language brief, and it duplicated and edited three detail screens in parallel while I stayed on direction.

The shipped app, from a short brief to a plan you can save. Two pacing plans to compare, real places with real drive times, a live map and one-tap swaps, each screen answering one of the four problems rather than just looking the part.

Hometrending + saved trips Plan a tripdestination, dates, budget, interests Generatingsearching real options Accommodationhotel by price tier Generatingbuilding both plans Comparisontwo plans, pick one Map viewstops on a static map Finalise & savereservations, export, save AI + Google Places verification Every stop is checked against Google Places. Only real, correctly-located places survive, then real travel times are added between them. Swap placeslist of swappable stops Swap placepick a real alternative saved trip
Hometrending + saved trips Plan a tripdestination, dates, budget, interests Generatingsearching real options Accommodationhotel by price tier Generatingbuilding both plans Comparisontwo plans, pick one Map viewstops on a static map Finalise & savereservations, export, save AI + Google Places verification Every stop is checked against Google Places. Only real, correctly-located places survive, then real travel times are added between them. Swap placeslist of swappable stops Swap placepick a real alternative saved trip
Home
trending + saved trips
Plan a trip
destination, dates, budget, interests
Generating
searching real options
Accommodation
hotel by price tier
Generating
building both plans
AI + Google Places verification
Every stop is checked against Google Places. Only real, correctly-located places survive, then real travel times are added between them.
Comparison
two plans, pick one
Peel off to swap a stop: Swap places, pick a real alternative, then back to the comparison.
Map view
stops on a static map
Finalise & save
reservations, export, save
A saved trip loops back to Home.

The end-to-end flow. A short brief becomes a plan, then you compare the two pacing options, open the map, or peel off to swap a stop, and any swap recomputes the itinerary around it.

Designing the prompt as much as the interface

One of the most important design artefacts was the system prompt, not a Figma frame. Getting itineraries that felt specific and appropriately scoped took as much iteration as any screen. Four decisions changed the output most.

01

Structured output

The model returns a consistent shape: time, place, category, cost, reasoning note. The UI renders it predictably regardless of destination.

02

Brief as context

Every field the user fills becomes a constraint the model reasons within, rather than a question it has to ask.

03

Budget as a hard limit

Essential, Comfort and Premium are injected as constraints, calibrating stays, dining and activities to the same tier.

04

Reasoning first

A one-line rationale for every suggestion, so the output feels advisory, not generated. It matched the core insight from my Muse project: unexplained recommendations do not build trust.

The Figma bridge

The usual handoff, static design files passed to a developer to implement by hand, was replaced by a live connection to the Figma file itself.

The bridge in action. Claude reads the live Roam file through MCP, pulling the real frames and component data straight from the design instead of working off a screenshot.

The bridge in action. Claude reads the live Roam file through MCP, pulling the real frames and component data straight from the design instead of working off a screenshot.

After the sprint

What only real use reveals

Forty-eight hours got a real, working product live. The stretch after launch is where it got genuinely good, and it is the part I am proudest of. Real use showed me the calls I had got wrong, and fixing them is work the sprint could never have produced.

The Vercel deployment log. Dozens of production ships in the weeks after the 48-hour build, each one a real fix or a considered refinement, not a cosmetic tweak.

The Vercel deployment log. Dozens of production ships in the weeks after the 48-hour build, each one a real fix or a considered refinement, not a cosmetic tweak.

Cutting the cloud bill

About a week in, Google Cloud credits were draining far faster than the traffic justified, roughly €134 of €263 gone in seven days. This was less a chore than a product constraint: the cost model quietly decides whether a solo project can be put in front of real users at all. Most of it traced back to the place search. Every lookup was asking Google for Enterprise-tier fields Roam never actually used, star ratings, review counts, price levels and opening hours, and any one of them tipped the call into the priciest bracket. Cutting the request down to the fields I actually render moved every search from Enterprise to Pro. Caching each lookup so I never paid for the same place twice, and serving photos from a CDN, did the rest.

The Google Cloud bill, line by line, the view that showed where the money was actually going, and exactly which calls to cut.

The Google Cloud bill, line by line, the view that showed where the money was actually going, and exactly which calls to cut.

Before ~€1.56
Place lookups39 calls · Enterprise
€1.25
Hotel search3 calls · Enterprise
€0.10
Photos~32 loaded
€0.21

Enterprise tier, nothing cached. The same place is paid for on every single generation.

After, first time ~€1.43
Place lookups39 calls · Pro
€1.13
Hotel search3 calls · Pro
€0.09
Photos~32 loaded
€0.21

Pro tier. A brand-new place still needs every lookup, just at the cheaper rate.

After, a repeat ~€0.50
Place lookupspartly cached, new places still bill
~€0.50
Hotel searchUpstash cache
€0.00
PhotosVercel CDN
€0.00

Photos and hotels come free from cache. A replan only pays for genuinely new places.

The cost of one full 3-day generation, at Google's per-call prices above the free tier; the repeat is an estimate.

A subtler leak only showed once the app was public: the home screen was fetching a live Google photo for every trending destination on every visit, so bots and idle browser tabs were quietly billing me for people who never planned a thing. Moving those curated photos to static files meant the app only costs money when someone actually generates a trip, not when someone merely looks at it.

The itinerary rulebook

The biggest body of work was a set of rules the model has to obey before a plan reaches the screen, enforced in the prompt and again on the server.

Rule Why it exists
No idle gaps The only space between two stops is the travel between them.
Fixed meal windows Dinner lands in the evening, not at five.
One meal per slot Exactly one breakfast, lunch and dinner a day. A café or restaurant can't slip in as an activity and read as a second meal.
Meal length follows pace Slow plans give each meal a longer, unhurried sitting; Packed keeps them brief, so the pace is felt at the table too.
Sensible hours Nothing before 09:00 or past 22:30, with a later cutoff for nightlife.
No place twice Dedupe on the resolved place, not the name. This caught a real Lahore itinerary that listed the fort and a palace inside it as two stops, both resolving to the same listing.
Distance-first routing Keep each day in one part of the city under a 60-minute travel ceiling, with the Slow plan carrying fewer stops than Packed.

Reworked and fixed

Four calls I got wrong, each one caught and fixed on my own before it ever reached a user. Unglamorous work, but it is the difference between a demo and something people can actually rely on.

Area What changed
Budget Moved the budget selector to the start of the flow. Set late, it meant regenerating the whole plan; upfront, it becomes a constraint the model plans within from the first call.
The map Shipped completely broken. Fixing it took a solo pass through Google Cloud: enabling Static Maps separately, attaching billing, and realigning a key that no longer matched the console.
Travel times A mislocated stop produced a 15-hour drive that pushed the day into the next one. Capped every leg at 60 minutes, so an impossible hop is dropped rather than displayed and the plan stays on a single day.
Swap The "Swap places" button pointed at a route that did not exist and opened a blank page. Repointed it to the swap flow with the correct plan variant.
Dates Selected dates landed a day early: the picker serialised in UTC, so a Monday start showed as Sunday. Moved the whole app onto a local-date helper.

Moving to TypeScript

The whole codebase is now typed end to end. The itinerary data carries real types from the API through to the screen, so a malformed plan fails at build time instead of reaching someone mid-trip, the same class of silent error the project exists to prevent.

User testing

What six real travellers taught me

The sprint proved I could ship it. Testing was where I found out whether anyone would actually trust it. Six people planned the same Lisbon weekend on their own phones, unguided, while the screen recorded. Most of the plan held. The one place it broke turned out to be the most important thing I learned.

Method

Unmoderated remote usability test on real phones, via UXtweak with screen recording. Success and time on task judged from the recordings, not a completion flag.

Task

One end to end task: plan a two-night Lisbon trip, choose where to stay, reach a finished plan and save it. Questions before and after.

Participants

6 people who plan their own leisure trips, a convenience sample. Five iPhone, one Android; five in Berlin, one in the UK. Mixed on how much they trust AI.

Measures

Completion, Single Ease, a trust rating, UMUX-Lite, would-follow and would-use intent, plus open text coded into themes. Small n, read as directional.

Every one of the six planned a full trip on Roam and saved it, and not one of them needed help from me to get there.

6/6

6/6

reached a finished, saved plan unaided, recordings confirmed

6.0/7

6.0/7

mean ease of planning the trip (range 4–7)

5.8/7

5.8/7

mean trust that places are correctly located (range 4–7)

~3m 40s

~3m 40s

median time from a blank screen to a saved plan

Reading the numbers

A small convenience sample of six people who plan their own trips, one unmoderated remote task. Directional, not representative. The fixed Lisbon destination made "would you follow it" awkward for anyone not actually travelling, which is where both "no"s came from; next round I'd let people plan their own trip and add think-aloud.

01

The core promise landed, even for sceptics

Everyone reached a plan in minutes and called it easy. "It's convenient to see a skeleton of a trip in just a few questions." Even the participant who dislikes itinerary apps praised "the variety of locations and activities."

02

The two pacing plans were the favourite idea

Five of six noticed them, usefulness 6.6 out of 7, and one wanted a third. From the video recordings, only three actually toggled between them, so people valued the reassurance of a choice without exercising it.

03

People stopped to read the reasoning

On every recording, participants paused on the one-line rationale for each place and hotel. The reasoning-first decision earned its place: the "why this" note is read, not skipped.

04

Seeing the map made it credible

Asked why the plan felt right, one participant just said: "A map with the itinerary is shown." The map itself did the convincing, and that is the thread the next finding pulls on.

What held up

Those are the wins, and they held across all six sessions. The same sessions also gave me a ranked list of what to fix.

Findings at a glance

Rated on Nielsen's severity scale, a blend of how bad, how frequent and how persistent. Each finding maps to one change.

What I found Severity The change it points to
Stops resolve to the wrong location. Two plans routed a day to another continent.2 of 6 plans · only 1 caught Critical Reject any stop outside the destination or over the day’s travel limit, and surface the Google Places check so correctness is shown, not assumed.
People want a visible sense of control, not less automation.Raised by 3 of 6 Major Surface the levers Roam already has: budget, timing and choosing between options.
Accommodation cards select but do not open to detail.1 tried it, 3 asked for it Minor Make cards expand to a detail view with photos, rough prices and reviews.
The two pacing plans are valued but under-used.3 of 6 never compared them Minor Make the Packed versus Slow difference visible at a glance so the choice gets used.
Swapping was not recognised as the way to change the plan.1 of 6 Minor Move the swap onto each stop so “change this” reads as an action.

The finding that mattered most: trust held even when the plan didn't

Two of six plans placed a stop on the wrong continent. Left: a first-timer's Day 1 ran from Lisbon to the US east coast; she never noticed and scored the plan 7 out of 7. Right: another participant's Day 3 sent him to the Azores, about 1,360 km into the Atlantic; he caught it at once and his trust fell to 4. The same bug, opposite reactions, and only the sceptic was protected by his own doubt.

What testing caught

"On day three the itinerary suggested an activity far outside Lisbon. The weird location was suspicious."

Participant 4, unprompted

Why it happened

The insight is sharper than "the AI hallucinated," because it didn't. Both places are genuine Google Places listings. The failure was resolution, not invention: a name matched a real entry in the wrong location, and the distance rule meant to keep a day inside one city let a 1,360 km outlier through. "Verify the place is real" and "verify the place belongs in this trip" turned out to be two different guarantees, and Roam only had the first.

The more uncomfortable half is the reaction. People never see the verification, so a confident tone carries the plan. One participant read an itinerary that would have flown her across the Atlantic, found it reasonable, and rated it a perfect seven. A high trust score partly measures how well a plan performs certainty, not how correct it is, which is exactly the risk the product exists to remove.

The finding that mattered most: trust held even when the plan didn't

Two of six plans placed a stop on the wrong continent. Left: a first-timer's Day 1 ran from Lisbon to the US east coast; she never noticed and scored the plan 7 out of 7. Right: another participant's Day 3 sent him to the Azores, about 1,360 km into the Atlantic; he caught it at once and his trust fell to 4. The same bug, opposite reactions, and only the sceptic was protected by his own doubt.

What testing caught

"On day three the itinerary suggested an activity far outside Lisbon. The weird location was suspicious."

Participant 4, unprompted

Why it happened

The insight is sharper than "the AI hallucinated," because it didn't. Both places are genuine Google Places listings. The failure was resolution, not invention: a name matched a real entry in the wrong location, and the distance rule meant to keep a day inside one city let a 1,360 km outlier through. "Verify the place is real" and "verify the place belongs in this trip" turned out to be two different guarantees, and Roam only had the first.

The more uncomfortable half is the reaction. People never see the verification, so a confident tone carries the plan. One participant read an itinerary that would have flown her across the Atlantic, found it reasonable, and rated it a perfect seven. A high trust score partly measures how well a plan performs certainty, not how correct it is, which is exactly the risk the product exists to remove.

That word, "feeling", is the point. The people who loved that Roam did everything for them and the people who wanted to steer are not actually in conflict. The automation should stay; what is missing is a visible sense of agency inside it. Tellingly, the participant who felt most in control praised "the high level of customisation given the few preferences I was asked to fill out," the same lightweight brief that left others feeling steered. The levers already exist. They are just not surfaced.

The takeaway

Six sessions turned a shipped app into a ranked to-do list. Roam is fast, easy and persuasive, sometimes more persuasive than it should be. The work ahead is narrow and clear: make correctness visible, so a wrong stop cannot ride on a confident tone, and give people the felt sense of control the automation quietly takes away.

What the recordings corrected

I assumed the comparison screen would be a problem screen. The video recordings say it mostly works: everyone reached the later days, and only one participant struggled to find how to swap, the others were simply happy with their plan. Watching the recordings kept a single-participant hunch from becoming an overstated claim, which is the reason to watch them at all.

What users wanted

"Give the user more feeling of control. I understand the idea of the app is to let the machine do the work, but I would like to have the feeling at least."

Participant 5, on what he'd change

The theme that ran through everything: give people the feeling of control

Three of the six wanted more say over the plan, even while liking it. It would have been easy to read that as "add more settings." One participant reframed the whole finding.

Closing the second guarantee

The fix goes straight at the gap the testing exposed. Roam already checked that a place was real, and now it also checks that a place belongs in the trip. When it looks up a stop, a name match is no longer trusted on its own. The place is only accepted if it sits within a sensible distance of where you are going, so the right name in the wrong part of the world is thrown out before it reaches the plan. If nothing real turns up nearby, the stop is left off the map rather than pinned somewhere impossible, and a day can no longer draw a line across an ocean. The 1,360 km outlier that slipped past testing is exactly the kind of thing it now catches, and it is live in the shipped app.

Closing the second guarantee

The fix goes straight at the gap the testing exposed. Roam already checked that a place was real, and now it also checks that a place belongs in the trip. When it looks up a stop, a name match is no longer trusted on its own. The place is only accepted if it sits within a sensible distance of where you are going, so the right name in the wrong part of the world is thrown out before it reaches the plan. If nothing real turns up nearby, the stop is left off the map rather than pinned somewhere impossible, and a day can no longer draw a line across an ocean. The 1,360 km outlier that slipped past testing is exactly the kind of thing it now catches, and it is live in the shipped app.

The theme that ran through everything: give people the feeling of control

Three of the six wanted more say over the plan, even while liking it. It would have been easy to read that as "add more settings." One participant reframed the whole finding.

What users wanted

"Give the user more feeling of control. I understand the idea of the app is to let the machine do the work, but I would like to have the feeling at least."

Participant 5, on what he'd change

That word, "feeling", is the point. The people who loved that Roam did everything for them and the people who wanted to steer are not actually in conflict. The automation should stay; what is missing is a visible sense of agency inside it. Tellingly, the participant who felt most in control praised "the high level of customisation given the few preferences I was asked to fill out," the same lightweight brief that left others feeling steered. The levers already exist. They are just not surfaced.

What the recordings corrected

I assumed the comparison screen would be a problem screen. The video recordings say it mostly works: everyone reached the later days, and only one participant struggled to find how to swap, the others were simply happy with their plan. Watching the recordings kept a single-participant hunch from becoming an overstated claim, which is the reason to watch them at all.

The takeaway

Six sessions turned a shipped app into a ranked to-do list. Roam is fast, easy and persuasive, sometimes more persuasive than it should be. The work ahead is narrow and clear: make correctness visible, so a wrong stop cannot ride on a confident tone, and give people the felt sense of control the automation quietly takes away.

Reflection

What building and testing this taught me

Shipping is where the real design starts

The sprint produced something that looked finished. Real trips showed what wasn't: plans that read well but fell apart, and calls I had to reverse. The most senior work happened after launch, not before it.

Trust is a feature you have to show, not just build

Roam verifies every place, but users never see that, so they trust the tone instead, and one trusted a plan that would have crossed an ocean. The verification exists; the next job is making it visible.

The system prompt is a design artefact

The decisions that changed output quality most were about how the model was instructed to behave, not layout or colour. Writing the prompt with the rigour of UX copy mattered more than any single screen.

Automation and control are not opposites

Testing pushed me off my own assumption. People want the machine to do the work and to feel in charge of it. The interesting problem is agency inside automation, not one or the other.

One designer can own the whole product now

One person can own an entire product now. Research, the design system, the front-end, deployment, testing, the whole line sat with me, and the tooling made that fast rather than just possible. That shift is the real headline of this project.

Next steps

What comes next

Roam is not finished, and it was never meant to be. The path from here is a real product, not a tidier prototype: a proper backend and accounts so trips persist, real booking so a saved plan becomes a trip you can actually take, and deeper coordination for the group travelling together. The foundation is live and tested. What it needs next is depth.

Six of six reached a plan they could save, and most would follow it. What I take from this is not just that a designer can ship alone, but that owning the whole thing, from the first research note to the deployed app to the one bug a stranger caught, makes you sharper at every part of it. The tools got a real product live in 48 hours. Knowing exactly how to make it better is what I walked away with.

Tech stack

Six platforms. One pipeline.

The 48-hour budget was not just a timeline; it was a design constraint. Every decision had to be defensible against a single question: does this justify the time? That discipline shaped the scope more cleanly than any brief could have.

Six platforms covered the full stack, with each one feeding directly into the next: design, engineering, data, editing and deployment. Figma Make generated the wireframes. Figma Agent populated the high-fidelity frames with real destination content. Token Studio exported the design tokens as CSS custom properties. Claude, connected to the Figma file via MCP, passed the live spec directly to Cursor, which built each React component from it. Vercel deployed the result.

The design and engineering decisions never really separated. Because Claude was reading node data directly from Figma, spacing values, component properties and typography all translated into code without a manual handoff step. That closed a gap that usually costs days.