Round #111Score 3.5/5Transport: rail

ListCard emerged after one pattern recurred across consumer screens

Route: /service-status
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

ListCard emerged after one pattern recurred across consumer screens

⁠Build log series⁠: For each entry, I give an AI unfamiliar with Gunjo (@gunjo/ui) the public npm package and the gunjo.jp docs, then ask for a working screen. ⁠The third passenger-facing rail round⁠ was ⁠a service-status page⁠ with line-by-line conditions, suspensions, and an update history, the kind of screen everyone checks when trains are delayed.

After limited-express booking in and journey planning in , this was the third passenger-facing rail screen. The central question was whether ⁠result cards and status rows would be hand-rolled for a third time and trigger a real component.⁠

Result: 3.5/5, and the first passenger component reached three cases

The line-status row became the third independent version of the same consumer pattern. The screen passed tsc and build, fit a mobile-first 375px layout, and produced no console errors across critical service notices, line status, line details, and update history. The agent reported:

⁠(a) The line-by-line service-status row was hand-rolled. It is the center of the screen, and the library had nothing for it.⁠ The missing status result row or list card needs a leading color swatch, title, status pill, supporting line, update time, severity accent, and chevron, all in one tappable row. "⁠This is the most reusable pattern in any consumer app that lists things with states, the library's largest consumer-facing gap, and the single most valuable addition.⁠" ⁠(b) ActionQueue fit critical service notices perfectly.⁠ It was the one place where the library felt unmistakably purpose-built, and "the reason to keep using the library."

⁠Three screens in a row⁠ produced the same result: train candidates in , journey candidates in , and line statuses in #111. ⁠Three separate agents independently hand-rolled the same tappable list row.⁠ The rule of three triggered. ⁠It was built for real immediately, becoming Gunjo's first consumer-facing component from this run.⁠

Built for real: ListCard

<ListCard
  leading={<span className="size-3 rounded-full bg-destructive" />}
  title="Chuo Line Rapid" description="Injury on the line"
  status={<Badge variant="destructive">Service suspended</Badge>}
  meta="Updated 7:42" severity="critical"
  onSelect={() => openLine("chuo")}
/>
  • Leading content, title, supporting text, tag, status, metadata, chevron, a left severity accent, and selected state.
  • With onSelect, the whole card is a real button at least 44px high⁠, addressing the test finding about undersized touch targets, with hover, focus, and aria-pressed behavior.
  • ⁠Status does not rely on color alone⁠, combining an icon-bearing Badge with the severity accent. ⁠Server rendering is safe by default.⁠
  • The same component serves search results and service-status rows as ⁠the component for lists of consumer-facing objects.⁠
  • Closed issue #135 with PR#359. On a 375px device, touch targets measured 58 to 73px, selection moved on tap, and the console stayed clear.

I also fixed false leads for status rows

This round, the table sent "status row" to PersonCell for people and "line information" to RouteStops for delivery stops. I renamed the group ⁠"lists, results, and tables,"⁠ added ListCard, and stated that this use case is ⁠not PersonCell for people, RouteStops for delivery stops, or DataTable for administrative tables.⁠ That corrected the false leads from , , and #111 together.

⁠What was added under src this round: ListCard, on its third case. ActionQueue was independently rediscovered for a fourth consecutive rail screen⁠, this time for triaging critical service information.

What I took away: consumers have a cross-industry foundation too

On staff-facing screens, the rule of three established a shared foundation in StatGroup for metrics, AmountBreakdown for money, and ActionQueue for items requiring action. ⁠The same process worked for consumers.⁠ ListCard, a list of objects, carries across search results, product comparisons, status lists, order rows, and device lists. It is ⁠the backbone of consumer apps.⁠ Three passenger screens were enough to add that backbone.

The table's accumulated improvements continued too. Since creating it in #100, I have added entries, documented unsuitable contexts, and corrected false leads on every round. This time I removed the status-row misdirection and pointed the table to ListCard. ⁠A component fills the gap, and the table points to it:⁠ that loop now works for consumers as well as staff. The remaining mode-specific consumer foundations are SeatMap (issue #356, one of three) and TransitItinerary (issue #358, one of three).

Next up: build log

  • Three passenger-facing rail screens complete this set. Next I may try ⁠passenger air booking for a second SeatMap case⁠, staff or passenger screens for bus, taxi, or trucking, or one more rail screen such as station navigation. I will also watch whether an agent in another industry finds ListCard independently.

The run

The third hand-built consumer list became ListCard immediately.

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指示書パック」、先行登録を受付中です。