Make it real before you build it: throwaway HTML mockups as the design tool you already have¶
In the previous post I made a confident claim: you do not need to draw a UI to specify one. You answer the right questions in the right order, you render the screen as an ASCII mockup made of + - | = characters, you correct it in plain language, and you freeze it into a file. I stand by all of that. But I also ended that post by naming, out loud, three things ASCII genuinely cannot do. It cannot express color. It cannot express motion. It cannot express exact spacing or how the layout reflows from a tablet down to a phone.
So here is the honest gap. After the ASCII step you have a frozen contract -- the right regions, in the right order, saying the right things, with the right things deliberately absent. What you do not have is any idea whether it actually looks right. A non-designer can read +--+ boxes all day and still not know if the screen is cramped, if the active player is obvious from across the room, if the join code is findable, if the whole thing feels like a toy or a tool. The ASCII froze the layout. It did not let me see it.
This post is about closing that gap, and the answer is not "now you finally have to learn a design tool." It is the same move as before, one notch richer: you ask the AI to render the frozen spec as a self-contained HTML page with real CSS, you open it in a browser, and you correct that in plain language. Still no Figma. Still no mouse. Still no canvas. Still committed to the repo as a versioned, pre-React artifact. The only thing that changed is that now you can see color, spacing, and reflow -- the exact three things the ASCII step told you it could not give you.
This is the third post in the builder's-eye "build an app with AI" series. The first, From an idea in a chat window to a repo the robot can build, set up the repo and the orchestrator. The second, Describe the screen, don't draw it (the UI-spec prompt playbook), produced the frozen ASCII spec. This post renders that spec into something you can look at. The next one, The orchestrated build-and-feedback loop, is where the rendered mockup finally becomes React.
The pipeline has three rungs, not two¶
It is worth being precise about where this step sits, because it is easy to collapse it into either of its neighbors.
- Frozen ASCII spec. The contract. Regions, content, states, and the must-not-appear list, in plain text. (That was post #13.)
- Throwaway HTML mockup. The same spec, rendered. One self-contained HTML file per screen, per state, with real CSS so you can see color, spacing, and reflow in a browser. Disposable, but version-controlled. (This post.)
- The React stage. The real build, wired to the live server, governed by the project's hard rules and its tests. The source of truth. (The next post.)
Rung 2 is not the build. Nothing in a mockup file ever runs in the real app -- there is no WebSocket, no server payload, no state machine, no React. It is a picture that happens to be made of HTML because HTML is the cheapest way for an AI to draw a high-fidelity picture you can open. And rung 2 is not the spec either: the spec says the active player gets a highlight; the mockup shows you that the highlight is a blue halo with a soft glow, 4 pixels thick, and lets you decide from across the room whether that reads as "it's your turn" or as "this cell is broken."
The reason to keep rung 2 as its own artifact -- rather than skipping from ASCII straight to React -- is that correcting a picture is an order of magnitude cheaper than correcting a build. "The call timer is too prominent" is a one-line CSS change in a throwaway file the AI re-emits in seconds. The same realization after the React stage ships is a ticket, a code review, and a regression test.
The artifact tier, named accurately¶
This is not a hypothetical. The project already has a sizable library of exactly these files, and being precise about their shape is half the point.
Each game with a UI spec has a mockups/ directory under the game docs. Inside it is one standalone HTML file per screen, per state, plus a single shared styles.css they all link, plus an index.html gallery that links every screen with a one-line description. The HTML is self-contained and inert: open the file, see the screen. Games that currently carry a mockup library are battleland, bluff, dice_room, memory_match, and werewolf; the session and lobby layer (home, join, profile, share, post-game) lives once under the overview docs and the per-game galleries inherit it rather than redrawing it. (I am deliberately not quoting exact file counts -- the library grows as games get specified, and a number I print today goes stale.)
Two more details make the tier traceable instead of a private art project:
The galleries cross-reference the spec they render. The Bluff gallery index opens by saying exactly what it is and what it is for:
Static HTML renderings of the screens enumerated in the Bluff gameplay UI spec. Throwaway artifacts to make the design tangible before any React lands. The session/lobby/admin layer is inherited from the Management UI mockups -- these cover gameplay surfaces only.
That is the whole thesis of the medium in four lines, written into the artifact itself: throwaway, to make the design tangible, before any React lands, gameplay surfaces only. Every individual screen file carries the same discipline -- the Memory Match TV file is titled for the spec section it renders ("Section 11 -- Table view"), so a reader can always walk a mockup back to the contract clause it is implementing.
A redirect stub keeps the spec library tidy. Alongside each game's spec sits a one-line mockups_index.md whose entire body is a redirect into the mockups/ gallery:
So the docs tree links to a clean Markdown path, and the reader lands in the rendered gallery. The HTML is the artifact; the Markdown stub is just the doorway.
Prompt 1: render one frozen screen as a self-contained HTML page¶
Here is the first of the two prompts that do the work. It takes one screen from your frozen spec and renders it. The non-negotiable parts are self-contained (so you can open the file with no build step and no server), cross-referenced (so the file names the spec section it implements), and one screen, one role (so you are looking at exactly one thing and can judge it).
You are rendering a frozen UI spec into a throwaway HTML mockup so I can SEE it in a browser. This is not the real build -- it is a disposable picture.
Here is the frozen spec section for the screen we are rendering:
Produce a SINGLE self-contained HTML file that renders this ONE screen for ONE role, in its normal / success state. Requirements:
- Self-contained: all CSS inline in a