Демо-проект
Мобильный магазин по макету: PrintCraft
Макет с размерными линиями и приложение, собранное по нему: обе половины лежат в одном репозитории.
макет и разработка · Flutter · Dart · HTML · CSS · Node.js · Playwright

Задача
«Сделать экран по макету» - один из самых частых мобильных заказов и одна из самых частых причин споров на приёмке. Дизайнер отдаёт макет, разработчик собирает экран, дальше идёт переписка скриншотами: отступ 16 превратился в 14, оранжевый стал чуть другим, шрифт подменился на системный. Заказчик не может проверить совпадение иначе, чем глазом, а разработчик не может доказать его иначе, чем на словах.
PrintCraft - мастерская 3D-печати: вещи для дома, рабочего стола и детей. Это демо-проект: мастерская, товары и цены вымышлены, приложение не принимает заказы и не проводит платежи. Фотографии товаров стоковые и иллюстративные, своей предметной съёмки у демо нет.
Решение
- Макет лежит в репозитории двумя артбордами на HTML и CSS: каталог и карточка товара. На каждом рамка экрана 402 x 874 pt в натуральную величину, размерные линии с числами, подписи отступов, палитра со свотчами, типографическая шкала, состояния кнопки. Файл Figma сюда положить нельзя: он не откроется у всех и потянет в кадр чужой аккаунт.
- Остальные три экрана - корзина, «заказ принят», «о приложении» - собраны из той же палитры, сетки и типографики, но отдельного артборда с размерными линиями у них нет.
- Значения макета - палитра, отступы, размеры, типографика, товары - лежат в двух файлах спецификации. В приложение они попадают машинным переносом:
tokens.g.dartиcatalog.g.dartсобраны из этих файлов генератором, а не перенабраны руками. Оговорка на сегодня: сам скрипт генератора из репозитория как есть не запускается, починка в списке доработок. - Пять экранов: каталог, карточка товара, корзина, «заказ принят», «о приложении». Каталог фильтруется по трём категориям без перезагрузки. В карточке - фотография во всю ширину, выбор цвета пластика и липкая кнопка, которая на полторы секунды становится «Добавлено».
- Корзина различает цвет: кашпо в мяте и то же кашпо в терракоте - две строки, а не одна с количеством два. Итог складывается по количеству, а не по числу строк. Двенадцать проверок каталога и корзины проходят.
- Артборды снимаются одной командой через Playwright, экраны - служебными средствами симулятора и эмулятора. Пара «макет и экран рядом» собирается из этих кадров.
Детали, которые легко не заметить
- В приложении нет готового набора компонентов: ни одна кнопка, ни один список не приносит чужой дизайн-язык. Всё нарисовано по макету, включая иконки - это векторные фигуры, а не иконочный шрифт, который поедет от обновления пакета.
- Файлы шрифтов лежат в репозитории, у макета и у приложения они совпадают побайтно. Популярный способ подключить шрифты одной строкой тянет их по сети: в кадр может попасть подмена, и типографика в паре разъедется.
- Переходы между экранами сделаны мгновенными. Снимок не поймает середину анимации, и повторный кадр совпадёт с предыдущим - иначе сравнение «до и после» перестаёт быть сравнением.
- Цена собирается вручную: «2 490 ₽» с пробелом в разрядах, без библиотеки локализации и лишних зависимостей.
- Если фотография товара не нашлась, рисуется аккуратная плашка, а не сообщение об ошибке во весь экран.
- Перед съёмкой строка состояния приводится к нейтральной: фиксированное время, полный заряд, оператор не подписан. Кадры снимаются только служебными командами, никогда с экрана: иначе в них попадёт личное или окно эмулятора. После кадра Android проверяется сигнатура PNG - старые версии инструментов молча портят файл.
- Дисклеймер разнесён на два уровня: строка мелким шрифтом внизу каталога и отдельный экран с полным текстом.
Что осталось
- Починить запуск генератора: файлы спецификации написаны под CommonJS, а пакет объявлен как ES-модуль.
- Досняться. Сейчас на iOS сняты каталог, карточка товара, корзина и «заказ принят», на Android - только каталог; экран «о приложении» не снят нигде.
Скриншоты




