/* Mini App в стиле бренд-бука Shafaatti Clothes (артефакт «Shafaatti Clothes — бренд-бук», v1.0):
   палитра из магазина — Графит, Молоко, Дуб, Песок, Пудра и Гранат (один акцент на экран: кнопка);
   заголовки, цены и подписи — Unbounded, текст — Manrope. Светлая тема всегда: так требует пропорция
   бренда 60 % светлого, а шапку и фон Telegram страница перекрашивает в Молоко сама (app.js).
   Панель со штрихкодом — Молоко с графитовыми полосами: на тёмном сканер код не читает. */
/* Шрифты свои, с версией Google Fonts в имени файла (кэш на год). Переменные: один файл на все начертания.
   unicode-range — из CSS Google слово в слово. cyrillic-ext взят по плану, но Қ, Ғ, Ҳ нет ни в Manrope, ни в Unbounded:
   для узбекской кириллицы браузер возьмёт системный шрифт. UZ-тексты сейчас латиницей (апостроф ‘ U+2018 — в latin).
   Лицензия — fonts/OFL.txt */
@font-face { font-family: 'Manrope'; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url(fonts/manrope-v23-cyrillic-ext.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; }
@font-face { font-family: 'Manrope'; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url(fonts/manrope-v23-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: 'Manrope'; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url(fonts/manrope-v23-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Manrope'; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url(fonts/manrope-v23-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Unbounded'; font-style: normal; font-weight: 500 600; font-display: swap;
  src: url(fonts/unbounded-v12-cyrillic-ext.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; }
@font-face { font-family: 'Unbounded'; font-style: normal; font-weight: 500 600; font-display: swap;
  src: url(fonts/unbounded-v12-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: 'Unbounded'; font-style: normal; font-weight: 500 600; font-display: swap;
  src: url(fonts/unbounded-v12-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Unbounded'; font-style: normal; font-weight: 500 600; font-display: swap;
  src: url(fonts/unbounded-v12-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

:root {
  --graphite: #1A1A1B;
  --milk: #F6F2EC;
  --oak: #A0825C;
  --sand: #E3D5BF;
  --powder: #EFD9D2;
  --garnet: #9E2B3A;
  --ink-2: #3A3734;       /* вторичный текст на светлом — из бренд-бука */
  --ink-3: #6B6560;       /* подписи на светлом */
  --line: #D6CCBD;        /* линии, листы, таббар */
  --field-line: #8C8379;  /* рамка поля ввода: 3,72:1 к белому, 3,34:1 к Молоку (WCAG 1.4.11 — от 3:1) */
  --on-dark-2: #CFC7BC;   /* вторичный текст на Графите */
  --white: #FFFFFF;       /* поля ввода — «белая бумага» */
  --radius: 4px;          /* в бренде прямые углы — здесь чуть смягчены под палец */
  --heading: "Unbounded", "Manrope", system-ui, sans-serif;
  --text: "Manrope", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --safe-top: var(--tg-content-safe-area-inset-top, 0px);
  --safe-bottom: var(--tg-safe-area-inset-bottom, env(safe-area-inset-bottom, 0px));
  color-scheme: light;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--milk); color: var(--graphite); min-height: 100vh;
  font: 16px/1.5 var(--text); -webkit-font-smoothing: antialiased; overscroll-behavior: none;
}
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
/* без !important блок с display: flex (.sheet-actions) атрибутом hidden не скрывается */
[hidden] { display: none !important; }
/* текст только для диктора (#live в index.html) */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* заголовки экранов — якорь фокуса после смены вкладки, рамка им не нужна */
[tabindex='-1']:focus { outline: none; }
input { font: inherit; color: inherit; }

.app {
  max-width: 460px; margin: 0 auto; min-height: 100vh; display: flex; flex-direction: column;
  padding: calc(14px + var(--safe-top)) 16px calc(20px + var(--safe-bottom));
}

/* подписи — капителью с разрядкой 0.2em, как в бренд-буке */
.caption { font: 500 11px/1.4 var(--heading); letter-spacing: 0.2em; text-transform: uppercase; }

/* логотип: по бренд-буку не уже 120 px на экране; охранное поле — около трети высоты знака */
.logo { display: block; width: 136px; height: 32.3px; flex: none; }   /* высота задана: место под знак не прыгает */
.top { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 48px; padding: 2px 0; }
/* цели касания — 44×44 с зазором (iOS 44 pt, Android 48 dp); шрифт 11 px — в пределах 11–12 px бренд-бука */
.langs { display: flex; flex: none; gap: 4px; }
.langs button { font: 500 11px/1 var(--heading); letter-spacing: 0.16em; padding: 0 10px; min-width: 44px; min-height: 44px; color: var(--ink-3); }
.langs button.on { color: var(--graphite); box-shadow: inset 0 -2px 0 var(--graphite); }

.center.loading { gap: 28px; }
.center.loading .logo { width: 168px; height: 39.9px; }
.center { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 48px 8px; gap: 14px; }
.spinner {
  width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--line); border-top-color: var(--graphite);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 2.4s; } }
.message { color: var(--ink-2); margin: 0; }

/* регистрация */
.join { flex: 1; display: flex; flex-direction: column; }
.join-body { flex: 1; display: flex; flex-direction: column; padding: 20px 0 20px; }
h1 { font: 600 28px/1.15 var(--heading); letter-spacing: -0.01em; margin: 0; text-wrap: balance; }
.rule { width: 40px; height: 2px; background: var(--oak); margin: 18px 0 16px; }
.lead { color: var(--ink-2); margin: 0; }
.fields { display: flex; flex-direction: column; gap: 14px; margin-top: 18px; }
/* только подпись поля: span ошибки и даты словами — без жирного */
.field > label { display: block; }
.field > .field-label { display: block; font-size: 14px; font-weight: 600; margin-bottom: 6px; }
/* пол на регистрации: переключатель во всю ширину, подписи — текстом поля, не капителью */
.segmented.gender { width: 100%; }
.segmented.gender button { flex: 1 1 0; min-height: 48px; font: 500 16px/1.2 var(--text); letter-spacing: 0; }
.segmented.gender button:disabled { opacity: .6; cursor: default; }
label.field > span, .field > label > span { display: block; font-size: 14px; font-weight: 600; margin-bottom: 6px; }
.field input, .row input {
  display: block; width: 100%; min-height: 48px; padding: 10px 12px; border: 1px solid var(--field-line); border-radius: var(--radius);
  background: var(--white); font-size: 16px;   /* 16px: iOS не увеличивает страницу при вводе */
}
.field input::placeholder, .row input::placeholder { color: var(--ink-3); opacity: 1; }
/* фокус и ошибка — 2 px Графита; Гранатом рамку не красим: он один на экране, у кнопки */
.field input:focus, .row input:focus, .field input[aria-invalid='true'], .row input[aria-invalid='true'] {
  outline: none; border-color: var(--graphite); box-shadow: 0 0 0 1px var(--graphite);
}
/* дата словами под полем: место держится всегда, чтобы кнопка не прыгала */
.date-echo { display: block; min-height: 21px; margin: 6px 2px 0; font-size: 13px; line-height: 1.5; color: var(--ink-3); }
.field .date-echo { font-weight: 400; margin-bottom: 0; }
.date-echo b { color: var(--graphite); font-weight: 600; }
.field input:disabled, .row input:disabled { opacity: 0.6; }

.cta {
  display: block; width: 100%; min-height: 54px; padding: 16px; border-radius: var(--radius);
  background: var(--garnet); color: var(--milk); font: 500 13px/1.2 var(--heading); letter-spacing: 0.14em; text-transform: uppercase;
}
.cta:disabled { opacity: 1; cursor: progress; }   /* «Оформляем…» читается: Молоко на Гранате, без бледности */
.cta[aria-busy='true'] { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 16px 12px; }
/* надпись занятой кнопки — в одну строку и мельче: кнопка не растёт и не прыгает (на 320 px «KARTA TAYYORLANMOQDA…»
   при 13 px и 0.14em переносилась). Не влезет при крупном системном шрифте — обрежется многоточием, высота та же */
.cta[aria-busy='true'] span:not(.spinner) { min-width: 0; font-size: 12px; letter-spacing: 0.08em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cta .spinner { flex: none; width: 16px; height: 16px; border-color: rgba(246,242,236,.4); border-top-color: var(--milk); }
.cta:focus-visible, .ghost:focus-visible, .langs button:focus-visible, .segmented button:focus-visible { outline: 2px solid var(--graphite); outline-offset: 2px; }
/* у .segmented overflow: hidden — рамка внутрь, на тёмной кнопке — Молоком */
.segmented button:focus-visible { outline-offset: -4px; }
.segmented button.on:focus-visible { outline-color: var(--milk); }
/* отклик на нажатие: подсветку касания убирает -webkit-tap-highlight-color, вместо неё — :active (app.js: touchstart) */
.cta:active:not(:disabled), .ghost:active:not(:disabled), .segmented button.on:active { opacity: .85; }
.tab:active, .langs button:active { color: var(--graphite); }
.segmented button:active:not(.on) { background: var(--sand); }
.check summary:active { background: rgba(26,26,27,.05); }
.consent { color: var(--ink-3); font-size: 12px; line-height: 1.45; margin: 0 2px 12px; }
/* при нативной MainButton: чего ждём — строкой Графитом, без второго пятна Граната */
/* приветственный бонус: на регистрации и под картой — Пудрой, как подсказки, без Граната */
.welcome-note { margin: 16px 0 0; padding: 12px 16px; background: var(--powder); border-radius: var(--radius); font-size: 14px; font-weight: 500; line-height: 1.45; }
.join .welcome-note { margin: 18px 0 0; }
.sheet.admin .segmented { flex: none; }
.admin-status { margin-right: auto; min-width: 0; }
/* коды продавцов: строка — код и чей, справа QR и «Удалить»; QR раскрывается под строкой */
.code-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.code-main { flex: 1 1 140px; min-width: 0; display: flex; flex-direction: column; }
.code-name { font: 600 15px/1.3 var(--heading); letter-spacing: .04em; overflow-wrap: anywhere; }
.code-meta { color: var(--ink-3); font-size: 13px; overflow-wrap: anywhere; }
.code-actions { display: flex; gap: 8px; flex: none; }
.code-seller { display: block; margin-top: 6px; }
.code-seller select { display: block; width: 100%; min-height: 44px; margin-top: 2px; padding: 8px 10px; border: 1px solid var(--field-line);
  border-radius: var(--radius); background: var(--white); font: inherit; font-size: 15px; color: var(--graphite); }
.ghost.small { min-height: 44px; padding: 8px 12px; font-size: 11px; }
.ghost.quiet { background: transparent; color: var(--graphite); box-shadow: inset 0 0 0 1px var(--graphite); }
.code-qr { flex: 1 1 100%; text-align: center; padding: 4px 0; }
.code-qr svg { display: block; width: 200px; height: 200px; margin: 0 auto 6px; background: var(--white); }
.code-link { margin: 0 0 10px; font-size: 12px; color: var(--ink-2); overflow-wrap: anywhere; }
.sheet.codes .fields.tight { margin-top: 14px; }
.field select { display: block; width: 100%; min-height: 48px; padding: 10px 12px; border: 1px solid var(--field-line);
  border-radius: var(--radius); background: var(--white); font: inherit; font-size: 16px; color: var(--graphite); }
.field select:focus { outline: none; border-color: var(--graphite); box-shadow: 0 0 0 1px var(--graphite); }
.admin-status .error { margin: 0; }
/* экран «Подпишитесь»: ссылки на канал и Instagram — листом, как соцсети на «Магазинах»; кнопка проверки — внизу */
.subscribe .sheet.stores { margin: 22px 0 0; }
.subscribe .error { margin: 14px 0 0; }
.join-status { display: flex; align-items: center; gap: 10px; margin: 14px 2px 0; color: var(--ink-2); font-size: 14px; line-height: 1.45; }
.join-status .spinner { flex: none; width: 16px; height: 16px; }
/* низкий экран (320×640 и меньше, в Telegram ещё минус его шапка): плотнее, чтобы согласие и кнопка были на первом экране */
@media (max-height: 700px) {
  .join-body { padding: 8px 0 10px; }
  .join h1 { font-size: 24px; }
  .join .rule { margin: 10px 0 12px; }
  .join .fields { margin-top: 14px; gap: 8px; }
  .join .field > label > span, .join .field > .field-label { margin-bottom: 4px; }
  .join .consent { margin-bottom: 10px; }
}
/* ошибка — плашка Пудры с графитовым текстом (12,86:1), не Гранат: второго красного пятна у кнопки нет */
.error {
  display: flex; gap: 8px; align-items: flex-start; margin: 0 0 12px; padding: 10px 12px; border-radius: var(--radius);
  background: var(--powder); color: var(--graphite); font-size: 14px; font-weight: 500; line-height: 1.45;
}
.error svg { flex: none; width: 18px; height: 18px; margin-top: 1px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.field .error { margin: 6px 0 0; }
.join-body > .error { margin: 14px 0 0; }

/* карта */
.member { background: var(--graphite); color: var(--milk); border-radius: var(--radius); padding: 20px 20px 18px; margin-top: 14px; }
/* подпись рядом с логотипом («КАРТА КЛУБА», «KLUB KARTASI») переносится по словам, а если не влезает (узкий экран,
   крупный системный шрифт), уходит на вторую строку к правому краю. flex-basis 0: перенос строки решает ширина самого длинного слова, а не всей подписи. Логотип не сжимаем */
.member-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 16px; color: var(--on-dark-2); padding: 4px 0 6px; }
.member-top .caption { flex: 1 1 0; margin-left: auto; text-align: right; }
.member-name { font: 500 19px/1.25 var(--heading); margin-top: 20px; overflow-wrap: anywhere; }
.balance { margin-top: 18px; }
.balance-label { color: var(--on-dark-2); }
.balance-value { font: 600 clamp(28px, 9.5vw, 34px)/1.1 var(--heading); letter-spacing: -0.02em; margin-top: 6px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.balance-value small { font: 500 15px var(--text); letter-spacing: 0; color: var(--on-dark-2); }
.balance-until { color: var(--on-dark-2); font-size: 13px; margin-top: 4px; }
.balance-until + .balance-until { margin-top: 0; }
/* бонусы скоро сгорят: единственное пятно Граната на главной (кнопки .cta там нет). Молоко на Гранате — 6,6:1 */
.expiring {
  display: inline-block; margin-top: 8px; padding: 4px 8px; border-radius: var(--radius);
  background: var(--garnet); color: var(--milk); font: 600 13px/1.4 var(--text);
}
.barcode { margin-top: 18px; background: var(--milk); color: var(--graphite); border-radius: var(--radius); padding: 14px 10px 10px; text-align: center; }
.barcode svg { display: block; width: 100%; height: 84px; }
.barcode-code { font-size: 15px; letter-spacing: 0.2em; font-variant-numeric: tabular-nums; margin-top: 8px; }
/* номер группами 1+4+4+4: промежутки — gap, не пробелы, разрядка 0.2em перекрыта своей */
/* промежутки — полями, не flex: в inline-flex Chrome копирует группы через переводы строк */
.card-no { display: inline; white-space: nowrap; font-variant-numeric: tabular-nums; }
.card-no span + span { margin-left: .45em; }
.barcode .card-no { font: 600 18px/1.3 var(--text); letter-spacing: .04em; color: var(--graphite); }
/* карта готовится или её нет: высота как у панели со штрихкодом (поля 24 + код 84 + 8 + строка номера ≈ 24,5 по замеру),
   чтобы карта не прыгнула, когда придёт код */
.barcode.pending {
  min-height: 140.5px; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 14px 16px;
}
.barcode.pending .spinner { margin: 0 auto; }
.barcode-note { font: 400 15px/1.4 var(--text); letter-spacing: 0; margin: 0; }
.scan-hint { text-align: center; color: var(--ink-3); font-size: 14px; margin: 12px 0 0; }
/* «Баланс на 14:32» — под картой: внутри неё строка сдвинула бы штрихкод */
.balance-at { text-align: center; color: var(--ink-3); font-size: 13px; margin: 12px 0 0; }
.scan-hint + .balance-at { margin-top: 2px; }

.row { display: flex; gap: 8px; }
.row input { flex: 1; min-width: 0; }
.ghost {
  min-height: 48px; padding: 10px 16px; border-radius: var(--radius); background: var(--graphite); color: var(--milk);
  font: 500 12px/1 var(--heading); letter-spacing: 0.12em; text-transform: uppercase;
}
.ghost:disabled { opacity: 0.6; cursor: default; }

/* мои покупки — плашки цвета Песок, как ценники */
.section-title { color: var(--oak); margin: 26px 2px 10px; }
.empty { color: var(--ink-3); margin: 0 2px; }
.checks { background: var(--sand); border-radius: var(--radius); overflow: hidden; }
/* разделитель темнее общего --line: на Песке тот даёт 1,10:1, этот — около 1,4:1 */
.check + .check { border-top: 1px solid rgba(26,26,27,.16); }
/* строка чека: что куплено (2 строки), сумма и шеврон — видно, что раскрывается; под ними на всю ширину
   «метка дата · магазин» */
.check summary {
  display: grid; grid-template-columns: minmax(0, 1fr) auto 18px; column-gap: 10px; row-gap: 2px; align-items: center;
  min-height: 60px; padding: 10px 12px 10px 16px; cursor: pointer; list-style: none;
}
.check summary::-webkit-details-marker { display: none; }
.check summary:focus-visible { outline: 2px solid var(--graphite); outline-offset: -2px; }
.check-title { grid-area: 1 / 1; min-width: 0; display: flex; flex-direction: column; }
/* обрезается только название: «и ещё N» отдельной строкой ниже */
.check-name {
  font: 600 16px/1.35 var(--text); overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.check-more { color: var(--ink-2); font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.check-meta {
  grid-column: 1 / -1; grid-row: 2; min-width: 0; display: flex; align-items: center;
  color: var(--ink-2); font-size: 13px; white-space: nowrap; font-variant-numeric: tabular-nums;
}
.check-date { flex: none; }
.check-shop { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* тип чека — графитовой рамкой: Пудра на Песке почти не видна (1,07:1), а Гранат — только у кнопки */
.kind-tag {
  flex: none; padding: 0 6px; margin-right: 6px; border: 1px solid var(--graphite); border-radius: var(--radius);
  font: 500 12px/1.5 var(--heading); letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; color: var(--graphite);
}
.check-end { grid-area: 1 / 2; display: flex; flex-direction: column; align-items: flex-end; }
.check-total { font: 600 15px/1.2 var(--heading); white-space: nowrap; font-variant-numeric: tabular-nums; }
.check-total.muted { color: var(--ink-2); }
/* бонусы по чеку — под суммой, без Граната и Дуба; длинное «оплачено бонусами …» переносится, а не съедает название */
.check-bonus { font: 400 13px/1.35 var(--text); color: var(--ink-2); font-variant-numeric: tabular-nums; text-align: right; max-width: 10.5em; margin-top: 2px; }
.check .chev { grid-area: 1 / 3; }
.chev { flex: none; width: 18px; height: 18px; fill: none; stroke: var(--ink-3); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.check[open] .chev, .rules[open] .chev { transform: rotate(180deg); }
@media (prefers-reduced-motion: no-preference) { .chev { transition: transform .15s; } }
.items { list-style: none; margin: 0; padding: 0 16px 12px; font-size: 14px; color: var(--ink-2); }
.items li { display: flex; gap: 10px; padding: 5px 0; align-items: baseline; }
.item-name { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.item-qty { white-space: nowrap; }
.item-sum { white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 5.2em; text-align: right; color: var(--graphite); }
/* номер и штрихкод чека — на Молоке, как штрихкод карты: на Песке полосам не хватает контраста для сканера */
.receipt { margin: 0 16px 14px; padding: 10px 12px; background: var(--milk); border-radius: var(--radius); text-align: center; }
.receipt-no { color: var(--ink-2); font-size: 14px; }
.receipt-no b { font-weight: 600; color: var(--graphite); }
.receipt svg { display: block; width: 100%; max-width: 300px; height: 56px; margin: 8px auto 0; }
.receipt-hint { margin: 6px 0 0; color: var(--ink-3); font-size: 12px; line-height: 1.4; }
/* узкий экран: название на всю ширину, «1 шт · 689 000» — строкой ниже, справа */
@media (max-width: 359px) {
  .items li { flex-wrap: wrap; justify-content: flex-end; }
  .item-name { flex-basis: 100%; }
}

.slogan { color: var(--oak); text-align: center; margin: 28px 0 4px; line-height: 1.8; }

/* вкладки: главная, покупки, магазины, профиль */
.app.with-tabs { padding-bottom: calc(84px + var(--safe-bottom)); }
.screen { display: flex; flex-direction: column; }
.screen-title { font: 600 22px/1.2 var(--heading); letter-spacing: -0.01em; margin: 18px 2px 16px; }
.center.small { padding: 32px 8px; flex: none; }
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 10; display: flex; justify-content: center;
  background: var(--milk); border-top: 1px solid var(--line); padding: 0 8px var(--safe-bottom);
}
.tab {
  flex: 1; max-width: 150px; min-height: 60px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  color: var(--ink-3); font: 600 12px/1 var(--text); letter-spacing: .01em;
}
/* четыре вкладки — 76 px каждая на экране 320 px: Unbounded капителью «МАГАЗИНЫ» — 100 px, Manrope «Do‘konlar» — 54 px */
.tab svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
/* активная — не только оттенком: полоса сверху и толще линия значка; без Граната */
.tab.on { color: var(--graphite); box-shadow: inset 0 2px 0 var(--graphite); }
.tab.on svg { stroke-width: 2.2; }
.tab:focus-visible { outline: 2px solid var(--graphite); outline-offset: -4px; }
/* открыта клавиатура (Android сжимает окно): панель не закрывает поле и «Сохранить». padding-bottom у .with-tabs
   не меняем — страница не прыгает */
.app.typing .tabbar { display: none; }

/* главная: подсказка про дату рождения и плашка «не удалось обновить» (без Граната) */
.nudge, .stale {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 16px; padding: 12px 12px 12px 16px;
  background: var(--powder); border-radius: var(--radius); font-size: 14px; font-weight: 500;
}
.nudge .ghost, .stale .ghost { min-height: 44px; flex: none; }
/* две кнопки (ярлык на экране телефона): текст — во всю ширину, кнопки под ним справа */
.nudge.wide { flex-wrap: wrap; }
.nudge.wide > span { flex: 1 1 100%; }
.nudge-actions { display: flex; gap: 8px; margin-left: auto; }

/* «Как работают бонусы» — Песок, как ценник; без Граната */
.rules { margin-top: 16px; background: var(--sand); color: var(--graphite); border-radius: var(--radius); }
.rules summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 48px; padding: 10px 12px 10px 16px;
  font: 600 15px/1.35 var(--text); cursor: pointer; list-style: none;
}
.rules summary::-webkit-details-marker { display: none; }
.rules summary:focus-visible { outline: 2px solid var(--graphite); outline-offset: -2px; }
.rules summary:active { background: rgba(26,26,27,.05); }
.rules .chev { stroke: var(--graphite); }
.rules ul { margin: 0; padding: 0 16px 14px 34px; font-size: 14px; line-height: 1.5; }
.rules li + li { margin-top: 6px; }

/* магазины: список и карточка — белые листы, как в профиле */
.sheet.stores { padding: 0; }
.store-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 18px; column-gap: 12px; align-items: center;
  width: 100%; min-height: 60px; padding: 12px 12px 12px 16px; text-align: left;
}
.store-row + .store-row { border-top: 1px solid var(--line); }
.store-row:active { background: rgba(26,26,27,.05); }
.store-row:focus-visible { outline: 2px solid var(--graphite); outline-offset: -2px; }
.store-name { grid-column: 1; font: 600 16px/1.35 var(--text); overflow-wrap: anywhere; }
.store-addr { grid-column: 1; color: var(--ink-2); font-size: 14px; line-height: 1.4; margin-top: 2px; overflow-wrap: anywhere; }
.store-row .chev { grid-column: 2; grid-row: 1 / span 2; }
/* карта — только картинка: нажатие открывает Яндекс Карты, жесты карты не мешают листать. Кадр OSM на 70 px шире
   с каждой стороны — его кнопки и подпись обрезаны; метка — своя, остриём в центре кадра */
.store-map { position: relative; height: 180px; border-radius: var(--radius); overflow: hidden; background: var(--sand); }
.store-map iframe {
  position: absolute; top: -70px; left: -70px; width: calc(100% + 140px); height: calc(100% + 140px);
  border: 0; pointer-events: none; filter: saturate(.55);
}
.store-pin { position: absolute; left: 50%; top: 50%; width: 30px; height: 40px; transform: translate(-50%, -100%); fill: var(--garnet); filter: drop-shadow(0 1px 1px rgba(26,26,27,.35)); }
.store-pin circle { fill: var(--milk); }
.store-map a { position: absolute; inset: 0; }
.map-credit { margin: 4px 2px 14px; text-align: right; color: var(--ink-3); font-size: 11px; line-height: 1.4; }
a.store-row { color: inherit; text-decoration: none; }
.store-map a:focus-visible { outline: 2px solid var(--graphite); outline-offset: -2px; }
.store-field { padding: 12px 0; }
.store-field + .store-field, .store-field + .info-row { border-top: 1px solid var(--line); }
.store-field .info-label { display: block; font-size: 13px; margin-bottom: 2px; }
.store-value { display: block; font-weight: 500; overflow-wrap: anywhere; }
.route-buttons { display: flex; gap: 8px; margin-bottom: 14px; }
.route-buttons .ghost {
  flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; padding: 10px 8px;
  text-align: center; text-decoration: none; line-height: 1.25; overflow-wrap: anywhere;
}
.screen > .section-title { margin-top: 12px; }

/* профиль: листы на «белой бумаге» */
.sheet { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 4px 16px; margin-bottom: 14px; }
/* имя и фамилия: поля сверху и снизу на равном расстоянии от края листа; «Сохранить» и ошибка — в тот же ритм 12 px */
.sheet .fields.tight { margin: 12px 0; gap: 12px; }
.sheet .fields.tight ~ .error { margin-bottom: 12px; }
.sheet .fields.tight ~ .sheet-actions { padding-top: 0; }
.sheet .error { margin: 10px 0 0; }
.sheet-actions { display: flex; align-items: center; justify-content: flex-end; gap: 12px; padding: 12px 0; }
.saved { color: var(--ink-2); font-size: 14px; }
.sheet-block { padding: 12px 0; border-top: 1px solid var(--line); }
.sheet > .sheet-block:first-child { border-top: 0; }     /* дата первым листом профиля */
.sheet-block .field > span { margin-bottom: 6px; }
.info-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 52px; }
.info-row + .info-row, .info-row + .sheet-block { border-top: 1px solid var(--line); }
.info-label { color: var(--ink-3); font-size: 14px; }
.info-value { font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.note { color: var(--ink-3); font-size: 12px; line-height: 1.45; margin: 4px 0 12px; }
/* «Связь»: номер — ссылка tel: высотой не меньше 44 px; Графитом с подчёркиванием, Гранат на экране не тратим */
.info-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 2px; color: var(--graphite); font-weight: 600;
  text-decoration: underline; text-underline-offset: 3px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.info-link:focus-visible { outline: 2px solid var(--graphite); outline-offset: 2px; }
.info-link:active { opacity: .7; }
.sheet .pending-note { margin: 14px 0; }
.segmented { display: flex; border: 1px solid var(--graphite); border-radius: var(--radius); overflow: hidden; }
.segmented button { min-width: 56px; min-height: 44px; font: 500 11px/1 var(--heading); letter-spacing: 0.14em; color: var(--graphite); }
.segmented button.on { background: var(--graphite); color: var(--milk); }
.retry { margin-top: 8px; width: auto; padding: 14px 26px; }
