Етап 08 · Tokens + Components

Дизайн-система

Той самий вигляд, нова архітектура. Плаский кіт етапу 07 розколовся на два рівні токенів і 84 файли компонентів, а продукт не змінився ні на піксель: доказ - 513 елементів × 46 властивостей × 2 в'юпорти, одна різниця, і та навмисна.

Код системи - у design/system/: його підключає продукт одним лінком. Вітрина - тут: її дивиться людина. Поділ простий - теку design/system/ можна взяти в інший проєкт цілком, стенд лишиться.

Файл дорівнює браузеру крок 7.4

Кожен файл компонента ніс два блоки - структуру з _wf.css і колір з kit.css, - які на кроці 3 склеїли, а не злили. Тому той самий селектор був написаний двічі, і там, де обидва блоки задавали ту саму властивість, перше оголошення не рендерилось ніколи. Читання файла згори давало число, якого браузер не вживає, і саме звідси бралися майже всі розбіжності між системою і сторінками.

Знято 1038 мертвих оголошень у 49 файлах: 571 з різними значеннями і 467 однакових. 159 правил лишились порожніми й видалені цілком. design/system - з 5041 рядка до 4860.

Доказ, що продукт не змінився: знімок обчислених стилів 73 сторінок (39 кольорових екранів і 34 сторінки стенда) у двох в'юпортах, по 75 властивостей і точна геометрія на кожен елемент - 62 514 елементів на 1280. До зведення той самий прохід зроблено двічі поспіль без жодної зміни, щоб дізнатись, що інструмент шумить сам: 14 елементів на 5 екранах завантаження, усі зі скелетонною анімацією. Після зведення різниця - рівно той самий список, в обох в'юпортах. Більше не зрушило нічого.

Обидва незалежні чекери показують 0 мертвих оголошень. Повний журнал - design/kit/docs/consolidation.md, крок 7.4.

Основи
Атоми 23 / 23
Кнопка
components/button.css
Основна дія екрана. Ця сторінка зібрана з перепису, а не зі стилю: браузер обійшов 180 екранів у двох...
683 рядки138 екранів
Поле
components/field.css
Текстове поле форми. Найбільший атом системи, бо саме тут живуть майже всі стани, які в продукті взагалі є....
286 рядків137 екранів
Обране
components/favourite.css
Серце в куті картки. Один дотик - товар у списку бажань, ще один -...
47 рядків30 екранів
Іконка
components/icon.css
Обгортка навколо inline-SVG з набору Solar. Сама іконка кольору не має: вона успадковує...
89 рядків4 екранів
OTP-комірка
components/otp.css
Шість комірок для коду з SMS. Єдиний спосіб увійти в Stack: рішення 5 - вхід без...
35 рядківJS
Чип
components/chip.css
Пілюля зі словом, яку натискають, щоб обрати. Найчисленніший контрол сайту, і до 7.31 єдиний, що позичав кільце фокуса в браузера
402 рядки503 екземпляри
Рейтинг
components/rating.css
Зірка, цифра і кількість відгуків. Зірка на піксель більша за цифру - одне правило замість чотирьох чисел у чотирьох файлах
164 рядки34 екрани
Скелетон
components/skeleton.css
Сірі фігури на місці контенту. Одна смуга замість шести редакцій у чотирьох файлах, і пульсація тепер зупиняється
355 рядків15 екранів
Радіо
components/radio.css
Вибір одного з кількох, який іде в замовлення. Три сім\'ї в трьох файлах, і жодна не була досяжна з клавіатури
229 рядків14 екранів
Перемикач вигляду
components/view-toggle.css
Два вигляди одного списку. Селектор писав, а дві латки під ним стирали - і ховер на 13 екранах не змінював нічого видимого
144 рядки7 груп
Рядок посилань
components/link-row.css
Текст, що веде кудись. Дві гучності замість тринадцяти редакцій у шести файлах, і найповторюваніше посилання сайту більше не малює атрибут style
270 рядків124 посилання
Мітка наявності
components/availability.css
Рядок про наявність. Каже словом, а не тільки кольором: «в наявності», «мало», «під...
141 рядок36 екранів
Статус-пілюля
components/status-pill.css
Одна форма, чотири імені в чотирьох файлах. Збіглися в геометрії, розійшлися в чотирьох легких значеннях.
190 рядків13 пілюль
Бейдж знижки
components/discount.css
Вісім імен, одна плашка. Колір не розходився ніколи, решта - постійно: дві гарнітури, дві ваги, чотири висоти.
168 рядків23 екрани
Чекбокс
components/checkbox.css
Незалежний вибір: фільтр у рейці, згода на умови. Кожен стоїть сам за...
236 рядків15 екранів
Перемикач
components/switch.css
Одна настройка, діє одразу. Роль і стан були в розмітці, крок табуляції - ні; друга редакція живе в cookie-banner і не злита
113 рядків2 у кольорі
Лічильник кількості
components/stepper.css
Мінус, число, плюс. Кількість товару в кошику і в...
142 рядки12 екранів
Ціна
components/price.css
Дев'ять поверхонь, шістнадцять імен, одна цифра. Заблоковане правило кольору тепер написане один раз, а не вісім.
418 рядків60 екранів
Лічильник
components/counter.css
470 штук, найчастіший елемент після ціни, і файл оголошував той єдиний, якого не видно.
62 рядки470 лічильників
Бейдж
components/badge.css
Файл тримав анотацію сірого прототипу. Справжні бейджі - 26 на фото - лежали в картці товару.
197 рядків26 бейджів
Дія стовпчиком
components/stack-action.css
Позначка над підписом: вкладка таббара і дія в хедері. Один контрол, написаний двічі всередині двох організмів; таббар не відповідав ні на що до 7.33
218 рядків134 екрани
Меню вибору
components/menu.css
Список, з якого обирають один пункт: сортування над каталогом. Нативний select лишається під ним і тримає клавіатуру
199 рядків14 екранів
Мініатюра товару
components/product-thumb.css
Квадратна коробка, у якій стоїть фотографія товару в рядку. Найменший файл системи і єдиний, що не має власного імені: він оголошує форму, а називають його інші.
83 рядки6 селекторів
Молекули 32 / 32
Стаття
components/article.css
Колонка прози завширшки в міру читання, а не в 760, яких немає в жодному реєстрі. Розділювач у вихідних даних першим написанням був лінією і не читався в жодній темі.
125 рядків1 сірий екран
FAQ магазину
components/faq-page.css
Згортка, яка стоїть ЗАКРИТОЮ, і саме тут її межа зі смугою довіри: блок довіри, що відкривався б кліком, ламав би принцип 1.
90 рядків1 сірий екран
Картка акції
components/promo-card.css
Та сама оболонка, що в картки блогу, і все ж інший компонент: одна просить прочитати, друга - купити на цих умовах. Дата закінчення, ніколи таймер.
72 рядки1 сірий екран
Підписку підтверджено
components/newsletter.css
Та сама форма, що в плити «замовлення оформлено», і навмисне не її родина: та намальована кольорами УСПІХУ, бо гроші перейшли. Тут нічого не куплено.
73 рядки1 сірий екран
Плитка розділу
components/nav-tile.css
Два агенти, які не знали один про одного, замовили те саме різними словами: картка бренду і плитка категорії оголошують ту саму оболонку.
89 рядків2 сірі екрани
Заголовок секції
components/section-head.css
Один рядок називав п'ять речей. Своя була одна, дві чужі, і двох останніх немає ніде в репозиторії.
159 рядків28 екранів
Порожній стан
components/empty-state.css
Файл звався «порожній стан» і тримав двох ведмедів, які порожнім станом не є. Плюс 1.5px, якого в браузері не існувало - знято на 7.62.
189 рядків29 екранів
Щабель лояльності
components/loyalty-rung.css
Колонка залишку бонусів на телефоні була відрізана і недосяжна. І базовий рівень не мав значка, бо його номер - нуль.
260 рядків39 екранів
Смуга довіри
components/trust-strip.css
Блок мобільних правил стояв вище тих, які мав перебивати: іконка довіри на телефоні три етапи малювалась десктопною.
238 рядків5 екранів
Таблиця складу
components/spec-table.css
Три таблиці й макет етикетки в одному файлі, і кожна каже «тут число» по-своєму: за колонкою, за розміткою, за позицією.
195 рядків2 екрани
Рядок кошика
components/cart-row.css
Товар, який уже вибрали. На ньому набір «один товар під п'ятьма іменами» нарешті видно цілком.
169 рядків11 екранів
Банер
components/banner.css
Шість непов'язаних блоків на чотирьох екранах: це не компонент, а стилевий лист головної.
291 рядок11 екранів
Картка товару
components/product-card.css
Два варіанти однієї картки, що відповідали курсору по-різному. Плюс селектор, який не збігався ні з чим: у списку назва звалась інакше.
431 рядок32 екрани
Хлібні крихти
components/breadcrumb.css
Роздільник не був атомом: 47 входжень, 0 поза крихтою. Плюс кільце фокуса, якого не було в жодної з 14.
78 рядків141 екран
Відгук
components/review-item.css
Три сім'ї в одному файлі, і відгук - одна з трьох. Рядок підсумку замовлення і третій ведмідь роз'їхались по своїх.
146 рядків4 екрани
Рядок замовлення
components/order-row.css
Замовлення було розкидано по чотирьох файлах. Четвертий переїзд зібрав його, і жоден із них не зрушив пікселя.
277 рядків2 екрани
Галерея
components/gallery.css
Половина файлу була липкою карткою товару. І здвоєний медіа-блок, який три кроки ховав від мене мій же вирішувач.
139 рядків4 екрани
Нотатка про поповнення
components/restock-note.css
Найчистіший файл із розібраних - і в ньому селектор, який не збігається ні з чим, та чергування фото, що тримається випадково.
163 рядки2 екрани
Картка адреси
components/address-card.css
Файл виявився чистим. Обидві знахідки - в розмітці: кнопка видалення нижча за драбину і чотири голі прапорці.
111 рядків9 екранів
Група фільтра
components/filter-group.css
Найгустіший компонент продукту: 140 груп і 350 опцій. Файл малював смугу ціни, а потім сам її стирав - 22 оголошення, які не доходили до пікселя.
99 рядків140 груп
Тулбар
components/toolbar.css
Дві смуги, які ніколи не бачать одне одного: до 860 мобільна, від 860 десктопна. Три правила перемикаються на одному пікселі.
97 рядків17 екранів
Рядок клієнта
components/client-row.css
Вісім селекторів із сімнадцяти не рендеряться в кольорі жодного разу. Первинна аудиторія - тренер, і в кольорі з його потоку є тільки запрошення.
145 рядків8 банерів
Плитка цілі
components/goal-tile.css
Увесь механізм наведення MVP: шість цілей, три сітки на 620 і 960. Обидві межі спрацьовують рівно на своєму пікселі.
106 рядків48 плиток
Картка блогу
components/blog-card.css
Єдина картка системи без ціни, без кнопки і без наявності. Фото за позицією, а базовий рядок - запасний варіант, а не мертвий.
89 рядків36 карток
Пагінація
components/pagination.css
Найменший компонент системи - 9 оголошень, жодного числа рукою. Третє оголошення виявилось фінішевим, а коментар про це - неправдивим.
70 рядків22 контроли
Логотип бренду
components/brand-logo.css
Шість чужих знаків, знебарвлених до фактури. Запасний варіант працює видаленням картинки, а не прапорцем.
34 рядки24 логотипи
Тост
components/toast.css
Єдиний компонент системи, якого в стані спокою не існує - і тому єдина область продукту, куди жоден прохід ніколи не дійшов.
76 рядків35 екранів
Мініатюра сертифіката
components/cert-thumb.css
Таблиця стилів писала слово, яке чують: посилання звалось «переглянути сертифікат (PDF) PDF». Вісім таких рядків у системі, двоє чути.
173 рядки5 екранів
Блок опису
components/desc-block.css
Вигляд коробки жив у скрипті: п'ять інлайн-властивостей, з них одна дані. У файлі стояло contain, на екрані - 84%.
131 рядок8 кадрів
SEO-текст
components/seo-text.css
Два кінці на різних краях сторінки. І «Читати більше» - один із п'яти акцентів на тексті, що не проходять контраст.
123 рядки22 ліди
Запитання
components/qa-item.css
Питання покупця і відповідь магазину. Помаранчева грань 2px замість другої бульбашки - і оголошення, яке скасовувало значення за замовчуванням.
121 рядок4 пари
Схожі товари
components/related.css
Найменший файл системи: 14 рядків, жодного мертвого оголошення. І та сама ідея, намальована двічі - тут і в рейці фільтрів.
14 рядків10 посилань
Організми 40 / 40
Квіз
components/quiz.css
Покроковий діалог цілі, вузол 4.x. Інвентар 07 його не бачив: у сірого аркуша немає жодного правила на q-*, весь діалог живе у власному style одного екрана.
233 рядки1 сірий екран
Блок контактів
components/contacts-block.css
Єдина сторінка родини без колонки прози: аркуш із двох колонок коротких відповідей замість неї.
92 рядки1 сірий екран
Сторінка інформації
components/info-page.css
Шість сервісних сторінок під одним тілом. Інвентар 07 його не бачив: у сірого аркуша немає жодного правила на info-*.
387 рядків6 сірих екранів
Замовлення оформлено
components/order-placed.css
Вузол 6.2. Екран, який не мав права нести власні стилі, і сім'я, яку архітектура паркувала як «роботу того екрана».
182 рядки2 сірі екрани
Панель підказок пошуку
components/search-overlay.css
Поверхня, якої система не мала: випадна панель, що на телефоні є шитом. Меню, оверлей і оверлей каталогу відмовляються кожен своїми словами.
129 рядків1 сірий екран
Оболонка кабінету
components/account-shell.css
Оболонка кабінету - це рейка розділів .acc-links на дев'яти екранах кабінету і рама сторінки навколо карток.
368 рядків46 екранів
Діалог входу
components/auth-dialog.css
Одні двері для всіх ролей: телефон, потім код, без пароля й без окремого входу для тренера.
248 рядків5 екранів
Смуга покупки
components/buy-bar.css
Телефонний двійник блоку покупки: .mbuybar прибитий до низу вікна position:fixed, z-index:40, і на 390 він 390x89 з шести елементів.
96 рядків3 екрани
Блок покупки
components/buy-box.css
Блок покупки стоїть на чотирьох екранах товару, по одному на екран: 125 елементів усередині кореня .bb, 358x1422 на 390 і 580x1103 на 1280.
306 рядків4 екрани
Шухляда кошика
components/cart-drawer.css
У кольоровому шарі це не шухляда, що відкривається: закритого стану в файлі немає зовсім - ні .cart-drawer.open, ні display: none, - і панель просто намальована поверх сторінки-привида...
269 рядків5 екранів
Оверлей каталогу
components/cat-overlay.css
Жоден кольоровий екран цього не малює, і це головне про файл. Розмітки оверлея немає у жодному html репозиторію: її створює wfCatOverlayEnsure() і дописує в body при першому тапі по...
121 рядокжодного екрана
Форма чекауту
components/checkout-form.css
Найбільший файл системи, і під одним іменем у ньому дві адреси: чекаут .co-* на п'яти екранах design/checkout*.html і картка профілю .pfcard, яка є рівно на одному -...
510 рядків40 екранів
Діалог міста
components/city-dialog.css
Найтиражніший діалог шару: він лежить на 34 з 40 кольорових екранів, і в ньому 816 кнопок міст плюс 272 бейджі популярних.
65 рядків134 екрани
Діалог клієнта
components/client-dialog.css
Файл названо діалогом клієнта, і саме діалог клієнта тут не має кольору. .cemodal і .cedlg це спільна коробка, яку wireframes/_nav.js будує на льоту для дев'яти діалогів: новий клієнт,...
117 рядків26 екранів
Банер cookie
components/cookie-banner.css
Жоден кольоровий екран цього не малює, і жоден не може: місце для банера - id="wf-cookie" - існує рівно в одному файлі всього репозиторію, wireframes/system.html, а wfCookie() пише...
84 рядки1 екран
Рейка фільтрів
components/filter-rail.css
У цьому файлі дві різні речі. .frail - колонка фільтрів на семи екранах лістингу: заміряно 240x1871 при 1280, 164 елементи всередині, і 0x0 при 390.
89 рядків22 екрани
Шит фільтрів
components/filter-sheet.css
Найтихіший файл шару: у жодному зі списків вирішувача - ні «збігається й ніколи не виграє», ні «не збігається ні з чим» - його немає жодного разу.
94 рядки13 екранів
Футер
components/footer.css
Тридцять один екран закінчується цим блоком, і він єдиний організм, який людина бачить на кожному з них.
101 рядок129 екранів
Хедер
components/header.css
Другий за розміром файл шару після checkout-form.css і найскладніша композиція в ньому: у корені .wfh заміряно до 631 елемента - мегапанель, діалог міста, меню мови, меню кабінету, пошук...
435 рядків134 екрани
Головний блок
components/hero.css
Сорок п'ять рядків, і 463 елементи в корені .hero-wrap на 1280 при власних 1032x593; на 390 це 358x1147.
62 рядки9 екранів
Мега-меню
components/mega-menu.css
Цей файл не можна прочитати без header.css. Корінь .wfh-mega описують три файли: хедер дає панелі коробку, цей файл - нутрощі, а filter-rail.css навмисно бере той самий клас для флайаута...
56 рядків134 екрани
Шухляда меню
components/nav-drawer.css
Це не діалог, а <nav aria-label="Меню"> з класом .open: крок 7.85 навмисно не дав їй role="dialog", бо назвати панель діалогом це рішення про семантику, а не ремонт поведінки.
99 рядків134 екрани
Оверлей
components/overlay.css
16 рядків, 4 селектори, 16 оголошень, жодної семантичної ролі й один примітив. Це не компонент - це два затемнення, яким не знайшлося іншого файлу.
58 рядків134 екрани
Вкладки товару
components/pdp-tabs.css
У файлі про вкладки лежать три різні фігури: липка полиця .pdp-tabs (два кольорові екрани), рядок чипів .ptabs на головній (чотири екрани) і двоколонкова сітка сторінки товару .pdp (три...
103 рядки8 екранів
Повзунок ціни
components/price-slider.css
Тридцять три рядки, три власні класи, жодної медіа-умови - і жодного з цих класів немає в розмітці сторінки.
33 рядки13 екранів
Сітка товарів
components/product-grid.css
Найменший організм, який щось важить: 2 селектори, 10 оголошень, 2 класи і жодної семантичної ролі.
34 рядки1 екран
Модалка відгуку
components/review-modal.css
.pm - це не одна модалка, а дві: «Залишити відгук» і «Поставити запитання» це та сама оболонка, яку wfPdpModals() будує однією функцією.
88 рядків3 екрани
Системна сторінка
components/system-page.css
Файл є, класи є, і кольору в ньому немає жодного рядка: шапка обіцяє колірний блок нижче, а колірного блоку у файлі нема - тільки структурний.
127 рядківжодного екрана
Таб-бар
components/tabbar.css
Сорок два рядки і рівно один власний клас, .wf-tabbar. Усе інше, що тут видно, належить сусідам: .wf-tab ділять із mega-menu.css, а .btn--stack, .ti, .tl і .tbadge - це stack-action.css.
80 рядків134 екрани
Панель Pro
components/upsell.css
«Ви досягли ліміту тарифу Free». Єдине місце, де система просить грошей, і тому єдине, де кожне рішення про наголос коштує довіри.
133 рядки16 селекторів
Картка тарифу
components/plan-card.css
Free або Pro, поруч, у два стовпці від 640. Три екрани малювали її під двома наборами імен, і обидва переписували грань, радіус і тло власноруч.
261 рядок31 селектор
Лендинг тренера
components/coach-landing.css
Публічні вхідні двері первинної бізнес-моделі, вузол 5.0. Єдина сторінка продукту, яку індексує пошук і яка продає, а не обслуговує.
769 рядків55 селекторів
Скрол-історія
components/scrollstory.css
Сцена на всю висоту екрана і шари, що їдуть по ній: спершу титульна картка сторінки, далі твердження по одному на екран. Кожен шар це функція від позиції скролу, а не булеве спрацювання з переходом - три числа без одиниць, які пише скрипт і читає css.
377 рядків63 селектори
Перевірка тренера
components/coach-verify.css
Вузол 5.1: покупець стає тренером. Роль активується поверх наявного акаунта, і між заявкою та гуртовою ціною стоїть людська перевірка.
972 рядки72 селектори
Кабінет тренера
components/coach-cabinet.css
Щоденний екран первинної аудиторії: вузол 5.2 «панель» і вузол 5.6 «історія замовлень». Два екрани в одному файлі, бо це один організм.
1027 рядків77 селекторів
Клієнти тренера
components/coach-clients.css
Вузол 5.3, збережений список людей, і вузол 5.4, картка однієї з них. Серце locked-рішення «тренер як покупець».
908 рядків81 селектор
Сесія замовлення
components/coach-session.css
Вузол 5.5, і це первинна робота всього продукту: один тренер, кілька клієнтів, кілька цілей, одне сидіння.
1052 рядки88 селекторів
Замовлення тренера
components/coach-order.css
Вузол 5.7, одне замовлення тренера, відкрите. Товари згруповані по клієнтах, кожна група закривається власною сумою і власним «повторити».
448 рядків27 селекторів
Тариф тренера
components/coach-tariff.css
Вузол 5.2a: екран, який показує чинний тариф і дає з нього піти. Єдиний екран, де locked-рішення про платний тариф тренера видно цілком.
443 рядки20 селекторів
Обране тренера
components/coach-wishlist.css
Вузол 5.8, збережені товари тренера. Восьмий тренерський організм і найдивніший файл системи: 278 рядків, два селектори, сім оголошень.
295 рядків3 селектори
Патерни 1

Рівень над компонентом, заведений на етапі 09: стала композиція цеглин, яку продукт повторює на трьох і більше екранах. Патерн не заводить власних стилів - він збирається з наявних компонентів і токенів, і в index.css імпортується після них.

Інвентар 89 компонентів + 1 патерн

Реєстр компонентного шару, і до етапу 09 його не було видно ніде. design/kit/docs/inventory.md лежав у теці, на нього посилалась проза двох сторінок, і жодна не показувала, що в ньому написано. Це і є та сама тиха поломка, яку правило «кожен md отримує видиме місце» існує щоб ловити: файл, у який ніхто не дивиться, ніхто й не перечитує - і саме в ньому крок 6 знайшов три застарілі підсумки, які прожили цілий етап.

РівеньФайлівРядків css або правилЩо містить
Атоми (1)234467нічого з кіта не містять
Молекули (2)273384містять атоми
Організми (3)348255містять молекули або є оболонкою екрана
Патерни14 правила, 3 класикомпозиція з наявних компонентів, власних стилів не заводить

На кожен рядок таблиці інвентар несе шість колонок: компонент, файл css, класи-якорі, що він знає про ширину, на скількох кольорових сторінках він справді стоїть, і скільки в ньому рядків. Колонка «Екрани» береться обходом браузера, а не грепом - інакше вона не бачить розмітку, яку пише скрипт.

Колонку «Ширина» дописав етап 10, і дописав її одразу на всі 84 рядки. Вона теж не набирається руками: у ній стоять числа медіазапитів самого файлу після зняття коментарів, плюс ramp, якщо в ньому є clamp(), і fluid, якщо є auto-fit, minmax() чи flex-wrap. Дзеркало (619, 859) читається як своя точка, бо це те саме рішення з іншого боку. Колонку заповнено після всіх чотирьох раундів, а не після першого: заповнена на один рівень із чотирьох, вона казала б «невідомо» про три інші у формі, яка читається як «нема чого сказати». Порожньої клітинки тут немає жодної - компонент, який свідомо не адаптується, несе –, і це відповідь, а не пропуск.

Числа тут не набираються руками. tools/inventory.mjs звіряє таблиці з диском і питає дев'ять речей: компонент без рядка, рядок без файла, рівень, що розійшовся між чотирма місцями, колонку Lines, підсумок під кожною таблицею, підсумковий абзац, друге видиме місце того самого твердження, рядок патерна і сторінку патерна. --apply переписує все, що є сумою. Прилад, який доповідає про власну помилку і не вміє її закрити, це половина приладу.

Перевірка
Перепис