Щабель лояльності
Два незалежні механізми на одному екрані: драбина персональної знижки за суму покупок за весь час і журнал руху бонусів. Плюс значок рівня, який ходить по всьому кабінету. Найдорожча помилка етапу знайшлась саме тут: колонку залишку бонусів на телефоні неможливо було побачити.
Розмітка звідси - та сама, що на account-loyalty.html, скопійована рядок у рядок. Значок рівня ставить uivTiers() з design/_nav.js, як і на екрані.
.loy-two ставить два механізми поруч від 760 і одне під одним нижче. Вони не зливаються в одну картку навмисно: у них різні правила, і головне - сума покупок не згорає, а бонуси згорають через 3 місяці.lt, 18px дисплейною. Значок метала попереду ставить не розмітка, а обхід тексту.lbar 8px, заливка --bg-action у капсулі. Єдине місце в компоненті, де з'являється помаранчевий.ls, і числа в ньому моноширинні: суму порівнюють з сумою, а не читають як текст.ladder, три щаблі в ряд. Показані ВСІ, а не тільки наступний: людина має бачити, куди веде дорога.lrung у чотирьох станах, нижчеaccount-loyaltyaccount-empty.done, .now і .next - це людина, яка вже купувала, .next + два .locked - та, яка ще ні| Стан | Що робить | Чому так |
|---|---|---|
.done | світле тло, щільна рамка, підпис --text-success | пройдене не святкують: воно просто перестає бути питанням |
.now | рамка --line-action + смужка 2px згори всередині | єдиний акцент на драбині. Помаранчевий тут маркер поточного місця, а не дія |
.next | пунктирна рамка | пунктир каже «ще не ваше» без жодного слова і без жодного кольору |
.locked | назва щабля йде в --text-muted | для нового покупця відкритих щаблів немає, і драбина не має виглядати як помилка |
.done, .now і .next стоять на account-loyalty та account; .locked - на account-empty, де покупець ще не зробив жодного замовлення.
Головна знахідка кроку. .led-wrap ніс overflow: hidden, а таблиця журналу на телефоні ширша за обгортку.
Рух бонусів
Як нараховуються →| Дата | Операція | Бонуси | Баланс |
|---|---|---|---|
| 12.06.2026 | Нараховано за замовлення № 10432 | +23 | 124 ₴ |
| 03.06.2026 | Використано в кошику (№ 10418) | −40 | 101 ₴ |
| 21.05.2026 | Згоріли бонуси (термін дії 3 міс.) | −12 | 129 ₴ |
| 02.05.2026 | Нараховано за замовлення № 10355 | +6 | 110 ₴ |
| Ширина | Обгортка | Таблиця | Зрізано від колонки «Баланс» (87px) |
|---|---|---|---|
| 360 | 328 | 411 | видно 3px із 87 |
| 390 | 358 | 411 | видно 33 із 87 |
| 430 | 398 | 411 | видно 72 із 87 |
| 720+ | 688 | 686 | вміщується цілком |
І доскролити було неможливо - саме це робить hidden. Перевірено справжнім жестом, а не присвоєнням scrollLeft: програмна прокрутка працює і при hidden, тому та перевірка нічого не доводила. Свайп на 360 до правки: scrollLeft лишається 0, від колонки видно 3px. Після: scrollLeft 85, видно всі 87.
Змінна: як поводиться таблиця, ширша за свою обгортку. Значення: вона прокручується. Чому: інакше покупець не бачить власного залишку бонусів на пристрої, під який магазин будують у першу чергу. Візерунок не вигаданий - overflow-x: auto з прихованою смугою вже стоїть у account-shell.css, chip.css, hero.css і pdp-tabs.css.
Друга половина правки знайшлась у прийманні, а не в декларації
Шапка й виноска - діти обгортки, тож щойно обгортка поїхала, вони поїхали з нею: заголовок «Рух бонусів» опинявся на -68 і зникав з екрана рівно тоді, коли приїжджала колонка балансу. Пришпилені до лівого краю черезposition: sticky; left: 0 - лишаються на +1, а таблиця йде під ними. Рухатись мала тільки таблиця.Чого тут навмисно немає
Смуга прокрутки прихована (scrollbar-width: none), як у чотирьох інших прокрутках системи. Це означає, що єдина підказка «далі є ще» - три видимі пікселі колонки. Достатньо цього чи потрібен градієнт біля краю - питання етапу 09, і я його не вирішую вигаданою тінню.| Рядок | Що робить | Чому так |
|---|---|---|
.amt.pos | --text-bonus, найважча вага | нарахування - це те, за чим приходять у журнал |
.amt.neg | --text-secondary | списання не помилка: людина сама витратила бонуси в кошику |
tr.burn | тло --bg-bonus-soft, сума --text-warning | згоряння - єдине, що сталось без участі покупця, і єдине, що варте окремого кольору. Бонуси діють 3 місяці, і журнал це показує, а не ховає |
Дата й обидві числові колонки моноширинні: у журналі колонку читають згори вниз, порівнюючи, а не зліва направо.
Перепись каже, що чотири селектори файлу не знаходять нічого на 40 кольорових екранах. Перевірив кожен - жоден не мертвий код.
Рух бонусів
Як нараховуються →wireframes/account-loyalty-max.html і wireframes/account-loyalty-empty.html - вони існують, але лише в сірому шарі| Селектор | Кольорових екранів | Що це насправді |
|---|---|---|
.lbar.maxed i | 0 | сірий близнюк є: wireframes/account-loyalty-max.html, і _wf.css:1307 це правило має. Той самий випадок, що .tband на 7.44 |
.led-empty, .led-empty b | 0 | сірий близнюк є: wireframes/account-loyalty-empty.html, _wf.css:1325-1326 |
.uiv-tier.t0 | було 0, стало 3 | не стан, якого немає - помилка, яка його ховала. Нижче |
Значок ставить не розмітка: uivTiers() обходить текст сторінки і міняє емодзі металу на знак системи - так само, як uivCurrency() робить з гривнею. Тому значок стоїть на 14 екранах кабінету, а не тільки на трьох екранах лояльності.
Помилка, яку знайшло приймання
Обхід питавif(UIV_TIER_EMOJI[part]), а базовий рівень у таблиці має номер 0, який у JavaScript хибний. Три метали з чотирьох ставали знаком системи, а четвертий лишався сирим кольоровим емодзі - на account-empty.html, екрані, який бачить покупець до першого замовлення. Заміряно до правки: 3 сирі емодзі на сторінці, 0 значків .uiv-tier.t0. Питання виправлено на те, яке код мав ставити: if(part in UIV_TIER_EMOJI) - чи є цей емодзі в таблиці, а не чи ненульовий його рівень. Після: 0 сирих, 3 значки.Це відкрило рішення власника: «журнал бонусів належить і 7.4, і 8.7». Ця відповідь варта більше за два екрани, які вона розсудила, бо вона вирішує форму всього додатку. table.led, .led-wrap, .led-head і .led-note тут ПЕРЕВИКОРИСТАНІ байт у байт - публічна сторінка показує той самий журнал, що й кабінет - а цей блок додає лише те, чого в кабінеті справді немає.
Що зміряно, перш ніж написано правило, і це більша частина екрана. Сірий блок вузла 8.7 оголошує .loy-mechs, .loy-card, .loy-tbl, .loy-faq, .loy-q, .loy-h2, .loy-qmark і десять імен me-*. Прочитані проти кольорового вузла 7.4, усі вони вже існують під іншими іменами: .loy-two - це сітка двох механізмів, .acard + .ah + .mech-kicker - картка механізму, .loy-tbl - це table.led, .loy-q - це .qaitem, .loy-h2 - це section-head, .loy-qmark - це .qmark з base.css, а вся родина me-* - це .lt + .lbar + .ls поруч із .big + .u + .warn. Опублікувати їх означало б записати ті самі десять рішень удруге під новими іменами.
Тому додано три речі й більше нічого: герой лендинга (кабінет нікому не представляється), драбина РЯДКАМИ і персональна смуга, яка є КОРОБКОЮ навколо вже наявних частин.
Знижка, яка не згорає, і бонуси, які повертаються
Два незалежні механізми: персональна знижка за суму покупок за весь час і бонусний рахунок з нарахуванням близько [?]1% з кожного замовлення.
Персональна смуга несе class="loy loy-me" навмисне: усе всередині неї - це власні .lt, .lbar і .ls обсягу .loy, а коробка додає край і другу колонку. Розділ на 620, не на 760 чи 800 із сірих блоків: жодне з тих чисел не стоїть у реєстрі точок, а bp.mjs валить прогін на третій.
Пороги в демо - [?]. 5 000 / 15 000 / 30 000 і три відсотки не мають джерела в даних; рішення 3 в CLAUDE.md тримає їх відкритими, і мітка каже це вголос замість того, щоб число тихо стало правдою.
Драбина - в кабінеті: на огляді й на сторінці лояльності. Журнал - тільки там, де є бонуси, тобто на сторінці лояльності. Значок рівня - будь-де, де названо метал, і ставить його обхід, а не автор сторінки.
Два механізми не змішуються. Знижка за суму покупок за весь час не згорає ніколи; бонуси згорають через 3 місяці. Це різні речі з різними правилами, тому в них дві картки, а не одна з двома числами.
Правило
Показуй усю драбину, включно з тим, що вже пройдено. Щабель має сенс лише в ряду інших: «−5%» саме по собі не число, а «−3% · −5% · −8%» це дорога.Антиправило
Не роби з лояльності гру. Ні відліку до згоряння, ні святкування переходу, ні бейджів. Принцип 4: серйозно для тих, хто ставиться серйозно. Згоряння бонусів названо прямо і один раз.Сторінка звіряє себе з файлом: 19 власних класів і 9 станів оголошено в loyalty-rung.css. Нижче - ті, яких на цій сторінці немає ні в демо, ні в розмітці.
ПОВЕДІНКА НА ШИРИНІ - етап 10, крок 4
Від якого порогу: жодного - запит зник. Було@media (min-width: 760px), числа немає в реєстрі. Що саме міняється: пара карток лояльності стає поруч, коли для кожної є --grid-col-min-panel (19rem), через auto-fit. Карток дві, тож auto-fit тут точний, а не приблизний: третьої розкладки він вигадати не може. Підлога спершу була 22rem і це було зміряно неправильно - вона сходилась із запитом на 360 і на 1280 і розходилась між ними, бо кабінет бере собі колонку навігації на 960 і лишає сітці 628px.Робота: ВІДПОВІДЬ. Рухається: колір посилання в журналі. Тривалість --dur-fast (150ms), крива --ease-standard. Значення читаються через var(): підміна токена в браузері веде за собою кожне з них, тобто числа у файлі немає. При prefers-reduced-motion рух зникає, а стан лишається.
Прочитані з loyalty-rung.css, не переписані руками: 20 семантичних ролей і 22 примітиви.
| Семантичні ролі (20) | Примітиви (29) |
|---|---|
--bg-action --bg-bonus-soft --bg-inverse --bg-page --bg-sunken --bg-surface --elevation-1 --line-action --line-hair --line-strong --mark-tier-bronze --mark-tier-silver --text-action --text-body --text-bonus --text-muted --text-primary --text-secondary --text-success --text-warning | --container-text --dur-fast --ease-standard --font-body --font-display --font-mono --fs-12 --fs-14 --fs-16 --fs-18 --fs-20 --fw-black --fw-bold --fw-semibold --grid-col-min-panel --lh-airy --ls-caps --radius-12 --radius-16 --radius-8 --radius-pill --size-26 --space-12 --space-16 --space-2 --space-24 --space-32 --space-4 --space-8 |
Два метали лояльності стали ролями. До кроку 7 етапу 08 файл читав примітиви --brown-600 і --slate-400 напряму, і це було єдине таке місце в компоненті: дві з чотирьох міток рангу не йшли за темою, поки дві сусідні (t0 на --text-muted, t3 на --text-action) йшли. Тепер там --mark-tier-bronze і --mark-tier-silver, а значення лишилися ті самі: мітка це гліф, а не текст, її межа 3:1, і обидві її проходять в обох темах - бронза 4.66 у світлій і 3.87 у темній, срібло 3.86 і 4.67. Метал упізнають за власною світлістю, тож підганяти темну редакцію під світлу означало б перестати бути сріблом.
Ширина смуги стоїть у style прямо в розмітці, бо це дані, а не оформлення: 62% це стан рахунку, і в CSS йому місця немає. Так само працює прогрес у кошику.
Якорі: .loy .led-wrap .uiv-tier
Заміряно в браузері на 360, 390, 720 і 1280 по всіх 40 кольорових екранах: драбина 3 рази (account, account-loyalty, account-empty), журнал 1 раз (account-loyalty, 6 рядків, з них один .burn), значок рівня - на 14 екранах кабінету й чекауту.
Мертвих селекторів: 0 з 49. Чотири не знаходять розмітки, і жоден з них не є зайвим кодом - три чекають кольорового близнюка, четвертий чекав виправлення помилки.
Чого бракує
- Двох кольорових екранів. «Максимальний рівень» і «порожній журнал» існують у сірому шарі й не мають кольорових двійників. Це не рішення про значення, це робота, яку видно й досі не зроблено
- Підказки, що таблиця прокручується. Смуга прихована, і єдиний сигнал - три видимі пікселі колонки
- Усі числа тут
[?]: пороги драбини, відсотки знижки, ставка нарахування, 3 місяці до згоряння. Так і має бути до реальних даних, і стенд називає це вголос, а не малює правдоподібне - Немає стану «бонуси згорять днями» у самій драбині - попередження живе в сусідній картці
.abonus, а щабель про це не знає
Не домальовано наперед і не замовчано: етап 09 стартує з цього списку, зведеного в design/kit/docs/architecture.md.