Round #147Score 4/5Transport: taxi

Four hand-built mobile action bars finally became one component

Route: /taxi-ride
Desktop preview
Mobile preview

Captured at a 375px viewport. Long pages scroll inside the frame.

The screenshots stay in Japanese. Every round is a real screen for a real Japanese industry, so an English re-render would no longer be the screen the agent actually produced.

Write-up

Four hand-built mobile action bars finally became one component

⁠Build log series⁠: I give an AI that has never seen Gunjo (@gunjo/ui) only the public npm package and the gunjo.jp docs, then ask it to build a real screen. This ⁠first passenger-facing taxi round⁠, after six staff screens, covered a ⁠ride-hailing app⁠: requesting a car, arrival estimates, driver and vehicle details, fares, and payment. It began deeper passenger coverage because one passenger screen would not balance six staff screens.

Result: 4/5, and a gap accumulated across four rounds triggered a build

The screen passed tsc and fit a 375px mobile-first layout. The agent reported:

⁠This was a complete mobile passenger toolkit.⁠ PageHeader, RadioCard, AmountBreakdown, ListCard, LoyaltySummaryCard, and PersonCell included targets at least 44px tall, Japanese and yen defaults, and cues beyond color. ⁠Only the fixed action bar that every transactional or real-time consumer screen needs was missing.⁠

The core observation: BottomActionBar returned for the fourth time

The agent again hand-rolled a fixed bottom bar with a ⁠ride summary and primary action⁠:

⁠There is no BottomBar, ActionBar, or BottomActionBar in the @gunjo/ui entry point or docs, and the catalog admits no dedicated component exists.⁠ StatusBar sounds promising but is a fixed-width desktop status strip using w-[640px], two grid columns, and a primary background. I hand-rolled bottom-0, a top border, backdrop blur, safe-area inset, fare or ETA on the left, and a large button on the right. ⁠The highest-value addition is BottomActionBar: a fixed button dock with a fare or ETA slot and safe-area handling, needed in payments, ride hailing, booking, and food ordering.⁠

Disruption rebooking in , refunds in , intercity bus booking in , and ride hailing here meant ⁠four independent agents had hand-rolled it.⁠ I had already passed the threshold at three and deferred the build. The fourth case removed any doubt.

What I built: BottomActionBar, the fifteenth component

<BottomActionBar actions={<Button size="lg" onClick={call}>Request this ride</Button>}>
  <div className="flex flex-col">
    <span className="text-xs text-muted-foreground">Estimated fare</span>
    <span className="font-semibold tabular-nums">¥1,200 and up, 4 min arrival</span>
  </div>
</BottomActionBar>
<BottomActionBar stack actions={<Button size="lg">Pay</Button>}>Summary</BottomActionBar>
  • children holds the ride summary, actions holds buttons, stack places a full-width action above the summary, sticky is the default, and maxWidth centers the bar on tablets. A top border, translucent background, backdrop blur, and pb-[env(safe-area-inset-bottom)] clear the home indicator.
  • It is safe for server rendering and has no hooks or handlers of its own. Callers put onClick on their buttons.
  • It is the bottom counterpart to PageHeader, the fixed top app bar. I replaced the catalog's unsupported note with BottomActionBar and documented why the fixed-width desktop StatusBar is not the same thing.
  • PR#401 verified the button, estimated fare, four-minute ETA, top border, and clean console at 375px.

⁠What I built under src this round: BottomActionBar, on its fourth observed case and as the fifteenth component. It resolved the BottomActionBar half of issue #391.⁠

What I took away: a top app bar predicts its bottom counterpart

The screen in that produced PageHeader also had hand-rolled layers at both the top and bottom. The top app bar settled after three cases; the bottom action dock took four. Mobile screens are framed by two fixed regions, navigation above and the primary action below. ⁠Once one half of a pair settles, the other tends to follow later.⁠

Gunjo has seen the same paired pattern elsewhere: PageHeader and BottomActionBar, ScanInput and TicketStub for reading and presenting a code, and RouteStops and Itinerary for tracking and planning. The foundation often finishes in pairs.

📊 Component scoreboard (⁠15 built⁠)

AmountBreakdown / ActionQueue / ListCard / Gantt-segments / SeatMap / LoyaltySummaryCard / RadioCard / FilterChips / PageHeader / Itinerary / TicketStub / Stringline / StatusBoard / ExpiryBadge / ⁠BottomActionBar⁠ In progress: ApproachCard for one live ETA, StatusLevel at two of three, TransitItinerary at two of three, LineChip at two of three, and Leaderboard or CaseTable.

📋 Mode progress: passenger-facing taxi coverage begins

  • ✈️ Air and 🚆 rail: five staff + six passenger screens each ✅ / 🚌 Bus: two staff + three passenger screens
  • 🚕 ⁠Taxi: six staff + one passenger screen (ride hailing)⁠, with passenger coverage continuing ✅

Next up: build log

  • I'll decide among deeper passenger bus coverage, trucking with staff operations and customer tracking, or another direction before the next round.

The run

Four hand-built bottom action docks became one component, and deeper passenger taxi coverage began. The bottom counterpart to PageHeader had finally arrived.

This series is co-created with AI (Claude and Codex). A human designs the experiments, makes the calls, and fact-checks before publishing; the AI does the hands-on work and drafting.

Components from @gunjo/ui

The components this screen's source imports directly.

The code the agent actually wrote

Click a file to expand its source.

業界別「AI指示書パック」、先行登録を受付中です。