Основи

Адаптив

Адаптив у цьому продукті вже був: 170 медіазапитів у 53 файлах із 88, і жодного названого. Цей етап його не додає, він його називає, вкладає в токен і зводить 27 різних меж ширини до двох. Значення прочитані з живого :root.

жива ширина цієї сторінки
вимірюю…
Три способи, і точка остання

Драбина читається згори вниз. Береш плинне; не виходить - контейнер; не виходить і це - аж тоді точка, і в аудиті стоїть рядок, чому плинне не змогло. «Так зручніше писати» причиною не є.

ПлиннеКонтейнерТочка
Питаннявміст сам розтягнеться?рядок не задовгий?поведінка інша?
Механізмclamp(), %, minmax(auto-fit), flex-wrapmax-width + margin-inline@media для оболонки, @container для компонента
Скільки в продуктібез обмеженьдва: --container-page, --container-textдва: --bp-grid-2col, --bp-shell-wide
Чим доводитьсятягнеш ширину, нічого не ламаєтьсявимірювана міра рядка в chрядок аудиту, який каже, чому плинне не змогло

Медіазапит питає про ЕКРАН, контейнерний - про МІСЦЕ

Картка не знає, стоїть вона в одноколонковій стрічці чи в сітці на три, і @media дасть їй неправильну відповідь: на широкому екрані теж буває вузька колонка. Оболонка міряє в'юпорт, компонент міряє свій контейнер, а container-type оголошує той, хто ставить компонент, бо місце не є властивістю цеглини. Сьогодні в системі нуль контейнерних запитів; вони приходять на кроці 4.
Дві точки, і обидві названі зміною

Ім'я точки називає що на ній відбувається, а не чийсь пристрій. --bp-tablet і --bp-desktop заборонені як імена: планшет через рік має іншу ширину, а слово «десктоп» повертає в голову модель «три версії продукту» навіть тоді, коли в коді її немає.

ТокенrempxЩо на ній вмикаєтьсяЗвідки число
--bp-grid-2col38.75rem620ряд карток перестає бути однією колонкоюперепис: 32 входження, тут повертають product-grid, goal-tile, review-item, section-head, coach-order
--bp-shell-wide53.75rem860оболонка міняє носія навігації, і з нею повертають ще шість поведінокперепис: 107 входжень, найгустіше число в проєкті
жива точка: цей блок міняє тло на 620 і додає рядок на 860
до 620 - одна колонка · від 620 - сітка у дві та більше · від 860 - широка оболонка

@media не вміє читати var(), і число тому написане двічі

@media (min-width: var(--bp-shell-wide)) тихо не працює: медіазапит обчислюється до каскаду змінних, помилки немає, правило просто ніколи не спрацьовує. Тому в запиті стоїть літерал, а токен лишається джерелом правди і реєстром. Це не два джерела: на кроці 6 греп проходить кожен @media у design/system/ і кожен мусить дати рівно одне з цих двох чисел. Будь-яке інше число в запиті продукту - дефект.

Чому саме дві, і що сталося з рештою

Перепис знайшов 36 сирих значень ширини, 27 після дзеркалення (max-width: 859 це дзеркало межі 860), 18 із них діють у продукті. Ці дві найгустіші з великим відривом. Решта 16 це або дзеркала цих двох, або дрейф, і крок 4 переводить їх сюди. Три шви перекриваються: 520, 620 і 760 написані і як min-width: N, і як max-width: N, тож рівно на N діють обидва правила.

Ці токени пари теми не мають, і це не пропуск

Пара :root / [data-theme="dark"] це властивість semantic-рівня, тобто кольору. Ширина, контейнер і відступ це геометрія: вона живе на primitive-рівні й у темі не змінюється. Шукати тут пару не треба. Токени руху (Рух) пари не мають з тієї самої причини: тривалість і крива теж не є кольором.

А чи РУХАЄТЬСЯ розкладка на точці - вирішує етап 11

Зміна розкладки на точці це кандидат у момент руху, і дефолт тут «ні»: точка спрацьовує рівно тоді, коли людина тягне край вікна і на вміст не дивиться, а анімація перебудови сітки дорога. Виняток - поверхня, якої на вузькій ширині не існувало (права панель спліт-в'ю, рейка): вона з'являється як елемент, і на неї працює звичайна робота «зв'язок». Рішення ухвалюється на кроці 4 сторінки Рух.
Контейнер і міра рядка

Найпомітніший дефект mobile-first продукту на великому моніторі це абзац на 1400px, у якому око не знаходить початку наступного рядка. Лікується не точкою, а контейнером.

згори - у межах --container-text (68ch), знизу - те саме без міри

Креатин моногідрат це найдослідженіша спортивна добавка з усіх, що є на ринку, і саме тому вона стоїть першою в наборі для набору маси. Доза 3-5 грамів на добу, приймати щодня, зокрема у дні без тренування.

Креатин моногідрат це найдослідженіша спортивна добавка з усіх, що є на ринку, і саме тому вона стоїть першою в наборі для набору маси. Доза 3-5 грамів на добу, приймати щодня, зокрема у дні без тренування.

ТокенЗначенняПерший читачРешта
--container-page75rem (1200px)design/_stand.css .wf-page, рамка сторінки кожного кольорового екрана з етапу 07.co-wrap (1200) і .cc-wrap (900) досі пишуть своє число, переїжджають на кроці 4
--container-text68chseo-text.css: .lintro і .seotext pпроза сторінок content-* ще сіра, це етап 12

Чому ch, а не пікселі

.lintro писав max-width: 760px, а 760px при 14px це близько 95 символів у рядку, далеко за межею 60-75, яку тримає око. 68ch усередині цієї межі й рухається разом зі шрифтом, чого піксельна цифра не вміє. Одиниця системі не нова: banner.css уже міряє .promo .pt у 22ch. А empty-state.css несе запис про ручну правку у двох розмірах, 42ch і 46ch, і це рівно той підпис, який токен прибирає.
Сітка: кількість колонок токеном не є

Сітка написана як repeat(auto-fit, minmax(var(--grid-col-min), 1fr)) і рахує колонки сама. На 1100px їх три, хоча такої ширини ніхто не передбачав. Токен --col-count-wide довелося б перемикати, а перемикання це саме те, чого весь цей етап уникає.

жива сітка: кількість колонок не задана ніде, тягніть край вікна
123456

--grid-gap НЕ заведено, і це рішення

Проміжок сітки це --space-16, щабель шкали відступів. Аліас --grid-gap був би другим іменем для одного значення, а tokens.css уже несе правило, яке його вбиває: «значення, вжите один раз, це значення, а не токен». Коли сітці знадобиться ритм, якого шкала не має, вона заробить токен того самого дня.
Типографіка теж адаптується, і теж плинно
згори - --fs-display, плинний; знизу - --fs-30, сталий. Тягніть край вікна
Спортивне харчування
Спортивне харчування

Шкала переїхала з px у rem, значення в значення. При типовому корені 16px кожен щабель дає те саме число, що й до цього, тож жоден екран не зрушив на піксель. Купує це читача, який поставив у браузері шрифт 20px: у px шкала його просто ігнорувала, і він отримував тісну мобільну міру на широкому моніторі.

А сама шкала лишилась сталою, і це навмисно

Шкала загальна: --fs-30 носить і H1 сторінки, і живу ціну в геро-плитці (.hdeal .hd-new), і гліф порожнього стану (.empty .ei). Обгорнути щабель у clamp() означало б змусити іконку дихати разом із в'юпортом, а такого рішення про розмір ніхто не ухвалював. Тому плинний розмір це окремий токен з поіменним списком читачів.
КласЧитач?Чому
.lh1такH1 родини листингу, повна ширина сторінки
.acc-h1такH1 кабінету, повна ширина
.co-h1такH1 оформлення, повна ширина
.bb h1ніназва товару стоїть у вузькій колонці поруч із галереєю: її розмір задає місце, а не екран, тож це @container на кроці 4
.auth-h1, .coach .cv-h1нідіалог і центрована форма, обидва обмежені близько 420-560. Заголовок, що росте з вікном усередині коробки, яка не росте, це дефект, а не адаптація
.hdeal .hd-new, .coachbox .cbnew, .empty .ei, .pm-stars .pmstніціна, цифра і два гліфи. Вони носять щабель 30, бо 30 це їхній розмір, а не бо вони заголовки

Обидва кінці в rem, і середній член несе rem-доданок

clamp(1.875rem, 1.58rem + 1.3vw, 2.75rem). Чистий vw у середньому члені ігнорує розмір шрифту читача і зупиняє масштабування сторінки зумом, що є провалом WCAG 1.4.4. Коліно поставлене рівно на 360px: 1.58rem + 1.3vw дає там 29.96px, трохи нижче підлоги 30px, тож на 360 clamp повертає підлогу і екран не рухається на піксель. Заміряно tools/tree-diff.mjs --widths=360 проти базового дерева, що відрізнялось цими сімома файлами й нічим більше: 0 зрушених боксів. Стеля досягається на 1440.

font-size на точці не перемикається ніколи

Перемикання дає стрибок рівно в ту мить, коли людина тягне край вікна, і лишає ширини між точками, на яких заголовок або завеликий, або замалий. Це та сама драбина, лише для тексту.
Оболонка: форма A, обрана власником

Оболонка це шапка плюс носій навігації верхнього рівня плюс контейнер сторінки. Форма на широкій ширині не обирається на смак - вона виводиться з навігаційної моделі етапу 03a трьома питаннями.

Питання до моделіВідповідьЩо з неї випливає
Скільки пунктів верхнього рівняП'ять, залоковані 2026-06-29: Головна · Каталог · Кошик · Обране · Акаунт. Пошук навмисно не таб - він у постійній верхній смузіп'ять або менше це критерій форми A
Чи є другий рівень, який мусить бути постійно видимимУ глобальної навігації ні: каталог це флайаут, а не постійне дерево. Постійний другий рівень у продукті один - рейка фільтрів від 860, але вона належить сторінцірейл зліва не потрібен, а на листингу він став би другою лівою колонкою
Чи забирає якийсь екран бічний простір під нову поведінкуТак. Split-view потоку тренера, 11 екранів, кандидат кроку 5, хоче ліву колонку під список клієнтівдругий аргумент проти рейла: оболонка зіткнулась би зі split-view

Рішення: A - пункти переїжджають у шапку, таб-бар на широкій ширині не рендериться

Обрано власником. Будувати не довелось нічого: ця форма вже стояла в коді, і крок її назвав, заміряв і записав. Уся зміна живе у двох файлах оболонки, header.css і tabbar.css, і в жодному файлі екрана.
жива оболонка в обох формах: та сама сторінка продукту, дві ширини
вузька форма, 360: таб-бар несе п'ять пунктів, шапка - утиліти
широка форма, 1100: шапка несе все, таб-бара немає в дереві

Рівно один носій навігації верхнього рівня, і це заміряно, а не написано

tools/tab-walk.mjs тисне Tab і читає document.activeElement. На 1280: носій один, шапка з 17 пунктами, таб-бар дає нуль фокусованих, бо він display: none і йде з дерева доступності разом із пікселями. На 360: носіїв два за ролями - смуга це первинна навігація, шапка це утиліти. Фокус на невидимому: 0 на обох ширинах, tabindex > 0 ніде, порядок фокусу збігається з візуальним.

Два пункти стоять в обох носіях на вузькій ширині

«Кошик» - за рішенням IA: navigation.md каже «a slim top bar kept for logo, search and cart». Дубль свідомий, але він усе одно дубль у дереві доступності. «Обране» - а цього специфікація не передбачає: там названо логотип, пошук і кошик. Це знахідка про IA, і виправляти її версткою заборонено: скільки пунктів і де вони - рішення етапу 03a. Навігаційна модель цим етапом не переглядається: міняється розкладка оболонки, а не набір, порядок чи стани пунктів.

Сторінки shell.html у цьому проєкті немає, і це сказано вголос

Пак припускає зібрану design/kit/shell.html. Тут її нема і ніколи не було: оболонка живе двома компонентами зі своїми сторінками, header.html і tabbar.html, і обидві щойно отримали підпункт «Поведінка на ширині». Заводити третю сторінку заради показу означало б завести артефакт без читача.
Поведінка компонентів: раунд 1, атоми

Крок 4 іде рівнями знизу вгору. Усі чотири раунди закриті. Затриманим лишився один файл, coach-session, і не на питанні, а на кроці: його пара 939/940 це коуч-спліт-в'ю, предмет кроку 5. Колонка «поведінка на ширині» лягає в inventory.md, коли зроблені всі чотири: колонка, заповнена на один рівень із чотирьох, каже «невідомо» про три інші у формі, яка читається як «нема чого сказати».

N = 23, M = 9 адаптуються, K = 14 свідомо ні. M + K = N

Перекличка взята з реєстру компонентів, а не з аудиту ширини: аудит відсортований за екранами, і атом, що стоїть лише на екранах «однаково», у ньому не трапляється жодного разу.
Що сталосяАтоми
уже плинні, нічого не змінилосьfield · link-row · radio · stack-action
запит зник у пандусbutton: @media (max-width: 479px) немає; паддінг це clamp(), 12px на 360 і 16px від 860, і перемикання кегля на .btn--l пішло разом із ним
запит згорнувся на реєстрову точкуmenu: 479 стало 619, дзеркало --bp-grid-2col. Випадайка, що стає повноекранним шитом, це поведінка, тож вона лишається точкою
три запити стали одним, і разом із ними пішов дефектskeleton: 620 / 959 / 1040 стали auto-fill на тих самих двох підлогах, що в product-grid.css. На 1280 справжня сітка дає три колонки по 248px, а скелет малював чотири по 185 - обіцянку, якої сторінка не приносила. Тепер обидві дають 248 x 3, піксель у піксель
правило переїхало до свого господаряstatus-pill: рядок @media (max-width: 639px){ .oh-status{ grid-area: stat } } переїхав у order-row.css, чий власний запит на тій самій ширині і оголошує grid-template-areas, без яких stat нічого не значить. Вирізано, не скопійовано
лишились названим екранним виняткомchip · view-toggle, обидва на --bp-shell-wide
свідомо не адаптуються (14)price · rating · availability · discount · favourite · checkbox · stepper · otp · switch · status-pill · badge · icon · product-thumb · counter. Причина одна на всіх: коробку вбудованого знака задає його власний вміст, і він їде разом із контейнером, що адаптується

Заміряно, і обіцянка асиметрична

На 360: tools/tree-diff.mjs по всіх 92 кольорових сторінках проти базового дерева, що відрізнялось лише цим раундом - 0 зрушених боксів. На 1280 зрушили три сторінки, і всі три це скелет, що приходить у згоду із сіткою, яку обіцяє.

Два екранні винятки поза оболонкою, обидва на реєстровій точці

chip.css ховає чипи цілей від 860 не тому, що їхня коробка стала широкою, а тому, що там на тому самому екрані видно плитки тих самих шести цілей: це факт про те, що показує екран, і контейнерний запит його не спитає. view-toggle.css - те саме: нижче точки листинг має одну колонку, і перемикатись немає між чим.

Контейнерних порогів після раунду 1 нуль, і це відповідь

Жодному атому він не знадобився: коробку атома задає його вміст, тож поведінки, залежної від місця, у нього немає. Єдиний кандидат - status-pill на 639 - виявився не тим: перебудовується рядок, а пілюлі він видає комірку.
Поведінка компонентів: раунд 2, молекули

N = 27, M = 23 адаптуються, K = 4 свідомо ні. M + K = N

Перекличка була пропозицією, і замір скасував третину її. Сім файлів пішли в неї кандидатами на auto-fit; чотири з них заповнення не бере, і причина в усіх чотирьох одна: repeat(auto-fit, minmax(F, 1fr)) заповнює ряд, а фіксована кількість елементів має збалансовані розкладки лише на своїх дільниках. Шість плиток цілей хочуть 2, 3 або 6 і ніколи 4+2; шість логотипів - 3 або 6; три картки блогу - 1 або 3. Підлоги, яка дає дільники і пропускає решту, не існує.
Що сталосяМолекули
запит зник у auto-fitaddress-card (720) · loyalty-rung (760) · banner .tbanners (720). У всіх трьох кількість або змінна, або дорівнює двом, тож заповнення тут точне, а не приблизне. Перші два читають новий токен --grid-col-min-panel, третій пише літерал 8rem, бо читач у нього один
запит зник у базове правилоrestock-note: 419 немає. flex-wrap піднявся в базу, поле несе підлогу 13rem, і ряд ламає свою лінію сам
три розміри стрибали на точці, тепер ідуть пандусомbanner .recbanner: гап, портрет і font-size - усі троє стрибали на 559. Кожен пандус кінчається тим самим числом, що стояло там раніше, тож обидва кінці не зрушили, а перестали бути урвищем тільки 200px між ними. .hpromo min-height вийшла зі свого запиту так само
складено на реєстрову точкуgoal-tile 960 -> 860 · blog-card 720 -> 620 · spec-table 720 -> 620 · banner 720 -> 620 · product-card 559 -> 619 · order-row 639 -> 619
уже на реєстровій точціsection-head · review-item · gallery · brand-logo · toolbar, чиї три окремі блоки 860 стали одним
уже плинні, нічого не мінялиempty-state · toast · cart-row · client-row · cert-thumb · desc-block · related
затримано на власникові (2)trust-strip (479, 559, 719, 720, 1180) і seo-text (759, 760). Три відкриті питання, нижче
свідомо не адаптуються (4)breadcrumb · pagination · filter-group · qa-item - і це зміряно, а не прочитано

Числа

До раунду рівень молекул тримав 37 запитів на 14 різних ширинах, чотири з них у реєстрі. Після: 30 запитів на 11 ширинах, і всі сім, що досі поза реєстром, стоять у двох затриманих файлах. Більше ніщо на цьому рівні не питає про ширину, якої реєстр не називає.

Четвірку «без механізму» зміряно, бо прилад шукає п'ять маркерів плинного, і рядковий текст не з них

breadcrumb, 91 екран, найносиміша молекула продукту: на 360 стежка переносить рядок рівно на 7 сторінках із 72 - три coach-order і чотири product, 47.2 -> 66.4px - і не переповнює ніде. pagination: нуль рефлоу на всіх 9; .pages це 87.2px і на 360, і на 1280. filter-group: на 360 у групи немає коробки взагалі (0x0), на 1280 вона 238 x 345.7 - адаптується її місце. qa-item: 157.8 -> 113px, це переноситься текст.

Дефект, який знайшов цей раунд, у файлі, який відмовлявся, щоб його чіпали

restock-note ніс запит max-width: 419 і коментар кроку 7.64 на його захист: «на 420, 440, 460 і 479 цей ряд НЕ переноситься, його двоє дітей виходять 26 + 350». Ці числа і є дефект. Кнопка носить btn--full, її width: 100% вигравала на флекс-лінії, і поле e-mail було 26 пікселів завширшки від 420 і до 1600: 26 + 410 на 480, 26 + 650 на 720. Запит нижче 419 це ховав, тому ніхто ніколи й не питав.

Контейнер сторінки НЕ монотонний за шириною вікна, і виявило це саме заповнення

Перша підлога для --grid-col-min-panel була 22rem. Вона сходилась із запитом на 360 і на 1280 - двох ширинах, на які всі дивляться - і розгортка знайшла її хибною між ними: кабінет бере собі колонку навігації на 960 і лишає списку адрес коробку 628px, де підлога 352 вміщає одну картку, а запит вміщав дві. На 19rem відтворюються всі кількості колонок, які давав запит, і додається одна, якої він не давав. Медіазапит питає вікно і не бачить 216px, які забрала оболонка; плинна підлога питає коробку і не може їх не побачити.

Заміряно, і обіцянка асиметрична

tools/tree-diff.mjs по всіх 92 кольорових сторінках проти базового дерева, що відрізнялось лише десятьма файлами цього раунду, на 360 і 1280: 6 різниць на 184 порівняння, і кожну названо. Чотири - це .tbanners на 1280, де обчислений список треків набув двох записів 0px: п'ять справжніх треків це 196.797 x4 + 196.812 до і після, бо auto-fit згортає треки, для яких немає елемента, а обчислене значення їх усе одно перелічує. Дві - на product-oos: на 360 змінилась лише flex-basis, а обидві коробки лишились 328 x 44 і 328 x 64; на 1280 поле пішло з 26px на 284px, і це та сама полагоджена діра. На 360 не зрушив жоден бокс.

Три питання затримано, і два файли з ними

1. Число талісмана. Одна поведінка - «талісман з'являється, коли поруч є місце» - записана двома неузгодженими числами, 759/760 у seo-text і 1180 у trust-strip, і жодного немає в реєстрі. Це питання про МІСЦЕ, тож чесний механізм тут @container, і це були б перші два контейнерні пороги системи; згорнути обидва на 860 - інша відповідь. 2. Розділювачі смуги довіри. Смуга йде 1 -> 2 -> 4 колонки, а волосини між клітинками це тіні через nth-child, які мусять знати кількість колонок; auto-fit робить її невідомою для CSS. Або дві точки лишаються і сідають на 620/860, або лінії перемальовуються рамкою клітинки - і це міняє те, як вони намальовані, тобто потребує піксельної звірки. 3. .cs-act на 559 - це переноситься ряд дій, а patterns/action-row.css володіє переносом для 53 імен контейнерів із кроку 9.1: схоже, правило належить раунду 4.

Два сказано вголос, а не полагоджено тихо

.listing{ grid-template-columns: 240px 1fr } живе в toolbar.css і є рамкою екрана лістингу, а не тулбара: воно належить оболонці кроку 3, і переносити його тихо всередині раунду молекул означало б це сховати. А ще одну знахідку знято при перевірці: розгортка сказала, що .addr-2col не стоїть на жодній кольоровій сторінці, що читається як «мертвий». Він стоїть - у стенді, на client-dialog.html, а корпус цього приладу це продукт. Нуль від приладу, який не бачить класу, не є нулем; прилад тепер шукає в стенді те, чого не знайшов на продукті, і каже, де саме знайшов.

Контейнерних порогів після раунду 2 і далі нуль

Жодній молекулі він теж не знадобився: кожна поведінка, залежна від місця, на цьому рівні виявилась або фіксованою кількістю (яку точка каже краще), або заповненням (яке auto-fit каже взагалі без порогу). Єдиний справжній кандидат - талісман - це перше з трьох затриманих питань.
Поведінка компонентів: раунд 3, організми

N = 34, M = 32 адаптуються, K = 2 свідомо ні. M + K = N

Найважчий рівень із чотирьох, і він упав удвічі двічі. До раунду 34 файли організмів тримали 86 запитів на 19 різних ширинах, 15 із них поза реєстром - більше, ніж атоми і молекули разом. Після: 80 запитів на 7 ширинах, 3 поза реєстром, і всі три стоять у затриманих файлах. По всій design/system/ тепер 117 запитів на 13 ширинах, і кожне позареєстрове число живе рівно в чотирьох файлах: trust-strip і seo-text (три питання власника з раунду 2), coach-session (крок 5) і pdp-tabs (у парі з талісманом).
Що сталосяОрганізми
два запити видалено, бо вони ніколи не малювалиproduct-grid - найбільша знахідка раунду, нижче
запит зник у пандусproduct-grid і skeleton (перемикач підлоги став --grid-col-fluid) · hero (min-height 130/164) · checkout-form (кегль, гліф і бічний паддінг)
друга оболонка склалась на першуaccount-shell: 960/959 → 860/859 і 640 → 620. Винне skeleton 959 поїхало разом
складено на реєстрову точкуauth-dialog 720/719 → 860/859 (вісім блоків) · coach-verify 760 → 860, 520 → 620 · footer 479 → 619, 720 → 860 · coach-landing 980 → 860, 559 → 619 · coach-clients · coach-cabinet · plan-card · system-page · buy-box (п'ять блоків) · city-dialog · client-dialog · coach-session · checkout-form
уже на реєстровій точціheader · nav-drawer · tabbar · mega-menu · filter-rail · filter-sheet · buy-bar · cart-drawer · coach-order · cat-overlay · cookie-banner
уже плинні або тримаються контейнеромprice-slider · coach-tariff · review-modal · upsell
затримано навмисноcoach-session 939/940 - коуч-спліт-в'ю, предмет кроку 5 · pdp-tabs 1180 - те саме число, що в затриманого талісмана
свідомо не адаптуються (2)overlay · coach-wishlist

Найбільша знахідка: product-grid ніс два мертві запити і сітку, яка йшла назад

1) Мертві. Структурна половина файлу писала repeat(3, 1fr) на 620 і repeat(4, 1fr) на 1040, а кольорова половина нижче перевизначає .prow із тією самою вагою - тож жоден із двох не малював ніколи. Перепис кроку 1 порахував 1040 діючою межею продукту; вона не діяла, і сказати це міг лише замір виходу.

2) Сітка губила колонку, коли вікно ширшало. Зміряно на десяти сторінках: 1 колонка на 320, 2 на 360, 3 на 520, 2 на 620, 3 на 680, 4 на 880. На 620 підлога стрибає зі 150 на 200 і коробка 588 перестає вміщати три - і це на точці, названій «ряд карток перестає бути однією колонкою». Одна підлога цього не лікує (три на 620 вимагають 185 або менше, чотири на 1280 - 194 або більше), тож дефектом є сам перемикач, і його замінив пандус. Тепер ряд читається 1 → 2 (360) → 3 (580) → 4 (880) → 5 (1320), монотонно, а 360 і 1280 не зрушили. Ціна названа: стан «три колонки» на 520-619 стає двома по 244.

Дефект старший за етап - обидві підлоги і мертва пара прийшли з розколу 08 - і пережив етапи 07, 08 і 09, бо звірка на двох ширинах, 360 і 1280, провалля на 620 не бачить.

Кабінет це друга оболонка, і складання було рішенням за замовчуванням

Від своєї точки кабінет відрощує колонку навігації 268px, а нижче ті самі посилання стають горизонтальним скролером. Число було 960 і в жодному реєстрі не стояло. Пак дозволяє третю точку, але лише як рішення власника, назване вголос - його не було, тож число склалось на --bp-shell-wide. Спершу зміряно: на 860 колонка навігації лишається 268, колонка вмісту виходить 528 проти сьогоднішніх 628, нового обрізання немає. Пара мусила їхати разом - скласти лише одну половину означало б покласти смугу 1253px у колонку 268px - і винне skeleton 959, яке раунд 1 лишив саме через цю пару, поїхало з нею.

Де в складання було два кандидати, вибирав замір

auth-dialog пішов на 860, а не на 620, бо на 620 модал обмежений вікном: панелі виходять 243.8 і 310.3, і колонка форми стає вужчою за однопанельну форму, яку вона замінила (618); на 860 вони 349.4 і 444.6. coach-verify - з тієї ж причини і з жорсткішої: примусовий ряд .cv-split на 620 обрізає .opt-tiles, 324 у 319. Самі плитки пішли в інший бік, на 620, де вони по 174.7 і не обрізають нічого.

Три нулі прочитано, а не повірено

comp-width.mjs показує cat-overlay, cookie-banner і system-page на нулі екранів, і жоден із трьох не мертвий. Перші два народжуються в акті: їх ставить _nav.js на подію, тож у завантаженому DOM, який міряє обхід, їх немає. У третього один екран, wireframes/system.html, і кольорового двійника в нього немає взагалі. Три нулі, три різні причини, і жодна з них не «видали файл».
Поведінка компонентів: раунд 4, патерни

N = 1, M = 1, K = 0, і це результат, а не пропуск

patterns/action-row.css це єдиний патерн системи, і в ньому нуль медіазапитів: flex-wrap: wrap стоїть у базовому правилі з кроку 9.1, а .actions--even каже «поділіть ширину» модифікатором розмітки, а не числом. Композиція, зібрана з компонентів, які вже вміють ширину, власної відповіді на неї не має. Одне правило перевірено і лишилось не тут: .cs-act у trust-strip.css нижче точки бере всю лінію і ділить її порівну - друга половина цього і є .actions--even, але модифікатор не вмикається за шириною без запиту, тож правило лишається у свого контейнера, складене на 619.
Затриманий файлБулоСталоЧому саме так
seo-text760 / 759860 / 859талісман біля SEO-тексту складається чисто: на 860 текстова колонка виходить 500 проти 400 на 760 сьогодні, не обрізає нічого
pdp-tabs1180немає1180 робило рівно одне - розширювало праву колонку з 540 до 580. 40px це РОЗМІР, тож він пандус між тими самими значеннями: 248 + 540 на 860 і 312 + 580 на 1180, до і після
trust-strip479, 559, 719/720, 1180619, 619, 859/860, 860 + два пандусинижче
coach-session939 / 940860 / 859закрито кроком 5: смуга клієнтів переїхала всередину сітки і стала вертикальною рейкою. Це була остання пара поза реєстром

Смуга довіри - там, де талісман відмовився складатись, і замір сказав це до правки

Увімкнений на 860 із повним резервом 150px, він робить чотири клітинки по 167 і дві з них обрізають текст. Резерв - це те, що смуга віддає, тож пандусом стає резерв: 108px на 860, 150px на 1180, а кроп-бокс ведмедя їде разом (108 → 180), бо інакше 180-піксельний ведмідь звисав би на 72px над четвертою клітинкою. Тоді на 860 клітинки виходять 177.5 і не обрізає нічого, а на 1180 обидва повертаються до повного розміру. Кроп-бокс для того й існує, щоб різати цього ведмедя, тож різати сильніше там, де менше місця, - це механізм робить свою роботу.

А кількості колонок смуги лишились ТОЧКАМИ

Волосини між клітинками намальовані тінями через nth-child, тобто мусять ЗНАТИ кількість колонок - а auto-fit саме той механізм, що робить її невідомою для CSS. Перемалювати лінії рамкою клітинки було іншим шляхом і його не взято: це міняє те, як намальована кожна лінія смуги, а приймання раунду міряється в пікселях. Третя точка була іншою відповіддю на талісмана, двічі, і її не взято: пак дозволяє одну, але лише як рішення власника, назване вголос.

Де система стоїть після чотирьох раундів

117 запитів на ЧОТИРЬОХ ширинах по всіх файлах design/system/: 619, 620, 859, 860. Це все - пару 939/940 закрив крок 5, і більше нічого поза реєстром немає. Перепис кроку 1 знайшов 27 різних значень ширини, що діяли в продукті, і жодного токена під жодне з них; лишилось два токени, два їхні дзеркала і одна свідомо відкладена поведінка.

tools/bp.mjs це те, що тримає стан: він читає реєстр із tokens.css і питає кожен запит продукту дати одне з його чисел, падає на @media у файлі екрана, на var() усередині запиту і на @container без жодного оголошеного container-type. Усі чотири класи доведено падінням - їх вносили навмисно і відкочували. Кожен оголошений список усередині нього сам перевірений на те, що покриває бодай щось.

Заборона записана у двох місцях

design/system/CLAUDE.md, правила 11 і 12, та architecture.md, розділ J, «A new ADAPTATION». Правило 12 - те, якого не бачить жоден grep і яке потрібне кожному читачеві: КІЛЬКІСТЬ і ПОВЕДІНКА можуть стрибати на точці, РОЗМІР не може.
Крок 5: нова поведінка - спліт-в'ю тренера

Аудит назвав вісім поведінок для широкої ширини, і сім із них уже стояли в коді після раунду 4. Восьма - ця. Джерело не вподобання: головний job каже дослівно «build a complete order for each client in one session», а на телефоні тренер ходить між списком клієнтів і кошиком клієнта туди-сюди, щоразу гублячи місце.

Поріг для спліта - не поріг патерна, і пак каже це прямо

Патерну треба три екрани; спліту - дві й більше пар «список + деталь» або одна пара головного флоу, бо спліт тягне новий стан, керування фокусом і роботу з історією. Тут виконано обидві умови, і дві пари - це різні питання, а не одне двічі.
ПараБагатоОдинРамка
клієнти.clist - збережені клієнти.cldetail - ціль, контакти, нотатки.clsplit
сесія.ctabs - клієнти цієї сесії.cs-panel - кошик того клієнта.cs-grid

Екран-деталь НЕ скасовано, і це правило пака, а не ввічливість

coach-client.html лишає власний URL, власні хлібні крихти і SEO-блок A-E. Нижче точки «Профіль» - звичайне посилання на нього; вище точки той самий запис додатково з'являється поруч зі списком. Поділене посилання й далі відкриває повний екран.

Панель відкривається ПОРОЖНЬОЮ, і рядок - це нова продуктова копія

На потоці «один екран за раз» стану «нічого не вибрано» не існує: ви або в списку, або в клієнті. Спліт цей стан вигадує, тож рядок написано за voice.md і він живе в microcopy.md - шість рядків, voice.html перезібрано тим самим кроком. Автовибір першого клієнта був іншим варіантом і його не взято: він кладе на екран запис, якого ніхто не просив, а на списку зі змінним порядком це щоразу інший запис.

У рамки й панелі ОДНА редакція, і це функція

Три екрани клієнтів несуть той самий список. Панель, скопійована в три файли, - це три редакції, і третя дрейфує першою. Тому wfClientSplit() знаходить .clist, сам загортає його в .clsplit і сам будує .cldetail. Екран лише кличе функцію і не каже про ширину нічого.

Немає списку - немає спліта, і це правило, а не пропуск. У coach-clients-empty і -error карток немає, тож поруч нема чого ставити. А -loading рамку отримує: без неї сторінка стрибнула б на 860 тієї миті, коли приходять дані - список склався б із власних колонок у рейку, і нізвідки з'явилась би панель. Скелетний варіант читається з aria-busy, а не з імені файла.

Пара сесії закрила останнє число поза реєстром

coach-session.css тримав 940 і 939 крізь усі чотири раунди навмисно - їх мав витратити крок 5. Смуга клієнтів переїхала всередину .cs-grid на всіх восьми екранах сесії, і від --bp-shell-wide вона стає вертикальною рейкою в лівій колонці 20rem зі зведенням сесії під нею - зведення підсумовує саме цей список, - а кошик активного клієнта бере решту. Звис таба в 1px, який існує, щоб приклеїти таб до панелі під ним, у рейці вимкнено: панелі під ним там немає.

Далі впав tools/bp.mjs, і це холостий контроль у роботі. Його масив EXCUSED усе ще називав 939 і 940 після того, як ці числа перестали існувати, а список, що називає те, чого ніхто не пише, читається як покриття. Масив тепер порожній.

Що це міряє, після того як критика це полагодила

Спліт більше не вмикається на точці оболонки. Він питає два питання в порядку їхньої ваги: @media (min-width: 860px) першим, бо двопанельне робоче місце належить ДЕСКТОПНІЙ ОБОЛОНЦІ, і @container (min-width: 41rem) всередині, бо навіть у тій оболонці місце не гарантоване.

41rem - це виведення, а не пристрій. Найменша панель, яку варто відкривати, - та, на якій .cd-row ще тримає підпис і значення поруч, тобто власний контейнерний поріг цього ж файла, 22rem. Додаємо рейку і зазор: 17.5rem + 1.5rem + 22rem = 41rem. Співвідношення записане в коментарі, бо запит його не втримає: @container, як і @media, обчислюється до змінних, тож ні calc(), ні var() усередині умови немає.
До критикиПісля
вмикається нав'юпорт 860в'юпорт 990, де .acc-main уперше дає 658
деталь там224px, вужче за рейку 280354px, ширше за поріг рейки
що вирішуєвікнобокс, який оболонка справді лишає

Голий контейнерний запит був НЕПРАВИЛЬНИЙ, і прилад спіймав це за один прогін

Питати лише @container означало вмикати спліт нижче 860 і вимикати між 860 і 960: нижче 860 в оболонки немає колонки навігації, тож .acc-main це повні 828 і тест проходить; на 860 оболонка забирає свої 268 і бокс падає до 528. Спліт з'являвся, зникав і повертався. Місце немонотонне у в'юпорті - той самий факт, що змусив --grid-col-min-panel опуститись до 19rem на кроці 4, - і одні ворота цього не бачать. Тому воріт двоє.

Що лишилось, і це стенда, а не продукту

Розгортка кроком 10px від 320 до 1600 дає в кольоровій копії три переходи: вмикається на 990 (бокс 658), вимикається на 1080 (бокс 532), вмикається знову на 1210 (бокс 662). Падіння на 1080 - це власна рейка роадмепу СТЕНДА, яка з'являється і перебудовує сторінку. У продукті такої рейки немає, і розгортка дає один перехід на 990. Прилад друкує кожен перехід разом із боксом, який його спричинив, тож це не стане тихо нормою; сама рейка лежить у backlog.md як те, що прибрало б мерехтіння.

Що ще полагодила критика

Панель відповідала не на те питання. Рядки були Ціль / Телефон / E-mail / Нотатки, тобто контактна книга, а картка в рейці над нею несла «8 замовлень · останнє 12 черв. 2026» - і панель, яка її деталізує, обидва факти викидала. Стало: Ціль · Замовлень · Останнє замовлення, нотатка тренера піднята в помічену смугу .cc-note (компонент, який coach-client.html для цього вже вживав), телефон і пошта - за «Профіль».

Дві назви на одне місце і загублена особистість. «Почати сесію» = «Нова сесія», «Уся картка клієнта» = «Профіль», і жодне не несло ?client=, який цей самий крок і винайшов. Тепер одна назва на місце, а ?client= проставляється і на кнопки панелі, і на посилання самої картки.

Картка не була кнопкою. role="button" містив два справжні посилання всередині, чого роль кнопки не дозволяє. Контрол переїхав на ІМ'Я клієнта - єдину доступну назву, яку цей контрол міг би хотіти, - а картка лишила клік по всій поверхні мишею, бо це не коштує жодної ARIA-заяви.

Двом новим контролам бракувало кільця. Обидва падали в дефолтний синій Chrome. Тепер --ring-focus-control, те саме, що бере кожен контрол системи.

Смуга сесії заявляла tablist і ним не була. Обробника не існувало взагалі. Таб став справжнім місцем призначення з ?client=, а поточний помічено aria-current - рівно тим самим знаком, що й поточна картка клієнта. Один акт, одна модель, один контракт.

Скелет обіцяв те, що не прийде - малював аватар і заповнену картку даних, а приходила порожня підказка. Тепер це форма самої порожньої коробки.

Чужий ?client= мовчав - тепер каже «Клієнта не знайдено» і чистить URL.

96px порожнечі в рейці сесії: панель охоплює обидва рядки, тож неявні auto auto ділили її висоту між ними. grid-template-rows: auto 1fr - зведення сіло під смугу, проміжок 20px.

Дефект, якого не знайшов жоден прилад

.cldetail-empty був приватним правилом у coach-clients.css - пунктирна рамка, radius-12, по центру, - тобто .emptybox.mini, написаний удруге всередині файла іншого компонента. Ціну заплачено одразу й мовчки: розмітка вже несла .et і .es, але empty-state.css пише їх як .emptybox .et, тож під приватним батьком вони не збігались ні з чим. Заголовок і текст малювались одним розміром і читались як один абзац - на екрані, який кожен прилад називав чистим, бо жоден прилад не питає, чи заголовок виглядає як заголовок. Знайдено тим, що сторінку відкрили. Стан тепер .emptybox mini, а приватне правило видалено, а не виправлено.

Прилад: tools/split.mjs

Спліт заявляє дві речі одночасно - рамка справді має дві колонки, і дві панелі справді в них сидять, - і жодної не видно в css, тож обидві питаються в getBoundingClientRect. Друга половина - перекличка: прилад обходить увесь корпус продукту і падає на будь-якій сторінці, що несе СПИСОК і стоїть поза рамкою. Саме ця перевірка спіймала б сім екранів сесії, які цей крок перевів, і саме вона спіймає восьмий, коли його додадуть.
Клас провалуДоведено тим, щоЩо надрукував
носій поза рамкою.ctabs винесено назад на coach-session-oos.ctabs поза .cs-grid
оголошена рамка нікому не належить.clsplit перейменовано на .no-such-frameне стоїть на жодній сторінці продукту
одна колонка вище точкидругу доріжку знято з .cs-gridширока ширина, а колонок 1
обрізає всередині рамкита сама правкаобрізано ctabs 118>0
сторінка їде вбікmin-width: 1700px на .cldetailгоризонтальна прокрутка сторінки

Дві хибні версії, обидві в шапці приладу

Перекличка спершу була grep-ом по джерелу: на екранах сесії вона відповідала правильно і на трьох із чотирьох екранів клієнтів відповіла б «спліта немає», хоча він там є, - бо wfClientSplit() будує їхню рамку на завантаженні і жодного з двох класів у тих файлах немає взагалі. А перший замір сесії вприскував ту розкладку, яку міряв: замість рухати в'юпорт він заштовхував у сторінку власний стиль-перекриття, і потім повідомив рейку 320 і кошик 488 поміняними місцями плюс обрізання qa-row 324 > 258, якого не існує на жодній ширині.
Перепис і аудит: три таблиці кроку 1

Повні таблиці лежать у design/kit/docs/responsive.md. Нижче - те, що з них видно з одного погляду.

КорпусФайлівТочкаПлиннеКонтейнерДоля
design/system/88170113316дім, тут воно й має жити
design/*.html9211013чуже місце, переїжджає на кроці 4
design/kit/10456115223стенд, у правила продукту не входить
wireframes/143176210390заморожений свідок, звідси нічого не переносимо

Чого немає взагалі

@container 0 · container-type 0 · clamp() 0 · rem усередині медіазапиту 0 · токен ширини, контейнера чи сітки 0. Усі 27 меж у px, усі міряють в'юпорт. minmax( зустрічається 27 разів, а auto-fit лише тричі: більшість сіток у системі несе фіксовану кількість колонок.
Категорія аудитуЕкранів зі 141
ОДНАКОВО62
ШИРШЕ · сітка24
ШИРШЕ · повітря16
НОВА ПОВЕДІНКА39

39 це набагато більше за три-чотири, і ось чесне читання

39 це число екранів. Число поведінок вісім, і сім із них уже стоять у коді: оболонка міняє носія навігації на 860 · рейка категорій з головної · мега-меню флайаутом замість шухляди · рейка фільтрів замість шита на 860 · PDP кладе галерею і бай-бокс поруч і прибирає липку смугу · кошик панеллю замість шухляди на 620 · оформлення формою і підсумком поруч. Восьму збудував крок 5: split-view потоку тренера, 11 екранів. Джерело не вподобання - головний job каже дослівно «build a complete order for each client in one session», а на телефоні тренер ходить між списком клієнтів і кошиком клієнта туди-сюди.

Число одинадцять не змінилось, а склад змінився - і саме це варто сказати вголос. Аудит поклав у ці одинадцять два екрани-ДЕТАЛІ (coach-client, coach-client-loading) і лишив за ними два порожні стани сесії. Крок 5 вирішив навпаки в обох випадках, і рішення прийшло з правила паку, а не зі смаку: спліт не скасовує екран-деталь, тож coach-client лишає власний URL і бере контейнер 900px, а смуга сесії несе рамку в кожному стані, бо сторінка, що виростила б другу колонку в момент приходу даних, стрибнула б тренеру під руками. Заміряно, а не заявлено: .cs-grid дає 328px на 360 і 320px 692px на 1280 і на coach-session-empty, і на coach-session-addempty.

Реєстр перезаміряно на кроці 4, і перший був неправильний тричі

Опубліковане тут число «13 компонентів нічого не знають про ширину» було хибним. Перший реєстр питав сірий корпус, де власних імен системи немає взагалі (мапа перейменувань етапу 08 пройшла лише по design/*.html), тож button.css відповів «нуль екранів». Другий читав class="..." із джерела - 68 рядків із 85 розійшлись із живим заміром, бо скрипти дописують класи на завантаженні. Третій брав кожен клас у файлі, і otp.css відповів «91 екран», бо його селектори називають ще й .field. Якір це клас, яким володіє рівно один файл, і питати треба браузером по кольоровому корпусу. Прилад: tools/comp-width.mjs, усі три хибні версії в його шапці. Чотири файли не мають власного класу - badge, icon, product-thumb, counter - і друкують -, а не 0.
РівеньКомпонентФайлЕкранівНайширша категоріяШирина сьогодні
атомКнопкаbutton.css90НОВА ПОВЕДІНКАплинне
атомПолеfield.css89НОВА ПОВЕДІНКАплинне
атомЧипchip.css86НОВА ПОВЕДІНКА@media 860 · плинне
атомДія стовпчикомstack-action.css86НОВА ПОВЕДІНКАплинне · контейнер
атомРядок посиланьlink-row.css85НОВА ПОВЕДІНКАплинне
атомЦінаprice.css45НОВА ПОВЕДІНКАнічого
атомРейтингrating.css22НОВА ПОВЕДІНКАнічого
атомМітка наявностіavailability.css22НОВА ПОВЕДІНКАнічого
атомБейдж знижкиdiscount.css21НОВА ПОВЕДІНКАнічого
атомОбранеfavourite.css21НОВА ПОВЕДІНКАнічого
атомМеню виборуmenu.css12НОВА ПОВЕДІНКА@media 619 · плинне · контейнер
атомСкелетонskeleton.css12НОВА ПОВЕДІНКА@media 620, 959 · плинне · контейнер
атомЧекбоксcheckbox.css12НОВА ПОВЕДІНКАнічого
атомЛічильник кількостіstepper.css12НОВА ПОВЕДІНКАнічого
атомСтатус-пілюляstatus-pill.css11НОВА ПОВЕДІНКАнічого
атомПеремикач виглядуview-toggle.css11НОВА ПОВЕДІНКА@media 860
атомРадіоradio.css9НОВА ПОВЕДІНКАплинне
атомOTP-коміркаotp.css4ОДНАКОВОнічого
атомПеремикачswitch.css2ОДНАКОВОнічого
атомБейджbadge.css–без свого класунічого
атомІконкаicon.css–без свого класунічого
атомМініатюра товаруproduct-thumb.css–без свого класунічого
атомЛічильникcounter.css–без свого класунічого
молекулаХлібні крихтиbreadcrumb.css91НОВА ПОВЕДІНКАнічого
молекулаЗаголовок секціїsection-head.css28НОВА ПОВЕДІНКА@media 620 · плинне · контейнер
молекулаПорожній станempty-state.css27НОВА ПОВЕДІНКАплинне · контейнер
молекулаЩабель лояльностіloyalty-rung.css26НОВА ПОВЕДІНКА@media 760 · плинне
молекулаКартка товаруproduct-card.css22НОВА ПОВЕДІНКА@media 559, 619, 859, 860 · плинне · контейнер
молекулаТостtoast.css20НОВА ПОВЕДІНКАплинне · контейнер
молекулаSEO-текстseo-text.css17НОВА ПОВЕДІНКА@media 759, 760 · контейнер
молекулаВідгукreview-item.css13НОВА ПОВЕДІНКА@media 620, 860 · плинне · контейнер
молекулаРядок кошикаcart-row.css11НОВА ПОВЕДІНКАплинне
молекулаГрупа фільтраfilter-group.css11НОВА ПОВЕДІНКАнічого
молекулаТулбарtoolbar.css11НОВА ПОВЕДІНКА@media 860 · плинне
молекулаПагінаціяpagination.css9НОВА ПОВЕДІНКАнічого
молекулаБанерbanner.css6НОВА ПОВЕДІНКА@media 559, 720 · плинне · контейнер
молекулаКартка блогуblog-card.css6НОВА ПОВЕДІНКА@media 720
молекулаСмуга довіриtrust-strip.css5НОВА ПОВЕДІНКА@media 479, 559, 719, 720, 1180 · плинне · контейнер
молекулаРядок клієнтаclient-row.css5НОВА ПОВЕДІНКАплинне · контейнер
молекулаГалереяgallery.css4НОВА ПОВЕДІНКА@media 859, 860 · плинне · контейнер
молекулаПлитка ціліgoal-tile.css4НОВА ПОВЕДІНКА@media 620, 960 · плинне
молекулаЛоготип брендуbrand-logo.css4НОВА ПОВЕДІНКА@media 620 · плинне · контейнер
молекулаМініатюра сертифікатаcert-thumb.css3НОВА ПОВЕДІНКАплинне
молекулаКартка адресиaddress-card.css3ШИРШЕ@media 720 · плинне
молекулаСхожі товариrelated.css3НОВА ПОВЕДІНКАплинне
молекулаРядок замовленняorder-row.css2ШИРШЕ@media 639, 860 · плинне · контейнер
молекулаТаблиця складуspec-table.css2НОВА ПОВЕДІНКА@media 720 · плинне
молекулаБлок описуdesc-block.css2НОВА ПОВЕДІНКАплинне · контейнер
молекулаЗапитанняqa-item.css2НОВА ПОВЕДІНКАнічого
молекулаНотатка про поповненняrestock-note.css2НОВА ПОВЕДІНКА@media 419 · плинне · контейнер
організмХедерheader.css86НОВА ПОВЕДІНКА@media 859, 860 · плинне · контейнер
організмШухляда менюnav-drawer.css86НОВА ПОВЕДІНКА@media 860 · плинне
організмТаб-барtabbar.css86НОВА ПОВЕДІНКА@media 859 · контейнер
організмМега-менюmega-menu.css86НОВА ПОВЕДІНКА@media 859 · плинне · контейнер
організмДіалог містаcity-dialog.css86НОВА ПОВЕДІНКА@media 479 · плинне · контейнер
організмОверлейoverlay.css86НОВА ПОВЕДІНКАнічого
організмФутерfooter.css81НОВА ПОВЕДІНКА@media 479, 720 · плинне · контейнер
організмСмуга покупкиbuy-bar.css69НОВА ПОВЕДІНКА@media 859, 860 · контейнер
організмФорма чекаутуcheckout-form.css36НОВА ПОВЕДІНКА@media 479, 480, 559, 860 · плинне · контейнер
організмОболонка кабінетуaccount-shell.css33НОВА ПОВЕДІНКА@media 640, 959, 960 · плинне · контейнер
організмСітка товарівproduct-grid.css21НОВА ПОВЕДІНКА@media 620, 1040 · плинне
організмРейка фільтрівfilter-rail.css15НОВА ПОВЕДІНКА@media 859, 860 · контейнер
організмДіалог клієнтаclient-dialog.css13НОВА ПОВЕДІНКА@media 479 · плинне · контейнер
організмШит фільтрівfilter-sheet.css11НОВА ПОВЕДІНКА@media 860
організмПовзунок ціниprice-slider.css11НОВА ПОВЕДІНКАплинне
організмКлієнти тренераcoach-clients.css10НОВА ПОВЕДІНКА@media 520, 640, 860 · плинне · контейнер
організмЗамовлення тренераcoach-order.css9НОВА ПОВЕДІНКА@media 620 · плинне · контейнер
організмКабінет тренераcoach-cabinet.css8НОВА ПОВЕДІНКА@media 520, 720 · плинне · контейнер
організмСесія замовленняcoach-session.css8НОВА ПОВЕДІНКА@media 479, 859, 939, 940 · плинне · контейнер
організмВкладки товаруpdp-tabs.css8НОВА ПОВЕДІНКА@media 860, 1180 · плинне
організмПеревірка тренераcoach-verify.css5ОДНАКОВО@media 520, 760 · плинне · контейнер
організмШухляда кошикаcart-drawer.css5НОВА ПОВЕДІНКА@media 620 · плинне · контейнер
організмДіалог входуauth-dialog.css5ОДНАКОВО@media 719, 720 · плинне · контейнер
організмГоловний блокhero.css4НОВА ПОВЕДІНКА@media 720, 860 · плинне · контейнер
організмТариф тренераcoach-tariff.css3ШИРШЕплинне · контейнер
організмБлок покупкиbuy-box.css3НОВА ПОВЕДІНКА@media 479, 619 · плинне · контейнер
організмКартка тарифуplan-card.css3ШИРШЕ@media 640
організмМодалка відгукуreview-modal.css3НОВА ПОВЕДІНКАконтейнер
організмПанель Proupsell.css2НОВА ПОВЕДІНКАплинне
організмЛендинг тренераcoach-landing.css1ШИРШЕ@media 559, 620, 860, 980 · плинне · контейнер
організмОбране тренераcoach-wishlist.css1ШИРШЕнічого
організмОверлей каталогуcat-overlay.css0не стоїть@media 859 · плинне · контейнер
організмБанер cookiecookie-banner.css0не стоїть@media 620 · плинне · контейнер
організмСистемна сторінкаsystem-page.css0не стоїть@media 720, 859 · плинне · контейнер
патернРяд дійaction-row.css15НОВА ПОВЕДІНКАплинне

Таблиця аудиту: рядок на кожен зі 141 екрана

Ідл-контроль: 141 екран у корпусі, 141 рядок, 0 без рядка. Стан екрана успадковує категорію своєї бази: скелет сітки це теж сітка.
ЕкранЩо людина тут робитьКатегоріяЧим досягається
404читає одне повідомлення і йде даліОДНАКОВОконтейнер
500читає одне повідомлення і йде даліОДНАКОВОконтейнер
accountоглядає кабінет: замовлення, бонуси, адресиШИРШЕ · сіткаплинне (auto-fit) + контейнер
account-addressesпереглядає свій списокШИРШЕ · сіткаплинне (auto-fit)
account-addresses-addзаповнює форму адреси в діалозіОДНАКОВОконтейнер
account-addresses-courierзаповнює форму адреси в діалозіОДНАКОВОконтейнер
account-addresses-deleteзаповнює форму адреси в діалозіОДНАКОВОконтейнер
account-addresses-editзаповнює форму адреси в діалозіОДНАКОВОконтейнер
account-addresses-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
account-addresses-postomatзаповнює форму адреси в діалозіОДНАКОВОконтейнер
account-addresses-viddilenniaзаповнює форму адреси в діалозіОДНАКОВОконтейнер
account-emptyоглядає кабінет: замовлення, бонуси, адресиШИРШЕ · сіткаплинне (auto-fit) + контейнер
account-errorчитає помилку і повторює спробуОДНАКОВОконтейнер
account-loadingоглядає кабінет: замовлення, бонуси, адресиШИРШЕ · сіткаплинне (auto-fit) + контейнер
account-loyaltyпереглядає свій списокШИРШЕ · сіткаплинне (auto-fit)
account-loyalty-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
account-loyalty-maxпереглядає свій списокШИРШЕ · сіткаплинне (auto-fit)
account-ordersпереглядає свій списокШИРШЕ · сіткаплинне (auto-fit)
account-orders-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
account-profileправить одне поле профілюОДНАКОВОконтейнер
account-profile-deleteправить одне поле профілюОДНАКОВОконтейнер
account-profile-emailправить одне поле профілюОДНАКОВОконтейнер
account-profile-langправить одне поле профілюОДНАКОВОконтейнер
account-profile-phoneправить одне поле профілюОДНАКОВОконтейнер
account-profile-withemailправить одне поле профілюОДНАКОВОконтейнер
account-wishlistпереглядає свій списокШИРШЕ · сіткаплинне (auto-fit)
account-wishlist-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
account-wishlist-manyпереглядає свій списокШИРШЕ · сіткаплинне (auto-fit)
authвводить номер і код зі SMSОДНАКОВОконтейнер ~420
auth-codeвводить номер і код зі SMSОДНАКОВОконтейнер ~420
auth-errorвводить номер і код зі SMSОДНАКОВОконтейнер ~420
auth-loadingвводить номер і код зі SMSОДНАКОВОконтейнер ~420
auth-newuserвводить номер і код зі SMSОДНАКОВОконтейнер ~420
brandsобирає бренд або категорію з набору плитокШИРШЕ · сіткаплинне (auto-fit)
brands-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
brands-errorчитає помилку і повторює спробуОДНАКОВОконтейнер
brands-loadingобирає бренд або категорію з набору плитокШИРШЕ · сіткаплинне (auto-fit)
cartпереглядає кошикНОВА ПОВЕДІНКА · є в кодіточка 620 (панель замість шухляди)
cart-coachпереглядає кошикНОВА ПОВЕДІНКА · є в кодіточка 620 (панель замість шухляди)
cart-coach-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
cart-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
cart-oosпереглядає кошикНОВА ПОВЕДІНКА · є в кодіточка 620 (панель замість шухляди)
catalog-pageобирає бренд або категорію з набору плитокШИРШЕ · сіткаплинне (auto-fit)
catalog-page-errorчитає помилку і повторює спробуОДНАКОВОконтейнер
catalog-page-loadingобирає бренд або категорію з набору плитокШИРШЕ · сіткаплинне (auto-fit)
checkoutоформлює замовленняНОВА ПОВЕДІНКА · є в кодіточка 860 (форма і підсумок поруч)
checkout-declinedчекає або читає, що оплату не завершеноОДНАКОВОконтейнер
checkout-loadingчекає або читає, що оплату не завершеноОДНАКОВОконтейнер
checkout-loggedinоформлює замовленняНОВА ПОВЕДІНКА · є в кодіточка 860 (форма і підсумок поруч)
checkout-noaddrоформлює замовленняНОВА ПОВЕДІНКА · є в кодіточка 860 (форма і підсумок поруч)
coach-clientведе список клієнтів і відкриває профільНОВА ПОВЕДІНКА · НЕМАЄточка 860, split-view список + деталь
coach-client-editзаповнює або підтверджує картку клієнта в діалозіОДНАКОВОконтейнер
coach-client-edit-confirmзаповнює або підтверджує картку клієнта в діалозіОДНАКОВОконтейнер
coach-client-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
coach-client-errorчитає помилку і повторює спробуОДНАКОВОконтейнер
coach-client-loadingведе список клієнтів і відкриває профільНОВА ПОВЕДІНКА · НЕМАЄточка 860, split-view список + деталь
coach-client-newзаповнює або підтверджує картку клієнта в діалозіОДНАКОВОконтейнер
coach-clientsведе список клієнтів і відкриває профільНОВА ПОВЕДІНКА · НЕМАЄточка 860, split-view список + деталь
coach-clients-capведе список клієнтів і відкриває профільНОВА ПОВЕДІНКА · НЕМАЄточка 860, split-view список + деталь
coach-clients-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
coach-clients-errorчитає помилку і повторює спробуОДНАКОВОконтейнер
coach-clients-loadingведе список клієнтів і відкриває профільНОВА ПОВЕДІНКА · НЕМАЄточка 860, split-view список + деталь
coach-homeоглядає кабінет тренераШИРШЕ · сіткаплинне (auto-fit) + контейнер
coach-home-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
coach-home-errorчитає помилку і повторює спробуОДНАКОВОконтейнер
coach-home-freeоглядає кабінет тренераШИРШЕ · сіткаплинне (auto-fit) + контейнер
coach-home-loadingоглядає кабінет тренераШИРШЕ · сіткаплинне (auto-fit) + контейнер
coach-landingчитає лендинг гуртового доступуШИРШЕ · сіткаплинне + контейнер
coach-orderчитає одне замовлення тренера, по клієнтахШИРШЕ · сіткаплинне + контейнер
coach-order-errorчитає помилку і повторює спробуОДНАКОВОконтейнер
coach-order-loadingчитає одне замовлення тренера, по клієнтахШИРШЕ · сіткаплинне + контейнер
coach-ordersпереглядає список замовленьШИРШЕ · сіткаплинне
coach-orders-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
coach-orders-errorчитає помилку і повторює спробуОДНАКОВОконтейнер
coach-orders-loadingпереглядає список замовленьШИРШЕ · сіткаплинне
coach-sessionзбирає замовлення на кількох клієнтів за одну сесіюНОВА ПОВЕДІНКА · НЕМАЄточка 860, split-view клієнти + кошик клієнта
coach-session-addclientзбирає замовлення на кількох клієнтів за одну сесіюНОВА ПОВЕДІНКА · НЕМАЄточка 860, split-view клієнти + кошик клієнта
coach-session-addemptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
coach-session-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
coach-session-loadingзбирає замовлення на кількох клієнтів за одну сесіюНОВА ПОВЕДІНКА · НЕМАЄточка 860, split-view клієнти + кошик клієнта
coach-session-newclientзбирає замовлення на кількох клієнтів за одну сесіюНОВА ПОВЕДІНКА · НЕМАЄточка 860, split-view клієнти + кошик клієнта
coach-session-oosзбирає замовлення на кількох клієнтів за одну сесіюНОВА ПОВЕДІНКА · НЕМАЄточка 860, split-view клієнти + кошик клієнта
coach-session-priceblockзбирає замовлення на кількох клієнтів за одну сесіюНОВА ПОВЕДІНКА · НЕМАЄточка 860, split-view клієнти + кошик клієнта
coach-tariffпорівнює два тарифи поручШИРШЕ · сіткаплинне (flex-wrap)
coach-tariff-cancelпідтверджує скасування тарифу в діалозіОДНАКОВОконтейнер
coach-tariff-freeпорівнює два тарифи поручШИРШЕ · сіткаплинне (flex-wrap)
coach-verifyподає заявку на гуртовий доступ, чекає, читає відповідьОДНАКОВОконтейнер
coach-verify-deadendподає заявку на гуртовий доступ, чекає, читає відповідьОДНАКОВОконтейнер
coach-verify-errorподає заявку на гуртовий доступ, чекає, читає відповідьОДНАКОВОконтейнер
coach-verify-loadingподає заявку на гуртовий доступ, чекає, читає відповідьОДНАКОВОконтейнер
coach-verify-tierподає заявку на гуртовий доступ, чекає, читає відповідьОДНАКОВОконтейнер
coach-wishlistпереглядає обране тренераШИРШЕ · сіткаплинне (auto-fit)
content-aboutчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-articleчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-blogчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-contactsчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-deliveryчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-faqчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-guaranteeчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-legalчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-loyaltyчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-loyalty-buyerчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-newsletterчитає, що підписку підтвердженоОДНАКОВОконтейнер
content-promoчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-returnsчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
content-reviewsчитає суцільний текстШИРШЕ · повітряконтейнер + міра рядка в ch
goalфільтрує видачуНОВА ПОВЕДІНКА · є в кодіточка 860 (постійна рейка фільтрів проти шита) + плинна сітка
goal-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
goal-errorчитає помилку і повторює спробуОДНАКОВОконтейнер
goal-loadingфільтрує видачуНОВА ПОВЕДІНКА · є в кодіточка 860 (постійна рейка фільтрів проти шита) + плинна сітка
home-buyerвходить у продукт: геро, цілі, добіркиНОВА ПОВЕДІНКА · є в кодіточка 860 (оболонка) + плинне
home-cartвходить у продукт: геро, цілі, добіркиНОВА ПОВЕДІНКА · є в кодіточка 860 (оболонка) + плинне
home-catalogвідкриває каталог рейкою категорійНОВА ПОВЕДІНКА · є в кодіточка 860 (оверлей проти рейки)
home-coachвходить у продукт: геро, цілі, добіркиНОВА ПОВЕДІНКА · є в кодіточка 860 (оболонка) + плинне
indexвходить у продукт: геро, цілі, добіркиНОВА ПОВЕДІНКА · є в кодіточка 860 (оболонка) + плинне
listingфільтрує видачуНОВА ПОВЕДІНКА · є в кодіточка 860 (постійна рейка фільтрів проти шита) + плинна сітка
listing-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
listing-errorчитає помилку і повторює спробуОДНАКОВОконтейнер
listing-filteredфільтрує видачуНОВА ПОВЕДІНКА · є в кодіточка 860 (постійна рейка фільтрів проти шита) + плинна сітка
listing-listфільтрує видачуНОВА ПОВЕДІНКА · є в кодіточка 860 (постійна рейка фільтрів проти шита) + плинна сітка
listing-loadingфільтрує видачуНОВА ПОВЕДІНКА · є в кодіточка 860 (постійна рейка фільтрів проти шита) + плинна сітка
listing-sheetфільтрує видачуНОВА ПОВЕДІНКА · є в кодіточка 860 (постійна рейка фільтрів проти шита) + плинна сітка
maintenanceчитає одне повідомлення і йде даліОДНАКОВОконтейнер
megamenuрозкриває каталог із шапкиНОВА ПОВЕДІНКА · є в кодіточка 860 (флайаут проти шухляди)
megamenu-healthрозкриває каталог із шапкиНОВА ПОВЕДІНКА · є в кодіточка 860 (флайаут проти шухляди)
megamenu-proteinрозкриває каталог із шапкиНОВА ПОВЕДІНКА · є в кодіточка 860 (флайаут проти шухляди)
megamenu-vitaminsрозкриває каталог із шапкиНОВА ПОВЕДІНКА · є в кодіточка 860 (флайаут проти шухляди)
order-placedчитає підтвердження, номер і наступний крокОДНАКОВОконтейнер
order-placed-account-endчитає підтвердження, номер і наступний крокОДНАКОВОконтейнер
productвивчає товар і додає в кошикНОВА ПОВЕДІНКА · є в кодіточка 860 (галерея і бай-бокс поруч, липка смуга зникає)
product-coachвивчає товар і додає в кошикНОВА ПОВЕДІНКА · є в кодіточка 860 (галерея і бай-бокс поруч, липка смуга зникає)
product-errorчитає помилку і повторює спробуОДНАКОВОконтейнер
product-loadingвивчає товар і додає в кошикНОВА ПОВЕДІНКА · є в кодіточка 860 (галерея і бай-бокс поруч, липка смуга зникає)
product-oosвивчає товар і додає в кошикНОВА ПОВЕДІНКА · є в кодіточка 860 (галерея і бай-бокс поруч, липка смуга зникає)
product-reviewsчитає відгуки і сертифікатШИРШЕ · повітряконтейнер + міра рядка
quizвідповідає на питання по одномуОДНАКОВОконтейнер
searchфільтрує видачуНОВА ПОВЕДІНКА · є в кодіточка 860 (постійна рейка фільтрів проти шита) + плинна сітка
search-emptyбачить порожній стан і один вихід із ньогоОДНАКОВОконтейнер
search-loadingфільтрує видачуНОВА ПОВЕДІНКА · є в кодіточка 860 (постійна рейка фільтрів проти шита) + плинна сітка
search-suggestбачить підказки під полем пошукуОДНАКОВОконтейнер
systemслужбовий індекс прототипу, не екран продуктуОДНАКОВОконтейнер
Крок 6: критика класами, зі статусом на кожному рядку

Два прилади плюс третій: Claude з апаратом проєкту і браузером, Codex read-only по джерелу, /impeccable audit ізольованим браузерним агентом. Набори зняті незалежно, дедуп після.

КласЗнайденоХто знайшовВиправленоЗнятоЗаписано, не взято
таблиця аудиту застаріла про власну поставку13 рядківClaude (11), Codex (2)13––
стенд описує файл, якому вже не відповідає6Claude, Codex6––
контейнерний поріг поза реєстром1обидва1––
токен, якого ніхто не читає3Codex1 видалено2–
міру рядка ігнорує суцільний текст5 селекторівimpeccable5––
px там, де правило каже rem58Codex58––
той самий блок оголошень двічі6 групCodex, Claude1–5
контрол без кільця фокуса51 + 4 + 2impeccable, Claudeусі––
кільце спрацьовує на :focus2 правилаimpeccable2––
доступне ім'я посилання це заповнювач222impeccable222––
схована смуга прокрутки без жодного знаку3impeccable3––
картинка вантажиться в закриту панель1 (2.28 МБ)impeccable1––
<img> без lazy і без розмірів28impeccable28––
лендмарк без доступного імені1impeccable1––
тач-таргет нижче підлоги3impeccable–3–
em dash в output-файлі13Codex–13–
інлайн-ширина на екрані28Codex1207
стиль оголошено на екрані80Codex, Claude––80
типографіка перемикається на точці29Claude, Codex––29
вага ассетів9.34 МБ на сторінкуimpeccable2.28 МБ–решта
ЛАМАЄТЬСЯ МІЖ ТОЧКАМИне мірянорозгортка, відкладена власником–––

Останній рядок це ДІРА, а не нуль

tools/split.mjs справді проходить 91 сторінку на 129 ширинах - але лише по рамках, які сам оголошує, ніколи по довільному елементу, носіях навігації чи мірі рядка. 84 з 92 кольорових сторінок і всі 103 сторінки стенда по ширинах не пройдені.

Форма кроку 6: п'ять із шести дефектів документів зробили два проходи перед ним

roles.mjs і inventory.mjs впали на файлах, які прохід по боргах правив годиною раніше. CLAUDE.md уже каже, що ремонт застарює сусідів; чого він не казав - що прилад, який це ловить, треба гнати ПІСЛЯ ремонту, а не до. Всередині самого кроку 6 цей цикл замкнувся ще чотири рази, і кожен займав хвилину, а не два етапи.

Найбільша знахідка не лежала в жодному файлі джерела

На coach-clients при 1280: з 80 видимих фокусованих 51 малював власне синє кільце Chrome rgb(0, 95, 204) - фіксоване значення user agent, яке не слідує темній темі. І чотири правила box-shadow: none на КОНТРОЛАХ видаляли кільце назавжди: (0,2,0) у файлі, що вантажиться після button.css, дає нічию, а нічия йде порядку джерела. Два файли, обидва правильні окремо, а дефект існує лише в розв'язаному виводі - тому саме вивід і питає tools/focus.mjs. Сьогодні: 19 071 контрол на 91 сторінці у двох ширинах, 0 синіх, 0 без кільця.
Крок 7: обхід ширин, тобто те, що етап лишив невиміряним

Етап 10 закрився з одним червоним рядком у власному чек-листі контракту: «розриви МІЖ точками - не заміряно». Обхід було відкладено власником до кінця Анімації. Анімація закрилась; це той борг.

Три прилади з чотирьох назвали б етап чистим

accept.mjs ходить по корпусу на 360 і 390 · tree-diff.mjs звіряє два дерева властивість за властивістю · grid-sweep.mjs рахує колонки · split.mjs обходить 129 ширин, але лише для рамок, які сам оголошує. Жоден не питає довільний елемент про довільну ширину, тож етап, чий предмет - ширина, закрився з нулем знахідок у своєму головному класі.
КласВище підлоги 360Що це було
документ гортається вбік0спрацьовує нижче підлоги на двох сторінках, тож це не нуль від сліпої перевірки
елемент за межею екрана1 → 0.ob-side на account-orders, 56.8px за краєм між 1076 і ~1160 - і ніщо не гортається: предок обрізає, тож панель не виштовхнута кудись, де її знайдуть, а відрізана мовчки
рядок довший за міру читання31 → 0етап 10 міряв прозу на ОДНІЙ ширині, 1600, і закапав п'ять. Проза перетинає міру не там, де вікно найширше, а там, де її колонка перестає ділити рядок
той самий пункт у двох носіях0визначення взяте дослівно з tab-walk.mjs, а не виведене вдруге; цей файл додає 129 ширин замість двох
за краєм, але У РЕЙЛІ15друкується, провалом не рахується: айтем за краєм горизонтального скролера - це і є рейл

Чому @container, а не третя точка

Питання ніколи не було про вікно. Між 1076 і ~1160 ВІКНО широке, тож оболонка відкриває бічну навігацію і колонка кабінету втрачає 216px одним стрибком; в'юпортний запит лишається істинним, 1fr не може стиснутись за власний min-content, і панель виштовхується. Розміщувач уже існував: .acc-main оголосив container-type: inline-size ще на кроці 5. Число - сума, а не пристрій: 292 + 24 + 268 - панель, --space-24 і заміряний min-content колонки підсумку, тобто 36.5rem. bp.mjs валив прогін, доки поріг не став у реєстр - гейт спрацював.

Найгірший рядок продукту був невидимий, доки не полагодили той, що перед ним

.tsb тягнеться на 132.1ch, майже вдвічі за міру, і стояв за .qans - бо перше написання приладу тримало лише найгіршого порушника на ширину. Прилад, який треба ганяти, правити й ганяти знову, щоб побачити на шар глибше, не відрізняє «чисто» від «ще один раунд попереду», і кількість раундів невидима в його ж виводі. Раундів знадобилось три.

Дві з перших двадцяти правок промахнулись, і сказав це сам обхід

.coach .crestock .rk-lead не покривав покупецький кабінет, де той самий блок не носить .coach; .cd-oosnote .m - інший .m, ніж на чекауті. Обидва названі в css, а не тихо розширені. Правило «ремонт переперевіряє той прилад, що знайшов дефект», яке спрацювало саме на собі.

І одна знахідка була про РІД числа, а не про ширину

.pf-note уже був закапаний - на max-width: 38.75rem, а це --bp-grid-2col: точка адаптиву, ужита як міра читання. Точка це поріг, який перетинає розкладка; міра це наскільки широким може бути рядок; 620px дорівнює 70.2ch при цьому кеглі випадково. Тепер каже, що означає, і рядок вужчає на ~20px навмисно.

Дванадцять хибних версій приладу, і чотири з них змінили, що він узагалі вміє

Міра бралася з КОРОБКИ, а міра - про РЯДОК: .qans доповідався на 132.3ch, а його текст - «Магазин: ~72 порції по 30 г.», двадцять вісім символів у широкій коробці, що не переноситься жодного разу. Знайшлось тільки тому, що всі 21 знахідку відкрили руками. · Один порушник на ширину - див. вище; заразом вилікувало сліпоту: з одним булевим на клас усе, що істинне від низу підлоги і вище, не звітувало нічого над нею, тому клас «за межею» стрибнув з 1 на 15, щойно власники отримали власні краї. · Рейл - не розрив. · Нутрощі <svg> - не розкладка.
Крок 6: контракт етапу як чек-лист

Третій прилад, і він навмисно окрема таблиця. Обидва прилади, що шукають дефекти, читають те, що існує, тому пропущений гейт не бачить жоден: кроку, якого не було, немає ні в жодному файлі, ні на жодній сторінці.

Гейт пакуСтатусЧим саме
гейт входу перед кроком 1зроблено84 компоненти, 1 патерн, два рівні токенів, 142 сірих, 92 кольорових
один крок, показ, чеканнязробленошість кроків, кожен показаний
рев'ю на кроці 2, до компонентівзробленотокени і драбина прийняті до раунду 1
дві точки, в rem, названі ЗМІНОЮзроблено38.75rem і 53.75rem. Третьої немає
кожен @media дає число реєструзробленоbp.mjs, 117 запитів, чотири числа
жодного @media у файлі екраназробленоєдиний виняток design/overview.html тепер записаний і в реєстрі, а не лише у власному коментарі
container-type оголошує ТОЙ, ХТО СТАВИТЬзробленотри пороги, три placer-и, усі названі
контейнерні пороги в реєстрізакрито на кроці 663rem бракувало; bp.mjs тепер питає в обидва боки
шкала плинна через clamp()зроблено на кроці 2і 29 оголошень усе ще перемикають типографіку в запиті - записано, не взято, з причиною
адаптивних px не лишилосьзакрито на кроці 658 переведено; 120 усередині умов лишаються за правилом самого паку
оболонка розв'язана розвилкою A/B/Cзробленоформа A, рішення власника, заміряно tab-walk
рівно один носій навігації на будь-якій ширинізробленоtab-walk, 4 сторінки × 2 ширини, 0 знахідок
розгортка ширини 320-1600НЕ ЗРОБЛЕНО - власник відклав до анімаційголовний прилад етапу. Клас, яким він володіє, не має знахідок, і це діра
ідл-контроль з обох боківзробленокожен оголошений список у кожному приладі, і кожен доведений зламом
широка ширина в ТЕМНІЙ темізробленоtheme.mjs, 277 з 281, 0 зламаних темою
нуль різниці на 360зробленоaccept 282/0; proof.mjs --against HEAD не зрушив нічого на 40 екранах
кожна різниця на десктопі пояснена рядком аудитучастковоп'ять обмежень міри і три маски пояснені тут; вони нові на кроці 6, а таблиця аудиту старша за них
критика в два приладизробленоClaude і Codex, набори незалежні, write: false у записі задачі
контракт як третій приладзробленоця таблиця
/impeccable auditзробленоізольований браузерний агент, 15 знахідок і 6 знятих ним самим
секція піксельного доказу етапу 10частковополовина на 360 доведена; кадри розгортки потребують розгортки
README, wip у /_nav.js, ритуал закриттяНЕ ЗРОБЛЕНОетап не можна закрити, поки не відпрацював його головний прилад

Не все зелене, і два червоні рядки це одне рішення

Розгортка це головний прилад етапу, і власник переніс її після анімацій; ритуал закриття чекає на неї. Сказати це тут - і є сенс таблиці: усі три інші прилади відрапортували б чистий етап.