/* Каталог, карточка товара, корзина, оформление, личный кабинет. */

/* --- Каталог --- */
.catalog { display: grid; grid-template-columns: 240px 1fr; gap: var(--s7); align-items: start; }
@media (max-width: 980px) { .catalog { grid-template-columns: 1fr; gap: var(--s4); } }

/* Фильтров у ресниц много: толщин, изгибов и длин десятки. Колонка
 * оказывается выше экрана, и чтобы добраться до нижних значений,
 * приходилось листать товары. Прокручиваем её отдельно. */
.filters {
  position: sticky;
  top: calc(var(--header-h) + var(--s4));
  max-height: calc(100vh - var(--header-h) - var(--s6));
  overflow-y: auto;
  /* Намеренно БЕЗ overscroll-behavior: contain. С ним прокрутка упиралась
   * в край списка фильтров и дальше не шла — кнопки «Показать» и «Сбросить»
   * оставались за нижней границей экрана, и до них приходилось добираться,
   * переводя мышь на другую половину страницы. */
  padding-right: var(--s2);
}
/* Полоса прокрутки не должна спорить с воздухом вокруг фильтров. */
.filters::-webkit-scrollbar { width: 6px; }
.filters::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }
.filters__group + .filters__group { margin-top: var(--s5); padding-top: var(--s5); border-top: 1px solid var(--line); }
.filters__group + .filters__group {
  margin-top: var(--s5); padding-top: var(--s5); border-top: 1px solid var(--line);
}
.filters__title {
  font-size: 11px; color: var(--ink); margin: 0 0 var(--s3);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
}
.filters__actions { margin-top: var(--s5); display: grid; gap: var(--s2); }

/* Значения фильтра — плитки, а не список с галочками: толщин и длин
 * у ресниц десятки, списком это простыня на два экрана.
 *
 * Селектор именно `.chip > span`: правило для всех вложенных span
 * попадало и на счётчик внутри, и тот получал собственную рамку и
 * уезжал на строку ниже. Плитка выглядела сломанной.
 */
.chips { display: flex; flex-wrap: wrap; gap: var(--s2); }
.chip { position: relative; }
.chip input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.chip > span {
  display: inline-flex; align-items: baseline; gap: var(--s2);
  padding: 7px var(--s3); font-size: 13px; line-height: 1;
  border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--white); cursor: pointer; white-space: nowrap;
  transition: border-color var(--fast) var(--ease),
              background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.chip > span:hover { border-color: var(--ink-soft); }

/* Счётчик — не второстепенная подпись, а подсказка «стоит ли сюда
   ходить»: ноль товаров за фильтром человек узнаёт до нажатия. */
.chip__count { font-size: 11px; color: var(--ink-mute); font-variant-numeric: tabular-nums; }

.chip input:checked + span {
  background: var(--brand); border-color: var(--brand); color: var(--on-brand);
}
.chip input:checked + span .chip__count { color: var(--on-brand-soft); }
.chip input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 2px; }

/* Варианта нет в наличии: бледная зачёркнутая плитка, но нажать её
   можно — выбор покажет «нет в наличии», а не молча ничего не сделает. */
.chip.is-out > span {
  color: var(--ink-mute); border-style: dashed; background: var(--paper);
  text-decoration: line-through; text-decoration-color: var(--ink-mute);
}
.chip.is-out input:checked + span {
  background: var(--ink-mute); border-color: var(--ink-mute); border-style: solid;
  color: var(--on-brand);
}

/* Отметки «только в наличии» и «по акции» — обычные флажки, а не
 * плитки: это не значение свойства, а переключатель, и выглядеть он
 * должен иначе, иначе читается как ещё одна толщина. */
.chip--switch > span {
  border: 0; background: none; padding: var(--s1) 0; border-radius: 0;
  gap: var(--s3); font-size: 14px;
}
.chip--switch > span::before {
  content: ""; width: 18px; height: 18px; flex: none;
  border: 1px solid var(--line); border-radius: var(--r-field);
  background: var(--white); transition: all var(--fast) var(--ease);
}
.chip--switch input:checked + span { background: none; color: var(--ink); }
.chip--switch input:checked + span::before {
  background: var(--brand); border-color: var(--brand);
  /* Галочка рисуется фоном, чтобы не тащить ради неё картинку. */
  background-image: linear-gradient(45deg, transparent 44%, var(--on-brand) 45%,
                    var(--on-brand) 55%, transparent 56%),
                    linear-gradient(-45deg, transparent 44%, var(--on-brand) 45%,
                    var(--on-brand) 55%, transparent 56%);
  background-size: 11px 2px, 7px 2px;
  background-position: 6px 9px, 3px 9px;
  background-repeat: no-repeat;
}

.catalog__bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4); margin-bottom: var(--s5); flex-wrap: wrap;
}
.catalog__count { color: var(--ink-mute); font-size: 14px; }
.filters-toggle { display: none; }
@media (max-width: 980px) {
  .filters-toggle { display: inline-flex; }
  .filters {
    position: static; display: none; max-height: none; overflow: visible;
    padding: var(--s4); background: var(--sand); border-radius: var(--radius);
  }
  .filters.is-open { display: block; }
}

/* Поиск внутри каталога: в шапке его не находят, когда уже смотрят товары. */
/* Поиск занимает всю ширину колонки: рядом с кнопкой на 240 пикселях
 * полю оставалось сантиметра три, и название товара в него не влезало. */
.filters__search { display: grid; gap: var(--s2); }
.filters__search .input { width: 100%; min-width: 0; }

/* --- Сетка товаров --- */
.products { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s5) var(--s4); }
@media (max-width: 860px) { .products { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 420px) { .products { grid-template-columns: repeat(2, 1fr); gap: var(--s4) var(--s2); } }

.card { display: flex; flex-direction: column; height: 100%; }
.card__media {
  position: relative; aspect-ratio: 3 / 4; background: var(--beige-soft);
  border-radius: var(--radius); overflow: hidden; margin-bottom: var(--s3);
}
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s var(--ease); }
.card:hover .card__media img { transform: scale(1.03); }
/* Заглушка вместо фото: снимков есть не у всех товаров, а пустой серый
 * прямоугольник читается как сломанная картинка. */
.card__media--empty {
  display: grid; place-items: center; color: var(--ink-soft); font-size: 11px;
  text-transform: uppercase; letter-spacing: var(--tracking-wide); text-align: center; padding: var(--s3);
}
.card__badges { position: absolute; top: var(--s2); left: var(--s2); display: grid; gap: var(--s1); justify-items: start; }
.card__cat { font-size: 11px; color: var(--accent-ink); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.card__name { margin: var(--s1) 0 var(--s2); font-size: 15px; line-height: 1.35; }
.card__foot { margin-top: auto; display: flex; align-items: baseline; gap: var(--s2); flex-wrap: wrap; }
.price { font-size: 16px; }
.price--old { color: var(--ink-mute); text-decoration: line-through; font-size: 14px; }
.price--sale { color: var(--sale); }
.card__note { font-size: 12px; color: var(--ink-mute); }
.card__buy { margin-top: var(--s3); }
.card__refusal { margin: var(--s1) 0 0; font-size: 12px; color: var(--sale); }
.card__stock { margin: var(--s1) 0 0; font-size: 13px; color: var(--accent-ink); }

/* --- Карточка товара --- */
.product { display: grid; grid-template-columns: minmax(0, 0.95fr) minmax(0, 1fr); gap: var(--s8); align-items: start; }
/* «Картинки на карточке великоваты» — просьба со встречи 5 октября.
 * Фото 4:5 во всю колонку уводило цену и кнопку за нижний край, а на
 * телефоне — тем более: «у единиц есть компьютеры». */
.product__gallery { max-width: 440px; }
.product__media { background: var(--beige-soft); border-radius: var(--radius); aspect-ratio: 4 / 5; overflow: hidden; }
.product__media img { width: 100%; height: 100%; object-fit: cover; }
.product__media--empty { display: grid; place-items: center; color: var(--ink-mute); }
.product__thumbs { display: flex; gap: var(--s2); margin-top: var(--s3); overflow-x: auto; }
.product__thumb {
  flex: 0 0 64px; height: 64px; padding: 0; border: 1px solid transparent;
  border-radius: var(--radius); background: var(--beige-soft); overflow: hidden; cursor: pointer;
}
.product__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.product__thumb[aria-current="true"] { border-color: var(--ink); }
@media (max-width: 900px) {
  .product { grid-template-columns: 1fr; gap: var(--s4); }
  .product__gallery { max-width: 280px; margin-inline: auto; }
  .product__media { aspect-ratio: 1 / 1; }
  /* Цель — цена и кнопка «В корзину» на первом экране телефона.
   *
   * Замерено на экране 375 × 812: цена стояла на 804, кнопка на 913.
   * До фото над ценой лежало 484 px обвязки — шапка, лента, хлебные
   * крошки, название и выбор признаков, плюс 119 px чистых пустот.
   *
   * Уменьшать одно фото было мало: оно и так ужалось с 469 до 320. */
  .product__title { margin: var(--s1) 0 var(--s2); }
  .product__price { margin: var(--s3) 0; }
  .product__buy { margin-top: var(--s3); }
  .options { margin-top: var(--s3); }
}
.product__panel { position: sticky; top: calc(var(--header-h) + var(--s5)); }
.product__brand { font-size: 12px; color: var(--accent-ink); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.product__title { margin: var(--s2) 0 var(--s3); }
.product__price { display: flex; align-items: baseline; gap: var(--s3); margin: var(--s5) 0; }
.product__price .price { font-size: 26px; }
.product__buy { display: grid; gap: var(--s3); margin-top: var(--s5); }
.product__note { font-size: 13px; color: var(--ink-mute); }

/* Свойства, которые у товара одни на все вариации: выбирать нечего,
 * но знать их надо — по ним человек искал в каталоге. */
.specs {
  display: grid; grid-template-columns: auto 1fr; gap: var(--s2) var(--s4);
  margin: var(--s4) 0 0; font-size: 14px;
}
.specs dt { color: var(--ink-mute); }
.specs dd { margin: 0; }

.back-link {
  display: inline-block; margin-top: var(--s2);
  font-size: 14px; color: var(--ink-soft);
}
.back-link:hover { color: var(--accent-ink); }

.options { display: grid; gap: var(--s4); margin-top: var(--s5); }
.option__label {
  display: flex; justify-content: space-between; font-size: 12px;
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
  color: var(--ink-mute); margin-bottom: var(--s2);
}
.option__value { color: var(--ink); }

.qty { display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: var(--radius); }
.qty button { width: 38px; height: 38px; border: 0; background: none; cursor: pointer; font-size: 17px; }
.qty button:hover { background: var(--sand); }
.qty input { width: 44px; height: 38px; border: 0; text-align: center; font: inherit; background: none; }
.qty input::-webkit-outer-spin-button, .qty input::-webkit-inner-spin-button { appearance: none; margin: 0; }

.tabs { margin-top: var(--s8); border-top: 1px solid var(--line); }
.tabs__head { display: flex; gap: var(--s5); flex-wrap: wrap; padding-top: var(--s4); }
.tabs__btn {
  border: 0; background: none; padding: var(--s2) 0; cursor: pointer;
  font-size: 13px; text-transform: uppercase; letter-spacing: var(--tracking-wide);
  color: var(--ink-mute); border-bottom: 1px solid transparent;
}
.tabs__btn[aria-selected="true"] { color: var(--ink); border-color: var(--ink); }
.tabs__panel { padding: var(--s5) 0; max-width: 46rem; }

/* --- Корзина и оформление --- */
.checkout { display: grid; grid-template-columns: 1fr 380px; gap: var(--s7); align-items: start; }
@media (max-width: 980px) { .checkout { grid-template-columns: 1fr; }
  .checkout--order > .summary { order: -1; position: static; } }
.summary {
  position: sticky; top: calc(var(--header-h) + var(--s4));
  background: var(--sand); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--s5);
}
.summary__row { display: flex; justify-content: space-between; gap: var(--s3); padding: var(--s2) 0; font-size: 15px; }
.summary__row--total { border-top: 1px solid var(--line); margin-top: var(--s3); padding-top: var(--s4); font-size: 19px; }

.lines { display: grid; gap: var(--s4); }
/* Строка корзины без картинки: списком, как в заказе 1С. Просили на
 * встрече по 1С — «когда заказ на восемьдесят тысяч, прикинь, сколько
 * картинок»: читать такой список невозможно, а прокручивать долго. */
.line {
  display: grid; grid-template-columns: 1fr auto; gap: var(--s4);
  align-items: start; padding-bottom: var(--s3); border-bottom: 1px solid var(--line);
}
.line__attrs-inline { color: var(--ink-mute); font-weight: 400; }
.line__media { aspect-ratio: 3 / 4; background: var(--beige-soft); border-radius: var(--radius); overflow: hidden; }
.line__media img { width: 100%; height: 100%; object-fit: cover; }
.line__name { font-size: 15px; }
.line__attrs { font-size: 13px; color: var(--ink-mute); margin-top: var(--s1); }
.line__controls { display: flex; align-items: center; gap: var(--s3); margin-top: var(--s3); }
.line__remove { border: 0; background: none; cursor: pointer; color: var(--ink-mute); font-size: 13px; text-decoration: underline; }
.line__remove:hover { color: var(--sale); }
.line__sum { text-align: right; white-space: nowrap; }

/* Строка, которую уже нельзя купить: товар сняли с продажи или
 * разобрали, пока она лежала в корзине. Бледная полоса без цвета
 * тревоги: вина не покупателя. */
.line--blocked { opacity: .65; }
.line--blocked .line__sum { text-decoration: line-through; }
.line__refusal { font-size: 13px; color: var(--sale); margin-top: var(--s1); }
.cart__blocked {
  font-size: 14px; color: var(--sale); background: var(--beige-soft);
  border-radius: var(--radius); padding: var(--s3) var(--s4);
}
@media (max-width: 560px) {
  .line { grid-template-columns: 1fr; }
  .line__sum { text-align: left; }
}

/* Две равные колонки, которые честно схлопываются на телефоне.
 * Раньше это была сетка оформления с прибитыми инлайном колонками —
 * она не сворачивалась, и страница входа уезжала вбок. */
.two-up { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s7); align-items: start; }
@media (max-width: 820px) { .two-up { grid-template-columns: 1fr; gap: var(--s6); } }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); }
.form-grid > .field--wide { grid-column: 1 / -1; }
@media (max-width: 560px) { .form-grid { grid-template-columns: 1fr; } }

/* Подсказки по адресу: выпадают под полем и перекрывают карту, поэтому
 * им нужен свой слой — у Leaflet собственные высоко лежащие элементы. */
.point-search { position: relative; }
.suggestions {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 1000;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: 0 8px 24px rgba(32,29,27,.12);
  max-height: 16rem; overflow-y: auto;
}
.suggestion {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  font: inherit; font-size: 14px; padding: 9px var(--s3); cursor: pointer;
}
.suggestion + .suggestion { border-top: 1px solid var(--line-2, var(--line)); }
.suggestion:hover { background: var(--sand); }

#map { height: 380px; border: 1px solid var(--line); border-radius: var(--radius); }
/* На телефоне карта не должна занимать весь экран: под ней кнопка заказа. */
@media (max-width: 560px) { #map { height: 300px; } }
/* Карта запирается в собственный слой: Leaflet раскладывает панели на
 * z-index до 1000 и перекрывал шапку с меню. Поднимать свои слои выше —
 * гонка, в которой выигрывает последняя подключённая библиотека.
 * Контекст наложения решает это раз и навсегда. */
.leaflet-container { position: relative; z-index: 0; }
.point-picked {
  display: flex; gap: var(--s3); align-items: center; padding: var(--s3) var(--s4);
  background: var(--sand); border-radius: var(--radius); font-size: 14px;
}

/* --- Оформление заказа --- */
/* Шаги пронумерованы: форма длинная, и человек должен видеть, сколько
 * ещё осталось, а не листать наугад. */
.step-block + .step-block { margin-top: var(--s7); }
.step-block__title {
  display: flex; align-items: center; gap: var(--s3);
  font-size: 17px; margin: 0 0 var(--s4);
}
.step-block__num {
  display: grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; background: var(--ink); color: var(--white);
  font-size: 13px; flex: none;
}
.field__hint { display: block; margin-top: var(--s2); font-size: 12px; color: var(--ink-mute); }

/* Пункт, куда уже заказывали: повторная покупка не должна начинаться
 * с поиска на карте того же адреса. */
.chip-btn {
  border: 1px solid var(--line); background: var(--white); cursor: pointer;
  border-radius: var(--radius); padding: 8px var(--s3); font: inherit;
  font-size: 13px; text-align: left; transition: all .15s var(--ease);
}
.chip-btn:hover { border-color: var(--ink); }
.chip-btn.is-chosen { background: var(--ink); border-color: var(--ink); color: var(--white); }

.point-picked--missing { background: var(--error-bg); color: var(--error-ink); }

/* --- Выбор перевозчика ---
 * Вкладки, а не переключатель: карта под ними одна и та же, меняется
 * только справочник. Ozon стоит первым и выбран заранее — на двадцать
 * заказов СДЭКом уезжают один-два, и остальным этот выбор делать
 * не приходится. */
.carriers {
  display: inline-flex; gap: 2px; padding: 2px; margin-bottom: var(--s4);
  background: var(--sand); border-radius: var(--r-pill);
}
.carriers__tab {
  font: inherit; font-size: 13px; line-height: 1;
  padding: 8px var(--s4); border: 0; border-radius: var(--r-pill);
  background: none; color: var(--ink-mute); cursor: pointer;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.carriers__tab:hover { color: var(--ink); }
.carriers__tab.is-chosen {
  background: var(--white); color: var(--ink); font-weight: 500;
  box-shadow: 0 1px 2px rgb(0 0 0 / .08);
}

.summary__title { font-size: 12px; color: var(--ink-mute); margin: 0 0 var(--s4); }
.summary__items {
  display: grid; gap: var(--s2); padding-bottom: var(--s3);
  margin-bottom: var(--s2); border-bottom: 1px solid var(--line);
}
.summary__item { display: flex; justify-content: space-between; gap: var(--s3); font-size: 14px; }

/* --- Оплата на странице заказа --- */
.pay {
  margin-top: var(--s5); padding-top: var(--s5); border-top: 1px solid var(--line);
  text-align: center;
}
.pay__title { font-size: 16px; margin: 0 0 var(--s2); }
.pay--done .pay__title { color: var(--ok-ink); }
.pay__qr {
  display: inline-block; margin: var(--s3) 0; padding: var(--s3);
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  min-height: 40px;
}
.pay__qr img, .pay__qr canvas { display: block; }

/* Состав уже оформленного заказа: картинок нет, менять нечего —
 * строка проще, чем строка корзины. */
.line--plain { grid-template-columns: 1fr auto; }

/* --- Личный кабинет --- */
.account { display: grid; grid-template-columns: 220px 1fr; gap: var(--s7); align-items: start; }
@media (max-width: 860px) { .account { grid-template-columns: 1fr; gap: var(--s5); } }
.account__nav { display: grid; gap: var(--s2); }
.account__nav a { padding: var(--s2) 0; font-size: 14px; color: var(--ink-soft); }
.account__nav a:hover { color: var(--ink); }
.account__nav a[aria-current="page"] { color: var(--ink); border-bottom: 1px solid var(--ink); justify-self: start; }
/* На телефоне меню кабинета — строкой вкладок, а не столбиком на
 * 200 px над каждой страницей. */
@media (max-width: 860px) {
  .account__nav { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s5);
                  align-items: center; border-bottom: 1px solid var(--line); }
  .account__nav form { margin-left: auto; }
}

.order-card { border: 1px solid var(--line); border-radius: var(--radius); padding: var(--s5); }
.order-card + .order-card { margin-top: var(--s4); }
.order-card__head { display: flex; justify-content: space-between; gap: var(--s4); flex-wrap: wrap; align-items: baseline; }

/* Шаги заказа: в строку на широком экране, столбиком на телефоне —
 * четыре подписи в ряд на 375px нечитаемы. */
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: var(--s3); margin-top: var(--s5); }
.step { padding-top: var(--s4); font-size: 13px; color: var(--ink-mute); border-top: 2px solid var(--line); }
.step--done { color: var(--ink); border-color: var(--ink); }
.step__at { display: block; font-size: 12px; color: var(--ink-mute); margin-top: var(--s1); }
@media (max-width: 640px) {
  .steps { grid-template-columns: 1fr; gap: 0; }
  .step { border-top: 0; border-left: 2px solid var(--line); padding: var(--s2) 0 var(--s3) var(--s4); }
}

.addresses { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s4); }
.address-card { border: 1px solid var(--line); border-radius: var(--radius); padding: var(--s4); display: grid; gap: var(--s2); }
.address-card--default { border-color: var(--ink); }
@media (max-width: 720px) { .addresses { grid-template-columns: 1fr; } }

/* --- «Нужна помощь?» --- */
.help {
  margin: var(--s8) 0 0;
  padding: var(--s6);
  background: var(--cream-soft);
}
.help__title { margin: 0 0 var(--s4); font-size: 22px; font-weight: 400; }
.help__row { display: flex; flex-wrap: wrap; gap: var(--s3); }
.help__row .btn { display: inline-flex; align-items: center; gap: var(--s2); }
@media (max-width: 720px) {
  .help { padding: var(--s5) var(--s4); }
  .help__row { display: grid; }
}

/* --- Опт: строка на карточке товара --- */
/* Форма целиком здесь мешала бы выбору толщины, ради которого человек
 * и пришёл, поэтому на карточке только одна строка. */
.wholesale-hint {
  margin: var(--s4) 0 0; padding: var(--s3) var(--s4);
  background: var(--cream-soft); font-size: 14px; color: var(--ink-soft);
}
.wholesale-hint a { color: var(--accent-ink); border-bottom: 1px solid currentColor; }

/* --- Разделы плитками над товарами ---
 *
 * Каталог начинается с выбора раздела, а не со списка всего подряд:
 * фильтры «толщина» и «изгиб» имеют смысл для ресниц и не имеют для
 * пинцетов, и человек должен сначала сказать, что ищет. */
.sections {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--s3); margin-bottom: var(--s6);
}
.section-tile {
  position: relative; display: grid; align-items: end;
  min-height: 108px; padding: var(--s3) var(--s4);
  background: var(--cream-soft); overflow: hidden;
  color: var(--ink); isolation: isolate;
}
.section-tile img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: -2; transition: transform .5s var(--ease);
}
/* Затемнение только под снимком: на пустой плитке оно ни к чему —
 * тёмный текст на кремовом и так читается. */
.section-tile:has(img)::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--photo-veil);
}
.section-tile:has(img) { color: var(--on-brand); }
.section-tile:hover img { transform: scale(1.04); }
.section-tile__name {
  position: relative; font-size: 15px; text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}
@media (max-width: 560px) {
  .sections { grid-template-columns: 1fr 1fr; gap: var(--s2); }
  .section-tile { min-height: 84px; padding: var(--s3); }
  /* «ДОПОЛНИТЕЛЬНЫЕ» заглавными в полэкрана не помещается одним словом
   * и обрезалось на телефоне. Переносим по слогам, а не прячем. */
  .section-tile__name { font-size: 13px; letter-spacing: .04em;
                        hyphens: auto; overflow-wrap: anywhere; }
}

/* Цена, которой ещё нет в 1С. Не приглушаем до серого: это не
 * второстепенная подпись, а ответ на главный вопрос покупателя. */
.price--ask { font-size: 14px; color: var(--accent-ink); }

/* Подтверждение соответствия — обязательные сведения, а не подпись
 * мелким шрифтом: с сентября 2026 карточка приравнена к документации. */
.specs--doc { margin-top: var(--s4); padding-top: var(--s4);
              border-top: 1px solid var(--line); }
.specs--doc a { color: var(--accent-ink); border-bottom: 1px solid currentColor; }

/* Ссылка на канал — строкой под кнопками, а не четвёртой кнопкой:
 * подписка это другое намерение, чем «написать нам сейчас». */
.help__channel {
  display: flex; align-items: center; gap: var(--s2);
  margin: var(--s4) 0 0; font-size: 14px; color: var(--ink-soft);
}
.help__channel svg { width: 18px; height: 18px; flex: none; }
.help__channel a { color: var(--accent-ink); border-bottom: 1px solid currentColor; }

/* --- Отзывы --- */
.reviews { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s4); }
.review {
  margin: 0; padding: var(--s5); background: var(--cream-soft);
  display: grid; gap: var(--s3); align-content: start;
}
/* Звёзды медью: это оценка, а не украшение, и серым она теряется. */
.review__stars { color: var(--accent-ink); letter-spacing: .1em; font-size: 15px; }
.review__text { margin: 0; font-size: 15px; line-height: 1.5; }
.review__who { font-size: 13px; color: var(--ink-soft); }
.review__when { margin-left: var(--s2); color: var(--ink-mute); }

/* Ответ магазина отделён сдвигом и линией, а не цветом: так видно,
 * что это другая сторона разговора, даже если цвет не прогрузился. */
.review__reply {
  margin-top: var(--s3); padding-left: var(--s4);
  border-left: 2px solid var(--line); font-size: 14px; line-height: 1.5;
}
.review__reply p { margin: 0; }
.review__reply-who { font-size: 11px; color: var(--ink-mute); margin: 0 0 2px; }

/* Форму видит только тот, кто покупал, поэтому она не борется за
 * внимание с карточкой товара: обычный блок в конце страницы. */
.review-form {
  display: grid; gap: var(--s4); max-width: 34rem;
  margin-top: var(--s6); padding-top: var(--s5);
  border-top: 1px solid var(--line);
}
.review-form__title { font-size: 16px; margin: 0; }
.review-form .btn { justify-self: start; }
.review-note { margin-top: var(--s5); font-size: 14px; }

/* --- Сборка палетки по длинам ---
 * Столбик, а не строка: так эту механику и описали — слева длина,
 * справа окошко с количеством. В строку девять полей не читаются. */
.lines {
  margin: var(--s5) 0; padding: var(--s4);
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--sand);
}
.lines__head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s3); margin-bottom: var(--s3);
}
.lines__title { margin: 0; font-size: 14px; font-weight: 500; }
.lines__left {
  margin: 0; font-size: 13px; color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}
.lines--over .lines__left { color: var(--error-ink); font-weight: 500; }

.lines__grid { display: grid; gap: var(--s2); }
.lines__row {
  display: grid; grid-template-columns: 1fr 5rem;
  align-items: center; gap: var(--s3);
}
.lines__len { font-size: 14px; }
.lines__input { text-align: center; padding: 6px var(--s2); }
.lines__input--filled { border-color: var(--brand); font-weight: 500; }
.lines--over .lines__input--filled { border-color: var(--error-ink); }
.lines__note { margin: var(--s3) 0 0; color: var(--ink-mute); min-height: 1.2em; }
.lines--over .lines__note { color: var(--error-ink); }
.lines [data-lines-clear] { margin-top: var(--s2); }

/* Звёзды задом наперёд: при наведении на третью должны загораться
 * три, а не одна. В обычном порядке соседа слева выбрать нельзя —
 * в CSS есть «следующий», но нет «предыдущего». */
.stars { display: flex; flex-direction: row-reverse; justify-content: flex-end;
         gap: 2px; border: 0; padding: 0; margin: 0; }
.stars legend { float: left; width: 100%; }
.stars__one input { position: absolute; opacity: 0; width: 0; height: 0; }
.stars__one span {
  display: block; font-size: 26px; line-height: 1; cursor: pointer;
  color: var(--line); transition: color .1s var(--ease);
}
.stars__one:hover span,
.stars__one:hover ~ .stars__one span,
.stars__one input:checked ~ span,
.stars__one:has(input:checked) ~ .stars__one span { color: var(--accent-ink); }
.stars__one input:focus-visible + span { outline: 2px solid var(--brand); }
@media (max-width: 720px) { .reviews { grid-template-columns: 1fr; } }

/* --- Нестандартная палетка: сборка из двух половин ---
 *
 * Две колонки рядом, а не форма из шести полей подряд: половины
 * равноправны, и читаться это должно как «вот эта и вот эта», а не как
 * список, где на четвёртом поле забываешь, к чему оно относится. */
.custom { margin: var(--s6) 0 var(--s9); }
.custom__title { font-size: 28px; font-weight: 300; margin: 0 0 var(--s3); }
.custom__lead { color: var(--ink-soft); max-width: 62ch; margin: 0 0 var(--s6); }

.custom__halves { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); }
.custom__half {
  border: 1px solid var(--line); padding: var(--s5);
  display: grid; gap: var(--s4); align-content: start;
}
.custom__half-title {
  padding: 0 var(--s2); font-size: 12px; text-transform: uppercase;
  letter-spacing: var(--tracking-wide); color: var(--accent-ink);
}
.custom__common,
.custom__contact { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4);
                   margin-top: var(--s5); }
.custom__contact { grid-template-columns: repeat(3, 1fr); }
.custom__wide { grid-column: 1 / -1; }
.custom__foot { display: flex; align-items: center; flex-wrap: wrap;
                gap: var(--s4); margin-top: var(--s5); }
.custom__legal { margin: 0; font-size: 12px; color: var(--ink-soft); max-width: 52ch; }

@media (max-width: 720px) {
  /* Половины друг под другом: рядом на телефоне они по 150 пикселей,
   * и выпадающий список не прочитать. */
  .custom__halves, .custom__common, .custom__contact { grid-template-columns: 1fr; }
  .custom__foot .btn { width: 100%; }
}

/* Вход в сборку нестандартной палетки — строкой над каталогом:
 * про такую возможность не знают, пока не увидят. */
.custom-hint {
  margin: 0 0 var(--s5); padding: var(--s3) var(--s4);
  background: var(--cream-soft); font-size: 14px; color: var(--ink-soft);
}
.custom-hint a { color: var(--accent-ink); border-bottom: 1px solid currentColor; }



/* --- Оплата со счёта ---
 * Блок отделён рамкой: это развилка, а не ещё одно поле формы. */
.payer {
  padding: var(--s4); border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--sand);
}
.payer__switch {
  display: flex; align-items: flex-start; gap: var(--s3);
  cursor: pointer; font-size: 14px;
}
.payer__switch input { margin-top: 3px; flex: none; }
.payer__fields { display: grid; gap: var(--s4); margin-top: var(--s4); }

/* Счёт на странице заказа. */
.invoice__qr { display: grid; place-items: center; margin: var(--s4) 0; }
.invoice__qr svg { width: 200px; height: 200px; }
.invoice__rows {
  display: grid; grid-template-columns: auto 1fr; gap: 6px var(--s4);
  margin: var(--s4) 0 0; font-size: 13px; text-align: left;
}
.invoice__rows dt { color: var(--ink-mute); }
.invoice__rows dd { margin: 0; }
/* Счета и БИК переписывают руками — моноширинный шрифт и цифры одной
 * ширины уменьшают шанс пропустить разряд. */
.invoice__num { font-variant-numeric: tabular-nums; letter-spacing: .02em; }


/* --- Адрес для Почты ---
 * У неё нет пунктов выдачи, поэтому вместо карты здесь поле адреса.
 * Блок отделён рамкой: это другой способ доставки, а не ещё одно
 * поле формы. */
.post-address {
  display: grid; gap: var(--s4); margin: var(--s4) 0;
  padding: var(--s4); border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--sand);
}
.post-address__note { margin: 0; color: var(--ink-mute); line-height: 1.5; }
.post-address button { justify-self: start; }
.post-address__result { margin: 0; min-height: 1.2em; }
.post-address__result--ok { color: var(--ok-ink); }
.post-address__result--bad { color: var(--error-ink); }

/* --- Палетка 2 в 1 ---
 *
 * Решение приёмки: сборку перенесли со отдельной страницы в корзину.
 * Человек видит собранные коробки, выгоду по каждой и то, что осталось
 * свободным, — не уходя со страницы, где он считает деньги.
 */
.pairs {
  grid-column: 1 / -1;
  margin-top: var(--s4);
  padding: var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r2);
  background: var(--surface-2, #fafafa);
}
.pairs__title { margin: 0 0 var(--s2); font-size: 1.05rem; }
.pairs__note { margin: 0 0 var(--s3); }
.pairs__box {
  display: flex; align-items: center; gap: var(--s2);
  flex-wrap: wrap;
  padding: var(--s2) 0;
  border-top: 1px solid var(--line);
}
.pairs__half { font-weight: 500; }
.pairs__plus { color: var(--muted); }
.pairs__qty { color: var(--muted); }
.pairs__saved { margin-left: auto; color: #1e6b2e; font-weight: 600; }
.pairs__make {
  display: flex; gap: var(--s2); flex-wrap: wrap;
  margin-top: var(--s3);
}
.pairs__make .input { flex: 1 1 220px; }
.summary__row--save span:last-child { color: #1e6b2e; }

@media (max-width: 640px) {
  .pairs__saved { margin-left: 0; }
}

/* Подсказка про оптовый порог: «добавьте ещё на столько-то». Просили на
   приёмке — покупатель, которому до скидки не хватает тысячи, добирает
   её охотнее, чем уходит. */
.summary__tier {
  display: block;
  margin-top: var(--s2);
  padding-top: var(--s2);
  border-top: 1px dashed var(--line);
  line-height: 1.4;
}

/* --- Набранное под рукой ---
 *
 * Панель с тем, что уже в корзине, видная во время сбора заказа.
 * Прижата к низу и свёрнута по умолчанию: на телефоне развёрнутый
 * список закрыл бы товар, ради которого человек на странице.
 */
.peek {
  position: fixed;
  right: var(--s3);
  bottom: calc(var(--s3) + env(safe-area-inset-bottom, 0px));
  z-index: 40;
  width: min(360px, calc(100vw - var(--s3) * 2));
  border: 1px solid var(--line);
  border-radius: var(--r2);
  background: var(--bg, #fff);
  box-shadow: 0 10px 30px rgb(0 0 0 / 12%);
  overflow: hidden;
}
.peek__toggle {
  display: flex; align-items: center; gap: var(--s2);
  width: 100%; padding: var(--s2) var(--s3);
  border: 0; background: none; cursor: pointer;
  font: inherit; text-align: left;
}
.peek__count {
  min-width: 1.6em; padding: 0 .4em;
  border-radius: 999px; background: var(--accent, #093C45); color: #fff;
  font-size: .85rem; line-height: 1.6em; text-align: center;
}
.peek__title { font-weight: 500; }
.peek__sum { margin-left: auto; font-weight: 600; }
.peek__chev {
  width: .55em; height: .55em; margin-left: .2em;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-135deg);
  transition: transform .15s ease;
}
.peek--open .peek__chev { transform: rotate(45deg); }
.peek__body { padding: 0 var(--s3) var(--s3); }
.peek__list { margin: 0 0 var(--s2); padding: 0; list-style: none; }
.peek__item {
  display: flex; gap: var(--s2); align-items: baseline;
  padding: var(--s1) 0; border-top: 1px solid var(--line);
  font-size: .9rem;
}
.peek__name { flex: 1 1 auto; min-width: 0; }
.peek__qty { color: var(--muted); white-space: nowrap; }
.peek__total { white-space: nowrap; font-weight: 500; }
.peek__more { margin: 0 0 var(--s2); }

/* На телефоне панель не должна налезать на нижнюю панель навигации. */
@media (max-width: 720px) {
  .peek { right: var(--s2); left: var(--s2); width: auto;
          bottom: calc(68px + env(safe-area-inset-bottom, 0px)); }
}

@media (prefers-reduced-motion: reduce) {
  .peek__chev { transition: none; }
}

/* Расчёт выгоды под суммой: «не просто минус 450, а сколько вышло». */
.pairs__math { display: block; font-size: 12px; color: var(--ink-mute); font-weight: 400; }

/* Ссылка «Впервые у нас?» нужна, только когда формы стоят друг под
 * другом: на широком экране регистрация и так видна справа. */
.login-jump { margin-top: var(--s2); }
@media (min-width: 821px) { .login-jump { display: none; } }
#register { scroll-margin-top: calc(var(--header-h) + var(--s4)); }

/* Варианты товара высотой 28 px — меньше пальца. На телефоне выше. */
@media (max-width: 720px) {
  .chip > span { padding: 10px var(--s3); font-size: 14px; }
}

/* Карточки заказов в кабинете выглядели по-разному из-за длины
 * списка товаров: держим его в две строки, полный состав — внутри. */
.order-card__items { display: -webkit-box; -webkit-line-clamp: 2;
                     -webkit-box-orient: vertical; overflow: hidden; }

/* Прилипший блок покупки — только на телефоне, где под ним нижняя
 * панель. На широком экране цена и кнопка и так рядом с выбором. */
.product__buy-price { display: none; }
@media (max-width: 720px) {
  .product__panel { position: static; }
  .product__buy {
    position: sticky; z-index: 30;
    bottom: calc(76px + env(safe-area-inset-bottom, 0px));
    margin-inline: calc(-1 * var(--s3)); padding: var(--s3);
    background: var(--white); border-radius: var(--r-field);
    box-shadow: var(--shadow-pop);
  }
  .product__buy-price { display: block; font-size: 18px; line-height: 1; }
  .product__buy-price:empty { display: none; }
  /* Когда в корзине что-то есть, над нижней панелью висит полоса
   * «В корзине» — блок покупки встаёт над ней, а не поверх. */
  body:has(.peek:not([hidden])) .product__buy {
    bottom: calc(128px + env(safe-area-inset-bottom, 0px));
  }
}

/* Строка корзины с фото слева. */
.line--thumb { grid-template-columns: 64px 1fr auto; }
.line__thumb { display: block; width: 64px; aspect-ratio: 1; overflow: hidden;
               background: var(--beige-soft); border-radius: var(--radius); }
.line__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (max-width: 560px) {
  .line--thumb { grid-template-columns: 56px 1fr; }
  .line__thumb { width: 56px; }
  .line--thumb > :last-child { grid-column: 2; }
}
