Czy programista może zbudować dobry design? Już nie musi.
Agent pisze ten sam widok za każdym razem inaczej. Lekarstwo: design.md i zamknięty zestaw komponentów Twig, z których składa widoki, zamiast wymyślać je od nowa.
Daj agentowi do napisania ekran edycji użytkownika. Zrobi go dobrze. Godzinę później poproś o ekran edycji produktu — bardzo podobny formularz. Też dobrze. Tyle że inaczej: tu label nad polem, tam placeholder w środku; przycisk „Zapisz" raz po prawej, raz po lewej; inny odstęp, inny select. Ten sam rodzaj widoku, napisany dwa razy, za każdym razem trochę inny.
To nie błąd. Agent nie pamięta, jak zrobił poprzedni formularz — generuje najbardziej prawdopodobny kod dla tego, o co właśnie prosisz, a „prawdopodobny" za każdym razem wypada minimalnie inaczej. Pomnóż to przez kilkadziesiąt widoków i parę miesięcy, a interfejs po cichu robi się patchworkiem: wszystko działa, nic do siebie nie pasuje.
I tu wraca pytanie z tytułu. Backendowiec, który to zleca, nie chce być designerem — nie po to robi backend, żeby pilnować, czy label jest nad polem, czy obok. Agent oka do designu nie ma w ogóle. Żaden z nich nie powinien decydować o tym od nowa przy każdym widoku. Więc trzeba im ten wybór odebrać.
„Bądź spójny" nie zadziała
Pierwszy odruch to dopisać do instrukcji agenta „trzymaj spójny styl". Nie zadziała, i to z konkretnego powodu: spójność nie jest regułą, którą da się zapamiętać, tylko skutkiem braku wyboru. Dopóki agent przy każdym widoku od nowa decyduje, jak wygląda pole formularza, będzie decydował za każdym razem trochę inaczej — choćby się starał. „Bądź spójny" to prośba, żeby setki drobnych decyzji wypadły identycznie. Nie wypadną.
Rozwiązanie nie polega więc na lepszym promptcie, tylko na tym, żeby tych decyzji w ogóle nie było. Agent ma nie projektować widoku, tylko składać go z gotowych klocków. A żeby miał z czego składać, klocki trzeba najpierw przygotować — w określonej kolejności.
Workflow: od design.md do gotowych klocków
Kolejność jest tu istotna, bo każdy krok karmi następny.
1. Najpierw design.md. To nie mój wymysł — to konkretny format od Google Labs: tokeny designu (kolory, typografia, odstępy, definicje komponentów) w nagłówku YAML plus sekcje opisowe w markdownie, które tłumaczą, do czego co służy. Agent czyta go jak resztę instrukcji projektu, tylko że to ustrukturyzowany format, nie luźne notatki — dostaje „trwałe, ustrukturyzowane rozumienie systemu designu". W komplecie idzie CLI: lint waliduje odwołania do tokenów i kontrast WCAG, export zrzuca je do Tailwinda czy CSS. Zanim powstanie pierwszy komponent, to tutaj zapadają decyzje o warstwie wizualnej — żeby nie zapadały później w każdym widoku z osobna.
---
colors:
ink: "#1A1C1E"
accent: "#FCCC61"
rounded:
sm: 6
components:
button-primary:
background: "{colors.accent}"
rounded: "{rounded.sm}"
---
## Akcent
Kolor `accent` rezerwujemy dla jednej głównej akcji na ekranie — nie dla dekoracji.
2. Na bazie design.md budujemy komponenty. Tokeny ubieramy w zamknięty zestaw komponentów Twig: <twig:Button>, <twig:Card>, <twig:DataGrid>, <twig:Badge>. Decyzja o wyglądzie mieszka teraz w jednym miejscu — w komponencie, który sięga po tokeny z design.md — a nie w głowie agenta przy każdym użyciu.
Osobno warte zachodu: formularze. Zamiast komponentu na każdy typ pola robimy motyw formularzy Twiga — własny form theme, który nadpisuje, jak Symfony renderuje form_row, form_label i form_widget. Dzięki temu działa natywne {{ form(form) }}: jedna linijka, a formularz renderuje się w Twoim design language, bez układania pól ręcznie. Wróćmy do dwóch ekranów z początku — edycji użytkownika i produktu. Z motywem formularzy oba to {{ form(form) }} i wyglądają tak samo, bo agent w ogóle ich nie układa. Nie ma jak ich rozjechać.
3. Z komponentów składamy „kitchen sink". Jedna strona, na której wyrenderowane są wszystkie komponenty we wszystkich wariantach — przyciski, pola, selecty, DataGrid, stany puste, formularz przez motyw. To Twój pulpit kontroli jakości: zamiast wyłapywać niespójności rozsiane po czterdziestu widokach, oglądasz cały język wizualny w jednym miejscu i jednym rzutem oka oceniasz, czy się trzyma.

4. Jeśli kitchen sink zadowala — wskazujesz go agentowi. Dopiero teraz wraca instrukcja, ale inna niż „bądź spójny": wzoruj się na kitchen sink, składaj widoki z tych komponentów, nie twórz własnych. Kitchen sink przestaje być tylko testem dla człowieka i staje się katalogiem dla agenta — skończoną listą klocków plus jedną stroną, która pokazuje, jak ich użyć. To zarazem jedyny fragment, który backendowiec może z czystym sumieniem zostawić na „vibe-code": wygląd ocenia okiem, na czuja — „to zostaw, to popraw" — i na tym koniec. Całą resztę uwagi przenosi tam, gdzie jest u siebie: na solidną architekturę, która ten design wdraża i utrzymuje.
Od tego momentu „ten sam widok, dwa razy inny" znika nie dlatego, że agent się postarał, tylko dlatego, że nie ma z czego zrobić go inaczej.
I tu jest rzecz, która zmienia ciężar całego workflow: większość z niego wykonuje sam agent. design.md napisze na nasze życzenie — wystarczy wskazać mu styl, którym się inspirujemy, a on przełoży go na konkretne reguły i tokeny. Kitchen sink też zaproponuje sam: dobierze komponenty, warianty, stany. Programista nie projektuje — prowadzi: ogląda, ocenia, mówi „to zostaw, to popraw". A kiedy komponenty już są, agent radzi sobie z nimi świetnie — rozkłada je w widokach, układa z klocków naprawdę ładne ekrany, przejmuje rolę designera. Programista wraca do tego, co dla niego ważne.
Ten sam zestaw — design.md, komponenty, motyw formularzy — pakuje się raz i wciąga do kolejnych aplikacji, więc spójna jest nie jedna apka, ale wszystkie naraz: wyglądają jak jeden produkt, bo są z tych samych klocków. Jak to spiąć architektonicznie, to osobny temat — tu liczy się, że raz zbudowany design się nie marnuje.
Buduj wcześnie
Jedna uczciwa uwaga: ten workflow jest tani na starcie i drogi po fakcie. Złożenie design.md, komponentów i kitchen sink na początku projektu to dzień–dwa pracy. Retrofit tego samego do czterdziestu istniejących, rozjechanych widoków to osobny projekt — każdy trzeba przepisać i pogodzić rozwiązania, które już się rozeszły. Im wcześniej odbierzesz wybór, tym mniej zdąży się nazbierać niespójności do sprzątania.
Programista nie musi już być designerem
Pytanie z tytułu brzmiało, czy programista może zbudować dobry design. Po tym workflow odpowiedź jest prostsza: nie musi. Raz spisany design.md, raz zbudowane komponenty, raz obejrzany kitchen sink — i dobry, spójny wygląd jest tym, co wychodzi domyślnie, z {{ form() }} i <twig:…>, a nie z talentu. Backendowiec składa widok z klocków. Agent składa go z tych samych klocków. Nikt nie projektuje tego samego formularza po raz trzeci.
To, czy interfejs jest spójny, przestaje zależeć od oka człowieka czy wersji modelu. Zależy od tego, czy ktoś raz poprowadził agenta, żeby te klocki powstały.
Masz pytanie albo podobny problem u siebie? Napisz: hello@incred.pl