/* ============================================================
   components.css — кнопки, чипы, карточки, списки, формы, скелетоны, пустые состояния…
   Поля и тумблеры — в forms.css, каркас (топбар, навигация, бейдж кошелька) — в chrome.css, шторки и тосты —
   в overlays.css, шторки энергии, магазина 💎 и планов — в paywall.css, закрытые медиа в чате — здесь (в конце).
   Hover-эффекты — только для мыши: @media (hover: hover) and (pointer: fine), чтобы на тач-экранах
   не «залипала» подсветка.
   ============================================================ */

/* 💎 гемы: цвет и градиент (бейдж кошелька, магазин, цены закрытых медиа) */
:root {
  --gem: #6ee7f9;
  --grad-gem: linear-gradient(135deg, #a5f3fc, #6ee7f9 45%, #a78bfa);
}

/* ---------- Кнопки ----------
   .btn                      — вторичная (карточная) кнопка
   .btn--primary             — главный CTA: градиент, свечение, блик
   .btn--soft / --ghost      — мягкая фиолетовая / контурная
   .btn--glass               — стекло поверх фото и видео
   .btn--danger              — опасное действие
   Размеры (единые для всего приложения, экраны их не переопределяют): по умолчанию 48 (шрифт 15),
   --lg 56 — главный CTA экрана (шрифт 17), --sm 40 (шрифт 13), --xs 36 (зона касания всё равно 44 —
   невидимый ::before), --icon 44×44 (не сжимается в тесной строке), --block — на всю ширину.
   Высоты — токены --btn-h / --btn-h-lg / --btn-h-sm (base.css). Исключение — круглые кнопки звонка.
   Состояния: :active (нажатие), :disabled / [aria-disabled="true"], .is-loading (спиннер вместо подписи) */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--btn-h);
  padding: 0 20px;
  border-radius: var(--r-pill);
  font-weight: var(--fw-bold);
  font-size: var(--fs-base);
  letter-spacing: -0.005em;
  color: var(--text);
  background: var(--card-2);
  border: 1px solid var(--line);
  box-shadow: var(--inner-hi);
  transition: transform var(--t-fast) var(--ease), opacity var(--t-fast), background-color var(--t-fast),
    border-color var(--t-fast), box-shadow var(--t), filter var(--t-fast);
  white-space: nowrap;
  touch-action: manipulation;
}
.btn:active { transform: scale(0.97); }
.btn--primary {
  color: #fff;
  /* блик сверху поверх градиента — объём вместо «плоской» заливки */
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0) 55%), var(--grad);
  border-color: transparent;
  box-shadow: var(--glow), inset 0 1px 0 rgba(255, 255, 255, 0.22);
  text-shadow: 0 1px 1px rgba(90, 0, 50, 0.25);
}
.btn--primary:active { box-shadow: 0 4px 16px rgba(255, 45, 120, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.18); }
.btn--ghost { background: transparent; border-color: var(--line-2); box-shadow: none; }
.btn--soft { background: rgba(139, 92, 246, 0.16); border-color: rgba(139, 92, 246, 0.35); }
.btn--secondary { background: var(--card-2); border-color: var(--line-2); }
.btn--glass {
  color: #fff;
  background: var(--glass-bg-media);
  border-color: rgba(255, 255, 255, 0.18);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
}
.btn--danger { color: #fff; background: var(--red); border-color: transparent; box-shadow: 0 8px 24px rgba(255, 77, 94, 0.35); }
.btn--block { width: 100%; white-space: normal; text-align: center; line-height: 1.2; } /* длинная подпись переносится, а не вылезает за края */
.btn--lg { min-height: var(--btn-h-lg); padding: 0 28px; font-size: var(--fs-md); }
.btn--sm { min-height: var(--btn-h-sm); padding: 0 16px; font-size: var(--fs-sm); }
.btn--xs { min-height: 36px; padding: 0 14px; font-size: 12px; font-weight: var(--fw-semibold); }
/* Вид мелкой кнопки прежний, а палец попадает в 44 px: невидимое расширение сверху и снизу */
.btn--xs::before { content: ""; position: absolute; inset: -4px 0; border-radius: inherit; }
.btn--icon {
  flex: 0 0 auto; /* длинное имя рядом не сжимает кнопку до 30 px */
  width: 44px; height: 44px; min-height: 44px; padding: 0;
  border-radius: 50%;
}
.btn--icon .icon { width: 20px; height: 20px; }
.btn .icon { width: 18px; height: 18px; }
.btn--lg .icon { width: 20px; height: 20px; }
.btn:disabled,
.btn[aria-disabled="true"] { opacity: 0.5; box-shadow: none; filter: saturate(0.6); transform: none; cursor: default; }
/* Загрузка: подпись прячется под «крышку» цвета кнопки, по центру — спиннер; размер не прыгает */
.btn.is-loading { pointer-events: none; color: transparent; text-shadow: none; }
.btn.is-loading::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: inherit;
}
.btn.is-loading::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 20px; height: 20px;
  margin: -10px 0 0 -10px;
  border-radius: 50%;
  border: 2.5px solid rgba(255, 255, 255, 0.28);
  border-top-color: #fff;
  animation: spin 0.7s linear infinite;
}
.btn--sm.is-loading::after, .btn--xs.is-loading::after { width: 16px; height: 16px; margin: -8px 0 0 -8px; border-width: 2px; }

@media (hover: hover) and (pointer: fine) {
  .btn:hover:not(:disabled) { background-color: var(--card-3); border-color: var(--line-2); }
  .btn--primary:hover:not(:disabled) { filter: brightness(1.08); box-shadow: var(--glow-strong); }
  .btn--ghost:hover:not(:disabled) { background-color: rgba(255, 255, 255, 0.05); }
  .btn--soft:hover:not(:disabled) { background-color: rgba(139, 92, 246, 0.24); }
  .btn--glass:hover:not(:disabled) { background-color: rgba(10, 8, 20, 0.62); }
  .btn--danger:hover:not(:disabled) { filter: brightness(1.08); background-color: var(--red); }
}

.icon { display: inline-flex; width: 22px; height: 22px; flex: 0 0 auto; }
.icon svg { width: 100%; height: 100%; display: block; }

/* ---------- Чипы и сегменты ---------- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 15px;
  border-radius: var(--r-pill);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--muted);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line-2);
  transition: all var(--t-fast) var(--ease);
  white-space: nowrap;
}
button.chip:active { transform: scale(0.96); }
.chip.is-active {
  color: #fff;
  border-color: transparent;
  background: var(--grad);
  box-shadow: 0 4px 14px rgba(255, 45, 120, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.chip--glass {
  min-height: 26px;
  font-weight: var(--fw-bold);
  padding: 0 10px;
  font-size: 12px;
  color: #fff;
  background: var(--glass-bg-media);
  border-color: rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.chip--pink { color: var(--pink); border-color: rgba(255, 45, 120, 0.4); background: rgba(255, 45, 120, 0.1); }
/* Чип-подпись (не кнопка): компактный. Если это всё же кнопка — зона касания 44 px (невидимый ::before) */
.chip--xs { min-height: 30px; padding: 0 11px; font-size: 12px; }
button.chip--xs, a.chip--xs { position: relative; }
button.chip--xs::before, a.chip--xs::before { content: ""; position: absolute; inset: -7px -2px; border-radius: inherit; }
.chip-group { display: flex; flex-wrap: wrap; gap: 8px; }
.chip-group .chip { min-height: 44px; } /* выбираемые чипы — полноценная тап-зона */
.chip:disabled { opacity: 0.45; }
@media (hover: hover) and (pointer: fine) {
  button.chip:not(.is-active):not(:disabled):hover { color: var(--text); border-color: rgba(255, 255, 255, 0.24); background: rgba(255, 255, 255, 0.07); }
}

/* Сегмент-переключатель: «Реализм | Аниме», «Всё | Фото | Видео», периоды статистики, режимы в формах.
   Один компонент и одно активное состояние на всё приложение: мягкий розово-фиолетовый градиент, светлая кромка
   и розовый отсвет снизу — заметно, но не спорит с главной кнопкой и чипами-фильтрами (у них полный градиент).
   Разметка: .seg[role=tablist|radiogroup] > .seg__item(.is-active). Экран задаёт только ширину и место.
   Модификаторы: .seg--glass — поверх фото и видео; .seg--sm — плотные панели админки (40 px, шрифт 13);
   .seg--scroll — много пунктов: строка прокручивается, пункты по ширине подписи. */
.seg {
  display: flex;
  gap: 2px;
  padding: 3px;
  border-radius: var(--r-pill);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.25);
}
.seg__item {
  flex: 1;
  min-height: var(--tap);
  padding: 0 14px;
  border-radius: var(--r-pill);
  font-weight: var(--fw-bold);
  font-size: 14px;
  color: var(--muted);
  transition: color var(--t-fast), background-color var(--t-fast), box-shadow var(--t), transform var(--t-fast) var(--ease);
}
.seg__item:active { transform: scale(0.97); }
.seg__item.is-active { color: #fff; background: var(--seg-active-bg); box-shadow: var(--seg-active-shadow); }
.seg--glass {
  background: var(--glass-bg-media);
  border-color: var(--glass-border);
  box-shadow: none;
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
}
.seg--glass .seg__item:not(.is-active) { color: rgba(255, 255, 255, 0.72); }
.seg--sm .seg__item { min-height: var(--btn-h-sm); padding: 0 12px; font-size: 13px; }
.seg--scroll { overflow-x: auto; scrollbar-width: none; } /* лучше .hscroll + attachHScroll (колесо, края) */
.seg--scroll::-webkit-scrollbar { display: none; }
.seg--scroll .seg__item { flex: 1 0 auto; white-space: nowrap; }
@media (hover: hover) and (pointer: fine) { .seg__item:not(.is-active):hover { color: var(--text); background-color: rgba(255, 255, 255, 0.04); } }

.tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--line);
}
.tabs__item {
  position: relative;
  padding: 12px 12px;
  min-height: 44px;
  font-weight: var(--fw-bold);
  font-size: var(--fs-base);
  color: var(--muted);
  transition: color var(--t-fast);
}
.tabs__item.is-active { color: var(--text); }
.tabs__item.is-active::after {
  content: "";
  position: absolute;
  left: 8px; right: 8px; bottom: -1px;
  height: 3px;
  border-radius: 3px 3px 0 0;
  background: var(--grad);
  box-shadow: 0 0 12px rgba(255, 45, 120, 0.55);
  animation: tab-in 260ms var(--ease-out) both;
}
@keyframes tab-in { from { transform: scaleX(0.3); opacity: 0; } to { transform: none; opacity: 1; } }
@media (hover: hover) and (pointer: fine) { .tabs__item:not(.is-active):hover { color: var(--text); } }

/* ---------- Горизонтальная лента .hscroll (core/hscroll.js: attachHScroll) ----------
   .hscroll — раскладка: строка пунктов, которая листается пальцем. attachHScroll(el) — поведение для любой
   такой строки: колесо мыши листает вбок (Telegram Desktop), край гаснет, только если в ту сторону есть
   что листать (класс .hscroll-fade + --fade-l / --fade-r).
   Правило: на телефоне в ленте только то, что видно без прокрутки; остальное — кнопка «Фильтры» со шторкой.
   Внутри .page/.container ленту обычно делают .full-bleed, а поля задаёт --hscroll-pad. */
.hscroll {
  display: flex;
  gap: var(--hscroll-gap, 8px);
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  padding-inline: var(--hscroll-pad, 0px);
  scroll-padding-inline: var(--hscroll-pad, 0px);
}
.hscroll::-webkit-scrollbar { display: none; }
.hscroll > * { flex: 0 0 auto; }
.hscroll-fade.has-fade {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade-l, 0px), #000 calc(100% - var(--fade-r, 0px)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade-l, 0px), #000 calc(100% - var(--fade-r, 0px)), transparent 100%);
}

/* ---------- Имена ----------
   .text-name — длинное имя переносится по слогам (lang="ru"), а не рвётся посреди слова, как с anywhere.
   .name-age — имя и возраст в одну строку: имя с многоточием, возраст не пропадает:
     <span class="name-age"><span class="name-age__name">Имя</span><span class="name-age__age">, 23</span></span> */
.text-name { overflow-wrap: break-word; -webkit-hyphens: auto; hyphens: auto; }
.name-age { display: flex; align-items: baseline; min-width: 0; max-width: 100%; }
.name-age__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.name-age__age { flex: 0 0 auto; white-space: pre; }

/* ---------- Карточки, списки ---------- */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 16px;
  box-shadow: var(--inner-hi);
}
.card--soft { background: var(--grad-soft); border-color: rgba(139, 92, 246, 0.3); }
.card--glass {
  background: var(--glass-bg);
  border-color: var(--glass-border);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
}
/* Кликабельная карточка: нажатие и подсветка под мышью */
.card--interactive { transition: transform var(--t-fast) var(--ease), border-color var(--t), background-color var(--t); cursor: pointer; }
.card--interactive:active { transform: scale(0.985); }
.list { display: flex; flex-direction: column; gap: 8px; }
.list-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 10px 14px;
  text-align: left;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text);
  box-shadow: var(--inner-hi);
  transition: background-color var(--t-fast), border-color var(--t-fast), transform var(--t-fast) var(--ease);
}
.list-row:active { background: var(--card-2); }
button.list-row:active { transform: scale(0.99); }
.list-row__body { flex: 1; min-width: 0; }
.list-row__title { font-weight: var(--fw-bold); }
.list-row__sub { font-size: var(--fs-sm); color: var(--muted); margin-top: 2px; }
.list-row__aside { font-size: 12px; color: var(--muted-2); flex: 0 0 auto; }
@media (hover: hover) and (pointer: fine) {
  .card--interactive:hover { border-color: var(--line-2); background-color: var(--card-2); }
  button.list-row:hover, a.list-row:hover { background-color: var(--card-2); border-color: var(--line-2); }
}

.avatar {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--card-3);
}
.avatar--lg { width: 64px; height: 64px; }
.avatar-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--fw-heavy);
  color: #fff;
  background: var(--grad-diag);
}
/* Кольцо-градиент вокруг аватара (онлайн, «история») */
.avatar-ring { padding: 2px; border-radius: 50%; background: var(--grad-diag); flex: 0 0 auto; }
.avatar-ring > .avatar { display: block; border: 2px solid var(--bg); }

/* Счётчик-бейдж (непрочитанные, «новое») */
.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: var(--fw-heavy);
  line-height: 1;
  color: #fff;
  background: var(--grad);
  box-shadow: 0 2px 8px rgba(255, 45, 120, 0.4);
}

/* ---------- Скелетоны, спиннер, пустые состояния ----------
   Скелетон: .skeleton + размер (или модификатор): --text (строка), --title, --circle, --card (3:4).
   Один и тот же блик (keyframes sheen) у всех — не заводите свои анимации загрузки. */
.skeleton {
  background-color: var(--card);
  background-image: linear-gradient(100deg, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0.07) 50%, rgba(255, 255, 255, 0) 70%);
  background-size: 200% 100%;
  background-repeat: no-repeat;
  animation: sheen 1.5s ease-in-out infinite;
  border-radius: var(--r);
}
.skeleton--text { height: 14px; border-radius: 6px; }
.skeleton--title { height: 22px; width: 60%; border-radius: 8px; }
.skeleton--circle { border-radius: 50%; aspect-ratio: 1; }
.skeleton--card { aspect-ratio: 3 / 4; border-radius: var(--r-lg); }
.spinner {
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.12);
  border-top-color: var(--pink);
  animation: spin 0.8s linear infinite;
}
.spinner--sm { width: 18px; height: 18px; border-width: 2px; }
.loader-center { display: flex; justify-content: center; padding: 32px; animation: fade-in 300ms 120ms var(--ease) both; }
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
  padding: 48px 24px;
  color: var(--muted);
}
.empty__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 88px;
  height: 88px;
  margin-bottom: 10px;
  border-radius: 50%;
  font-size: 40px;
  line-height: 1;
  background: radial-gradient(circle at 50% 35%, rgba(139, 92, 246, 0.32), rgba(255, 45, 120, 0.08) 70%);
  box-shadow: inset 0 0 0 1px var(--line-2), 0 12px 40px rgba(139, 92, 246, 0.18);
}
.empty__icon .icon { width: 38px; height: 38px; color: var(--text); }
.empty__title { text-wrap: balance; font-size: 18px; font-weight: var(--fw-heavy); letter-spacing: -0.01em; color: var(--text); }
.empty .small { max-width: 300px; color: var(--muted); line-height: var(--lh-base); text-wrap: pretty; }
.empty .btn { margin-top: 12px; }
/* Компактное: ошибка или «пусто» внутри экрана с шапкой, фильтрами, навигацией — кнопка сразу под текстом
   и не уходит под навигацию на маленьких экранах. Правило: у сетевой ошибки всегда есть «Повторить»,
   у «не найдено» (404) — «Назад» (emptyState({compact: true, …}) в core/dom.js) */
.empty--compact { gap: 6px; padding: 20px 16px; }
.empty--compact .empty__icon { width: 32px; height: 32px; margin-bottom: 2px; font-size: 18px; box-shadow: inset 0 0 0 1px var(--line-2); }
.empty--compact .empty__icon .icon { width: 18px; height: 18px; }
.empty--compact .empty__title { font-size: 16px; }
.empty--compact .btn { margin-top: 8px; }
/* Кнопка здесь --sm (40 px на вид), палец попадает в 44: невидимое расширение сверху и снизу (К7).
   inset считается от внутреннего края рамки (1 px): −4 px — это 3 px за внешним краем, зона 46. Запас нужен:
   кнопка стоит на дробной координате, а попадание считается по целым пикселям */
.empty--compact .btn--sm:not(.is-loading)::before { content: ""; position: absolute; inset: -4px 0; border-radius: inherit; }
.empty__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 8px; }
.empty__actions .btn { margin-top: 0; }

/* «Печатает…» точки */
.typing { display: inline-flex; gap: 4px; padding: 4px 2px; }
.typing i {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--muted);
  animation: bounce-dot 1.2s infinite ease-in-out;
}
.typing i:nth-child(2) { animation-delay: 0.15s; }
.typing i:nth-child(3) { animation-delay: 0.3s; }

/* ---------- Полноэкранный просмотр медиа ---------- */
.viewer {
  position: fixed; inset: 0; z-index: 55;
  display: flex; flex-direction: column;
  background: rgba(3, 2, 8, 0.96);
  animation: fade-in var(--t) both;
}
.viewer__top { display: flex; justify-content: flex-end; padding: calc(var(--sat) + 10px) 12px 0; }
.viewer__media { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; padding: 8px; }
.viewer__media img, .viewer__media video { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 12px; }
.viewer__caption { padding: 10px 20px calc(20px + var(--sab)); display: flex; align-items: center; gap: 12px; }
.viewer__caption .grow { min-width: 0; }

/* ---------- Экран правил 18+ ---------- */
.terms {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 16px;
  padding: calc(var(--sat) + 40px) 28px calc(var(--sab) + 32px);
}
.terms__age {
  width: 96px; height: 96px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 34px; font-weight: var(--fw-black);
  background: var(--grad);
  box-shadow: var(--glow), inset 0 1px 0 rgba(255, 255, 255, 0.25);
  color: #fff;
}
.terms__text { color: var(--muted); max-width: 320px; line-height: var(--lh-base); }
.terms a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 8px; font-weight: var(--fw-semibold); }
.terms .btn { margin-top: 4px; }
@media (min-width: 600px) { .terms .btn { min-width: 320px; } }

/* ---------- Карточка стоимости ---------- */
.costs {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}
.costs span { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.costs span + span::before { content: "·"; margin-right: 6px; color: var(--muted-2); }
.costs b { color: var(--text); }
.price-tag { font-weight: var(--fw-bold); color: var(--amber); }

/* «Живой» аватар (components/liveAvatar.js): картинка сразу, зацикленное видео проявляется поверх,
   когда реально пошло воспроизведение (.is-live) — без чёрного кадра и мигания */
.live-avatar { position: relative; overflow: hidden; background: var(--card); }
.live-avatar__img,
.live-avatar__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.live-avatar__video { opacity: 0; transition: opacity 0.45s ease; pointer-events: none; }
.live-avatar.is-live .live-avatar__video { opacity: 1; }
.live-avatar__placeholder { position: absolute; inset: 0; background: linear-gradient(160deg, var(--card-2), var(--card)); }
@media (prefers-reduced-motion: reduce) { .live-avatar__video { display: none; } }

/* ---------- Закрытые медиа в чате и звонке (components/lockedMedia.js, скрины Luna 23, 25) ----------
   Размытое превью 3:4 с замком и ценой «💎5»; справа — [🎞 Видео] (розовая) и [↻ Ещё раз]; реплика — пузырём под
   карточкой. Файл закрытого не грузится: только крошечное превью, размытое здесь. */
.locked-msg { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; max-width: 100%; }
.locked-msg__text { max-width: min(78vw, 420px); }
/* «Снято для тебя» — своё фото по просьбе */
.locked-msg__own { font-size: 12px; font-weight: 700; letter-spacing: 0.01em; color: color-mix(in srgb, var(--pink) 70%, var(--text)); }
.locked-media { display: flex; align-items: flex-end; gap: 10px; min-width: 0; }
.locked-media__card {
  position: relative;
  flex: 0 0 auto;
  width: clamp(128px, 40vw, 168px);
  aspect-ratio: 3 / 4;
  overflow: hidden;
  isolation: isolate;
  border-radius: 18px;
  background: linear-gradient(160deg, var(--card-2), var(--card));
  border: 1px solid var(--line);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  transition: transform var(--t-fast) var(--ease);
}
.locked-media__card:active { transform: scale(0.97); }
/* Силуэт и цвета видны, детали — нет (как .pv__blur; карточка уже, поэтому и радиус меньше) */
.locked-media__blur {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: blur(8px) saturate(1.3) brightness(0.85);
  transform: scale(1.3);
  z-index: -1;
}
.locked-media__lock {
  position: absolute;
  top: 50%; left: 50%;
  width: 48px; height: 48px;
  margin: -24px 0 0 -24px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  color: #fff;
  background: rgba(11, 10, 20, 0.38);
  border: 1px solid rgba(255, 255, 255, 0.28);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.locked-media__lock .icon { width: 22px; height: 22px; }
.locked-media__kind {
  position: absolute; top: 8px; right: 8px;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  color: #fff;
  background: rgba(11, 10, 20, 0.45);
}
.locked-media__kind .icon { width: 14px; height: 14px; }
.locked-media__price {
  position: absolute;
  left: 8px; right: 8px; bottom: 8px;
  display: flex; align-items: center; justify-content: center; gap: 4px;
  min-height: 30px;
  border-radius: var(--r-pill);
  font-size: 14px;
  font-weight: var(--fw-heavy);
  font-variant-numeric: tabular-nums;
  color: #fff;
  background: rgba(11, 10, 20, 0.55);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.locked-media__price .icon { width: 14px; height: 14px; color: var(--gem); }
.locked-media__price.is-free { color: var(--green); font-size: 13px; }
/* Скрыто долгом: цены нет (второй раз не спишется), тихая подпись «скрыто» */
.locked-media__price.is-hidden-debt { color: var(--text-2); font-size: 13px; font-weight: var(--fw-semibold); }
.locked-media__actions { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
/* 40 px — цель мыши (Desktop, планшет); на телефоне зона касания 44 px даёт ::before у .btn--xs (К7) */
.locked-media__actions .btn { justify-content: flex-start; min-height: 40px; }
.locked-media__again { background: rgba(255, 255, 255, 0.06); border-color: var(--line-2); }
@media (hover: hover) and (pointer: fine) { .locked-media__card:hover { border-color: var(--line-2); } }

/* Чип «✨ Сделать такое фото · 10💎» под сообщением: занят — спиннер (runAction ставит .is-loading) */
/* 40 px на вид, палец попадает в 44 px (невидимое расширение, К7) */
.offer-chip { position: relative; margin-top: 6px; min-height: 40px; border-color: rgba(255, 45, 120, 0.4); background: rgba(255, 45, 120, 0.1); color: var(--text); font-weight: var(--fw-bold); }
.offer-chip::before { content: ""; position: absolute; inset: -4px 0; border-radius: inherit; } /* внутри рамки 38 + 8 = 46, как у .btn--xs */
.offer-chip.is-loading { opacity: 0.6; pointer-events: none; }
.offer-chip:disabled { opacity: 0.55; border-color: var(--line); background: var(--card); color: var(--muted); }
/* «Показать ↑» — к закрытому, которое уже прислано: подсветка сообщения, к которому прокрутили */
.msg--flash { animation: msg-flash 1.6s ease-out; }
@keyframes msg-flash { 0%, 40% { filter: drop-shadow(0 0 10px rgba(255, 45, 120, 0.55)); } 100% { filter: none; } }
@media (prefers-reduced-motion: reduce) { .msg--flash { animation: none; outline: 2px solid rgba(255, 45, 120, 0.5); } }

/* Цена кадра на закрытой плитке сетки (components/mediaTile.js): под замком «💎5» */
.media-tile__lock { flex-direction: column; gap: 6px; }
.media-tile__price {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  font-size: 12px;
  font-weight: var(--fw-heavy);
  font-variant-numeric: tabular-nums;
  color: #fff;
  background: rgba(11, 10, 20, 0.5);
}
.media-tile__price .icon { width: 12px; height: 12px; color: var(--gem); }
.media-tile__price.is-free { color: var(--green); }

/* Шторка «Фото / Видео» композера: превью бесплатно, гемы — при открытии */
.composer__price.composer__price--free { padding: 3px 8px; color: var(--green); background: rgba(45, 212, 160, 0.14); white-space: nowrap; }
