Случилось вот что: я зашёл на собственную веб-версию продукта и просто не узнал его, потому что у меня тихо выросло два разных приложения вместо одного. В Telegram Mini App всё понятно, а на сайте, как я сам себе тогда написал, ни по дизайну ни по ux не понятно ничего, хотя backend у них один и тот же. И корень тут простой: два независимо написанных фронтенда, которые делят только API, а всё остальное у каждого своё. Чинил я это неделю, и свелось всё к одному решению — один фронт назначаешь эталоном, а второй подстраиваешь под него по токенам, шрифту и иконкам один в один, а не так что скопировал цвета и надеешься что прокатит.
Дальше расскажу как до этого вообще дошло, почему поверхностный фикс только разозлил меня ещё больше, и что я в итоге понял про вайбкодинг сайта, когда у одного продукта несколько экранов.
Как из одного продукта получилось два
У меня Картара живёт сразу в двух местах. Есть Telegram Mini App, который запускается прямо из телеги, и есть веб-версия для тех кто заходит с компа или из обычного мобильного браузера. И технически это две отдельные кодовые базы: веб на Next.js, мини-апка на Vite с React. Общий у них ровно один кусок — backend, то есть API. А всё что выше этого API — кнопки, карточки, отступы, иконки, как расположен профиль, как выглядит шапка с балансом — каждый фронт писал по-своему.
Сначала это казалось нормальным. Ну два фронта и два фронта, движки у них разные, ограничения разные, мини-апка вообще живёт внутри телеграма со своими правилами. Claude Code написал веб, я оркестрировал, потом отдельно занимались мини-апкой, и каждый раз когда делали веб — брали у мини-апки цвета и шли дальше. А цвета, как выяснилось, это вообще не дизайн. Это процентов пять от того что делает продукт узнаваемым, остальное где-то рядом и про него все забыли.
И вот в какой-то момент я просто зашёл и посмотрел на веб глазами обычного человека, а не разработчика который помнит что где лежит. И не понял вообще ничего. Если в мини-апку захожу — всё понятно, а тут непонятно, ни по дизайну ни по ux. Один и тот же продукт, одна и та же Картара, а ощущение что попал в два разных сервиса от двух разных команд.
Почему «скопировали цвета» — это не единый стиль
Когда я начал копать, картина вылезла такая. Веб действительно взял у мини-апки палитру, и на этом всё. А дальше разошлось буквально по каждому слою: по-разному сделаны акценты под разные разделы, по-разному собраны карточки — те самые примитивы, из которых строится весь интерфейс, разные иконки в одних и тех же местах, кнопки действия выглядят не так, отступы и скругления чуть-чуть другие. И вот из этих «чуть-чуть» и складывается то самое чувство чужого продукта, хотя по отдельности ни к одной детали не придерёшься.
Я тогда прямо так и спрашивал у Claude Code: почему визуально отличается от мини-апки, иконки где-то разные, какие-то компоненты, в целом расположено не так, разве не надо стиль сделать единый? И главный вопрос, который бесил меня больше всего — почему веб не продолжает мини-апку, а мини-апка не продолжает веб, почему вообще так вышло что у меня два фронта живут как два незнакомых человека.
Ответ простой и неприятный. Потому что никто им не сказал быть одинаковыми. Дизайн-язык не задаётся сам собой из того что backend общий. Если ты не вынес токены, шрифты, набор иконок и компоненты в одно место и не заставил оба фронта тянуть оттуда — они разъедутся, тут вариантов нет. И дело не в том что AI тупой, а в том что AI делает ровно то что ты попросил, а попросил ты «сделай веб» и «сделай мини-апку» по отдельности, в разные дни, разными заходами. Меняется только исполнитель. А кожаные разработчики разъезжаются точно так же, если у них нет общей дизайн-системы, так что тут с ИИ всё честно. Тот же дрейф я разбирал на одном поле ввода, которое разъехалось между двумя фронтами — и там переиспользование компонента само по себе копипасту не убрало.
Поверхностный фикс, который меня только разозлил
Первая попытка починить была классическая и провальная. Раз непонятно что где — давай хотя бы навигацию подравняем, чтобы по экранам ходилось похоже. Подкрутили только навигацию. И это меня разозлило ещё больше, потому что стало только очевиднее: навигация теперь немного похожа, а всё остальное по-прежнему из другого мира. Получился косметический пластырь на проблему которая сидит в самом фундаменте. О том, почему перестановка навигации это вообще не фикс UX-рассинхрона, я отдельно разбирал — корень там тот же самый.
Это вообще частая ловушка, когда работаешь с ии для автоматизации своей же рутины. Ты видишь симптом — «тут кнопка не такая» — и просишь поправить кнопку, AI правит кнопку. Просишь поправить навигацию — он правит навигацию. И так можно месяц латать по одной детали, а корневая причина — что нет единого источника правды для дизайна — никуда не девается. Пришлось остановиться и сказать честно: проблема не в кнопке, проблема в том что у меня два продукта вместо одного, и чинить надо не симптом а причину.
Решение: один эталон, второй подстраивается
Дальше всё стало понятно, как только я перестал латать и сформулировал что вообще хочу. А хотел я простого — чтобы оно было похожим, чтобы с компа, с мобильного браузера или из телеги везде всё знакомо, понятно и выглядит одинаково. Один продукт, а не три впечатления от трёх разных сервисов.
Из этого вылезло первое решение — назначить эталон. Я выбрал мини-апку как образец, потому что именно в ней всё понятно, именно её не стыдно показывать, и именно к ней привыкли пользователи. Веб подстраивается под мини-апку, а не наоборот и не «встретимся где-то посередине». Когда есть один источник правды, спорить не о чем: вот эталон, вот к чему приводим всё остальное.
Второе — синхронизация дизайн-токенов один к одному. То есть цвета, отступы, скругления, размеры — не «скопировали на глаз», а буквально одни и те же значения в обоих фронтах. Плюс общий шрифт и единый набор иконок, чтобы в одинаковых местах стояли одинаковые значки, а не где-то один комплект, где-то другой. Это та скучная инфраструктурная работа, которую обычно никто не хочет делать, потому что на скриншоте её не видно, но именно она и есть «единый стиль».
И третье, уже на будущее — идея сделать веб как приложение в один экран, с нижней навигацией как в мини-апке, чтобы сайт ощущался не как страница, а как апка, которую открыл и сразу узнал. Что-то вроде того как на маке окна и док — компактно, узнаваемо, всё на своём месте. Это уже не про «починить», это про то чтобы довести продукт до одного языка целиком.
Что я с этого понял
Главный вывод тут дороже самой недели работы. Когда у тебя один продукт живёт на нескольких экранах — сайт, мобильный браузер, Telegram Mini App — это не три проекта, это один проект с тремя витринами, и дизайн у них обязан быть один. Не похожий, не «в той же гамме», а буквально из одного источника. Иначе ты собственными руками выращиваешь два разных приложения и потом сам же не узнаёшь своё в зеркале, как со мной и вышло.
Технически вся работа по сведению заняла неделю постраничного прохода — профиль, шапка с балансом, календарик подарков, таро, чат, каждый экран приводили к эталону по очереди. Код, как всегда, писал Claude Code под моим управлением, я задавал что считать правдой и проверял результат глазами обычного пользователя. И вот это «проверял глазами пользователя, а не разработчика» — отдельный навык, который мне дался не сразу. Я ведь полгода не замечал что веб разъехался, потому что смотрел на него как человек который помнит где что лежит. А пользователю помнить нечего, он просто видит чужой непонятный экран и уходит.
Так что если делаете свой продукт через вайбкодинг и он у вас выходит больше чем на один экран — заведите единый дизайн-язык с первого дня, вынесите токены и иконки в одно место, назначьте эталон. Это скучно и на демо этого не видно, зато потом не придётся неделю сводить два фронта, которые тихо разбежались пока вы смотрели в backend. Я эту шишку набил, рассказываю чтобы вы свою не набивали. Похожую историю про то как мы переделывали лицо продукта я уже описывал в посте про то, как переделал сайт за вечер, потому что не смог описать сам себя — там тоже всё свелось к тому, что снаружи и внутри должно быть про одно и то же. Вот и делайте выводы.