Przekazanie projektu od designera do inżyniera zawodzi dostępność
studium 50 plików Figma
Uzyskaliśmy dostęp tylko do odczytu do 50 produkcyjnych plików Figma z 28 zespołów produktowych, za zgodą i przy pełnej anonimizacji, a następnie przeszliśmy przez każdy z nich z jednym pytaniem: gdy inżynier otwiera ten plik i zaczyna implementację, jakie decyzje dotyczące dostępności designer już podjął — a które pozostawił inżynierowi do wymyślenia o 16:00 w piątek? Odpowiedź, plik po pliku, jest taka, że większość z nich nadal jest wymyślana o 16:00.
1. Jak przeprowadziliśmy audyt 50 plików
Próba obejmuje 50 plików Figma z 28 zespołów produktowych z sektorów SaaS, handlu detalicznego, fintech, sektora publicznego i edtech. Uzyskaliśmy dostęp tylko do odczytu na zasadzie nieprzypisywania autorstwa: nic w tym artykule nie identyfikuje marki, zespołu ani designera. Pliki wybrano tak, aby odzwierciedlały to, co inżynier faktycznie otrzymuje przy przekazaniu — nie dopracowane studium przypadku z portfolio — dlatego poprosiliśmy każdy zespół o udostępnienie pliku, z którego dostarczono ostatnią funkcję, a nie pliku, z którego są najbardziej dumni. Dwanaście plików pochodziło od zespołów z dedykowaną praktyką systemu projektowania; pozostałe 38 to pliki na poziomie produktu, które importowały bibliotekę systemu lub tworzyły komponenty lokalnie.
Przeglądaliśmy każdy plik pod kątem pięciu właściwości dostępności: projektu stanu fokusa na każdym interaktywnym komponencie, adnotacji tekstu alternatywnego na każdym obrazie lub ikonie niebędącej dekoracją, dokumentacji kolejności czytania w całym układzie, obsługi preferencji ruchu dla każdego animowanego lub przechodzącego elementu oraz specyfikacji kontrastu w trybie ciemnym dla każdego komponentu dostarczanego zarówno w jasnym, jak i ciemnym motywie. Dla każdej właściwości plik był oceniany jako „udokumentowany“ tylko wtedy, gdy kompetentny inżynier mógłby zaimplementować projekt bez samodzielnego wymyślania odpowiedzi. „Wspomniane w notatce samoprzylepnej“ nie liczyło się. „Kolor szesnastkowy podany w jednym stanie hover“ nie liczyło się. Poprzeczka była: czy decyzja jest w pliku w formie, na której inżynier może działać bez pytania?
Główne ustalenie jest takie, że przy tej poprzeczce, przekazanie pomija decyzje dotyczące dostępności znacznie częściej niż je zawiera. Projekt stanu fokusa pojawił się na ok. 40% interaktywnych komponentów w całym korpusie. Adnotacje tekstu alternatywnego pojawiły się na ok. 22% obrazów, które ich potrzebowały. Kolejność czytania była wyraźnie udokumentowana w 16% plików. Preferencje ruchu zostały uwzględnione w 10%. Kontrast w trybie ciemnym — dla 31 plików dostarczanych w obu motywach — był określony dla 30% komponentów. Luka nie dotyczy żadnej konkretnej właściwości. Dotyczy wszystkich pięciu, a inżynier musi je wypełniać jednym osądem na raz.
Zastosowaliśmy kryterium „inżynier czyta i implementuje“. Stan fokusa liczy się jako udokumentowany, jeśli plik pokazuje specyfikację wizualną — kolor obrysu, szerokość, przesunięcie, kontrast względem tła fokusowanego elementu — w formie, którą inżynier może odwzorować na token CSS. Pobliski komunikat Slack mówiący „użyj niebieskiego marki“ nie liczy się, ponieważ komunikaty Slack nie przeżywają przekazania projektu. Plik musi nieść decyzję samodzielnie.
„Przekazanie projektu nie zawodzi dlatego, że designerów nie obchodzi dostępność. Zawodzi dlatego, że format pliku traktuje dostępność jako adnotację w komentarzu, podczas gdy powinna być właściwością pierwszej klasy każdego komponentu.“
2. Projekt stanu fokusa: luka 60%
Spośród ok. 1800 interaktywnych komponentów objętych audytem w całym korpusie — przycisków, łączy, pól wejściowych, pól wyboru, przełączników, zakładek, list rozwijanych, elementów menu, kart-jako-przycisków, wszystkiego, co użytkownik klawiatury może osiągnąć — ok. 40% zawierało zaprojektowany stan fokusa. Pozostałe 60% zawierało stan domyślny, aktywny i hover, a następnie się zatrzymywało. Inżynier budujący komponent wybiera kontur fokusa podczas implementacji, zazwyczaj kopiując domyślny styl przeglądarki, zazwyczaj bez sprawdzenia, czy domyślny ma kontrast 3:1 względem powierzchni komponentu zarówno w jasnym, jak i ciemnym motywie, w których plik jest dostarczany.
Jak wygląda „brak projektu stanu fokusa“ w praktyce? Wygląda jak komponent przycisku z trzema wariantami na kanwie — domyślny, hover, naciśnięty — i bez czwartego wariantu. Wygląda jak pole wejściowe ze stylizowaną ramką i bez drugiego stylu ramki dla stanu fokusa. Wygląda jak prymityw pola wyboru z pierścieniem fokusa tylko w wariancie domyślnym, a inżynier musi zgadywać, czy ten sam pierścień powinien pojawiać się w wariancie zaznaczonym lub nieokreślonym. Wzorzec powtarza się w komponentach, w zespołach, w sektorach. Jest to jedyna największa luka dostępności w korpusie i jednocześnie ta najłatwiejsza do zaprojektowania.
Zespoły, które dobrze projektowały stany fokusa, miały jedną z dwóch rzeczy. Pierwsza to wyraźna reguła systemu projektowania: każdy interaktywny komponent musi zawierać wariant, którego nazwa zaczyna się od focus-, a komponent nie jest wydawany do biblioteki, dopóki ten wariant nie istnieje. Drugą była właściwość komponentu Figma o nazwie state z fokusem, focus-visible i focus-within jako wartościami wyliczanymi, dzięki czemu przeglądarka komponentów pliku wizualnie eksponuje brakujące warianty. Zespoły bez jednego z tych dwóch rusztowań pozostawiały stan fokusa inżynierowi mniej więcej dziewięć razy na dziesięć.
Komponent przycisku, cztery warianty: state=default, state=hover, state=pressed, state=focus-visible. Wariant focus-visible pokazuje obrys 2px, przesunięcie 2px, token koloru —focus-ring (który z kolei jest odwzorowany na wartość szesnastkową spełniającą 3:1 względem powierzchni przycisku w obu motywach). Inżynier odczytuje panel inspekcji i kopiuje odwołanie do tokenu; niczego nie wymyśla.
Ten sam komponent przycisku, trzy warianty: default, hover, pressed. Brak wariantu fokusa na kanwie. Notatka samoprzylepna od designera mówi „użyj systemowego pierścienia fokusa“. Inżynier przeszukuje bibliotekę systemu projektowania, znajduje dwa kandydackie pierścienie fokusa (jeden z przycisków, jeden z pól wejściowych, nieco różne szerokości), wybiera jeden, dostarcza go, a trzy tygodnie później przegląd QA oznacza problem, ponieważ wybrany pierścień spada poniżej 3:1 na powierzchni wyłączonego, ale nadal fokusowanego przycisku drugorzędnego.
Gdy stan fokusa nie jest w pliku, inżynierowie często dostarczają domyślny styl przeglądarki — a domyślny styl przeglądarki jest nadpisywany przez globalne *:focus { outline: none } w większości resetów CSS, które ten sam inżynier dodał sześć miesięcy wcześniej, aby rozwiązać inny komentarz z przeglądu. Wynikiem jest komponent, który wygląda dobrze w podglądzie Figma, wygląda dobrze w środowisku deweloperskim z wyłączonym resetem, i jest dostarczany bez żadnego widocznego wskaźnika fokusa.
3. Adnotacje tekstu alternatywnego: przeważnie puste
Spośród plików w korpusie zawierających obrazy treści — zdjęcia produktów, ilustracje hero, przyciski z samymi ikonami, figury infograficzne — 78% nie miało adnotacji tekstu alternatywnego na warstwach obrazów. Obraz był umieszczony, przeskalowany i ostylowany; tekstowy odpowiednik, który inżynier miał wstawić do renderowanego <img>, nie był w pliku. Osiem z 50 plików miało tekst alternatywny na niektórych obrazach, ale nie wszystkich — zazwyczaj z adnotacją na ilustracji hero i pustymi obrazami w treści. Trzy pliki miały tekst alternatywny na każdym obrazie. Inżynier, w 47 z 50 plików, był zobowiązany do wymyślenia tekstu alternatywnego — a w praktyce często dziedziczył go z nazwy pliku, figcaption lub dowolnego ciągu pasującego do rytmu wizualnego.
Luka ma strukturalne podłoże w prymitywie obrazu Figma. Nie istnieje natywna właściwość „alt“ w wypełnieniu obrazu ani w warstwie obrazu; tekst alternatywny musi być przenoszony jako nazwa warstwy, komentarz, notatka samoprzylepna, oddzielny dokument specyfikacji lub pole dodane przez wtyczkę. Żadne z nich nie przechodzi przez panel inspekcji domyślnie, więc inżynier odczytujący plik w widoku inspekcji nie widzi tekstu alternatywnego nawet jeśli designer go gdzieś napisał. Zespoły, które konsekwentnie zamykały tę lukę, stosowały jedno z trzech obejść: pola tekstu alternatywnego zarządzane przez wtyczkę na każdym wariancie obrazu, udokumentowaną konwencję, że nazwa warstwy jest tekstem alternatywnym, lub osobny arkusz kalkulacyjny tekstu alternatywnego z kluczem na podstawie nazw plików obrazów, dostarczany wraz z plikiem.
Przyciski z samymi ikonami były subporażką wewnątrz tego trybu awarii. W 41 z 50 plików przyciski z ikonami — lupka wyszukiwania, hamburger menu, X zamknięcia, strzałka udostępniania — nie miały adnotacji dostępnej nazwy, pozostawiając inżynierowi napisanie aria-label=“Szukaj” na podstawie kontekstu wizualnego bez potwierdzenia, że „Szukaj“ to właściwe słowo w głosie marki (czy to „Znajdź“? czy „Wyszukaj“? czy nic, bo przycisk otwiera panel oznaczony w innym miejscu?). Nazewnictwo ikon to dokładnie taki rodzaj decyzji dotyczącej mikrotekstu, który korzysta z pióra designera, i dokładnie taki, który przekazanie traci.
Każdy obraz jest albo dekoracyjny (atrybut alt powinien być pusty, czytnik ekranu go pomija) albo informacyjny (alt niesie informację, którą obraz przekazuje wizualnie). Ten wybór to decyzja dotycząca treści i należy do designera lub redaktora, a nie do inżyniera zgadującego o północy. Plik, który nic nie mówi o tym, które obrazy są dekoracyjne, dostarcza albo zbyt wiele tekstu alternatywnego (każdy obraz jest obszernie opisany, włącznie z tymi będącymi czystą ozdobą) albo za mało (ilustracja hero jest opisana, każdy obraz w treści otrzymuje alt="", bo inżynier zachował ostrożność).
4. Kolejność czytania, ruch, kontrast w trybie ciemnym
Trzy pozostałe właściwości miały odrębne kształty awarii. Kolejność czytania — kolejność, w której czytnik ekranu narruje stronę, która we współczesnych responsywnych układach nie jest już gwarantowana zgodna z wizualną kolejnością od góry do dołu — była udokumentowana w 16% plików. Dokumentacja, tam gdzie istniała, zazwyczaj stanowiła numerowaną nakładkę na kanwie (1, 2, 3 …) dodaną za pomocą wtyczki. Pozostałe 84% pozostawiało inżynierowi mapowanie kolejności czytania na podstawie kolejności DOM, którą się zdarzało pisać, która w układzie CSS Grid z jawnym umieszczaniem w wierszach i kolumnach może się różnić od układu wizualnego o całą kolumnę.
Preferencje ruchu wypadły najgorzej. Dziesięć procent plików w ogóle wspominało prefers-reduced-motion. Pozostałe 90% określało animacje i przejścia — wejścia modalu, rozwijanie akordeonu, przesuwanie powiadomień, przejścia stron — bez określania, co ten sam komponent powinien robić, gdy użytkownik ma włączone zmniejszone animacje. Inżynier albo budował przypadek zmniejszonego ruchu podczas implementacji (często bez odniesienia wizualnego), albo dostarczał tę samą animację wszystkim, co jest wartością domyślną i narusza kryterium 2.3.3 Animacja z interakcji dla użytkowników, którzy ustawili tę preferencję.
Kontrast w trybie ciemnym był określony dla 30% komponentów w plikach dostarczanych w obu motywach. Pozostałe 70% określało kontrast jasnego motywu — zazwyczaj z adnotacją Stark lub sprawdzarki kontrastu w pliku — a następnie wydawało ciemny motyw z odwróconą paletą kolorów, pozostawiając inżynierowi sprawdzenie, czy odwrócona para nadal osiąga 4,5:1 dla tekstu głównego i 3:1 dla komponentów interfejsu. W ok. jednej piątej z 31 plików z podwójnym motywem przynajmniej jeden komponent spadał poniżej progu kontrastu w ciemnym motywie, ponieważ ciemna powierzchnia i ciemny tekst były oba dostrojone do matematyki kontrastu jasnego motywu, a nie ciemnego.
Macierz śledzi „wskaźnik realizacji“ dla każdej właściwości w całym korpusie — udział plików, w których właściwość była udokumentowana zgodnie z kryterium „inżynier czyta i implementuje“. Kolumny dzielą wskaźnik według tego, czy plik pochodził od zespołu z dedykowaną praktyką systemu projektowania, czy od zespołu produktowego tworzącego komponenty lokalnie; różnica między dwiema kolumnami to delta system-kontra-brak-systemu.
| Właściwość dostępności | Wszystkie 50 plików | Zespoły z systemem projektowania (12) | Zespoły produktowe (38) | Delta system kontra produkt |
|---|---|---|---|---|
| Projekt stanu fokusa (komponenty interaktywne) | 40% | 75% | 29% | +46 pp |
| Adnotacje tekstu alternatywnego (obrazy treści) | 22% | 50% | 13% | +37 pp |
| Kolejność czytania (poziom kanwy) | 16% | 42% | 8% | +34 pp |
| Preferencje ruchu (elementy animowane) | 10% | 33% | 3% | +30 pp |
| Kontrast w trybie ciemnym (tylko pliki z podwójnym motywem, n=31) | 30% | 55% | 19% | +36 pp |
„Zespoły z systemem projektowania dokumentują decyzje dotyczące dostępności mniej więcej dwukrotnie częściej niż zespoły produktowe — ale nawet te z systemem spełniają kryterium tylko dla jednej właściwości na pięć przez większość czasu.“
5. Stark i Able: nierówne wdrożenie
Dwie wtyczki, które najczęściej pojawiają się w korpusie, to Stark i Able. Obie są dojrzałe, obie cieszą się dobrą opinią, a obie oferują funkcje zamykające kilka z udokumentowanych powyżej luk. Stark dodaje sprawdzarkę kontrastu, nakładkę kolejności fokusa, podgląd zmniejszonego ruchu i pole adnotacji tekstu alternatywnego na warstwach obrazów. Able dodaje inspektor kontrastu kolorów, nakładkę symulacji widzenia i sprawdzarkę obszarów dotyku. Każda z tych wtyczek, stosowana konsekwentnie w całym pliku, wywindowałaby ten plik z dolnego kwartyla korpusu.
„Stosowana konsekwentnie“ to kluczowe wyrażenie. Spośród 50 plików Stark był zainstalowany i wyraźnie używany w 18, a Able w 11. W plikach, w których wtyczka była używana, zazwyczaj stosowano ją do komponentu hero i głównego CTA — komponentów z największym prawdopodobieństwem widocznych na kanwie, gdy designer otwierał wtyczkę — i tylko sporadycznie gdzie indziej. Sześć plików używało Stark do globalnego przeglądu; jeden używał Able do globalnego przeglądu. Wzorzec jest następujący: wtyczki istnieją, designerzy o nich wiedzą, są stosowane do wyrywkowych kontroli, a kontrola zatrzymuje się na komponentach, na które designer patrzył, gdy wtyczka była otwarta.
Dwa zespoły, które zamknęły audyt pod względem użycia wtyczek, robiły jedną rzecz inaczej: uruchamiały funkcję audytu wtyczki na każdej stronie pliku jako krok bramki wydania przed udostępnieniem pliku inżynierii. Audyt był uruchamiany w pliku, generował raport, a raport musiał być pusty (lub z udokumentowanymi wyjątkami) zanim plik przeszedł z „w projektowaniu“ do „gotowy do inżynierii“. To wtyczka jako przepływ pracy, a nie wtyczka jako wyrywkowa kontrola — i to różnica między pokryciem 80% a 20% w naszej próbie.
Wtyczka podnosi minimalny poziom: sprawdzarka kontrastu wyłapuje oczywiste awarie 2,1:1, pole tekstu alternatywnego daje designerowi miejsce do wpisania. Nic z tego nie pomaga, jeśli wtyczka jest uruchamiana na trzech komponentach, a nie na pozostałych 27. Rozwiązaniem jest umieszczenie wtyczki w przepływie pracy — krok bramki wydania, lista kontrolna przed przekazaniem, gałąź Figma, której nie można scalić bez pustego raportu wtyczki — a nie w uznaniu designera w momencie, gdy sobie o niej przypomni.
6. Lista kontrolna przekazania i kontrakt tokenów
Audyt generuje listę kontrolną i kontrakt. Lista kontrolna to to, co designer powinien móc odfajkować przed udostępnieniem pliku inżynierii. Kontrakt to kształt tokenów projektowych towarzyszących plikowi, dzięki czemu inżynier odwzorowuje zmienne Figma na właściwości niestandardowe CSS bez wymyślania wartości pośrednich. Obie są celowo krótkie: każda pozycja na liście kontrolnej to właściwość zmierzona przez audyt, a każdy token w kontrakcie to wartość, która zamknęła lukę w korpusie.
Każdy interaktywny komponent zawiera wariant state=focus-visible.
Nie „system ma pierścień fokusa“. Wariant o nazwie focus-visible na samym komponencie, z kolorem obrysu, szerokością i przesunięciem powiązanymi z tokenem pierścienia fokusa. Wariant jest tym, co inżynier kopiuje do implementacji; bez niego inżynier zgaduje.
Każdy obraz treści ma tekst alternatywny w polu zarządzanym przez wtyczkę lub udokumentowanej konwencji nazwy warstwy.
Należy wybrać jedną lokalizację i ją egzekwować. Pole tekstu alternatywnego Stark, nazwa warstwy traktowana jako alt lub towarzyszący arkusz kalkulacyjny — każde z trzech działa, ale tylko jeśli każdy obraz w pliku używa tego samego. Przyciski z samymi ikonami również otrzymują adnotację dostępnej nazwy w tej samej lokalizacji, z dokładnym ciągiem, który inżynier powinien umieścić w aria-label.
Kolejność czytania jest udokumentowana na każdej stronie, gdzie kolejność DOM będzie różnić się od kolejności wizualnej.
Najprostszą dokumentacją jest numerowana nakładka dodana za pomocą wtyczki (Stark ma taką, kilka wtyczek społecznościowych również). Dla stron, których kolejność jest trywialnie od góry do dołu i od lewej do prawej, można pominąć nakładkę; dla wszystkich używających umieszczania w CSS Grid, obszarów nazwanych lub pozycjonowania absolutnego, nakładka jest obowiązkowa.
Każdy animowany lub przechodzący element ma wariant ze zmniejszonym ruchem na kanwie.
Drugi ramka, drugi wariant lub udokumentowana wersja „bez animacji“. Inżynier nie powinien wymyślać przypadku zmniejszonego ruchu — designer powinien określić, czy modal pojawia się przez przenikanie zamiast przesuwania, czy powiadomienie pojawia się natychmiast zamiast przesuwania, czy przejście strony jest całkowicie pominięte.
W przypadku plików z podwójnym motywem kontrast jest sprawdzany osobno w ciemnym motywie, a nie wyprowadzany z jasnego.
Matematyka kontrastu trybu ciemnego to osobny problem; odwrócenie palety kolorów nie wystarcza. Należy uruchomić Stark lub Able na każdym komponencie w trybie ciemnym, nie tylko jasnym. Stosunek kontrastu należy udokumentować w notatkach wariantu, aby inżynier mógł potwierdzić, że implementacja jest zgodna.
Plik jest dostarczany z kontraktem tokenów: płaską listą każdej zmiennej Figma odwzorowanej na jej właściwość niestandardową CSS.
Kontrakt jest mostem między plikiem a bazą kodu. Typowy kontrakt wygląda jak poniższa tabela: każdy wiersz nazywa zmienną Figma, właściwość niestandardową CSS, którą inżynier powinien do niej powiązać, wartość w jasnym motywie, wartość w ciemnym motywie i kryterium WCAG, w którym token uczestniczy.
| Zmienna Figma | Właściwość niestandardowa CSS | Wartość jasna | Wartość ciemna | Powiązania WCAG |
|---|---|---|---|---|
| color/focus-ring | —focus-ring | #0B57D0 | #A8C7FA | 2.4.7, 1.4.11 |
| color/text/body | —text-body | #1F1F1F | #E3E3E3 | 1.4.3 (4,5:1 na powierzchni) |
| color/surface/raised | —surface-raised | #FFFFFF | #1F1F1F | 1.4.11 (3:1 względem sąsiada) |
| size/touch-target/min | —touch-target-min | 44px | 44px | 2.5.5, 2.5.8 |
| motion/duration/standard | —motion-standard | 200ms | 200ms | 2.3.3 (pominąć przy zmniejszonym ruchu) |
| motion/duration/reduced | —motion-reduced | 0ms | 0ms | 2.3.3 |
Gdy kontrakt istnieje, zadanie inżyniera jest mechaniczne: powiąż właściwość niestandardową CSS ze zmienną Figma, dostarcz implementację, przeprowadź audyt porównując wyrenderowane wartości z kontraktem. Bez kontraktu każde powiązanie jest osądem, a osądy kumulują się w lukę 60%. Kontrakt to jedyny artefakt, który przesuwa dostępność od „inżynier jest odpowiedzialny podczas przekazania“ do „system jest odpowiedzialny podczas projektowania“.
Podsumowanie: plik jest kontraktem
Audyt 50 plików kończy się prostym ustaleniem. Przekazanie projektu zawodzi dostępność nie dlatego, że designerom na niej nie zależy, i nie dlatego, że inżynierom na niej nie zależy, ale dlatego, że plik — plik Figma, jedyny artefakt, który każda ze stron czyta — nie nosi decyzji dotyczących dostępności jako właściwości pierwszej klasy. Stany fokusa, tekst alternatywny, kolejność czytania, preferencje ruchu, kontrast w trybie ciemnym: każda z tych właściwości to decyzja projektowa, każda należy do pliku, każda jest obecnie gdzieś indziej. W notatce samoprzylepnej, w wiadomości Slack, w osobnym arkuszu kalkulacyjnym, w głowie inżyniera o 16:00 w piątek.
Rozwiązaniem nie jest heroiczny designer ani heroiczny inżynier. To zmiana przepływu pracy na poziomie zespołu: każdy interaktywny komponent zawiera wariant fokusa, każdy obraz nosi tekst alternatywny w jednym miejscu zarządzanym przez wtyczkę, kolejność czytania jest nakładana na każdej nietrywialnej stronie, animacje określają swój odpowiednik ze zmniejszonym ruchem, kontrast w trybie ciemnym jest sprawdzany osobno od jasnego, a plik jest dostarczany wraz z kontraktem tokenów, który nazywa każdą zmienną, do której implementacja się powiązuje. Żaden z tych kroków nie jest nowy, żaden nie wymaga narzędzia, którego jeszcze nie mamy, a każdy zespół, który wdroży je jako kroki bramki wydania, zamknie większość zmierzonych przez nas luk w jednym cyklu wydawniczym.
Głębsze ustalenie jest takie, że zespoły z systemem projektowania już to robią mniej więcej dwukrotnie częściej niż zespoły produktowe. Dźwignia, jaką zapewniają zespoły z systemem projektowania, to dokładnie ta dźwignia, którą narzuca dyscyplina budowania systemu: komponenty są nazwane, właściwości są wyliczone, warianty są widoczne, tokeny są jawne. Przeniesienie tej samej dyscypliny do plików na poziomie produktu — nawet bez pełnego systemu projektowania poniżej — zamyka większość luki przekazania. To już nie jest problem narzędziowy. To wybór przepływu pracy.
„Plik powinien docierać z decyzjami dotyczącymi dostępności już podjętymi. Cokolwiek innego to inżynier wymyślający je w najgorszym możliwym momencie, z najmniejszym możliwym kontekstem, w najściślejszym możliwym terminie.“