Організм · рівень 3

Хедер

Другий за розміром файл шару після checkout-form.css і найскладніша композиція в ньому: у корені .wfh заміряно до 631 елемента - мегапанель, діалог міста, меню мови, меню кабінету, пошук і чотири дії в одному рядку. Висота кореня 73 при 390 і 112 при 1280: різницю робить верхня смуга, якої на телефоні немає. Одне !important у файлі, і воно про межу 860.

рівень 3design/system/components/header.css435 рядків153 селектори383 оголошення134 екрани
З чого складається

Хедер майже нічого не малює сам: він тримає місце. Діалог міста лежить усередині <header> прихованим і в демо не видно жодного з його десяти класів - у спокої він закритий.

ФайлКласівЯкі саме
mega-menu.css12.gi .gtx .mega-cat-goals .mega-cats .mega-goalcard .mega-goalgrid .mega-goalrow .mega-groups ...
city-dialog.css10.city-az .city-badge .city-lbl .city-list .city-note .city-pop .city-search .wf-city ...
field.css4.field .field--s .field-grp .field-grp--s
loyalty-rung.css2.t2 .uiv-tier
button.css2.btn--icon .btn--s
stack-action.css1.btn--stack
overlay.css1.wf-ov
chip.css1.mgchip

7 класів усередині кореня мають більш ніж одного власника, тож із коду не видно, чий вони: .btn--accent .btn--ghost .btn--outline .gc .go .uiv-trail .x

Анатомія

Розмітка тут - не переписана від руки. Її знято з design/index.html у цій же сесії, обробники зняті, посилання підняті на рівень. Корінь тут fixed або sticky і в продукті видимий, тож open йому не додавали. Сцена потрібна тільки щоб він лишався всередині свого демо.

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

1Верхня смуга .wfh-meta - display:none до 859 і block від 860. Стеля max-height:52px і перехід 220ms: на прокрутці смуга згортається в нуль, а не зникає стрибком
2Головний рядок .wfh-main - position:relative, і саме від нього міряється мегапанель. Крок 7.25: доти вона висіла на кнопці «Каталог» і при вікні 900 виїжджала правим краєм на 1155 при сторінці 885
3Мегапанель .wfh-mega - 226px minmax(0, 1fr) 196px, стеля max-width:940px. При 1280 заміряно 940x595: панель стоїть рівно у своїй стелі. Її нутрощі описує mega-menu.css, а флайаут рейки на головній бере цей самий клас і переписує його
4Кнопка-лічильник .wfh-act.numbtn - min-width:124px. Підлога взята з найширшого ПОРОЖНЬОГО стану: чотири заміряні при 1280 стани дали 124 / 98.6 / 100 / 103, і хедер смикався на 25px просто від того, що приходив баланс
5Висота рядка .wfh-actions .wfh-act - --size-44, і пошук .wfh-search тягнеться до тієї самої сходинки. 44 - це пальцева сходинка системи, а не третя висота поруч з 40 і 46
6Мобільний ряд знаків .wfh-mi - коробка 21x32 не може ширшати, не штовхнувши сусіда, тому ціль розтягує a::after{ inset:-6px -8px }: 8 виміряно по проміжку, тож ціль зупиняється ПЕРЕД сусіднім знаком, а не накриває його

Єдине !important файлу

Це @media (max-width: 859px){ .wfh-scrim{ display:none !important } }, і б'є воно .wfh-scrim.open, .wfh-scrim.pinned{ display:block } - два класи проти одного. Без нього скрим лишався б на телефоні, якби JavaScript встиг покласти на нього .open. У всьому шарі !important рівно п'ять, у чотирьох файлах, і всі п'ять - одне речення на межі 860: три вимикають десктопне нижче межі, два - мобільне вище. Системі просто нема чим сказати «цього компонента на цій ширині не існує», крім жорсткого перебиття.

Чого немає в демо. Розмітку знято з design/index.html, а це гість, тож сім класів меню кабінету - .wfh-cab .wfh-cabmenu .cab-head .cab-nm .cab-tier .cab-lvl .cab-sep - тут не показані, хоча на account*.html вони малюються. .wfh-scrim лежить сусідом, поза коренем. Мегапанель у розмітці є, але закрита - як у спокої. А .drawer-open, .wfh-menuopen, .mega-pinned і .pinned - це класи станів, які кладе JavaScript.
Три обличчя, яких у гостьовій шапці немає

.mega-pinned і .pinned - не стани продукту, а власна мета цих класів. У всьому репозиторії їх ставлять рівно чотири сірі екрани, wireframes/megamenu*.html, і wireframes/docs/screens.md каже прямо: «.mega-pinned тримає відкритим для демо». Тобто це клас для показу, і рамка нижче робить із ним те саме, що ті чотири екрани, - шапку будує wfHeader(), далі панель приколюють.

.wfh-scrim - на <body>, а не всередині шапки: шапка тримає власний контекст накладання, тож дитина ніколи не змогла б лягти під неї. На тілі скрим сидить на 28, під шапкою на 30, і сторінка гасне, поки шапка лишається чіткою

Меню кабінету є лише у ввійшлого, і воно різне для двох ролей: .cab-lvl - рядок рівня лояльності покупця, .cab-tier - пігулка тарифу тренера. Одне .cab-head, дві відповіді, тож і рамок дві. Обидві будує wfHeader(role), відкриває toggleCab().

Покупець: .cab-nm з іменем і .cab-lvl «🥈 Срібний рівень» під ним
Тренер: та сама голова, але .cab-tier «Pro» - твердження про акаунт, а не рівень. І чотири пункти замість двох, бо тренерський потік - первинний

ПОВЕДІНКА НА ШИРИНІ - етап 10, крок 3

Що робить: від --bp-shell-wide шапка приймає всю навігацію верхнього рівня - з'являється мета-смуга, розкривається головне меню, поле пошуку і зона дій, а бургер і мобільний ряд іконок ховаються. Заміряно: 5 фокусованих пунктів нижче точки і 17 від неї. Від якої точки: 860px - 859 це дзеркало тієї самої межі, а 899, який ще видно в тексті, живе тільки всередині коментаря про правило, прибране на 7.25.

І одне число, яке не є точкою: 63rem на @container. Прохід по боргах закрив дірку, якої не бачила жодна точка: між точкою оболонки і приблизно 1010 поле пошуку схлопувалось до 44px. Це питання не про екран, а про МІСЦЕ - місця бракує РЯДОВІ, а ширина рядка це не ширина вікна. Тому container-type: inline-size лягає на .wfh-main, а підписи чотирьох дій ідуть у візуальне приховування на @container (max-width: 63rem). Число - це сума, яку рядок мусить утримати з підписами всередині: 65 лого + 198 меню + 18rem підлога пошуку + 408 зона дій + чотири зазори. Поріг записаний у реєстрі «Container thresholds» файла responsive.md, і tools/bp.mjs валить прогін, якщо поріг зникне з реєстру або реєстр назве поріг, якого не несе жоден файл.

Підписи ховаються від ОКА, не від читача. display: none зняв би доступне ім'я з чотирьох контролів, у яких цей текст єдиний; п'ять оголошень кліпу лишають їх у дереві доступності. Це .vh з base.css, і файл називає утиліту, якій дорівнює, а не вдає, що винайшов форму.

Оцінка про другу половину була НЕПРАВИЛЬНА, і це записано, а не тихо виправлено. Передбачалось, що дії віддадуть 408px. Вони віддають 44: кнопки лишають при собі іконки, падінги і бейджі, тож поле йде 44 → 88 на порозі, а підписи повертаються на 1040.

Чому саме така форма (A). Три питання до навігаційної моделі етапу 03a: пунктів верхнього рівня п'ять і вони залоковані 2026-06-29 · постійного другого рівня в глобальній навігації немає (каталог це флайаут) · бічний простір на широкій ширині вже забирають рейка фільтрів на листингу і split-view тренера з кроку 5. Вертикальний рейл зліва зіткнувся б з обома, тож пункти йдуть у шапку.

Навігаційна модель тут не переглядається. Ті самі пункти, той самий порядок, ті самі стани: міняється тільки розкладка оболонки. Інші пункти на широкій ширині це правка етапу 03a, а не рішення верстки.
Стани
СтанЩо робитьЧому так
спокійsticky на var(--shell-top, 0px), z-index 30, знизу волосина --line-hair, тіні немаєпоза стендом --shell-top дорівнює 0: правило системне, число - стендове
прокручено .uiv-scrolledсмуга йде в max-height:0 і opacity:0, з'являється --elevation-bar-bottom, нижня рамка стає прозороюдва пороги замість одного: згортання забирає ~34px висоти, і з одним порогом хедер блимав би вічно. Вирішувач цього стану не бачив - сторінку читають не гортаючи
мегапанель відкрита .mega-opendisplay:grid плюс місток ::after під кнопкою заввишки 16+8клас кладе openMega(), знімає closeMega() із затримкою 140ms, щоб швидкий діагональний рух у панель її не закривав. У демо вище панель закрита, як і в спокої: її показує власний стенд «Мега-меню»
наведення :hoverпосилання смуги й мобільні знаки йдуть у --text-action; картка .ms-feat бере ще --elevation-action-hoverєдиний стан наведення, який файл оголошує
до 859бургер і .wfh-mi видно, смуга, навігація, пошук і дії - ні; скрим вимкнено жорсткона телефоні хедер це логотип, пошук і п'ять знаків - решта йде в шухляду й таб-бар
Межі

У файлі 2 медіа-умови, і кожна з них - межа, якої стандартні ширини перепису (360 / 390 / 720 / 1280) не бачать зсередини смуги. Заміряти їх треба власними ширинами, по одній з кожного боку.

Обмеження

Правила вживання, які називають саме цей компонент: U1 · U2. Автор правил один, і це architecture.html, розділ I; тут - витяг.

Одна шапка на екран, і її викликає wfHeader(), а не пише розмітка. У флоу оформлення замовлення і на службових сторінках шапки немає взагалі: заміряно 8 сірих екранів без неї, і conventions.md розділ 7 називає для оформлення спрощену шапку.

Перемикач теми 8.7

.wfh-theme - єдиний контрол мета-смуги, якого немає в розмітці жодного екрана: його малює uivThemeBtn() з design/_nav.js і ставить одразу за вибором мови. Тому знімок шапки вище його не містить - знімок зроблено з файла, а кнопка з'являється в браузері.

Кнопка показує те, що ЗРОБИТЬ, а не те, що ввімкнено: місяць означає «перейти в темну». Контрол, підписаний поточним станом, це стара половина перемикача - вона читається як «ви тут», а не як «натисніть мене».

Холостий контроль

Сторінка звіряє себе з файлом: 44 власні класи і 4 стани.

Три класи стоять у станах, а не в класах, бо всі три дописує classList у мить дії, і кожен - на шапку, а не всередині неї: .drawer-open на #wf-header, поки відкрита шухляда; .mega-open на .wfh, поки розкрито мегаменю; .wfh-menuopen на .wfh-meta, поки розкрито меню кабінету. Шапка тримає їх, щоб знати, що поверх неї щось стоїть; у спокої жодного з них не існує.

Рух

Робота: ВІДПОВІДЬ + перехід у компоненті. Рухається: колір посилань і дій, рамка й тінь шапки, згортання мета-рядка на скролі. Тривалість --dur-fast і --dur-base, крива --ease-standard. Значення читаються через var(): підміна токена в браузері веде за собою кожне з них. При prefers-reduced-motion рух зникає, а стан лишається.

Єдиний організм із двома щаблями, і це не збіг. Наведення на посилання це ВІДПОВІДЬ і бере --dur-fast. Згортання мета-рядка на скролі це перехід УСЕРЕДИНІ компонента і бере --dur-base - разом із тінню шапки, бо обидва змінюються в ту саму мить і раніше несли різні числа (.22s, .16s, .2s). max-height це РОЗКЛАДКА, перегляд на кроці 5.

Крок 4, три поверхні. Мовне меню і меню кабінету не подорожують, і це рішення з причиною: вони приклеєні до контрола, який їх відкрив, і стоять на один зазор під ним - тобто вже там, звідки прийшли; десятипіксельний стрибок на поповері такого розміру читається як ривок, а не як походження. Проявляються на --dur-base. Скрим мега-меню бере --dur-slow, бо супроводжує поверхню на всю ширину, і обидва його класи стану - .open (наведення) і .pinned (клік) - це два входи в одну поверхню, а не дві поверхні.

Токени

Прочитані з header.css: 22 семантичні ролі і 30 примітиви.

Семантичні ролі (22)Примітиви (30)
--bg-hatch --bg-inverse --bg-page --bg-sunken --bg-surface --elevation-3 --elevation-action-hover --elevation-bar-bottom --line-action --line-hair --line-inverse --line-strong --mark-faint --ring-focus --scrim-overlay --text-action --text-body --text-danger --text-muted --text-oninverse --text-primary --text-secondary--container-page --dur-base --dur-fast --dur-slow --ease-enter --ease-exit --ease-standard --font-display --fs-10 --fs-12 --fs-14 --fs-20 --fw-black --fw-bold --fw-semibold --lh-flat --lh-snug --ls-caps --ls-display --radius-12 --radius-4 --radius-8 --radius-pill --size-20 --size-44 --space-12 --space-16 --space-2 --space-4 --space-8
Що знайшов вирішувач

По всіх 95 селекторах: 15 оголошень збігаються з елементами й ніде не виграють, ще 17 не збіглися з жодним елементом. Чотири з п'ятнадцяти - це .wfh-in{ padding }: воно збігається 136 разів і програє двічі, .wfh-meta .wfh-in (68) і .wfh-main (68). У продукті .wfh-in буває рівно двох видів, і кожен переписує свій падінг сам, тож спільний рядок не діє ніде. Дев'ять - це штрихування .wfh-mega .ms-ph: кожен такий заповнювач лежить усередині .ms-feat, де колірний блок кладе на нього справжнє фото, тож смужки не малюються ніколи.

Три оголошення без жодного елемента

.wfh-meta .wfh-loc .uiv-ic:last-child svg{ width:10px; height:10px; stroke-width:2.4 } не збіглося ні з чим. У знятій розмітці .wfh-loc тримає ОДИН .uiv-ic, і він перший, а останній нащадок - .wfh-city-lbl з назвою міста. Друга половина того самого правила, про .wfh-lang, виграє: там шеврон є. Тобто одягнено знак, якого в чипі міста немає. Решта чотирнадцяти незбіглих - це стани (.open, .mega-open, .drawer-open, .uiv-scrolled), і це не мертвий код, а незаміряна поведінка: вирішувач читає сторінку в спокої.

Ще одне число варте окремого рядка. .wfh-mega{ border-top-color } зі структурного блоку збіглося 76 разів: 68 панелей хедера і 8 .hrail-fly.wfh-mega - флайаутів рейки фільтрів. Це і є доказ того, що клас кореня має трьох власників, узятий не з читання, а з браузера.

Немає в коді -> етап 09

Чого бракує

  • Згорнутий хедер не заміряно. Чотири оголошення .uiv-scrolled не збіглися ні з чим, бо сторінку читали не гортаючи. Це головна поведінка хедера, і про неї немає жодного числа
  • .wfh-in{ padding } не діє. Обидва його користувачі переписують падінг; рішення - зняти рядок або лишити його базою, сказавши це вголос
  • Шеврон міста. Правило є, знака немає: або додати другий .uiv-ic у чип, або зняти три оголошення
  • .mega-pinned і .pinned живуть лише в сірому - їх кладуть чотири сторінки wireframes/megamenu*.html, у яких немає кольорового двійника
  • Хедер є на 34 з 40 кольорових екранів, і в жодного з 42 екранів тренера кольору немає узагалі, а тренер - первинна аудиторія. Меню кабінету в ролі тренера не заміряно ніде

Не домальовано наперед і не замовчано: етап 09 стартує з цього списку, зведеного в design/kit/docs/architecture.md.