Demo project

Mobile shop built to spec: PrintCraft

A redlined spec sheet and the app built to it - both halves live in one repository.

spec sheet and development · Flutter · Dart · HTML · CSS · Node.js · Playwright

5 screenscatalog through to order confirmation
6 productsthree categories, two products each
5 colorsof filament; color splits the cart line
2 artboardscatalog and product page, redlined
iOS + Androidone codebase, both platforms
Demo first screen: Mobile shop built to spec: PrintCraft

The task

“Build this screen from the design” is one of the most common mobile jobs and one of the most common reasons handover drags on. The designer sends a mockup, the developer builds the screen, and then the screenshots start going back and forth: the 16pt gutter became 14, the orange is slightly off, the font fell back to the system one. The client has no way to check the match except by eye, and the developer has no way to prove it except by saying so.

PrintCraft is a 3D-printing workshop making objects for the home, the desk and kids. This is a demo: the workshop, its products and its prices are invented, and the app takes no orders and handles no payments. The product photos are stock and illustrative - the demo has no photography of its own.

The solution

  • The spec lives in the repository as two HTML and CSS artboards: the catalog and the product page. Each carries a life-size 402 x 874 pt screen frame, dimension lines with numbers, spacing callouts, a palette with swatches, a type scale and button states. A Figma file cannot live here - it would not open for everyone, and it drags someone’s account into the shot.
  • The other three screens - cart, order confirmation, about - are built from the same palette, grid and type scale, but they have no redlined artboard of their own.
  • The spec’s values - palette, spacing, sizes, type, products - sit in two source files. They reach the app by machine: tokens.g.dart and catalog.g.dart are built from those files by a generator rather than retyped by hand. One caveat as of today: the generator script itself does not run from the repository as it stands, and fixing that is on the list.
  • Five screens: catalog, product, cart, order confirmation, about. The catalog filters across three categories with no reload. The product page has a full-width photo, filament color swatches and a sticky button that reads “Added” for a second and a half.
  • The cart tells colors apart: a planter in mint and the same planter in terracotta are two lines, not one with quantity two. The total counts items, not lines. Twelve checks over the catalog and the cart pass.
  • The artboards are captured by a single Playwright command; the screens come off the simulator and the emulator through platform tooling. The side-by-side “spec and screen” pair is assembled from those frames.

Details that are easy to miss

  • The app ships without a stock component kit: no button and no list brings in somebody else’s design language. Everything is drawn to the spec, icons included - they are vector paths, not an icon font that shifts the day a package updates.
  • The font files sit in the repository, and the spec and the app use byte-identical copies. The convenient one-line way to add fonts fetches them over the network; a substituted face would make the typography in the pair disagree.
  • Screen transitions are instant on purpose. A capture cannot catch the middle of an animation, so a retake matches the previous frame - otherwise a before-and-after comparison stops comparing anything.
  • Prices are formatted by hand, “2 490 ₽” with a space between thousands, instead of pulling in a localization library.
  • If a product photo is missing, a tidy placeholder is drawn rather than a full-screen error.
  • Before a capture the status bar is normalized: fixed time, full battery, no carrier name. Frames are taken with platform commands only, never off the display, or personal data and the emulator window end up in the shot. After an Android capture the PNG signature is verified, because older tooling corrupts the file silently.
  • The disclaimer works on two levels: a small line at the foot of the catalog and a separate screen with the full text.

Still open

  • Fixing the generator: the spec files are written as CommonJS while the package is declared an ES module.
  • The remaining captures. iOS has the catalog, product page, cart and order confirmation; Android has only the catalog; the about screen has not been shot on either.