/* ============================================================
   VIDRO — components
   Джерело: components.md §1–16 + «Стани системи».
   Тіней немає ніде, крім кільця свотча (це не тінь, а обведення).
   Зона дотику ≥ 44×44px у кожного інтерактивного елемента.
   ============================================================ */

/* ---------- §1–3. Кнопки ---------- */

.v-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--fs-btn);
  line-height: 1;
  text-align: center;
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.v-btn:active { transform: scale(0.98); }
.v-btn[disabled], .v-btn[aria-disabled='true'] { cursor: not-allowed; transform: none; }

.v-btn--primary {
  height: var(--btn-h-primary);
  padding-inline: 40px;
  background: var(--color-btn);
  color: var(--color-on-btn);
  border: 0;
}
@media (hover: hover) { .v-btn--primary:hover { background: var(--color-btn-hover); } }
.v-btn--primary[disabled], .v-btn--primary[aria-disabled='true'] {
  background: var(--color-btn-disabled);
}

.v-btn--secondary {
  height: var(--btn-h-secondary);
  padding-inline: var(--sp-6);
  background: transparent;
  color: var(--color-btn);
  border: 1px solid var(--color-btn);
}
@media (hover: hover) {
  .v-btn--secondary:hover { background: var(--color-btn); color: var(--color-on-btn); }
}
.v-btn--secondary[disabled] { border-color: var(--color-btn-disabled); color: var(--color-btn-disabled); }

.v-btn--ghost {
  min-height: var(--tap-min);
  padding: 0;
  font-size: var(--fs-meta);
  color: var(--color-body);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}
@media (hover: hover) { .v-btn--ghost:hover { color: #000; } }

.v-btn--block { width: 100%; }

/* Loading: текст лишається, спінерів немає (components.md §1) */
.v-btn[aria-busy='true'] { opacity: 0.7; pointer-events: none; }

/* ---------- §4. Бейдж ---------- */

.v-badge {
  position: absolute;
  top: var(--sp-3);
  left: var(--sp-3);
  z-index: 2;
  padding: 3px 7px;
  border-radius: var(--radius-badge);
  font-size: var(--fs-badge);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.3px;
  color: var(--color-on-badge);
  text-transform: uppercase;
}
/* Аудит: контраст бейджів 2,1–2,96:1 при білому тексті.
   Фірмові кольори лишаємо — міняємо колір напису:
     рожевий #F44EE6 + темний текст = 6,04:1
     золотий #D4AF37 + темний текст = 8,53:1
     червоний #E03131 + білий      = 4,51:1 (і так проходив)
   Так вимога виконана без правки палітри бренду. */
.v-badge--new  { background: var(--color-badge-new);  color: var(--color-ink); }
.v-badge--best { background: var(--color-badge-best); color: var(--color-ink); }
.v-badge--sale { background: var(--color-badge-sale); color: var(--color-on-badge); }

/* ---------- §5. Свотч кольору ---------- */

.v-swatches { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }

.v-swatch {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  border: 0;
  border-radius: var(--radius-pill);
}
.v-swatch__dot {
  position: relative;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-pill);
  background: var(--swatch-color, var(--color-surface));
  transition: box-shadow var(--dur-fast) var(--ease);
}
/* Білий свотч має внутрішню рамку, інакше зникає на білому фоні */
.v-swatch__dot--light { border: 1px solid var(--color-line); }

.v-swatch[aria-checked='true'] .v-swatch__dot {
  box-shadow: 0 0 0 3px var(--color-bg), 0 0 0 5px var(--color-ink);
}
.v-swatch[data-unavailable='true'] { opacity: 0.4; }
.v-swatch[data-unavailable='true'] .v-swatch__dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--radius-pill);
  background: linear-gradient(to top left,
    transparent calc(50% - 1px), var(--color-ink) calc(50% - 1px),
    var(--color-ink) calc(50% + 1px), transparent calc(50% + 1px));
}
/* Підпис поруч — колір ніколи не єдиний носій сенсу */
.v-swatches__label { font-size: var(--fs-meta); color: var(--color-body); margin-left: var(--sp-1); }

/* ---------- §6. Пігулка розміру ---------- */

.v-sizes { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

.v-size {
  min-width: 56px;
  height: var(--btn-h-secondary);
  padding-inline: var(--sp-4);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-pill);
  background: var(--color-bg);
  color: var(--color-body);
  font-size: var(--fs-btn);
  line-height: 1;
  transition: background-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.v-size[aria-checked='true'] {
  background: var(--color-btn);
  border-color: var(--color-btn);
  color: var(--color-on-btn);
}
/* Немає в наявності: перекреслена, але КЛІКАБЕЛЬНА → «повідомити» */
.v-size[data-soldout='true'] {
  color: var(--color-btn-disabled);
  text-decoration: line-through;
}

.v-sizes__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: var(--sp-2);
}

/* ---------- §7. Картка товару ---------- */

/* Швидкий вибір розміру просто з картки.

   Кнопка виглядає як звичайний підпис розміру, доки на картку не
   навели: інакше сітка каталогу перетворюється на панель керування, а
   людина прийшла дивитись принти. */
.v-card__size--pick {
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  border-radius: 4px;
}
.v-card__size--pick:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

@media (hover: hover) and (min-width: 1024px) {
  .v-card:hover .v-card__size--pick {
    background: var(--color-surface, #f2f2f2);
  }
  .v-card__size--pick:hover {
    background: var(--color-btn, #171717);
    color: var(--color-on-btn, #fff);
  }
}

/* На телефоні тап по розміру має відкривати товар, а не класти щось у
   кошик: цілі дрібні, а помилка коштує повернення. */
@media (max-width: 1023px) {
  .v-card__size--pick { pointer-events: none; }
}

/* Рядок цифр довіри. Числа крупні, підписи дрібні; на телефоні
   в один ряд, бо їх максимум чотири й вони короткі. */
.v-numbers__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5) var(--sp-6);
  margin: 0;
}
.v-numbers__item { flex: 1 1 auto; min-width: 120px; }
.v-numbers__value {
  font-family: var(--font-display, inherit);
  font-size: var(--fs-display-section, 32px);
  line-height: 1.1;
  color: var(--color-ink);
}
.v-numbers__label {
  margin: 4px 0 0;
  font-size: var(--fs-meta, 13px);
  line-height: 1.3;
  color: var(--color-muted);
}

/* «Sale» у шторці каталогу. Помітний, але не кричущий: колір знижки
   вже працює на бейджах карток, тут він лише підкреслює посилання. */
.v-menu__sale { margin-top: var(--sp-4); }
.v-menu__link--sale {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  color: var(--color-sale, #c0392b);
}
.v-menu__sale-count { font-size: var(--fs-meta, 13px); opacity: 0.7; }

/* Зріст і розмір моделі під галереєю на картці товару. */
.v-pdp__model-note {
  margin-top: var(--sp-2);
  font-size: var(--fs-meta, 13px);
  color: var(--color-muted, #6b6b6b);
}

.v-card { position: relative; display: block; text-decoration: none; }

/* Клікабельна вся картка, але посилання одне — на назві. ::after
   розтягує його на всю площу; усе, що має лишитись клікабельним окремо
   (серце), піднімається над ним z-index'ом. */
.v-card__link { color: inherit; text-decoration: none; }
.v-card__link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
}
.v-card__link:focus-visible { outline: none; }
.v-card__link:focus-visible::after {
  outline: 2px solid currentColor;
  outline-offset: -2px;
}

.v-wish--card {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-bg, #fff) 82%, transparent);
  color: var(--color-ink, #171717);
  cursor: pointer;
}
.v-wish--card svg { width: 20px; height: 20px; }
.v-wish--card[aria-pressed='true'] svg { fill: currentColor; }
.v-wish--card:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.v-card__media {
  position: relative;
  aspect-ratio: var(--ratio-product);
  background: var(--color-surface);
  border-radius: var(--radius-card);
  overflow: hidden;
}
/* Наведення приближає принт, а не підміняє кадр іншим кольором.
   Підміна збивала: людина фільтрує білі, наводить — бачить чорну річ.
   Кадрування ховає вихід за межі, тому масштабується саме зображення. */
.v-card__media { overflow: hidden; }
.v-card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow, 320ms) var(--ease);
}
/* Другий кадр з'являється поверх першого. Приближення лишили тільки
   там, де другого кадру немає: інакше картка і зумить, і підміняє —
   надто багато руху на одну дію. */
.v-card__img--hover {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--dur-base, 220ms) var(--ease);
}
@media (hover: hover) {
  .v-card:hover .v-card__img--hover { opacity: 1; }
}
/* На телефоні наведення не існує, тож другий кадр там не показується
   ніколи — але з opacity: 0 браузер його все одно качав. Кожна картка
   тягнула два фото замість одного; на головній із трьома стрічками це
   і були ті «зайві сотні кілобайт». display: none знімає завантаження
   разом із показом: lazy-картинку в display: none браузер не тягне. */
@media (hover: none) {
  .v-card__img--hover { display: none; }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .v-card:not(:has(.v-card__img--hover)):hover .v-card__img { transform: scale(1.18); }
}
/* На дотику наведення не існує, тож приближення дає натиск і утримання. */
@media (hover: none) {
  .v-card:active .v-card__img { transform: scale(1.18); }
}
.v-card__title {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-name-card);
  line-height: var(--lh-name);
  color: var(--color-body);
  font-weight: 400;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.v-card__price {
  margin-top: var(--sp-1);
  font-size: var(--fs-price-card);
  line-height: var(--lh-tight);
  color: #000;
}
.v-card__price del { color: var(--color-muted); margin-right: var(--sp-2); }
/* Рядок розмірів під ціною. Дрібний і неяскравий навмисно: це довідка
   «мій розмір є», а не другий заклик до дії — інакше він перебиває ціну. */
/* Рядок розмірів під ціною.

   Тут було два недогляди, і обидва помітив аудит 08.09.

   Колір брався з `--v-muted`, якого в токенах немає взагалі — одрук,
   що мовчки падав на запасний #6b6b6b. Працювало випадково.

   Недоступні розміри гасились через `opacity: 0.45`, і це роняло
   контраст до 1.89:1. Закреслення саме по собі каже, що розміру немає,
   тож прозорість прибрана: колір лишається читабельним (5.7:1). */
.v-card__sizes {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 4px;
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.2;
  color: var(--color-muted);
}

/* Кожен розмір — ціль не менша за 24×24 навіть при 12 px тексту:
   Lighthouse нарахував 82 порушення target-size саме на цьому рядку.
   Відступи компенсовані зменшеним gap, тож рядок не став вищим. */
.v-card__size {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 24px;
  padding-inline: 4px;
}
.v-card__size--out { text-decoration: line-through; }

.v-card__swatches { display: flex; gap: 6px; align-items: center; margin-top: 6px; }
.v-card__swatch {
  width: 12px; height: 12px;
  border-radius: var(--radius-pill);
  background: var(--swatch-color, var(--color-surface));
}
.v-card__swatch--light { border: 1px solid var(--color-line); }
.v-card__swatch-more { font-size: var(--fs-small); color: var(--color-muted); }

/* Сітка колекції: 2 колонки на sm — картка ≈187px при 390px */
.v-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--grid-gap);
  row-gap: var(--sp-6);
}
@media (min-width: 1024px) { .v-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* ---------- §8. Акордеон ---------- */

.v-accordion { border-top: var(--border); }
.v-accordion__item { border-bottom: var(--border); }
.v-accordion__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  width: 100%;
  min-height: var(--tap-min);
  padding: 20px 0;
  font-size: var(--fs-body);
  text-align: left;
  color: var(--color-body);
}
.v-accordion__sign { flex: 0 0 auto; font-size: 20px; line-height: 1; color: var(--color-ink); }
.v-accordion__trigger[aria-expanded='true'] .v-accordion__sign--plus { display: none; }
.v-accordion__trigger[aria-expanded='false'] .v-accordion__sign--minus { display: none; }
.v-accordion__panel {
  overflow: hidden;
  max-height: 0;
  transition: max-height var(--dur-base) var(--ease);
}
.v-accordion__panel > div { padding-bottom: 20px; }

/* ---------- §9. Sticky-бар покупки ---------- */

.v-buybar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--sticky-bar-h);
  padding: var(--sp-2) var(--gutter);
  padding-bottom: calc(var(--sp-2) + var(--safe-bottom));
  background: var(--color-bg);
  border-top: var(--border);
  transform: translateY(110%);
  transition: transform var(--dur-base) var(--ease);
}
.v-buybar[data-visible='true'] { transform: translateY(0); }
.v-buybar[data-suppressed='true'] { transform: translateY(110%); }
.v-buybar__thumb { flex: 0 0 auto; width: 48px; height: 48px; object-fit: cover; background: var(--color-surface); }
.v-buybar__info { flex: 1 1 auto; min-width: 0; }
.v-buybar__price { font-size: var(--fs-price-card); line-height: var(--lh-tight); color: var(--color-ink); }
.v-buybar__meta { font-size: var(--fs-small); color: var(--color-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.v-buybar .v-btn--primary { flex: 0 0 auto; height: 48px; padding-inline: var(--sp-6); }
@media (min-width: 1024px) { .v-buybar { display: none; } }

/* ---------- Scrim, drawer, шторка ---------- */

/* Селектор із атрибутом — не для краси, а заради ваги.
   Dawn у base.css ховає порожні блоки правилом "div:empty { display: none }",
   а scrim — саме порожній div. Через це затемнення позаду шторки не
   з'являлось узагалі: шторка виїжджала на неприглушену сторінку, і тап
   повз неї нічого не закривав. Одного класу тут мало: ":empty" додає
   специфічності, тож перебиваємо атрибутом. */
.v-scrim[data-vidro-scrim] {
  display: block;
}

.v-scrim {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: var(--color-scrim);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-base) var(--ease), visibility 0s linear var(--dur-base);
}
.v-scrim[data-open='true'] {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--dur-base) var(--ease), visibility 0s linear 0s;
}

.v-panel {
  position: fixed;
  z-index: 51;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  /* Ховаємо саме visibility, а не тільки виносимо за екран трансформом:
     на desktop шторка перетворюється на центровану модалку, і без цього
     вона видима навіть закритою. Заразом закрита шторка перестає ловити
     фокус і зникає для читалок екрана. */
  visibility: hidden;
  /* Затримка рівно на час руху: при закритті шторка спершу з'їжджає,
     і лише потім зникає для фокуса й читалок. */
  transition: transform var(--dur-base) var(--ease),
              visibility 0s linear var(--dur-base);
}

/* А при відкритті — навпаки, без затримки.
   Це не косметика: focus() ігнорує невидимий елемент, тож поки видимість
   вмикалася «десь протягом переходу», фокус після відкриття лишався на
   сторінці під шторкою. Для того, хто ходить клавіатурою або читалкою,
   діалог відкривався повз нього. */
.v-panel[data-open='true'] {
  visibility: visible;
  transition: transform var(--dur-base) var(--ease),
              visibility 0s linear 0s;
}
.v-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--gutter);
  border-bottom: var(--border);
}
.v-panel__title { font-size: var(--fs-body); color: var(--color-ink); margin: 0; }
.v-panel__close {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--tap-min); height: var(--tap-min);
  margin-right: calc(var(--sp-2) * -1);
  font-size: 20px; line-height: 1;
}
.v-panel__body { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.v-panel__foot {
  flex: 0 0 auto;
  padding: var(--sp-4) var(--gutter);
  padding-bottom: calc(var(--sp-4) + var(--safe-bottom));
  border-top: var(--border);
}

/* Шторка знизу (mobile): §11, §14, вибір розміру, «повідомити» */
.v-panel--sheet {
  left: 0; right: 0; bottom: 0;
  max-height: 90dvh;
  transform: translateY(100%);
}
.v-panel--sheet[data-open='true'] { transform: translateY(0); }

/* Кошик-drawer: §10 — справа на desktop, знизу на mobile */
.v-panel--cart {
  left: 0; right: 0; bottom: 0;
  height: 90dvh;
  transform: translateY(100%);
}
.v-panel--cart[data-open='true'] { transform: translateY(0); }
@media (min-width: 1024px) {
  .v-panel--cart {
    left: auto; top: 0; bottom: 0;
    width: 420px; height: 100dvh;
    transform: translateX(100%);
    border-left: var(--border);
  }
  .v-panel--cart[data-open='true'] { transform: translateX(0); }
}

/* Меню-drawer: §16 — зліва */
.v-panel--menu {
  left: 0; top: 0; bottom: 0;
  width: min(88vw, 400px);
  height: 100dvh;
  transform: translateX(-100%);
  border-right: var(--border);
}
.v-panel--menu[data-open='true'] { transform: translateX(0); }

/* Пошук-overlay: §15 — виїжджає зверху */
.v-panel--search {
  left: 0; right: 0; top: 0;
  max-height: 100dvh;
  transform: translateY(-100%);
}
.v-panel--search[data-open='true'] { transform: translateY(0); }

/* Модалка таблиці розмірів на desktop: §14 */
@media (min-width: 1024px) {
  .v-panel--modal {
    left: 50%; top: 50%; right: auto; bottom: auto;
    width: 640px; max-height: 80dvh;
    transform: translate(-50%, -50%) scale(0.98);
    border: var(--border);
  }
  .v-panel--modal[data-open='true'] { transform: translate(-50%, -50%) scale(1); }
}

/* ---------- §10. Позиція кошика ---------- */

.v-cart-item {
  display: grid;
  grid-template-columns: 72px 1fr;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--gutter);
  border-bottom: var(--border);
}
.v-cart-item__media { width: 72px; height: 90px; object-fit: cover; background: var(--color-surface); }
.v-cart-item__title { font-size: var(--fs-name-card); line-height: var(--lh-name); margin: 0; }
.v-cart-item__meta  { font-size: var(--fs-meta); color: var(--color-muted); margin-top: var(--sp-1); }
.v-cart-item__price { font-size: var(--fs-price-card); color: var(--color-ink); margin-top: var(--sp-2); }
.v-cart-item__row   { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-top: var(--sp-2); }

.v-stepper { display: inline-flex; align-items: center; border: var(--border); border-radius: var(--radius-pill); }
.v-stepper button {
  width: var(--tap-min); height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--fs-body);
}
.v-stepper output { min-width: 24px; text-align: center; font-size: var(--fs-meta); }

.v-cart-total {
  display: flex; align-items: baseline; justify-content: space-between;
  font-size: var(--fs-price-pdp); color: var(--color-ink);
}

/* Контейнер під віджет застосунку в кошику (вибір відділення Нової пошти).
   Порожній він нічого не займає — розмітка з'явиться тільки коли блок
   реально додали в конструкторі теми. */
.v-cart-page__app:not(:empty) { margin-bottom: var(--sp-4); }
.v-cart-page__app select,
.v-cart-page__app input[type='text'],
.v-cart-page__app input[type='search'] { max-width: 100%; }

/* Підказка про відділення Нової пошти. Сіра плашка, а не просто дрібний
   текст: її треба помітити до того, як натиснути «Оформити». */
.v-cart__np-hint {
  margin: 0 0 var(--sp-4);
  padding: var(--sp-3);
  background: var(--color-surface);
  color: var(--color-body);
  /* Довге «перевізника,» на вузькому екрані виїжджало за край шторки.
     Корінь був у переповненні документа (див. overflow-x: clip у
     vidro-base.css), але страховка тут дешева і не заважає. */
  overflow-wrap: anywhere;
}

/* Місто й відділення Нової пошти в кошику.

   Та сама сіра плашка, що була в підказки: блок треба помітити до того,
   як натиснути «Оформити», а не після. Поля всередині — на всю ширину:
   назви відділень довгі («Поштомат № 27384: вул. Городоцька, 179»), і в
   два стовпчики вони не читаються навіть на десктопі. */
.v-np {
  display: block;
  margin: 0 0 var(--sp-4);
  padding: var(--sp-3);
  background: var(--color-surface);
  overflow-wrap: anywhere;
}
.v-np__title {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-meta);
  font-weight: 600;
  color: var(--color-ink);
}
.v-np__field + .v-np__field { margin-top: var(--sp-3); }
.v-np__label {
  display: block;
  margin-bottom: 4px;
  font-size: var(--fs-meta);
  color: var(--color-body);
}
.v-np .v-input { width: 100%; }
/* Червона рамка — не єдиний носій помилки: під полями є ще й текст. */
.v-np .v-input[aria-invalid='true'] { border-color: var(--color-error); }
.v-np__hint { margin: var(--sp-2) 0 0; }
.v-np__error { margin: var(--sp-3) 0 0; }
/* `.v-notice` — це display:flex, а він сильніший за типове
   `[hidden] { display: none }` з таблиці браузера. Без цього рядка
   порожня червона рамка висить під полями від самого відкриття кошика й
   лякає людину помилкою, якої немає. */
.v-np__error[hidden] { display: none; }

/* Прогрес-бар безкоштовної доставки (Промт 2, §6.5) */
.v-shipbar { padding: var(--sp-3) var(--gutter); border-bottom: var(--border); }
.v-shipbar__text { font-size: var(--fs-meta); color: var(--color-body); }
.v-shipbar__track { height: 4px; margin-top: var(--sp-2); background: var(--color-line); border-radius: var(--radius-pill); overflow: hidden; }
.v-shipbar__fill  { height: 100%; background: var(--color-ink); transition: width var(--dur-base) var(--ease); }
.v-shipbar[data-reached='true'] .v-shipbar__fill { background: var(--color-success); }
.v-shipbar[data-reached='true'] .v-shipbar__text { color: var(--color-success); }

/* ---------- §11. Рядок опції у шторці фільтра ---------- */

.v-option-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: 52px;
  padding: var(--sp-2) var(--gutter);
  font-size: var(--fs-body);
  text-align: left;
  border-bottom: var(--border);
}
.v-option-row__box {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  border: 1px solid var(--color-line);
  border-radius: 4px;
  color: transparent;
  font-size: 13px;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
/* Стан лежить на схованому інпуті, а не на мітці: правило нижче
   малювало галочку за aria-checked, який тут ніхто не ставив, тож
   фільтр працював, а відмітки не було видно. Інпут стоїть прямо перед
   квадратиком, тому вистачає сусіднього селектора. */
.v-option-row input:checked + .v-option-row__box,
.v-option-row[aria-checked='true'] .v-option-row__box {
  background: var(--color-btn);
  border-color: var(--color-btn);
  color: var(--color-on-btn);
}
.v-option-row__dot { width: 20px; height: 20px; border-radius: var(--radius-pill); background: var(--swatch-color, var(--color-surface)); }
.v-option-row__dot--light { border: 1px solid var(--color-line); }
.v-option-row__count { margin-left: auto; font-size: var(--fs-meta); color: var(--color-muted); }

/* Чипи фільтрів — горизонтальна стрічка, sticky під хедером */
.v-chips {
  display: flex; gap: var(--sp-2);
  overflow-x: auto;
  scrollbar-width: none;
  padding-block: var(--sp-3);
}
.v-chips::-webkit-scrollbar { display: none; }
.v-chip {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 6px;
  min-height: var(--tap-min);
  padding-inline: var(--sp-4);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-pill);
  font-size: var(--fs-meta);
  white-space: nowrap;
  background: var(--color-bg);
}
.v-chip[data-active='true'] { border-color: var(--color-ink); }
.v-chip--applied { background: var(--color-surface); border-color: var(--color-surface); }

/* ---------- §12. Поле вводу ---------- */

.v-field { display: block; }
.v-field__label { display: block; font-size: var(--fs-meta); color: var(--color-muted); margin-bottom: 6px; }
.v-input {
  width: 100%;
  height: var(--input-h);
  padding-inline: var(--sp-4);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-input);
  background: var(--color-bg);
  font-size: 16px; /* менше — iOS Safari зумить сторінку при фокусі */
  line-height: 1;
  color: var(--color-body);
}
/* outline: none тут не було чим замінити для клавіатури: зміна рамки з
   #E5E5E5 на #202020 читається мишею, але слабо — а глобальне кільце
   *:focus-visible ми самі й глушили. Тепер рамка лишається для будь-якого
   фокуса, а кільце домальовується тільки клавіатурному. */
.v-input:focus { border-color: var(--color-ink); }
.v-input[aria-invalid='true'] { border-color: var(--color-error); }
.v-input:disabled { background: var(--color-surface); color: var(--color-muted); }
.v-field__error { display: block; margin-top: 6px; font-size: var(--fs-small); color: var(--color-error); }

/* ---------- §13. Зоряний рейтинг ---------- */

.v-rating { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-meta); color: var(--color-body); text-decoration: none; }
.v-rating__stars { font-size: 14px; letter-spacing: 1px; color: var(--color-star-on); }
.v-rating__stars span { color: var(--color-star-off); }
.v-rating__count { color: var(--color-muted); }

/* ---------- Три рядки довіри під кнопкою ---------- */

.v-trust { display: grid; gap: var(--sp-2); margin-top: var(--sp-4); }
.v-trust__row { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-meta); color: var(--color-body); }
.v-trust__row svg { flex: 0 0 auto; width: 18px; height: 18px; }

/* ---------- Скелетон ---------- */

.v-skeleton { background: var(--color-surface); }
.v-skeleton--media { aspect-ratio: var(--ratio-product); }
.v-skeleton--line { height: 12px; margin-top: var(--sp-2); }
.v-skeleton--line.is-short { width: 40%; }

/* ---------- Порожні стани й помилки ---------- */

.v-empty { text-align: center; padding-block: var(--sp-12); }
.v-empty__title {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  line-height: var(--display-lh);
  text-transform: uppercase;
  font-size: var(--fs-section);
  color: var(--color-ink);
  margin: 0 0 var(--sp-4);
}

.v-notice {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--color-error);
  border-radius: var(--radius-input);
  font-size: var(--fs-meta);
  color: var(--color-error);
}

/* Коли відкрита будь-яка шторка — сторінка під нею не скролиться */
body[data-panel-open='true'] { overflow: hidden; }

/* ============================================================
   §17. Галерея товару (Промт 2, розділ 6.2)
   Деградація за кількістю фото — жорстко, без порожніх слотів:
   1 кадр  — каруселі немає, крапок і лічильника немає
   2–3     — крапки є, лічильник прихований («2/3» виглядає бідно)
   4+      — повний режим
   0       — плейсхолдер, товар не ховається
   ============================================================ */

.v-gallery { position: relative; }

.v-gallery__track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  transition: opacity var(--dur-slow) var(--ease);
}
.v-gallery__track::-webkit-scrollbar { display: none; }
.v-gallery__track[hidden] { display: none; }
.v-gallery[data-swapping='true'] .v-gallery__track { opacity: 0; }

.v-gallery__slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  margin: 0;
  aspect-ratio: var(--ratio-product);
  background: var(--color-surface);
  overflow: hidden;
}
.v-gallery__slide img { width: 100%; height: 100%; object-fit: cover; }

/* Один кадр — свідоме рішення, а не недобудована карусель */
.v-gallery[data-count='1'] .v-gallery__track { overflow-x: hidden; scroll-snap-type: none; }

.v-gallery__counter {
  position: absolute;
  top: var(--sp-3);
  right: var(--sp-3);
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  background: var(--color-scrim);
  color: #fff;
  font-size: var(--fs-small);
  line-height: 1.4;
  pointer-events: none;
}
.v-gallery[data-count='0'] .v-gallery__counter,
.v-gallery[data-count='1'] .v-gallery__counter,
.v-gallery[data-count='2'] .v-gallery__counter,
.v-gallery[data-count='3'] .v-gallery__counter { display: none; }

.v-gallery__dots {
  display: flex;
  justify-content: center;
  gap: 0;
  padding-top: var(--sp-2);
}
.v-gallery[data-count='0'] .v-gallery__dots,
.v-gallery[data-count='1'] .v-gallery__dots { display: none; }

.v-gallery__dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 24px — мінімум, який вимагає Lighthouse для сусідніх цілей.
     Було 20: за самою зоною дотику 44px усе гаразд, але перевірка
     дивиться на ширину елемента, а сусіди стоять упритул. */
  width: 24px;
  height: var(--tap-min); /* візуально 6px, зона дотику 44px */
}
.v-gallery__dot::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--color-line);
  transition: background-color var(--dur-fast) var(--ease);
}
.v-gallery__dot[aria-selected='true']::before { background: var(--color-ink); }

/* Плейсхолдер, коли фото немає взагалі */
.v-gallery__empty {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: var(--ratio-product);
  background: var(--color-surface);
  font-family: var(--font-display);
  font-size: 32px;
  line-height: 1;
  text-transform: uppercase;
  color: var(--color-line);
}

/* Desktop: та сама горизонтальна карусель, що й на телефоні.
   Вертикальна стрічка змушувала гортати сторінку, щоб побачити друге
   фото, — тобто йти від товару, а не роздивлятись його. Крапки й
   лічильник лишаються видимими: без них незрозуміло, що кадрів більше. */
@media (min-width: 1024px) {
  .v-gallery__track {
    display: flex;
    gap: 0;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
  }

  /* Зум при наведенні — тільки на пристроях із курсором */
  @media (hover: hover) and (pointer: fine) {
    .v-gallery__slide img {
      transition: transform var(--dur-fast) var(--ease);
      cursor: zoom-in;
    }
    .v-gallery__slide[data-zoomed='true'] img { transition-duration: var(--dur-base); }
  }
}

/* Фулскрін-в'ювер */
.v-viewer { inset: 0; width: 100vw; height: 100dvh; background: var(--color-bg); transform: translateY(100%); }
.v-viewer[data-open='true'] { transform: translateY(0); }
.v-viewer__stage {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  touch-action: none;
  background: var(--color-bg);
}
.v-viewer__img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  transform-origin: 0 0;
  will-change: transform;
}
.v-viewer__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--gutter);
  padding-bottom: calc(var(--sp-3) + var(--safe-bottom));
  border-top: var(--border);
}
.v-viewer__nav button {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--tap-min); height: var(--tap-min);
  font-size: var(--fs-body);
}
.v-viewer__nav button[disabled] { color: var(--color-btn-disabled); }

/* ============================================================
   §18. Блоки під картиною товару: виробництво, відгуки, стрічки
   ============================================================ */

.v-production__heading { margin-bottom: var(--sp-6); }
.v-production__media { margin-inline: calc(var(--gutter) * -1); }
.v-production__media img { width: 100%; }
.v-production__text { margin-top: var(--sp-6); max-width: 60ch; }

@media (min-width: 1024px) {
  .v-production__media { margin-inline: 0; }
}

.v-reviews__summary { margin: var(--sp-4) 0 var(--sp-6); }

/* Фото й текст ідуть парою, тому окремої сітки кадрів більше немає.
   .v-reviews__media та .v-reviews__shot прибрані разом із нею. */

.v-reviews__list { margin-top: var(--sp-8); }

/* Відгуки — горизонтальна стрічка карток, а не стовпчик.
   Власник: «хотів, щоб там горизонтально крутились фотографії людей».
   Ширини — ті самі, що в стрічці товарів, щоб сторінка мала один ритм. */
.v-rail--reviews > * { width: calc(66% - var(--grid-gap)); }
@media (min-width: 600px)  { .v-rail--reviews > * { width: calc(40% - var(--grid-gap)); } }
@media (min-width: 1024px) { .v-rail--reviews > * { width: calc(28% - var(--grid-gap)); } }

.v-review { display: block; }

/* Кадр покупця — головний елемент картки. Пропорція та сама, що в
   галереї товару: знімки з телефонів приходять різної висоти, і без
   фіксованої клітинки стрічка стрибала б на кожній картці. */
.v-review__shot {
  width: 100%;
  aspect-ratio: var(--ratio-product);
  object-fit: cover;
  background: var(--color-surface);
  display: block;
}

.v-review__body { margin-top: var(--sp-3); }
.v-review__text { margin: var(--sp-2) 0; }
.v-review__verified { color: var(--color-success); }

/* Відгук без фото не лишає порожньої рамки — тільки текст, але з тим
   самим відступом, щоб картка не «підстрибувала» в ряду. */
.v-review--plain .v-review__body { margin-top: 0; }

.v-reviews__more { margin-top: var(--sp-6); }

/* Стрічка на mobile, сітка на desktop */
@media (min-width: 1024px) {
  .v-rail--grid-lg {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    overflow: visible;
    scroll-snap-type: none;
    margin-inline: 0;
    padding-inline: 0;
  }
  .v-rail--grid-lg > * { width: auto; }
}

/* ---------- §19. Апсели в кошику ---------- */

.v-fillers { padding: var(--sp-4) var(--gutter); border-top: var(--border); }
.v-fillers__title { margin: 0 0 var(--sp-3); }

.v-filler { width: 128px; }
.v-filler__media {
  display: block;
  aspect-ratio: var(--ratio-product);
  background: var(--color-surface);
  overflow: hidden;
}
.v-filler__media img { width: 100%; height: 100%; object-fit: cover; }
.v-filler__title {
  margin: var(--sp-2) 0 0;
  font-size: var(--fs-small);
  line-height: var(--lh-name);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.v-filler__price { margin: var(--sp-1) 0 var(--sp-2); font-size: var(--fs-meta); color: var(--color-ink); }
.v-filler__add { width: 100%; height: 40px; padding-inline: var(--sp-2); font-size: var(--fs-meta); }

/* Сторінка /cart — запасний вихід, дві колонки на desktop */
.v-cart-page__items { border-top: var(--border); }
.v-cart-page__summary { padding-top: var(--sp-6); }
@media (min-width: 1024px) {
  .v-cart-page {
    display: grid;
    grid-template-columns: 1fr 380px;
    gap: var(--sp-12);
    align-items: start;
  }
  .v-cart-page__summary { position: sticky; top: var(--sp-8); padding-top: 0; }
}

/* Заголовок опції, у якому значення стоїть одразу біля назви */
.v-sizes__head--start { justify-content: flex-start; }

/* ---------- Футер ---------- */
/* Стилі футера жили у vidro-home.css, який підключає лише секція
   головної. Футер же стоїть на кожній сторінці — тож усюди, крім
   головної, він показувався голим списком із маркерами. */

.v-footer {
  margin-top: var(--section-gap);
  padding-block: var(--sp-12) var(--sp-8);
  border-top: var(--border);
}

.v-footer__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-8);
}
/* Колонок стало чотири: два меню, звʼязок і підписка. На середньому
   екрані вони лягають по дві, щоб рядки лишались читабельними. */
@media (min-width: 600px)  { .v-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .v-footer__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.v-footer__col--wide { grid-column: span 1; }
@media (min-width: 600px) and (max-width: 1023px) { .v-footer__col--wide { grid-column: 1 / -1; } }

/* Підписка: поле й кнопка в рядок, на вузькому — стовпчиком. */
.v-subscribe { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }
.v-subscribe__input { flex: 1 1 180px; }
.v-subscribe__btn { flex: 0 0 auto; padding-inline: var(--sp-6); height: var(--input-h); }
.v-subscribe__ok { flex: 1 0 100%; color: var(--color-success); }
.v-subscribe__err { flex: 1 0 100%; color: var(--color-error); }

.v-footer__title {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-meta);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--color-muted);
}
.v-footer__list { list-style: none; margin: 0; padding: 0; }
.v-footer__list a {
  display: flex;
  align-items: center;
  min-height: var(--tap-min);
  font-size: var(--fs-body);
  color: var(--color-body);
  text-decoration: none;
}
@media (hover: hover) { .v-footer__list a:hover { text-decoration: underline; text-underline-offset: 4px; } }

.v-footer__text { max-width: 40ch; }

.v-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-top: var(--sp-12);
  padding-top: var(--sp-4);
  border-top: var(--border);
}
.v-footer__payments {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  list-style: none;
  margin: 0;
  padding: 0;
}
.v-footer__payment { height: 24px; width: auto; }

/* ---------- Текстова сторінка ---------- */

.v-page { padding-bottom: var(--sp-16); }

.v-page__body {
  /* 70 символів у рядку. Оферта — це 19 тисяч знаків суцільним текстом,
     і рядок у всю ширину монітора око просто не дочитує до кінця. */
  max-width: 70ch;
  margin-top: var(--sp-6);
}

.v-page__body h2 {
  margin: var(--sp-12) 0 var(--sp-3);
  font-family: var(--font-display);
  font-size: var(--fs-doc-head);
  line-height: var(--lh-tight);
  text-transform: uppercase;
}
.v-page__body h3 {
  margin: var(--sp-8) 0 var(--sp-2);
  font-size: var(--fs-body);
  font-weight: 700;
}
.v-page__body p { margin: 0 0 var(--sp-4); }
.v-page__body ul,
.v-page__body ol { margin: 0 0 var(--sp-4); padding-left: var(--sp-6); }
.v-page__body li { margin-bottom: var(--sp-2); }
.v-page__body a { color: var(--color-ink); text-underline-offset: 3px; }

/* Раніше це давав клас .rte з base.css. Оскільки base.css більше не
   підключаємо, картинки й таблиці всередині тексту треба вгамувати
   самим: картинка з адмінки легко приходить у 2000px завширшки. */
.v-page__body img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: var(--sp-6) 0;
}

/* Фото в тексті сторінки («Про нас»). На телефоні — на всю ширину, як
   і будь-яка картинка. На широкому екрані обтікається текстом: колонка
   тут 70ch ≈ 640px, і портретний кадр на всю ширину дає 770px висоти —
   заголовок розділу й перший абзац опиняються на різних екранах. */
.v-page__body .v-page__figure { margin: var(--sp-6) 0; }
.v-page__body a.v-page__figure { display: block; }
.v-page__body a.v-page__figure img { margin: 0; }

@media (min-width: 900px) {
  .v-page__body .v-page__figure {
    float: right;
    width: 38%;
    margin: var(--sp-1) 0 var(--sp-6) var(--sp-8);
  }
  /* Наступний розділ починається під фото, а не збоку від нього. */
  .v-page__body h2 { clear: both; }
}
.v-page__body table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--sp-6) 0;
  font-size: var(--fs-meta);
}
.v-page__body th,
.v-page__body td {
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--color-line);
  text-align: left;
}
.v-page__body blockquote {
  margin: var(--sp-6) 0;
  padding-left: var(--sp-4);
  border-left: 2px solid var(--color-line);
  color: var(--color-muted);
}

/* Перший заголовок після H1 не має відриватись від нього зайвим полем */
.v-page__body > h2:first-child,
.v-page__body > h3:first-child { margin-top: 0; }

/* ---------- Категорійні плитки ---------- */
/* Не тільки для головної: тими самими плитками показуємо список усіх
   категорій. Поки стилі жили у vidro-home.css, та сторінка була гола. */

.v-tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--grid-gap);
  margin-top: var(--sp-6);
}
@media (min-width: 1024px) { .v-tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.v-tile { display: block; text-decoration: none; color: var(--color-body); }
.v-tile__media {
  display: block;
  aspect-ratio: var(--ratio-product);
  background: var(--color-surface);
  overflow: hidden;
}
.v-tile__media img { width: 100%; height: 100%; object-fit: cover; }
.v-tile__title {
  display: block;
  margin-top: var(--sp-3);
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  line-height: var(--display-lh);
  font-size: 20px;
  text-transform: uppercase;
  color: var(--color-ink);
}

/* ---------- 404 і список категорій ---------- */

.v-404 { padding-block: var(--sp-12) var(--sp-16); }

/* Число велике й приглушене: воно тут як покажчик, а не як заголовок.
   Читає людина наступний рядок, а не «404». */
.v-404__code {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  line-height: 1;
  font-size: var(--fs-hero);
  color: var(--color-ghost);
}

.v-404__lead { max-width: 46ch; margin: var(--sp-4) 0 var(--sp-8); }

.v-404__search {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  max-width: 520px;
}
.v-404__search .v-input { flex: 1 1 240px; }
.v-404__links { margin-top: var(--sp-6); }

.v-collections { padding-bottom: var(--sp-16); }
.v-collections .v-tiles { margin-top: var(--sp-8); }

/* ---------- Журнал ---------- */

.v-blog { padding-bottom: var(--sp-16); }
.v-blog__list { margin-top: var(--sp-8); }
@media (min-width: 1024px) {
  .v-blog__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.v-post { display: block; text-decoration: none; color: var(--color-body); }
.v-post__media {
  display: block;
  aspect-ratio: var(--ratio-product);
  background: var(--color-surface);
  overflow: hidden;
}
.v-post__media img { width: 100%; height: 100%; object-fit: cover; }
.v-post__title {
  display: block;
  margin-top: var(--sp-3);
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  line-height: var(--display-lh);
  font-size: 20px;
  text-transform: uppercase;
  color: var(--color-ink);
}
.v-post__meta {
  display: block;
  margin-top: var(--sp-1);
  font-size: var(--fs-small);
  color: var(--color-muted);
}
.v-post__excerpt {
  display: block;
  margin-top: var(--sp-2);
  font-size: var(--fs-meta);
  color: var(--color-body);
}

.v-article { padding-bottom: var(--sp-16); }
.v-article__date { margin: var(--sp-2) 0 var(--sp-6); }
.v-article__cover {
  display: block;
  width: 100%;
  max-width: 900px;
  height: auto;
  margin-bottom: var(--sp-8);
}
.v-article__back { margin-top: var(--sp-12); }

/* ---------- Форма зв'язку ---------- */

/* .v-notice спершу існував тільки як помилка — червона рамка була
   вшита в базовий клас. Тепер колір задає модифікатор, інакше
   повідомлення про успішну відправку виглядало б як збій. */
.v-notice--ok {
  border-color: var(--color-line);
  color: var(--color-ink);
}
.v-notice--error { border-color: var(--color-error); color: var(--color-error); }
.v-notice--error ul { margin: var(--sp-2) 0 0; padding-left: var(--sp-6); }
.v-notice { display: block; }

.v-contact { padding-bottom: var(--sp-16); }
.v-contact__form {
  display: grid;
  gap: var(--sp-4);
  max-width: 520px;
  margin: 0;
}
.v-contact__form .v-btn { justify-self: start; }

/* Багаторядкове поле не може мати фіксовану висоту рядка-інпута */
.v-input--area {
  height: auto;
  padding-block: var(--sp-3);
  line-height: var(--lh-body);
  resize: vertical;
}

/* ---------- Мова ---------- */

.v-footer__lang { display: flex; }

.v-lang {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  margin: 0;
}
.v-lang__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding-inline: var(--sp-2);
  font-size: var(--fs-small);
  letter-spacing: 0.5px;
  color: var(--color-muted);
}
.v-lang__item[aria-current='true'] { color: var(--color-ink); }
.v-lang__item--btn {
  border: 0;
  background: none;
  cursor: pointer;
  font-family: inherit;
}
@media (hover: hover) {
  .v-lang__item--btn:hover { color: var(--color-ink); text-decoration: underline; text-underline-offset: 4px; }
}

/* Смуга над хедером. Тонка навмисне: це пропозиція, а не оголошення. */
.v-langbar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--gutter);
  background: var(--color-surface);
  border-bottom: var(--border);
  font-size: var(--fs-small);
}
.v-langbar[hidden] { display: none; }
.v-langbar__form { display: contents; margin: 0; }
.v-langbar__text { color: var(--color-body); }
.v-langbar__go {
  border: 0;
  background: none;
  padding: 0;
  font-family: inherit;
  font-size: inherit;
  color: var(--color-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.v-langbar__close {
  position: absolute;
  right: var(--gutter);
  border: 0;
  background: none;
  padding: var(--sp-1);
  font-size: var(--fs-small);
  line-height: 1;
  color: var(--color-muted);
  cursor: pointer;
}
.v-langbar { position: relative; }

/* ---------- Промокод у кошику ---------- */

.v-promo { display: block; margin-bottom: var(--sp-4); }

/* Кнопка-текст, а не поле: відкрите поле знижки бачить і той, у кого коду
   немає, — і йде його шукати замість того, щоб оформити замовлення. */
.v-promo__toggle {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: var(--fs-small);
  color: var(--color-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.v-promo__toggle:hover { color: var(--color-ink); }
.v-promo__toggle:focus-visible { outline: 2px solid var(--color-ink); outline-offset: 3px; }

.v-promo__row { display: flex; gap: var(--sp-2); align-items: stretch; }
.v-promo__row[hidden] { display: none; }
.v-promo__input { flex: 1 1 auto; min-width: 0; text-transform: uppercase; }
.v-promo__apply { flex: 0 0 auto; }

.v-promo__applied {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-small);
  color: var(--color-success);
}
.v-promo__error {
  margin: var(--sp-2) 0 0;
  font-size: var(--fs-small);
  color: var(--color-error, #B3261E);
}

/* ---------- §26. Стрічка, що гортається і на desktop ---------- */
/* Власник: «прямо топчик — має бути стрічка яка гортається, а не 3 товари»,
   «що шукаєте — теж стрічка, а не 4 плитки».

   Ключове тут — НЕ додати ще картинок у сітку, а прибрати саму сітку:
   .v-rail--grid-lg на широкому екрані вимикав скрол і робив рівно чотири
   колонки, тож скільки товарів не постав, у першому ряду їх лишалось
   чотири, а решта падала другим рядом. Модифікатор --wide лишає стрічку
   стрічкою на всіх ширинах. */

@media (min-width: 1024px) {
  /* Некругле число навмисно: обрізаний край останньої картки видно, і
     він читається як «далі є ще». Рівно чотири виглядали б завершеною
     сіткою, і ніхто б не гортав.

     Було 23% і 19% — на 1440 це давало картку 235 px і шість штук на
     екран. Для одягу замало: власник «на головній збільшити основні
     фото, бо наразі вони дуже малі». Тепер 30% і 25,5% — на 1440 це
     363 px і майже чотири картки, тобто фото більші вдвічі за площею,
     а натяк на прокрутку лишився. */
  .v-rail--wide > * { width: calc(30% - var(--grid-gap)); }
}
@media (min-width: 1400px) {
  .v-rail--wide > * { width: calc(25.5% - var(--grid-gap)); }
}

/* Стрілки: тільки для миші. На тачскріні вони зайві й з'їдають кадр.

   Стоять під стрічкою у звичайному потоці, а не абсолютом біля
   заголовка: абсолют довелось би підганяти окремими відступами під
   кожну секцію, і будь-яка зміна заголовка його б зсувала. */
/* Було ще й `min-width: 1024px`, і на ноутбуці у вузькому вікні стрілок
   не було зовсім — власник: «на головній додати стрілочки в кожному
   блоці, щоб можна було гортати». Умова про мишу лишається: на
   тачскріні стрічка гортається пальцем, і кнопки там тільки з'їдають
   кадр. */
.v-rail__nav { display: none; }

@media (hover: hover) and (pointer: fine) {
  vidro-rail[data-scrollable] .v-rail__nav {
    display: flex;
    justify-content: flex-end;
    gap: var(--sp-2);
    margin-top: var(--sp-4);
  }

  .v-rail__arrow {
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
    padding: 0;
    border: var(--border);
    background: var(--color-bg);
    color: var(--color-ink);
    cursor: pointer;
    transition: background 0.15s, color 0.15s, opacity 0.15s;
  }
  .v-rail__arrow:hover { background: var(--color-ink); color: var(--color-bg); }
  .v-rail__arrow:disabled { opacity: 0.3; cursor: default; }
  .v-rail__arrow:disabled:hover { background: var(--color-bg); color: var(--color-ink); }
}

/* Плитки категорій стрічкою: та сама механіка, інші пропорції —
   плитка ширша за картку товару, бо на ній лише назва. */
.v-tiles--rail {
  display: flex;
  grid-template-columns: none;
  gap: var(--grid-gap);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.v-tiles--rail::-webkit-scrollbar { display: none; }
.v-tiles--rail > * { scroll-snap-align: start; flex: 0 0 auto; width: calc(66% - var(--grid-gap)); }

@media (min-width: 600px)  { .v-tiles--rail > * { width: calc(40% - var(--grid-gap)); } }
@media (min-width: 1024px) { .v-tiles--rail > * { width: calc(28% - var(--grid-gap)); } }
@media (min-width: 1400px) { .v-tiles--rail > * { width: calc(23% - var(--grid-gap)); } }

/* ---------- §27. Бігуча строка ---------- */

.v-marquee {
  /* Доріжка всередині ширша за екран навмисно — так рядок і їде.
     `contain: paint` каже браузеру, що назовні з цього блоку нічого
     не малюється, тож його ширина більше не впливає на ширину
     документа. Без цього scrollWidth сторінки був 3508 px. */
  contain: paint;
  max-width: 100%;
  overflow: hidden;
  background: var(--marquee-bg, var(--color-ink));
  color: var(--marquee-fg, var(--color-bg));
  padding-block: var(--sp-3);
  /* Смуга йде від краю до краю екрана, а не по сітці контенту:
     обрізаний край — і є ознака того, що рядок рухається далі. */
  width: 100%;
}

.v-marquee__track {
  display: flex;
  width: max-content;
  animation: v-marquee-run var(--marquee-speed, 40s) linear infinite;
}
.v-marquee[data-direction='right'] .v-marquee__track { animation-direction: reverse; }

/* Пауза під курсором: дає прочитати фразу, яка зачепила. */
.v-marquee:hover .v-marquee__track { animation-play-state: paused; }

.v-marquee__run {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding-inline-end: var(--sp-4);
  white-space: nowrap;
}

.v-marquee__item {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-size: 20px;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.v-marquee__dot { opacity: 0.5; font-size: 14px; }

@media (min-width: 1024px) {
  .v-marquee__item { font-size: 26px; }
  .v-marquee__run { gap: var(--sp-6); padding-inline-end: var(--sp-6); }
}

/* Рівно −50%: track складається з двох однакових прогонів, тож у цій
   точці другий стоїть точно там, де на старті стояв перший. Будь-яке
   інше число дало б помітний стрибок. */
@keyframes v-marquee-run {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .v-marquee__track { animation: none; }
  /* Без руху другий прогін — просто дубль тексту, ховаємо. */
  .v-marquee__run + .v-marquee__run { display: none; }
  .v-marquee__track { width: 100%; overflow-x: auto; }
}

/* Інформаційний варіант смуги: без прогресу, лише умови доставки. */
.v-shipbar--plain .v-shipbar__text { margin: 0; }

/* ============================================================
   Кабінет покупця (класичний)
   ============================================================
   Сторінки входу, реєстрації, замовлень і адрес малює тема, а не
   Shopify: нові «customer accounts» приходили англійською і з
   «Unsupported locale: uk-UA» у консолі.
   ============================================================ */

/* Вузька колонка для форм. 34rem — це ≈54 символи в полі, далі поле
   стає незручно довгим, а очі губляться між лейблом і значенням. */
.v-narrow { max-width: 34rem; }

.v-h3 {
  font-size: var(--fs-doc-head);
  line-height: 1.2;
  margin: 0 0 var(--sp-3);
}

.v-link { text-decoration: underline; text-underline-offset: 3px; }
.v-link:hover { color: var(--color-ink); }

.v-account__form { display: grid; gap: var(--sp-4); margin-top: var(--sp-4); }
.v-account__aside { margin-top: var(--sp-12); padding-top: var(--sp-6); border-top: var(--border); }
.v-account__switch { margin-top: var(--sp-6); }
.v-account__block { margin-top: var(--sp-8); padding-top: var(--sp-6); border-top: var(--border); }

.v-account__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  align-items: baseline;
  justify-content: space-between;
}

.v-account__grid { display: grid; gap: var(--sp-8); margin-top: var(--sp-6); }
@media (min-width: 900px) {
  .v-account__grid { grid-template-columns: minmax(0, 1fr) 18rem; gap: var(--sp-12); }
}

.v-account__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

.v-check { display: flex; gap: var(--sp-2); align-items: center; }
.v-check input { width: 18px; height: 18px; }

/* Замовлення. На телефоні таблиця не влазить, тому це список: кожен
   рядок — стовпчик, на ширині від 700px розкладається в лінію. */
.v-orders { list-style: none; margin: var(--sp-4) 0 0; padding: 0; }
.v-orders__row {
  display: grid;
  gap: var(--sp-1);
  padding-block: var(--sp-4);
  border-bottom: var(--border);
}
.v-orders__row--total { font-weight: 600; }
.v-orders--totals { border-top: var(--border); margin-top: var(--sp-6); }

@media (min-width: 700px) {
  .v-orders__row {
    grid-template-columns: minmax(0, 2fr) repeat(3, minmax(0, 1fr)) auto;
    gap: var(--sp-4);
    align-items: baseline;
  }
}

/* ---------- Обране й «ви дивились» ---------- */

/* Серце на картці товару. Контур, а не заливка: заповнене серце в
   каталозі читається як «уже додано», і людина не тисне. */
.v-wish {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-text, #171717);
  cursor: pointer;
  border-radius: 999px;
}
.v-wish svg { width: 22px; height: 22px; }
.v-wish:hover svg { transform: scale(1.08); }
.v-wish svg { transition: transform 120ms ease, fill 120ms ease; }
.v-wish.is-on svg { fill: currentColor; }
.v-wish:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

.v-pdp__titlerow {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
/* Серце не має тягнути на себе висоту рядка заголовка */
.v-wish--pdp { flex: 0 0 auto; margin-top: -4px; }

.v-header__wish { position: relative; }

.v-saved__empty {
  display: grid;
  gap: 16px;
  justify-items: start;
  padding: 24px 0;
}

/* ---------- Плаваюча кнопка «Написати» ---------- */

/* Праворуч знизу, але вище краю: на iOS там панель Safari, і кнопка
   впритул до низу непритискається. safe-area-inset рахує «чубчик» і
   домашню смугу. */
.v-fab {
  position: fixed;
  right: 16px;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 40;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 48px;
  padding-inline: 16px;
  border-radius: 999px;
  background: var(--color-btn, #171717);
  color: var(--color-on-btn, #fff);
  text-decoration: none;
  font-size: var(--fs-btn, 14px);
  line-height: 1;
}
.v-fab svg { width: 22px; height: 22px; flex: 0 0 auto; }
.v-fab:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

/* На телефоні лишається тільки іконка: підпис забирає пів екрана в
   ширину і накриває картки в каталозі. */
@media (max-width: 599px) {
  .v-fab { padding-inline: 0; width: 48px; justify-content: center; }
  .v-fab__text { display: none; }
}

.v-faq__intro { margin-bottom: 24px; }
.v-faq__rest { margin-top: 32px; }

/* ---------- Плашка промокоду ---------- */

/* Зверху по центру, а не знизу: внизу вже стоїть кнопка «Написати», а на
   картці товару — липкий бар «Купити». Три елементи в одному куті
   перекривають один одного на телефоні. */
.v-toast {
  position: fixed;
  top: calc(12px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: calc(100vw - 24px);
  padding: 12px 12px 12px 16px;
  border-radius: 999px;
  background: var(--color-btn, #171717);
  color: var(--color-on-btn, #fff);
  font-size: var(--fs-meta, 13px);
  line-height: 1.3;
}
.v-toast[hidden] { display: none; }
.v-toast__text { min-width: 0; }
.v-toast__close {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  color: inherit;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.v-toast__close:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

/* ---------- «Це подарунок» ---------- */

.v-gift { display: block; margin-top: 12px; }
.v-gift__row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: var(--tap-min, 44px);
  cursor: pointer;
  font-size: var(--fs-meta, 13px);
}
.v-gift__row input { width: 18px; height: 18px; flex: 0 0 auto; }
.v-gift__note { margin-top: 8px; }
.v-gift__note textarea { width: 100%; resize: vertical; }
.v-gift__hint { margin-top: 4px; }

/* ---------- Кадри покупців ---------- */

.v-ugc__sub { margin-bottom: 16px; }
.v-ugc__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
@media (min-width: 600px) { .v-ugc__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .v-ugc__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.v-ugc__item {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: var(--radius-card, 4px);
  background: var(--color-surface, #f6f6f6);
  text-decoration: none;
}
.v-ugc__item img { width: 100%; height: 100%; object-fit: cover; }

/* Підпис товару з'являється на наведення. На дотику наведення немає,
   тому там він видимий завжди — інакше на телефоні незрозуміло, що
   кадр веде на товар. */
.v-ugc__tag {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  padding: 6px 10px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.72);
  color: #fff;
  font-size: 12px;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (hover: hover) {
  .v-ugc__tag { opacity: 0; transition: opacity var(--dur-fast, 140ms) var(--ease, ease); }
  .v-ugc__item:hover .v-ugc__tag,
  .v-ugc__item:focus-visible .v-ugc__tag { opacity: 1; }
}
.v-ugc__more { margin-top: 20px; }
