Галерея
Головне фото товару й чотири мініатюри під ним. Найвізуальніший компонент продукту й водночас найтихіший: банка стоїть у світлі, а не на білому, і нічого більше на цьому місці не відбувається.
Розмітка звідси - та сама, що на product.html.
_nav.js лише всередині .pdp, і це саме та межа, яку цей крок знайшовaspect-ratio: 1, радіус 16, найбільший у системі. Всередині два градієнти: тінь під банкою знизу й дуже світлий вертикальний схилobject-fit: contain і padding: 9%, тож банка не торкається країв. mix-blend-mode: multiply садить її на підкладку без білого прямокутника довкола.gtag, чорна пігулка з зіркою через ::before. Абсолютна, 12 від лівого верхнього кута. Дві на весь продукт--line-action, наведення піднімає на 2px. Це єдиний рух у компоненті.pminiПоловина файлу була не галереєю. .pmini - це липка панель на сторінці відгуків, яка тримає товар перед очима, поки ви читаєте чужі думки.
| Що | Скільки | Де |
|---|---|---|
.pmini та її правила | 9 правил, 1 екземпляр | product-reviews.html |
з них перекладають .pcard | 5 із 9 | .pcard - 99 екземплярів на 17 екранах |
Обгортка, яка існує щоб розмістити картку, це справа картки. Поїхало в product-card.css цілком - та сама форма, що .packlabel на 7.43 і .wfh-logo на 7.50: файл, у якому щось лежить, не є компонентом, яким воно є.
Крок 7.55 прочитав це невірно, і 7.57 його виправив
Я побачив два блоки з однією умовою й назвав це здвоєним блоком - поламкою 7.46. Звів у один і видаливtop: 120px, бо виграє 88.
Читання було хибне. Перший блок стояв у секції структури, другий - у секції кольору. Це поділ етапу 08, який несе кожен файл системи, і про який заголовок кожного файлу каже вголос: «кольоровий блок нижче - той, що виграє, рівно так, як два стилевих листи стояли один на одному до поділу». Повторення тут - це запис поділу, а не випадковість. Обидва видання повернуті, у своєму порядку. Коштує це нічого: 88 виграє так само, як виграв до 7.55 і після.Що з цього лишилось правдою: .pmini справді не галерея й справді поїхав у product-card.css. І вирішувач справді складав вердикти під ключем, що зливав два правила в одне - це виправлення теж лишається, воно окреме й корисне.
А потім статичний скан порахував усі такі пари в системі. Їх 74, і жодна з них не є поламкою:
| Що це | Скільки | Чи поламка |
|---|---|---|
| груповане правило, а потім правило для одного з його імен | 32 | ні - база й перекриття |
| секція структури, а потім секція кольору | 22 | ні - поділ етапу 08, навмисне |
| те саме значення написане двічі | 19 | мертве, але нічого не втрачається |
| жодне з переліченого | 1 | ця сторінка, і вона моя: обидва видання .pmini тепер лежать в одній секції чужого файлу |
Тобто здвоєних медіа-блоків у системі немає жодного. Вісім «мертвих оголошень у трьох файлах», які я записав на 7.56 для auth-dialog, pdp-tabs і product-grid, - усі до одного той самий поділ структури й кольору. Скан бачив форму й не бачив причини; причину видно тільки читанням файлу.
.skpulse - клас скелета зі skeleton.css; цей файл дає йому лише ґрунт: --bg-sunken замість градієнтів, бо порожня рамка не має вдавати, що в ній щось стоїть| Що | Як приглушено | Чому не однаково |
|---|---|---|
| велике фото | filter: grayscale(.75) + opacity: .85 | це справжній img, фільтр на ньому нічого більше не зачіпає |
| мініатюри | background-blend-mode: luminosity | фото тут фон, і фільтр висушив би разом із ним помаранчеве кільце обраної |
Обидві половини приїхали в цей файл: друга стоїть тут із кроку 3, першу 7.53 забрав із restock-note.css. Одне рішення - товар знебарвлюють, а не гасять - було написане у двох файлах, і той, хто змінив би одну половину, не побачив би другої.
Чому не сірий прямокутник
Знебарвлення на 75%, а не на 100, і прозорість 85, а не 50. Товар має лишитись упізнаваним: людина прийшла по конкретну банку і мусить бачити, що це вона. Чесно, а не драматично -voice.md 5.Вирішувач каже: чотири оголошення файлу не виграють ніде.
| Оголошення | Збігів | Хто виграє |
|---|---|---|
.gal .gthumb{ background-image } | 32 | inline ×24 · .gthumb.skpulse ×8 |
{ background-position-x } · -y | 32 | те саме |
{ background-size } | 32 | те саме |
design/_nav.js:918 ставить кожній мініатюрі style.backgroundImage, backgroundSize і backgroundPosition - чотири різні кадри одного знімка, кожен зі своїм масштабом і зсувом. Css такого знати не може.
Не видаляю
background: var(--bg-page) center/74% no-repeat віддає п'ять значень, і js перебиває три. Два, що лишаються - колір ґрунту й no-repeat - виграють завжди. А center/74% це запас: те, як мініатюра виглядає, якщо скрипт не відпрацював. Та сама причина, з якої 7.49 лишив .emptybox без .mini, а 7.48 - .led-empty.Шостий стан заведено на 8.16, і до нього рамка товару без знімка була порожнім квадратом із тінню під ним. Ось він живий:
Фото готуємо
.loadnote з empty-state.css - той самий атом, що несе «Завантажуємо товар…» на трьох екранах завантаження, і той самий час дієслова. Цей файл додає рівно одне оголошення - ґрунт: градієнти малюють предмет, що стоїть у світлі, а коли предмета немає, тінь падає від нічого. Слова й колір слів приносить сам атом| Стан | Що робить | Чому так |
|---|---|---|
| спокій | банка в рамці, чотири мініатюри під нею | жодного руху: фото товару це факт, а не запрошення |
| обрана мініатюра | .on: рамка 2px --line-action замість 1px волосини | єдине помаранчеве в компоненті, і воно означає «ви дивитесь на це» |
| наведення на мініатюру | підйом на 2px, перехід 150ms | найменший рух, який видно. Курсор є тільки на десктопі, тож на телефоні стану немає взагалі |
| завантаження | .skpulse: рамка й мініатюри стають --bg-sunken | градієнти зняті: порожня рамка не вдає, що в ній щось стоїть |
| немає в наявності | .oosgal: фото знебарвлене, мініатюри злиті по яскравості | дві техніки, бо одна з них висушила б помаранчеве кільце |
| фото немає 8.16 | :has(.loadnote): градієнти зняті, у рамці один рядок «Фото готуємо» | у кольорі плейсхолдер «фото товару» не блідий, а невидимий - рамка має font-size: 0. Слова ставить атом, файл додає лише ґрунт |
| до 859 / від 860 | ширина min(100%, 430px) / 540px, мініатюри по центру на вузькому | на телефоні галерея - весь екран, на десктопі вона половина сітки й не має розповзатись |
Правило
Банка стоїть у світлі, а не на білому. Два градієнти йmultiply дають тінь під дном і теплий схил згори. Товар за 2 000 грн на голому білому виглядає як картинка з прайсу, а не як річ, яку можна взяти в руки.Антиправило
Не став на галерею більше однієї мітки..gtag - дві на весь продукт. Три значки в кутку фото перетворюють товар на вітрину розпродажу, а принцип 4 каже: спокійно й упевнено, без терміновості.Сторінка звіряє себе з файлом: 8 власних класів і 6 станів оголошено в gallery.css. Власних класів після 8.16 так само вісім: стан «фото немає» питає :has(.loadnote), тобто чужий клас усередині свого, і жодного нового імені в розмітку не заводить.
ПОВЕДІНКА НА ШИРИНІ - етап 10, крок 4
Від якого порогу:--bp-shell-wide, парою 859/860. Що саме міняється: нижче точки галерея тримається в min(100%, 430px) і центрує мініатюри, від точки розтягується до 540 і центрується сама. Обидва числа вже стояли на реєстрі; раунд молекул нічого не складав.Робота: ВІДПОВІДЬ. Рухається: збільшення головного фото і рамка мініатюри. Тривалість --dur-fast (150ms), крива --ease-standard. Значення читаються через var(): підміна токена в браузері веде за собою кожне з них, тобто числа у файлі немає. При prefers-reduced-motion рух зникає, а стан лишається.
.25s на фото згорнулось у швидкий щабель: наведення на фото і наведення на мініатюру це одна робота.
Прочитані з gallery.css: 12 семантичних ролей і 10 примітивів.
| Семантичні ролі (12) | Примітиви (10) |
|---|---|
--bg-photo --bg-photo-far --bg-photo-mark --bg-sunken --elevation-mark --fade-photo --line-action --line-hair --mark-faint --shadow-floor --text-action --text-photo-mark | --fs-10 --fw-black --lh-flat --ls-caps --radius-8 --radius-16 --radius-pill --space-4 --space-8 --space-12 |
| – | --dur-fast --ease-standard |
Повз шкалу: 70px (мініатюра - не щабель драбини розмірів), 12px двічі на позицію мітки, 9% і 74% (поля фото й масштаб кадру), 540px і 430px (дві максимальні ширини), 2px підйому, і п'ять відсотків усередині радіального градієнта. Це найбільш «відсотковий» файл системи, і по-іншому фото в рамці не поставити.
Три проходи по 40 екранах на чотирьох ширинах: HEAD, HEAD ще раз і робоче дерево. Нульовий прохід 0, різниця 0.
Дев'ять правил переїхали на 5 імпортів пізніше, здвоєний медіа-блок звівся в один, мертве top: 120px видалено - і жоден екран не намалювався інакше. Заміряно й напряму: .pmini до і після має ті самі position: sticky, top: 88px, ту саму сітку 116px 210px на 360 і той самий колір посилання.
Файл був п'ять медіа-блоків, став два. Одна точка перелому 860 була написана чотирма способами - з пробілом і без, у чотирьох місцях. Тепер її дві, і обидві однакові.
Чого бракує
- Точка перелому 860 повз набір 480 / 720 / 1180. Сьома в списку, разом із 419, 559, 620, 640, 820 і 859
- Два способи сказати «квадрат» в одному файлі:
aspect-ratio: 1у рамці й70px×70pxу мініатюрі - Колір рамки названо двічі тим самим токеном -
border: 1px solid --line-hairу структурі йborder-color: --line-hairу кольорі. Так побудовано весь поділ етапу 08, тож це рішення про угоду, а не про цей файл - Мініатюри не мають фокуса з клавіатури -
_nav.jsдає їмrole="button"іaria-label, але неtabindex, тож перемкнути кадр можна лише мишею
Не домальовано наперед і не замовчано: етап 09 стартує з цього списку, зведеного в design/kit/docs/architecture.md.