/* Основные стили для Telegram Mini App */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    background-color: var(--tg-theme-bg-color, #ffffff);
    color: var(--tg-theme-text-color, #000000);
    font-size: 16px;
    line-height: 1.5;
}

/* Атрибут hidden проигрывает любому display в стилях — например, счётчик
   фильтров с display: inline-flex оставался виден с нулём внутри */
[hidden] {
    display: none !important;
}

/* Переменные темы Telegram */
:root {
    --primary-color: #2481cc;
    --secondary-color: #f0f0f0;
    --success-color: #4caf50;
    --danger-color: #f44336;
    --warning-color: #ff9800;
}

/* Заголовки экранов. По умолчанию h2 на телефоне занимал почти два
   сантиметра высоты и отжимал содержимое вниз. */
.tab-content > h2 {
    font-size: 1.25rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Имя пользователя переехало сюда из удалённой шапки приложения */
.profile-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 16px;
}


.user-info {
    font-size: 1.05rem;
    font-weight: 500;
    color: var(--tg-theme-text-color, #000);
}

/* Навигация */
.app-nav {
    display: none;
}

/* Значки интерфейса.
   Наследуют цвет и размер от родителя, поэтому одна и та же иконка
   подстраивается под текст рядом с ней и под тему Телеграма. */
.icon {
    width: 1em;
    height: 1em;
    flex-shrink: 0;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    vertical-align: -0.15em;
}

/* Нижняя навигация.
   Цвета берутся из темы Телеграма, а не зашиты: раньше панель оставалась
   тёмной даже у пользователей со светлой темой и смотрелась инородно. */
.bottom-nav {
    position: fixed !important;
    bottom: 0 !important;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--tg-theme-secondary-bg-color, #f4f4f5);
    border-top: 1px solid var(--tg-theme-hint-color, #d8d8dc);
    padding: 6px 0 14px 0;
    z-index: 1000 !important;
}

/* С открытой клавиатурой меню прячется: см. trackViewportHeight().
   display: none, а не прозрачность — полоса должна и место освободить,
   а не только исчезнуть с глаз. */
body.keyboard-open .bottom-nav {
    display: none !important;
}

.bottom-nav-btn {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    border: none;
    background: none;
    color: var(--tg-theme-hint-color, #8a8a8e);
    padding: 4px 2px;
    cursor: pointer;
    transition: color 0.15s ease;
    gap: 3px;
    position: relative;
}

/* Выбранная вкладка окрашивается целиком — и значок, и подпись.
   С эмодзи так не получалось: картинку нельзя перекрасить. */
.bottom-nav-btn.active {
    color: var(--tg-theme-button-color, #2481cc);
}

.nav-icon {
    font-size: 23px;
    line-height: 0;
}

.nav-label {
    font-size: 11px;
    font-weight: 500;
}

@media (max-width: 400px) {
    .nav-icon {
        font-size: 21px;
    }
    .nav-label {
        font-size: 10px;
    }
}

/* Основной контент. Отступ сверху меньше прежнего: своей шапки больше нет,
   над содержимым сразу системная панель Телеграма. */
.app-main {
    padding: 12px 16px 80px;
    min-height: calc(100vh - 60px);
}

.tab-content {
    display: none !important;
}

.tab-content.active {
    display: block !important;
    min-height: 500px !important;
    height: auto !important;
}

#admin-tab {
    position: relative !important;
    z-index: 1 !important;
}

#admin-tab.active {
    position: static !important;
}

/* Поиск.
   Лупа и кнопка фильтров лежат внутри одной обоймы, а не отдельными
   элементами: три самостоятельных прямоугольника подряд на ширине 375px
   выглядели панелью инструментов, а не строкой поиска. */
/* Строка держится у верха при прокрутке. Обойма нужна, чтобы под ней не
   просвечивала лента: отрицательные поля гасят отступы .app-main, и полоса
   с фоном страницы перекрывает всю ширину, а не только саму строку. */
.search-sticky {
    position: sticky;
    top: 0;
    z-index: 100;
    margin: -12px -16px 12px;
    padding: 12px 16px 8px;
    background-color: var(--tg-theme-bg-color, #ffffff);
}

.search-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 12px 0 12px;
    border: 1px solid var(--tg-theme-hint-color, #e0e0e0);
    border-radius: 12px;
    background-color: var(--tg-theme-secondary-bg-color, #f2f2f2);
}

.search-bar-icon {
    flex-shrink: 0;
    color: var(--tg-theme-hint-color, #999);
}

.search-bar input {
    flex: 1;
    min-width: 0;
    padding: 12px 0;
    border: none;
    background: none;
    color: var(--tg-theme-text-color, #000000);
    font-size: 1rem;
}

.search-bar input:focus {
    outline: none;
}

.search-bar input::placeholder {
    color: var(--tg-theme-hint-color, #999);
}

.filters-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
    padding: 6px 0 6px 10px;
    border: none;
    border-left: 1px solid var(--tg-theme-hint-color, #e0e0e0);
    background: none;
    color: var(--tg-theme-link-color, #2481cc);
    font-size: 0.9rem;
    font-weight: 500;
    cursor: pointer;
}

.filters-toggle.active {
    color: var(--tg-theme-button-color, #2481cc);
}

/* Счётчик применённых условий. Без него свёрнутая панель молча отсекает
   лоты, и непонятно, почему лента полупустая. */
.filters-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: var(--tg-theme-button-color, #2481cc);
    color: var(--tg-theme-button-text-color, #fff);
    font-size: 0.7rem;
    font-weight: 600;
}

.filters-panel {
    margin-bottom: 12px;
    padding: 14px;
    border: 1px solid var(--tg-theme-hint-color, #e0e0e0);
    border-radius: 12px;
    background-color: var(--tg-theme-secondary-bg-color, #f8f8f8);
}

.filters-grid {
    display: grid;
    gap: 12px;
}

.filters-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.filters-field {
    display: block;
}

.filters-field > span {
    display: block;
    margin-bottom: 4px;
    font-size: 0.85rem;
    color: var(--tg-theme-hint-color, #888);
}

.filters-field select,
.filters-field input {
    width: 100%;
    box-sizing: border-box;
    padding: 9px 10px;
    border: 1px solid var(--tg-theme-hint-color, #e0e0e0);
    border-radius: 8px;
    background-color: var(--tg-theme-bg-color, #fff);
    color: var(--tg-theme-text-color, #000);
    font-family: inherit;
    font-size: 0.95rem;
}

.filters-actions {
    display: flex;
    gap: 8px;
}

.filters-actions button {
    flex: 1;
    padding: 10px;
    border: none;
    border-radius: 8px;
    font-size: 0.95rem;
    font-weight: 500;
    cursor: pointer;
}

.filters-apply {
    background: var(--tg-theme-button-color, #2481cc);
    color: var(--tg-theme-button-text-color, #fff);
}

/* Сброс — второстепенное действие, поэтому контур, а не заливка */
.filters-reset {
    background: none;
    border: 1px solid var(--tg-theme-hint-color, #ccc) !important;
    color: var(--tg-theme-text-color, #000);
}

/* Строка поиска и колокольчик в один ряд */
.search-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.search-row .search-bar {
    flex: 1;
    min-width: 0;
}

.notifications-btn {
    position: relative;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 1px solid var(--tg-theme-hint-color, #e0e0e0);
    border-radius: 12px;
    background-color: var(--tg-theme-secondary-bg-color, #f2f2f2);
    color: var(--tg-theme-text-color, #000);
    font-size: 21px;
    cursor: pointer;
}

.notifications-btn .badge {
    position: absolute;
    top: -5px;
    right: -5px;
}

/* ============= ПРОФИЛЬ ============= */

/* Карточка сама и есть кнопка «изменить имя»: отдельная строка в меню ради
   одного поля выглядела бы избыточно */
.profile-card {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    margin-bottom: 16px;
    padding: 0;
    border: none;
    background: none;
    color: var(--tg-theme-text-color, #000);
    text-align: left;
    cursor: pointer;
}

.profile-card-text {
    flex: 1;
    min-width: 0;
}

.profile-subtitle {
    font-size: 0.85rem;
    color: var(--tg-theme-hint-color, #888);
}

/* Счётчики в две колонки. Каждый — вход в свой раздел: раньше числа лежали
   в недостижимом экране статистики и никуда не вели. */
.profile-tiles {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-bottom: 16px;
}

.profile-tile {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: 14px;
    border: none;
    border-radius: 12px;
    background: var(--tg-theme-secondary-bg-color, #f2f2f2);
    color: var(--tg-theme-text-color, #000);
    text-align: left;
    cursor: pointer;
}

.profile-tile-value {
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.1;
}

.profile-tile-label {
    font-size: 0.85rem;
    color: var(--tg-theme-hint-color, #888);
}

/* Служебные ссылки — не часть основного экрана, поэтому без рамки и мельче
   остального. Профиль растягивается на высоту экрана, и список уходит вниз,
   под счётчики: там его ищут, когда всё остальное уже просмотрено. */
#my-neebay-tab.active {
    display: flex !important;
    flex-direction: column;
    min-height: calc(var(--vvh, 100dvh) - 92px) !important;
}

#my-neebay-tab .profile-menu {
    margin-top: auto;
}

.profile-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 12px 4px;
    border: none;
    background: none;
    color: var(--tg-theme-hint-color, #888);
    font-size: 0.9rem;
    text-align: left;
    cursor: pointer;
}

.profile-menu-item + .profile-menu-item {
    border-top: 1px solid var(--tg-theme-hint-color, #e0e0e0);
}

.profile-menu-item > span {
    flex: 1;
}

.profile-menu-arrow {
    color: var(--tg-theme-hint-color, #888);
}

/* ============= ЭКРАН РАЗДЕЛА ============= */

/* Разделы профиля и уведомления открываются поверх, как лот и чат: своя
   шапка со стрелкой и содержимое под ней */
.screen {
    display: flex;
    flex-direction: column;
    height: var(--vvh, 100dvh);
}

.screen-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--tg-theme-hint-color, #e0e0e0);
}

.screen-header h2 {
    font-size: 1.1rem;
    font-weight: 600;
}

.screen-back {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: none;
    background: none;
    color: var(--tg-theme-text-color, #000);
    font-size: 22px;
    cursor: pointer;
}

.screen-body {
    flex: 1;
    overflow-y: auto;
    padding: 12px;
}

/* Документы — правила и политика. Текст приходит с сервера из Markdown,
   поэтому здесь вёрстка для голых тегов: заголовки, абзацы, списки,
   таблицы. Читать это будут с телефона, отсюда узкие отступы и таблица,
   которая прокручивается сама, а не растягивает экран. */
.document-body {
    padding: 4px 16px 40px;
    font-size: 0.95rem;
    line-height: 1.55;
}

.document-body h2 {
    font-size: 1.1rem;
    margin: 26px 0 8px;
}

.document-body h3 {
    font-size: 1rem;
    margin: 18px 0 6px;
}

.document-body p,
.document-body li {
    margin: 0 0 8px;
}

.document-body ul {
    padding-left: 20px;
}

.document-body hr {
    border: 0;
    border-top: 1px solid var(--tg-theme-hint-color, #ddd);
    opacity: 0.4;
    margin: 22px 0;
}

.document-body table {
    display: block;
    overflow-x: auto;
    border-collapse: collapse;
    width: 100%;
    margin: 10px 0 14px;
    font-size: 0.88rem;
}

.document-body th,
.document-body td {
    text-align: left;
    vertical-align: top;
    padding: 6px 8px;
    border-bottom: 1px solid var(--tg-theme-hint-color, #ddd);
}

.document-body th {
    font-weight: 600;
}

.document-body a {
    color: var(--tg-theme-link-color, #2481cc);
}

/* Ссылка вглубь раздела не должна упираться в последнюю карточку списка */
.screen-body .profile-menu {
    margin-top: 16px;
}

/* Строка под карточкой в «Моих ставках»: лидирую или перебит */
/* Исход торгов в списках продавца. Цветом, а не серым: в длинном списке
   живые, проданные и непроданные лоты сливались в одну кашу. */
.lot-unsold {
    color: var(--danger-color, #f44336);
    font-weight: 500;
}

.lot-sold {
    color: var(--success-color, #4caf50);
    font-weight: 500;
}

.bid-status {
    margin: 6px 0 0;
    padding: 6px 10px;
    border-radius: 8px;
    font-size: 0.8rem;
    font-weight: 500;
}

.bid-status-leading {
    background: rgba(76, 175, 80, 0.15);
    color: var(--success-color);
}

.bid-status-outbid {
    background: rgba(244, 67, 54, 0.15);
    color: var(--danger-color);
}

/* ============= УВЕДОМЛЕНИЯ ============= */

.notification {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 12px 4px;
    border: none;
    border-bottom: 1px solid var(--tg-theme-hint-color, #e0e0e0);
    background: none;
    color: var(--tg-theme-text-color, #000);
    text-align: left;
    cursor: pointer;
}

.notification-icon {
    flex-shrink: 0;
    font-size: 22px;
    color: var(--tg-theme-hint-color, #888);
}

/* Непрочитанное отмечено точкой слева, а не заливкой строки: заливка
   в тёмной теме читается как выделение, а не как «новое» */
.notification-unread .notification-icon {
    color: var(--tg-theme-button-color, #2481cc);
}

.notification-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.notification-title {
    font-size: 0.95rem;
}

.notification-unread .notification-title {
    font-weight: 600;
}

.notification-lot {
    font-size: 0.85rem;
    color: var(--tg-theme-hint-color, #888);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.notification-time {
    flex-shrink: 0;
    font-size: 0.72rem;
    color: var(--tg-theme-hint-color, #888);
}

/* ============= АДМИНКА ============= */

/* Сводка — три числа, а не графики: при десятке пользователей график
   рисует красивую линию вместо ответа на вопрос «жива ли площадка» */
.admin-pulse {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    margin-bottom: 20px;
}

.admin-pulse-cell {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 12px 10px;
    border-radius: 12px;
    background: var(--tg-theme-secondary-bg-color, #f2f2f2);
}

.admin-pulse-value {
    font-size: 1.4rem;
    font-weight: 700;
    line-height: 1.1;
}

.admin-pulse-label {
    font-size: 0.75rem;
    color: var(--tg-theme-hint-color, #888);
}

/* Открытые жалобы — единственное, что требует действия прямо сейчас */
.admin-pulse-alarm .admin-pulse-value {
    color: var(--danger-color, #f44336);
}

.admin-section-title {
    margin-bottom: 12px;
    font-size: 1.05rem;
}

.admin-tools {
    margin-top: 24px;
}

/* Карточка жалобы: снимок, суть и решение — без перехода на другие экраны */
.report-card {
    padding: 12px;
    margin-bottom: 10px;
    border-radius: 12px;
    background: var(--tg-theme-secondary-bg-color, #f5f5f5);
}

.report-head {
    display: flex;
    gap: 10px;
}

.report-photo {
    flex-shrink: 0;
    width: 64px;
    height: 64px;
    object-fit: cover;
    border-radius: 8px;
    background: var(--tg-theme-bg-color, #fff);
}

.report-photo-empty {
    background: var(--tg-theme-bg-color, #e0e0e0);
}

.report-head-text {
    min-width: 0;
}

.report-reason {
    font-weight: 600;
    color: var(--danger-color, #f44336);
}

.report-lot {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.report-meta,
.report-seller {
    font-size: 0.82rem;
    color: var(--tg-theme-hint-color, #888);
}

.report-comment {
    margin-top: 8px;
    font-size: 0.9rem;
}

/* Продавец и действие с ним в одной строке: предупредить можно и не снимая
   лот — раньше предупреждение висело только на шаге после снятия */
.report-seller {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 8px;
}

.report-inline-btn {
    flex-shrink: 0;
    padding: 4px 10px;
    border: 1px solid var(--tg-theme-hint-color, #ccc);
    border-radius: 14px;
    background: none;
    color: var(--tg-theme-text-color, #000);
    font-size: 0.78rem;
    cursor: pointer;
}

.admin-row-actions {
    display: flex;
    flex-shrink: 0;
    gap: 6px;
    margin-left: auto;
}

.admin-btn-warn {
    padding: 6px 10px;
    border: 1px solid var(--warning-color, #ff9800);
    border-radius: 8px;
    background: none;
    color: var(--warning-color, #ff9800);
    font-size: 0.8rem;
    cursor: pointer;
}

/* Вход в историю человека прямо из жалобы: при повторной жалобе иначе
   пришлось бы вспоминать про журнал и искать там нужного продавца */
.report-history-link {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 6px;
    padding: 0;
    border: none;
    background: none;
    color: var(--tg-theme-link-color, #2481cc);
    font-size: 0.82rem;
    cursor: pointer;
}

/* Отсутствие записей проговаривается словами: пустая строка не отличается
   от «не загрузилось» */
.report-history-empty {
    margin-top: 6px;
    font-size: 0.82rem;
    color: var(--tg-theme-hint-color, #888);
}

.admin-btn-history {
    padding: 6px 10px;
    border: 1px solid var(--tg-theme-hint-color, #ccc);
    border-radius: 8px;
    background: none;
    color: var(--tg-theme-text-color, #000);
    font-size: 0.8rem;
    cursor: pointer;
}

.report-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 10px;
}

.report-btn {
    flex: 1;
    min-width: 96px;
    padding: 8px 10px;
    border: none;
    border-radius: 8px;
    background: var(--tg-theme-button-color, #2481cc);
    color: var(--tg-theme-button-text-color, #fff);
    font-size: 0.85rem;
    cursor: pointer;
}

.report-btn-danger {
    background: var(--danger-color, #f44336);
}

.report-btn-quiet {
    background: none;
    border: 1px solid var(--tg-theme-hint-color, #ccc);
    color: var(--tg-theme-text-color, #000);
}

/* Второстепенный выход из окна выбора: «ничего не делать» тоже решение.
   Составной селектор — чтобы перебить .modal-submit ниже по файлу */
.modal-submit.modal-submit-quiet {
    background: none;
    border: 1px solid var(--tg-theme-hint-color, #ccc);
    color: var(--tg-theme-text-color, #000);
}

.admin-log-row {
    display: flex;
    gap: 10px;
    padding: 10px 0;
    border-bottom: 1px solid var(--tg-theme-hint-color, #e0e0e0);
}

.admin-log-main {
    flex: 1;
    min-width: 0;
}

.admin-log-action {
    font-weight: 500;
}

.admin-log-target,
.admin-log-reason {
    font-size: 0.85rem;
    color: var(--tg-theme-hint-color, #888);
}

.admin-log-time {
    flex-shrink: 0;
    font-size: 0.75rem;
    color: var(--tg-theme-hint-color, #888);
}

/* Пустая выдача. Отличается от «лотов нет вовсе» тем, что предлагает выход */
.empty-state {
    grid-column: 1 / -1;
    padding: 32px 16px;
    text-align: center;
    color: var(--tg-theme-hint-color, #888);
}

/* Вторая строка — подсказка, поэтому мельче и с отбивкой: слитно с первой
   она читалась как одно длинное предложение */
.empty-state p + p {
    margin-top: 8px;
    font-size: 0.9rem;
}

.empty-state button {
    margin-top: 12px;
    padding: 10px 18px;
    border: 1px solid var(--tg-theme-hint-color, #ccc);
    border-radius: 8px;
    background: none;
    color: var(--tg-theme-link-color, #2481cc);
    font-size: 0.95rem;
    cursor: pointer;
}

/* Сетка лотов.
   Две колонки на телефоне: при трёх на карточку оставалось ~110px, из-за чего
   названия обрезались на полуслове, а строка цены разваливалась на две. */
.lots-grid {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 10px;
    padding: 0 4px;
}

/* Десктоп - больше колонок */
@media (min-width: 768px) {
    .lots-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
        gap: 12px;
    }
}

@media (min-width: 1200px) {
    .lots-grid {
        grid-template-columns: repeat(6, minmax(0, 1fr)) !important;
    }
}

/* Карточка лота - компактная */
.lot-card {
    position: relative; /* якорь для кружка выбора в углу */
    background-color: var(--tg-theme-secondary-bg-color, #f8f8f8);
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    display: flex;
    flex-direction: column;
    height: 100%;
}

/* Компактная версия для истории (Покупки) - в 2 раза меньше */
.lot-card-compact .lot-image {
    height: 60px; /* Уменьшено с 80px для компактности */
}

.lot-card-compact .lot-content {
    padding: 6px; /* Небольшой padding */
}

.lot-card-compact .lot-title {
    font-size: 0.8rem !important;
    margin-bottom: 2px !important;
    line-height: 1.2 !important;
}

.lot-card-compact .lot-description {
    font-size: 0.7rem !important;
    margin-bottom: 4px !important;
    max-height: 1.6em !important;
    line-height: 1.2 !important;
}

.lot-card-compact > div[style*="padding"] {
    padding: 4px 6px !important;
    margin-bottom: 4px !important;
}

.lot-card-compact > div[style*="padding"] > div:first-child {
    font-size: 0.75rem !important;
    margin-bottom: 1px !important;
}

.lot-card-compact > div[style*="padding"] > div:last-child {
    font-size: 0.65rem !important;
}

.lot-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}

.lot-image {
    width: 100%;
    height: 140px;
    object-fit: cover;
    background-color: var(--tg-theme-secondary-bg-color, #e0e0e0);
    flex-shrink: 0;
}

.lot-content {
    padding: 8px 9px 10px;
    display: flex;
    flex-direction: column;
    flex-grow: 1;
}

/* Цена — главный якорь взгляда. Обычного цвета, а не акцентного:
   цвет приберегаем для срочности, иначе он перестаёт что-либо значить. */
.lot-price {
    font-size: 1rem;
    font-weight: 600;
    color: var(--tg-theme-text-color, #000000);
    margin-bottom: 3px;
    white-space: nowrap;
}

.lot-title {
    font-size: 0.8rem;
    font-weight: 400;
    margin: 0 0 6px;
    color: var(--tg-theme-text-color, #000000);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.3;
    min-height: 2.6em;
}

.lot-description {
    display: none;
}

/* Ставки и остаток времени — то, чем аукцион отличается от доски объявлений */
.lot-meta {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
    font-size: 0.7rem;
    color: var(--tg-theme-hint-color, #888888);
    margin-top: auto;
}

.lot-meta-sep {
    opacity: 0.6;
}

.time-remaining {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 0.7rem;
}

/* Часы у срока: без них «8ч 20м» стоит рядом с «2 ставки» и читается
   как ещё одно число. Значок чуть меньше текста и приглушён — он
   подсказывает, а не спорит с самим временем. */
.icon-time {
    width: 0.9em;
    height: 0.9em;
    opacity: 0.75;
    vertical-align: 0;
}

/* Красный только в последний час */
.time-remaining.urgent {
    color: var(--danger-color);
    font-weight: 600;
}

.bid-btn {
    display: none;
}

/* Формы.
   Без карточки и без своих отступов: серая карточка на сером фоне вкладки
   добавляла слой, внутри которого каждое поле сидело ещё в одной рамке.
   Форма занимала полтора экрана при семи полях. */
.lot-form {
    display: block;
}

.form-group {
    margin-bottom: 14px;
}

/* Подпись поля — основным цветом текста, но мельче содержимого: серым она
   сливалась с подсказкой внутри поля, и было не разобрать, где название
   поля, а где пример заполнения */
.form-group label {
    display: block;
    margin-bottom: 6px;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--tg-theme-text-color, #000000);
}

.form-group input,
.form-group textarea,
.form-group select {
    width: 100%;
    padding: 11px 12px;
    border: 1px solid var(--tg-theme-hint-color, #e0e0e0);
    border-radius: 10px;
    background-color: var(--tg-theme-secondary-bg-color, #f5f5f5);
    color: var(--tg-theme-text-color, #000000);
    font-family: inherit;
    font-size: 1rem;
}

.form-group textarea {
    resize: vertical;
    min-height: 76px;
}

/* Своя стрелка вместо системной: у системной положение задаёт браузер, и она
   упирается в самую границу поля. Цвет нейтрально-серый — он одинаково
   читается и на светлой, и на тёмной теме, а фон в data-URI не подставить. */
.form-group select,
.filters-field select {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 34px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' stroke='%238a8a8e' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
}

/* Подсказка внутри поля объясняет, что писать, и исчезает при вводе —
   в отличие от подписи снизу, которая занимала бы место всегда */
.form-group input::placeholder,
.form-group textarea::placeholder {
    color: var(--tg-theme-hint-color, #999);
    opacity: 0.55;
}

/* Единица измерения лежит в поле справа, а не в подписи: в подписи «(₽)»
   читается как часть названия, а не как то, в чём вводят */
.input-with-unit {
    position: relative;
}

.input-with-unit input {
    padding-right: 34px;
}

.input-unit {
    position: absolute;
    top: 50%;
    right: 12px;
    transform: translateY(-50%);
    color: var(--tg-theme-hint-color, #888);
    pointer-events: none;
}

/* Подпись переключателя — слева, сам он справа, как в системных настройках */
.form-group label.switch-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 0;
    font-size: 1rem;
    color: var(--tg-theme-text-color, #000);
    cursor: pointer;
    user-select: none;
}

.field-hint {
    margin-top: 4px;
    font-size: 0.85rem;
    color: var(--tg-theme-hint-color, #888);
}

/* Подпись и счётчик в одной строке: счётчик отдельной строкой отнимал бы
   высоту у формы, которая и так длинная */
.form-group label.label-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.label-counter {
    flex-shrink: 0;
    font-size: 0.78rem;
    color: var(--tg-theme-hint-color, #888);
}

/* Незаполненное поле подсвечивается рамкой, без подписи снизу: правило на
   всю форму одно — пустое красное, — и объяснять словами нечего. Подписи
   отнимали бы высоту у формы и делали её вид тревожным. */
.field-invalid input,
.field-invalid textarea,
.field-invalid select,
.field-invalid .photo-add-btn {
    border-color: var(--danger-color, #f44336);
}

/* «Очистить» под кнопкой создания: намеренно неприметная — это выход
   из начатого дела, а не то, к чему стоит подталкивать. */
.clear-draft-btn {
    display: block;
    width: 100%;
    margin-top: 10px;
    padding: 10px;
    border: none;
    background: none;
    color: var(--tg-theme-hint-color, #999);
    font-family: inherit;
    font-size: 0.85rem;
    cursor: pointer;
}

/* Аватар из буквы имени.
   Фотографии из Телеграма здесь нет намеренно: показывать своё лицо
   покупателям человек не разрешал, а буква решает ту же задачу —
   отличать собеседников — и персональными данными не является.

   Кегль везде равен половине диаметра. При меньшем буква тонет: чернила
   заглавной занимают около 0,7 кегля, то есть примерно треть круга, и
   кружок читается пустым. line-height: 1 обязателен — иначе строчный
   бокс выше круга и центрирование по флексу уезжает.

   Подгонки вертикали здесь нет намеренно: замеры показали, что чернила
   заглавной отходят от центра круга меньше чем на 0,4 пикселя, а любой
   фиксированный сдвиг в em этот остаток на одних размерах уменьшает, на
   других увеличивает — он от округления метрик шрифта, а не от кегля. */
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: #fff;
    font-weight: 600;
    font-size: 20px;
    line-height: 1;
    text-transform: uppercase;
}

.avatar-sm {
    width: 24px;
    height: 24px;
    font-size: 12px;
}

.avatar-xs {
    width: 18px;
    height: 18px;
    font-size: 9px;
}

/* Цвет ставит JS по user_id — здесь только размер. Правило идёт после
   .avatar: сила селекторов равна, и побеждает то, что ниже. */
.profile-head-avatar {
    width: 38px;
    height: 38px;
    font-size: 19px;
}

/* Слои окон, чтобы не перебирать их заново на каждом баге:
   .modal.modal-full 3000 — экран раздела
   .lot-detail-modal 3500 — лот поверх раздела
   .modal.modal-full.modal-over-lot 3600 — лоты продавца поверх лота
   .chat-modal 3700 — переписка поверх всего этого
   .modal 3800 — диалоги (ставка, жалоба, имя)
   .photo-modal 4000 — фотография во весь экран

   У чата своё окно, а не общий .modal: тот лежит ниже экрана лота, и
   «Связаться с продавцом» открывал переписку ПОД лотом, а заодно затирал
   список «Куплено», который занимал тот же .modal. */
.chat-modal {
    position: fixed;
    top: var(--vv-offset, 0px);
    left: 0;
    right: 0;
    width: 100%;
    height: var(--vvh, 100dvh);
    z-index: 3700;
    display: none;
    flex-direction: column;
    background: var(--tg-theme-bg-color, #fff);
}

/* Пока человек печатает, под формой держится пустое место: иначе нижние
   поля физически нельзя поднять над клавиатурой — страница кончается, и
   прокрутка встаёт на полпути. */
.lot-form.is-typing {
    padding-bottom: 60vh;
}

/* Заголовок раздаётся, прижимая кнопку к правому краю */
.screen-title-grow {
    flex: 1;
}

/* Почему кнопок нет. Пустое место на их месте выглядело бы поломкой,
   а строка объясняет причину. */
.lot-owner-note {
    padding: 14px 16px;
    text-align: center;
    font-size: 0.85rem;
    color: var(--tg-theme-hint-color, #999);
}

/* Счётчик суммы: минус, сумма, плюс — одной строкой.
   Сумма показана крупно и по центру, потому что это главное число в
   окне; кнопки по краям спокойные, они помощники, а не действие. */
.bid-stepper {
    display: flex;
    align-items: stretch;
    gap: 8px;
    margin: 14px 0 6px;
}

.bid-stepper input {
    flex: 1;
    min-width: 0;
    text-align: center;
    font-size: 1.5rem;
    font-weight: 700;
    padding: 10px 4px;
    border: 1px solid var(--tg-theme-hint-color, #ccc);
    border-radius: 10px;
    background: var(--tg-theme-bg-color, #fff);
    color: var(--tg-theme-text-color, #000);
    /* Стрелки браузера тут лишние: шаг задают кнопки по краям */
    appearance: textfield;
    -moz-appearance: textfield;
}

.bid-stepper input::-webkit-outer-spin-button,
.bid-stepper input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.bid-stepper-btn {
    width: 54px;
    flex-shrink: 0;
    border: 1px solid var(--tg-theme-hint-color, #ccc);
    border-radius: 10px;
    background: var(--tg-theme-secondary-bg-color, #f4f4f5);
    color: var(--tg-theme-text-color, #000);
    font-size: 1.4rem;
    font-family: inherit;
    cursor: pointer;
}

.bid-stepper-btn:disabled {
    opacity: 0.35;
    cursor: default;
}

.bid-step-hint {
    margin-bottom: 14px;
    text-align: center;
    font-size: 0.8rem;
    color: var(--tg-theme-hint-color, #999);
}

/* Остаток суточного лимита под кнопкой создания */
.lot-quota {
    margin-top: 10px;
    text-align: center;
    font-size: 0.8rem;
    color: var(--tg-theme-hint-color, #999);
}

.lot-quota-empty {
    color: var(--danger-color, #f44336);
}

/* Карточка человека в админке: ID и числа, по которым принимают решение */
.admin-user-card {
    padding: 12px 14px;
    margin-bottom: 12px;
    border-radius: 10px;
    background: var(--tg-theme-secondary-bg-color, #f4f4f5);
}

.admin-user-id {
    font-size: 0.8rem;
    color: var(--tg-theme-hint-color, #888);
}

.admin-user-facts {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 5px;
    font-size: 0.9rem;
}

/* Изменённый лимит выделен: обычный — фон, изменённый — решение,
   которое кто-то принял, и его надо заметить */
.admin-limit-custom {
    color: var(--tg-theme-button-color, #2481cc);
    font-weight: 600;
}

.admin-limit-edit {
    margin-left: auto;
    padding: 4px;
    border: none;
    background: none;
    color: var(--tg-theme-link-color, #2481cc);
    cursor: pointer;
}

/* Шапка чатов: заголовок слева, «Выбрать» справа */
.chats-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 16px;
}

.chats-header h2 {
    margin: 0;
}

/* Одна разметка выбора на три списка: чаты, уведомления и разделы профиля.
   Классы называются нейтрально именно поэтому — «chats-» на экране
   уведомлений было бы враньём в исходнике. */
.select-btn {
    border: none;
    background: none;
    padding: 6px 2px;
    color: var(--tg-theme-link-color, #2481cc);
    font-family: inherit;
    font-size: 0.9rem;
    cursor: pointer;
}

.select-actions {
    display: flex;
    align-items: center;
    gap: 14px;
}

.select-delete-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: none;
    background: none;
    padding: 6px 2px;
    color: var(--danger-color, #f44336);
    font-family: inherit;
    font-size: 0.9rem;
    cursor: pointer;
}

/* Ведро без выбранных ничего не сделает — гасим, а не прячем: пропадающая
   кнопка выглядит как сбой, погашенная объясняет, что надо сначала выбрать */
.select-delete-btn:disabled {
    opacity: 0.35;
    cursor: default;
}

/* Кружок появляется только в режиме выбора и раздвигает строку */
.select-check {
    display: none;
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    border: 2px solid var(--tg-theme-hint-color, #bbb);
    border-radius: 50%;
}

.is-selecting .select-check {
    display: block;
}

.is-selecting .is-selected > .select-check {
    border-color: var(--tg-theme-button-color, #2481cc);
    background: var(--tg-theme-button-color, #2481cc);
    box-shadow: inset 0 0 0 3px var(--tg-theme-bg-color, #fff);
}

/* На карточке кружку места в потоке нет — он ложится поверх фотографии.
   Под ним затемнение: белая рамка на светлом снимке пропадает. */
.lot-card > .select-check {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 2;
    border-color: #fff;
    background: rgba(0, 0, 0, 0.35);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

/* Выбранную карточку видно и по самой карточке: кружок в углу мелкий,
   а в сетке взгляд идёт по плиткам, не по углам */
.is-selecting .lot-card.is-selected {
    outline: 2px solid var(--tg-theme-button-color, #2481cc);
    outline-offset: -2px;
}

/* Карточку, которую убрать нельзя (идущие торги), в режиме выбора гасим —
   иначе непонятно, почему нажатие ничего не даёт.
   Через filter, а не opacity: карточки въезжают анимацией fade-in, которая
   держит opacity: 1 до конца страницы и любое своё значение перебивает. */
.is-selecting .lot-card:not([data-select-key]) {
    filter: grayscale(0.7) opacity(0.45);
}

/* Подсказка про жест: тихая строка под списком */
/* Предупреждение о том, что уведомления не дойдут в чат. Не ошибка —
   поэтому не красное; но и не подсказка — поэтому заметнее обычной строки. */
.delivery-warning {
    margin: 0 0 12px;
    padding: 10px 12px;
    border-radius: 10px;
    background: var(--tg-theme-secondary-bg-color, #f1f1f1);
    color: var(--tg-theme-text-color, #222);
    font-size: 0.85rem;
    line-height: 1.45;
}

.list-hint {
    padding: 14px 16px 4px;
    text-align: center;
    font-size: 0.75rem;
    color: var(--tg-theme-hint-color, #999);
}

/* Подсказки станций.
   Список висит НАД формой (position: absolute), иначе появление подсказок
   двигало бы все поля ниже — а человек в этот момент читает варианты. */
.place-picker {
    position: relative;
}

.place-results {
    position: absolute;
    top: calc(100% + 4px);
    bottom: auto;
    left: 0;
    right: 0;
    z-index: 20;
    margin: 0;
    padding: 4px 0;
    list-style: none;
    overflow-y: auto;
    background: var(--tg-theme-bg-color, #fff);
    border: 1px solid var(--tg-theme-hint-color, #ccc);
    border-radius: 10px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
}

/* С открытой клавиатурой поле стоит у самой нижней границы видимого, и
   снизу места нет — раскрываемся вверх. Высоту ставит JS по остатку. */
.place-results-up {
    top: auto;
    bottom: calc(100% + 4px);
}

.place-option {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 11px 14px;
    cursor: pointer;
}

.place-option:active {
    background: var(--tg-theme-secondary-bg-color, #f1f1f1);
}

.place-name {
    color: var(--tg-theme-text-color, #000);
}

/* Направление подсказывает, где это, тем кто не знает станцию наизусть */
.place-zone {
    flex-shrink: 0;
    font-size: 0.8rem;
    color: var(--tg-theme-hint-color, #999);
}

.place-empty {
    padding: 12px 14px;
    font-size: 0.9rem;
    color: var(--tg-theme-hint-color, #999);
}

.submit-btn {
    width: 100%;
    margin-top: 6px;
    padding: 14px;
    background-color: var(--tg-theme-button-color, #2481cc);
    color: var(--tg-theme-button-text-color, #ffffff);
    border: none;
    border-radius: 8px;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.submit-btn:hover {
    opacity: 0.9;
}

.submit-btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Чекбоксы способов получения.
   Раньше .form-group label задавал display:block вложенным подписям, из-за чего
   эмодзи отрывался от слова и уезжал на отдельную строку. */
.checkbox-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.form-group label.checkbox-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 0;
    font-weight: 400;
    cursor: pointer;
}

.checkbox-row input[type="checkbox"] {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    margin: 0;
}

.checkbox-row span {
    font-size: 0.9rem;
    white-space: nowrap;
}

/* Превью фотографий */
.photo-preview {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
}

.photo-preview img {
    width: 80px;
    height: 80px;
    object-fit: cover;
    border-radius: 4px;
    border: 1px solid var(--tg-theme-hint-color, #e0e0e0);
}

/* Модальные окна */
/* Высота окна должна сжиматься вместе с клавиатурой.
   С height:100% iOS считает высоту по слою БЕЗ клавиатуры, поэтому низ формы
   с кнопкой отправки уезжал под неё, а прокрутки не было — достать кнопку
   было нечем. --vvh обновляется из JS по visualViewport, 100dvh — запасной
   вариант для браузеров без него. */
/* Один и тот же элемент играет две роли на разной глубине: диалог поверх
   всего (жалоба, ставка, имя) и полноэкранный режим под экраном лота
   (разделы профиля, чат, уведомления). Поэтому диалогу — верхний слой,
   а полноэкранному режиму ниже, см. .modal.modal-full. */
.modal {
    display: none;
    position: fixed;
    z-index: 3800;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    height: 100dvh;
    height: var(--vvh, 100dvh);
    /* Подложка плотнее прежних 0.5: в тёмной теме карточки лотов светлее фона
       страницы, и сквозь полупрозрачный слой их скруглённые углы читались
       по бокам окна как посторонние рамки */
    background-color: rgba(0, 0, 0, 0.72);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 16px 0;
}

/* margin:auto центрирует по вертикали во flex, но, в отличие от
   align-items:center, не обрезает верх, когда содержимое выше экрана */
/* Вторичный фон темы, а не основной: он на тон светлее в тёмной теме и на
   тон темнее в светлой, поэтому окно отделяется от страницы само.
   С основным фоном в чёрной теме границы не было вовсе — окно сливалось,
   и крестик выглядел висящим в пустоте. */
.modal-content {
    background-color: var(--tg-theme-secondary-bg-color, #ffffff);
    border: 1px solid var(--tg-theme-hint-color, #e0e0e0);
    margin: auto;
    padding: 16px;
    border-radius: 14px;
    width: 90%;
    max-width: 400px;
    position: relative;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
}

/* Крестик стоит в строке заголовка, а не обтекается справа:
   при float он отрывался от текста и висел сам по себе */
.close {
    color: var(--tg-theme-hint-color, #888888);
    font-size: 26px;
    font-weight: 500;
    cursor: pointer;
    line-height: 1;
    flex-shrink: 0;
    padding-left: 12px;
}

.close:hover {
    color: var(--tg-theme-text-color, #000000);
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--tg-theme-hint-color, #e0e0e0);
}

.modal-header h3 {
    margin: 0;
    font-size: 1.1rem;
    color: var(--tg-theme-text-color, #000);
}

/* Крестик — обычный элемент строки заголовка. Абсолютное позиционирование
   отсчитывалось от края окна и не совпадало с высотой строки заголовка:
   значок оказывался выше текста и не выглядел его частью. */
.modal-close {
    background: none;
    border: none;
    font-size: 24px;
    color: var(--tg-theme-hint-color, #888);
    cursor: pointer;
    padding: 0 0 0 12px;
    line-height: 1;
    flex-shrink: 0;
}

.modal-close:hover {
    color: var(--tg-theme-text-color, #000);
}

/* Поле ввода и кнопка в один столбец во всю ширину окна: раньше каждое окно
   несло свои инлайновые стили, из-за чего поля были разной ширины и высоты */
.modal-textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    border: 1px solid var(--tg-theme-hint-color, #ddd);
    border-radius: 10px;
    background-color: var(--tg-theme-bg-color, #fff);
    color: var(--tg-theme-text-color, #000);
    font-family: inherit;
    font-size: 1rem;
    line-height: 1.4;
    resize: none;
}

/* Удаление — необратимое действие, поэтому и строка меню, и кнопка
   подтверждения окрашены в цвет опасности */
.profile-menu-danger,
.profile-menu-danger .profile-menu-arrow {
    color: var(--danger-color, #f44336);
}

/* Составной селектор, чтобы перебить .modal-submit ниже по файлу */
.modal-submit.modal-submit-danger {
    background: var(--danger-color, #f44336);
    color: #fff;
}

.delete-account-list {
    margin: 0 0 12px;
    padding-left: 20px;
    font-size: 0.95rem;
}

.delete-account-list li {
    margin-bottom: 4px;
}

/* Кнопка во время отправки: притухает и не реагирует. У кнопок со значком
   вместо самолётика крутится колечко — иначе на медленной связи непонятно,
   притухла она или так и было. */
button:disabled {
    opacity: 0.6;
    cursor: default;
}

.is-sending .icon {
    display: none;
}

.is-sending::after {
    content: "";
    width: 18px;
    height: 18px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: submit-spin 0.7s linear infinite;
}

@keyframes submit-spin {
    to { transform: rotate(360deg); }
}

/* Ошибка проверки поля: показывается между полем и кнопкой, чтобы
   объяснение стояло там же, где человек только что печатал */
.form-error {
    margin-top: 8px;
    font-size: 0.85rem;
    color: var(--danger-color, #f44336);
}

.modal-submit {
    width: 100%;
    margin-top: 12px;
    padding: 12px;
    background: var(--tg-theme-button-color, #2481cc);
    color: var(--tg-theme-button-text-color, #fff);
    border: none;
    border-radius: 10px;
    font-size: 1rem;
    font-weight: 500;
    cursor: pointer;
}

.modal-body {
    padding-top: 8px;
}

.modal-body label {
    color: var(--tg-theme-text-color, #000);
}

.modal-body select,
.modal-body textarea,
.modal-body input {
    background: var(--tg-theme-secondary-bg-color, #f5f5f5);
    color: var(--tg-theme-text-color, #000);
    border: 1px solid var(--tg-theme-hint-color, #ddd);
}

/* Загрузка */
.loading {
    text-align: center;
    padding: 40px 20px;
    color: var(--tg-theme-hint-color, #888888);
    font-size: 1rem;
}

/* Состояния */
.success {
    color: var(--success-color);
    font-weight: 600;
}

.error {
    color: var(--danger-color);
    font-weight: 600;
}

.warning {
    color: var(--warning-color);
    font-weight: 600;
}

/* Анимации */
@keyframes fadeIn {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes fadeOut {
    from { opacity: 1; transform: scale(1); }
    to { opacity: 0; transform: scale(0.9); }
}

.fade-in {
    animation: fadeIn 0.3s ease forwards;
}

/* ============= СЛАЙДЕР ФОТО В КАРТОЧКЕ ============= */

.lot-image-container {
    cursor: pointer;
}

.slider-dots {
    position: absolute;
    bottom: 10px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 8px;
    z-index: 10;
}

.dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.5);
    cursor: pointer;
    transition: all 0.2s ease;
}

.dot.active {
    background: white;
    width: 24px;
    border-radius: 4px;
}

/* ============= МОДАЛЬНОЕ ОКНО ФОТО ============= */

/* Самый верхний слой: просмотр фото открывается с экрана лота, который
   теперь сам лежит выше модальных окон */
.photo-modal {
    display: none;
    position: fixed;
    z-index: 4000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.95);
    align-items: center;
    justify-content: center;
}

.photo-modal-content {
    position: relative;
    width: 90%;
    max-width: 1200px;
    max-height: 90vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

.photo-modal-image {
    max-width: 100%;
    max-height: 90vh;
    object-fit: contain;
    border-radius: 8px;
}

.photo-modal-close {
    position: absolute;
    top: -40px;
    right: 0;
    color: white;
    font-size: 36px;
    font-weight: bold;
    cursor: pointer;
    z-index: 4001;
    transition: opacity 0.2s ease;
}

.photo-modal-close:hover {
    opacity: 0.7;
}

.photo-modal-prev,
.photo-modal-next {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(255, 255, 255, 0.2);
    color: white;
    border: none;
    padding: 16px 20px;
    font-size: 24px;
    cursor: pointer;
    z-index: 4001;
    border-radius: 8px;
    transition: background 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
}

.photo-modal-prev:hover,
.photo-modal-next:hover {
    background: rgba(255, 255, 255, 0.4);
}

.photo-modal-prev {
    left: 20px;
}

.photo-modal-next {
    right: 20px;
}

.photo-modal-counter {
    position: absolute;
    bottom: -40px;
    left: 50%;
    transform: translateX(-50%);
    color: white;
    font-size: 16px;
    font-weight: 500;
    background: rgba(0, 0, 0, 0.5);
    padding: 8px 16px;
    border-radius: 20px;
}

/* Мобильная адаптация */
@media (max-width: 768px) {
    .photo-modal-prev,
    .photo-modal-next {
        padding: 12px 16px;
        font-size: 20px;
    }
    
    .photo-modal-prev {
        left: 10px;
    }
    
    .photo-modal-next {
        right: 10px;
    }
    
    .photo-modal-close {
        top: 10px;
        right: 10px;
        font-size: 32px;
    }
    
    .photo-modal-counter {
        bottom: 20px;
    }
    
    .modal-content {
        width: 90%;
        max-width: 400px;
    }
}

/* ============= МОДАЛЬНОЕ ОКНО ДЕТАЛЕЙ ЛОТА ============= */

/* Лот открывается отдельным экраном, а не шторкой поверх списка.
   Шторка была ограничена 90% высоты ради полоски списка сверху, которая
   ничего не показывала, но отнимала место и в тёмной теме просвечивала. */
/* Выше .modal: экран лота открывается поверх экрана раздела профиля, а тот
   живёт в общем модальном окне. С прежним порядком лот открывался под
   списком и оставался невидимым — нажатие на карточку выглядело как отказ. */
.lot-detail-modal {
    display: none;
    position: fixed;
    z-index: 3500;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    height: var(--vvh, 100dvh);
    background-color: var(--tg-theme-bg-color, #ffffff);
    overflow: hidden;
}

/* Сдвиг справа вместо выезда снизу: движение снизу — язык шторки,
   а сдвиг вбок читается как переход вглубь, откуда логично вернуться */
.lot-detail-content {
    position: absolute;
    inset: 0;
    background-color: var(--tg-theme-bg-color, #ffffff);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    animation: slideInRight 0.25s ease-out;
}

@keyframes slideInRight {
    from { transform: translateX(100%); }
    to { transform: translateX(0); }
}

@keyframes slideUp {
    from {
        transform: translateY(100%);
    }
    to {
        transform: translateY(0);
    }
}

/* Возврат слева, как на обычном экране: на полном экране крестик читался бы
   как «закрыть приложение», а стрелка — как «назад к списку» */
.lot-detail-header {
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--tg-theme-bg-color, #ffffff);
    padding: 10px 14px;
    border-bottom: 1px solid var(--tg-theme-hint-color, #e0e0e0);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

/* «Поделиться» и «в избранное» переехали сюда с фотографии — снимок
   остаётся чистым, а действия собраны в одном месте */
.lot-detail-header-actions {
    display: flex;
    align-items: center;
    gap: 4px;
}

/* Селектор составной намеренно: у .favorite-btn задано абсолютное
   позиционирование для плиток, и с одинаковой силой оно перебивало static —
   кнопки в шапке наезжали одна на другую */
.lot-detail-header .header-action {
    position: static;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    padding: 0;
    border-radius: 50%;
    font-size: 21px;
    color: var(--tg-theme-text-color, #000);
    cursor: pointer;
}

.header-action.favorite-btn .icon {
    color: var(--tg-theme-text-color, #000);
    stroke-width: 2;
    filter: none;
}

.header-action.favorite-btn.active .icon {
    color: #ff4757;
    fill: currentColor;
}

/* Жалоба внизу экрана, приглушённая */
.report-link {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    margin-top: 20px;
    padding: 10px;
    background: none;
    border: none;
    color: var(--tg-theme-hint-color, #999);
    font-size: 0.85rem;
    cursor: pointer;
}

.lot-detail-close {
    flex-shrink: 0;
    font-size: 22px;
    color: var(--tg-theme-text-color, #000);
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    transition: background 0.2s;
}

.lot-detail-close:hover {
    background: var(--tg-theme-secondary-bg-color, #f0f0f0);
}

/* Фото занимает около 45% экрана — на решении о покупке смотрят именно на
   него. Потолок нужен, чтобы очень вертикальный кадр не вытолкнул цену
   и кнопку ставки за пределы видимого. */
.lot-detail-images {
    position: relative;
    width: 100%;
    height: calc(var(--vvh, 100dvh) * 0.45);
    max-height: 420px;
    background: var(--tg-theme-secondary-bg-color, #e8e8e8);
    overflow: hidden;
}

/* Карусель на нативной прокрутке с примагничиванием: кадр следует за пальцем,
   на отпускании встаёт на место сам. Инерцию и плавность даёт браузер —
   самодельная обработка свайпа для этого не нужна. */
.photo-carousel {
    display: flex;
    width: 100%;
    height: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.photo-carousel::-webkit-scrollbar {
    display: none;
}

.carousel-slide {
    position: relative;
    flex: 0 0 100%;
    height: 100%;
    scroll-snap-align: center;
    overflow: hidden;
}

/* Позади снимка — он же, увеличенный и размытый.
   Вертикальное фото в горизонтальной рамке иначе оставляет по бокам пустые
   поля в половину ширины экрана. Обрезать вместо этого нельзя: на барахолке
   вещь должна быть видна целиком до того, как человек сделает ставку. */
.detail-photo-blur {
    position: absolute;
    inset: -24px;
    background-size: cover;
    background-position: center;
    filter: blur(22px) brightness(0.75);
    transform: scale(1.08);
}

.detail-photo-img {
    position: relative;
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    cursor: pointer;
}

.lot-detail-body {
    padding: 16px;
}

.lot-detail-title {
    font-size: 1.15rem;
    font-weight: 600;
    line-height: 1.3;
    margin-bottom: 10px;
    color: var(--tg-theme-text-color, #000);
}

/* В шапке окна — название лота, а не слово «Детали лота»:
   заголовок должен сообщать, что открыто */
.lot-detail-header-title {
    margin: 0;
    font-size: 0.95rem;
    font-weight: 500;
    line-height: 1.3;
    color: var(--tg-theme-text-color, #000);
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    padding-right: 12px;
}


.lot-detail-description {
    font-size: 0.95rem;
    line-height: 1.5;
    color: var(--tg-theme-text-color, #333);
    margin-bottom: 20px;
}

.lot-detail-price-section {
    background: var(--tg-theme-secondary-bg-color, #f8f8f8);
    padding: 14px 16px;
    border-radius: 12px;
    margin-bottom: 16px;
}

.lot-detail-price-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

/* Цена обычного цвета — как в списке лотов.
   Синий приберегаем для действий, красный для срочности. */
.lot-detail-price {
    font-size: 1.7rem;
    font-weight: 600;
    color: var(--tg-theme-text-color, #000);
    white-space: nowrap;
}

.lot-detail-timer {
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--tg-theme-hint-color, #888);
    white-space: nowrap;
}

.lot-detail-timer.urgent {
    color: var(--danger-color);
    font-weight: 600;
}

/* Ставки — то, ради чего человек открыл лот */
.lot-detail-price-sub {
    font-size: 0.85rem;
    color: var(--tg-theme-hint-color, #888);
    margin-top: 4px;
}

/* Метки перенесены под название: раньше категория и город стояли выше
   фотографии, и товар опознавался последним */
.lot-detail-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 12px;
}

.lot-tag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border-radius: 20px;
    background: var(--tg-theme-secondary-bg-color, #f0f0f0);
    color: var(--tg-theme-hint-color, #777);
    font-size: 0.78rem;
    white-space: nowrap;
}

.lot-tag .icon {
    font-size: 0.85rem;
}

/* Второстепенное действие: контур вместо заливки, чтобы не спорить
   с главной кнопкой «Сделать ставку» */
.btn-secondary {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    margin: 12px 0;
    padding: 11px;
    background: none;
    color: var(--tg-theme-button-color, #2481cc);
    border: 1px solid var(--tg-theme-button-color, #2481cc);
    border-radius: 8px;
    font-size: 0.95rem;
    font-weight: 500;
    cursor: pointer;
}

/* Удаление не должно быть заметнее безопасного действия рядом */
.btn-danger-quiet {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 13px;
    background: none;
    color: var(--danger-color);
    border: 1px solid var(--danger-color);
    border-radius: 8px;
    font-size: 0.95rem;
    font-weight: 500;
    cursor: pointer;
}

.lot-detail-bids-history {
    margin-bottom: 20px;
}

.lot-detail-bids-title {
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 12px;
    color: var(--tg-theme-text-color, #000);
}

.bid-history-item {
    padding: 12px;
    background: var(--tg-theme-secondary-bg-color, #f8f8f8);
    border-radius: 8px;
    margin-bottom: 8px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

/* Своя ставка выделена: раньше в списке «Участник №2» человек не мог
   понять, какая из ставок его */
.bid-history-item.mine {
    border: 1px solid var(--tg-theme-button-color, #2481cc);
}

.bid-history-item.mine .bid-history-user {
    color: var(--tg-theme-button-color, #2481cc);
}

/* ===== Строки списков в админке ===== */
/* Имя занимает строку целиком, кнопки уходят под него и жмутся вправо:
   в одну строку на 375px имя переносилось по слогам */
.admin-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 10px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--tg-theme-hint-color, #e8e8e8);
}

.admin-row-main {
    flex: 1 1 100%;
    min-width: 0;
}

.admin-row-name {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--tg-theme-text-color, #000);
}

.admin-row-sub {
    font-size: 0.75rem;
    color: var(--tg-theme-hint-color, #888);
    margin-top: 2px;
}

.admin-badge {
    padding: 1px 7px;
    border-radius: 20px;
    font-size: 0.68rem;
    font-weight: 500;
    background: var(--tg-theme-secondary-bg-color, #eee);
    color: var(--tg-theme-hint-color, #777);
}

.admin-badge.blocked {
    background: var(--danger-color);
    color: #fff;
}

.admin-btn-block,
.admin-btn-restore {
    flex-shrink: 0;
    padding: 6px 12px;
    font-size: 0.75rem;
    font-weight: 500;
    border-radius: 6px;
    background: none;
    cursor: pointer;
}

.admin-btn-block {
    color: var(--danger-color);
    border: 1px solid var(--danger-color);
}

.admin-btn-restore {
    color: var(--success-color);
    border: 1px solid var(--success-color);
}

.bid-history-user {
    font-weight: 600;
    color: var(--tg-theme-text-color, #000);
}

.bid-history-amount {
    font-weight: 600;
    color: var(--tg-theme-text-color, #000);
    white-space: nowrap;
}

.bid-history-time {
    font-size: 0.8rem;
    color: var(--tg-theme-hint-color, #888);
}

.lot-detail-footer {
    position: sticky;
    bottom: 0;
    background: var(--tg-theme-bg-color, #ffffff);
    padding: 16px;
    border-top: 1px solid var(--tg-theme-hint-color, #e0e0e0);
}

/* Продавец на экране лота. Раньше его имя было видно только в шапке чата,
   то есть уже после того, как человек написал. */
.lot-seller {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 14px;
    color: var(--tg-theme-text-color, #000);
}

.lot-seller-link {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 4px;
    padding: 0;
    border: none;
    background: none;
    color: var(--tg-theme-link-color, #2481cc);
    font-size: 0.9rem;
    cursor: pointer;
}

/* Вместо кнопки ставки — состояние: лидеру поднимать свою же ставку незачем */
.lot-detail-leading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    padding: 14px;
    border-radius: 10px;
    background: rgba(76, 175, 80, 0.15);
    color: var(--success-color, #4caf50);
    font-weight: 500;
}

.lot-detail-bid-btn {
    width: 100%;
    padding: 16px;
    background-color: var(--tg-theme-button-color, #2481cc);
    color: var(--tg-theme-button-text-color, #ffffff);
    border: none;
    border-radius: 12px;
    font-size: 1.1rem;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.2s ease;
}

.lot-detail-bid-btn:hover {
    opacity: 0.9;
}

.lot-detail-bid-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ============= ПОДВКЛАДКИ "МОЙ NEEBAY" ============= */

.sub-tabs {
    display: flex;
    gap: 8px;
    margin-bottom: 20px;
    overflow-x: auto;
    padding-bottom: 4px;
}

.sub-tab-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    padding: 10px 8px;
    background: var(--tg-theme-secondary-bg-color, #f0f0f0);
    border: none;
    border-radius: 8px;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--tg-theme-text-color, #000);
    cursor: pointer;
    transition: all 0.2s ease;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sub-tab-btn .icon {
    font-size: 1.05rem;
}

.sub-tab-btn.active {
    background: var(--tg-theme-button-color, #2481cc);
    color: var(--tg-theme-button-text-color, #ffffff);
}

.sub-tab-btn:hover:not(.active) {
    background: var(--tg-theme-hint-color, #e0e0e0);
}

/* ============= ФИЛЬТРЫ "МОИ ЛОТЫ" (ПРОДАЖИ) ============= */

.my-lots-filter-btn {
    flex: 1;
    min-width: 90px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 7px 10px;
    background: var(--tg-theme-secondary-bg-color, #f0f0f0);
    border: 1px solid var(--tg-theme-hint-color, #e0e0e0);
    border-radius: 20px;
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--tg-theme-hint-color, #999);
    cursor: pointer;
    transition: all 0.2s ease;
    white-space: nowrap;
}

.my-lots-filter-btn .icon {
    font-size: 0.95rem;
}

.my-lots-filter-btn.active {
    background: var(--tg-theme-button-color, #2481cc);
    border-color: var(--tg-theme-button-color, #2481cc);
    color: var(--tg-theme-button-text-color, #ffffff);
    box-shadow: 0 2px 8px rgba(36, 129, 204, 0.3);
}

.my-lots-filter-btn:hover:not(.active) {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.2);
}

/* ============================================= */

.sub-tab-content-wrapper {
    position: relative;
}

.sub-tab-content {
    display: none;
}

.sub-tab-content.active {
    display: block;
}

/* ============= КНОПКА ИЗБРАННОГО (СЕРДЕЧКО) ============= */

/* Без подложки-кружка: он перекрывал фото и утяжелял карточку.
   Читаемость на светлых снимках держится на тени под самим значком. */
.favorite-btn {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 28px;
    height: 28px;
    background: none;
    border: none;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 10;
    transition: transform 0.2s ease;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45));
}

.favorite-btn:hover {
    transform: scale(1.1);
}

.favorite-btn:active {
    transform: scale(0.95);
}

.favorite-icon {
    font-size: 21px;
    line-height: 0;
    display: block;
}

/* Не в избранном — белый контур поверх фото.
   В избранном — залитое красное сердце, состояние видно с одного взгляда. */
.favorite-btn .icon {
    color: #ffffff;
    stroke-width: 2.2;
}

.favorite-btn.active .icon {
    color: #ff4757;
    fill: currentColor;
}

/* Анимация сердечка */
@keyframes heartbeat {
    0%, 100% { transform: scale(1); }
    25% { transform: scale(1.3); }
    50% { transform: scale(1.1); }
}

.favorite-btn.active:active .favorite-icon {
    animation: heartbeat 0.3s ease;
}

/* Относительное позиционирование для карточек */
.lot-card {
    position: relative;
}

/* Мобильная адаптация */
@media (max-width: 768px) {
    .sub-tabs {
        gap: 6px;
    }
    
    .sub-tab-btn {
        padding: 8px 10px;
        font-size: 0.8rem;
    }
    
    .favorite-btn {
        width: 28px;
        height: 28px;
        top: 6px;
        right: 6px;
    }
    
    .favorite-icon {
        font-size: 16px;
    }
}

/* ============= СВИТЧ ============= */

.switch {
    position: relative;
    display: inline-block;
    width: 48px;
    height: 26px;
    flex-shrink: 0;
}

.switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    transition: 0.3s;
    border-radius: 26px;
}

.slider:before {
    position: absolute;
    content: "";
    height: 20px;
    width: 20px;
    left: 3px;
    bottom: 3px;
    background-color: white;
    transition: 0.3s;
    border-radius: 50%;
}

input:checked + .slider {
    background-color: var(--tg-theme-button-color, #2481cc);
}

input:checked + .slider:before {
    transform: translateX(22px);
}

/* ============= КНОПКА ДОБАВЛЕНИЯ ФОТО ============= */

.photo-add-btn {
    width: 104px;
    height: 104px;
    gap: 6px;
    font-size: 22px;
    border: 2px dashed var(--tg-theme-hint-color, #ccc);
    background: var(--tg-theme-secondary-bg-color, #f8f8f8);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s;
    color: var(--tg-theme-hint-color, #888);
}

.photo-add-btn span {
    padding: 0 6px;
    font-size: 0.75rem;
    line-height: 1.2;
    text-align: center;
}

/* Места под ещё не добавленные фотографии. Только контур: это не кнопка
   и нажимать тут нечего — весь смысл в том, чтобы показать, сколько
   снимков помещается. */
.photo-slot-empty {
    width: 104px;
    height: 104px;
    border: 2px dashed var(--tg-theme-hint-color, #ccc);
    border-radius: 8px;
    opacity: 0.35;
}

.photo-add-btn:hover {
    border-color: var(--tg-theme-button-color, #2481cc);
    background: var(--tg-theme-bg-color, #fff);
    color: var(--tg-theme-button-color, #2481cc);
}

.photo-preview {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 8px;
}

.photo-preview-item {
    position: relative;
    width: 104px;
    height: 104px;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--tg-theme-hint-color, #e0e0e0);
}

/* Вертикаль остаётся странице, горизонталь достаётся перетаскиванию:
   фотографии стоят в один ряд, поэтому горизонтали хватает, а список
   продолжает листаться пальцем по плитке. */
.photo-preview-item {
    touch-action: pan-y;
}

/* Плитка в руке: приподнята и полупрозрачна, чтобы было видно, что она
   оторвалась от ряда и сейчас переедет */
.photo-dragging {
    transform: scale(1.06);
    opacity: 0.75;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.3);
    z-index: 3;
}

/* Первая фотография уходит в ленту — без подписи порядок выглядит
   произвольным, и непонятно, зачем его вообще менять */
.photo-cover-badge {
    position: absolute;
    left: 0;
    bottom: 0;
    right: 0;
    padding: 3px 0;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 0.65rem;
    text-align: center;
    pointer-events: none;
}

.photo-preview-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.photo-preview-item button {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.6);
    color: white;
    border: none;
    cursor: pointer;
    font-size: 18px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}

.photo-preview-item button:hover {
    background: rgba(220, 53, 69, 0.9);
}
/* Badge для непрочитанных сообщений */
.badge {
    position: absolute;
    top: 4px;
    right: 8px;
    background: var(--danger-color);
    color: white;
    font-size: 0.7rem;
    padding: 2px 6px;
    border-radius: 10px;
    font-weight: bold;
    min-width: 18px;
    text-align: center;
}

/* Карточка переписки */
/* Строка списка переписок: высота задаётся фотографией, текст в две строки.
   Прежняя карточка занимала около 125px из-за рамки, отступов в 16px и
   отдельной строки с именем собеседника — на экран помещалось три чата. */
.conversation-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 4px;
    border-bottom: 1px solid var(--tg-theme-hint-color, #e8e8e8);
    cursor: pointer;
}

.conversation-photo {
    width: 52px;
    height: 52px;
    object-fit: cover;
    border-radius: 10px;
    flex-shrink: 0;
}

.conversation-photo-empty {
    background: var(--tg-theme-secondary-bg-color, #e8e8e8);
}

.conversation-body {
    flex: 1;
    min-width: 0;
}

.conversation-line {
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.conversation-line + .conversation-line {
    margin-top: 3px;
}

.conversation-lot-title {
    flex: 1;
    min-width: 0;
    font-weight: 600;
    font-size: 0.92rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.conversation-time {
    flex-shrink: 0;
    font-size: 0.72rem;
    color: var(--tg-theme-hint-color, #888);
    white-space: nowrap;
}

.conversation-last-message {
    display: flex;
    align-items: center;
    gap: 5px;
    flex: 1;
    min-width: 0;
    font-size: 0.85rem;
    color: var(--tg-theme-hint-color, #888);
}

/* Многоточием обрезается только сам текст сообщения: кружок и имя должны
   остаться целыми, иначе непонятно, от кого строка */
.conversation-last-message > .conversation-author {
    flex-shrink: 0;
}

.conversation-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Собеседник переехал сюда из отдельной строки */
.conversation-author {
    color: var(--tg-theme-text-color, #333);
}

.conversation-unread {
    flex-shrink: 0;
    min-width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--tg-theme-button-color, #2481cc);
    color: var(--tg-theme-button-text-color, #fff);
    font-size: 0.72rem;
    font-weight: 600;
    padding: 0 6px;
    border-radius: 10px;
}

/* Окно чата */
/* Полноэкранный режим для переписки. Диалог поверх списка требовал подложки,
   а сквозь неё в тёмной теме просвечивали карточки; плюс поля окна и отступы
   съедали место, которого в чате и так мало. */
.modal.modal-full {
    padding: 0;
    background: var(--tg-theme-bg-color, #fff);
}

/* Рамка и тень нужны окну, которое лежит поверх страницы, чтобы отделиться
   от неё. Здесь окно и есть вся страница: рамка превращалась в полоски по
   краям экрана, а тень — в тёмный ободок. */
/* Экран, который открывается с экрана лота и должен лежать поверх него,
   но под диалогами. Возврат при этом ведёт обратно на лот — цепочку
   восстанавливает closeModal, там уже есть проверка открытого лота. */
.modal.modal-full.modal-over-lot {
    z-index: 3600;
}

/* Ниже экрана лота: он открывается поверх раздела профиля и чата.
   Размер и положение — по видимой области, а не по странице: с открытой
   клавиатурой на iOS страница остаётся прежней высоты и вдобавок съезжает
   вниз, поэтому поле ввода оказывалось под клавиатурой. */
.modal.modal-full {
    z-index: 3000;
    top: var(--vv-offset, 0px);
    height: var(--vvh, 100dvh);
}

.modal.modal-full .modal-content {
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    box-shadow: none;
    /* Основной фон, а не вторичный: вторичным окрашены облачка сообщений
       собеседника, и на одинаковом фоне они переставали читаться */
    background-color: var(--tg-theme-bg-color, #fff);
    /* Ровно по видимой области, а не «не меньше»: с min-height содержимое
       выходило за нижний край, когда клавиатура ужимала экран */
    height: var(--vvh, 100dvh);
}

/* Высота считается от реально видимой области, а не от 100vh: с открытой
   клавиатурой на iOS 100vh продолжает включать закрытую ею часть экрана */
.chat-container {
    display: flex;
    flex-direction: column;
    height: var(--vvh, 100dvh);
}

/* Поле ввода и отправка в одну строку — кнопка во всю ширину под полем
   съедала место, которого в чате и так немного */
.chat-composer {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    border-top: 1px solid var(--tg-theme-hint-color, #ddd);
}

/* Цвета заданы явно: системные поля не следуют теме Телеграма сами */
.chat-input {
    flex: 1;
    min-width: 0;
    padding: 10px 14px;
    border: 1px solid var(--tg-theme-hint-color, #ddd);
    border-radius: 20px;
    font-size: 1rem;
    background: var(--tg-theme-secondary-bg-color, #f5f5f5);
    color: var(--tg-theme-text-color, #000);
}

.chat-input::placeholder {
    color: var(--tg-theme-hint-color, #999);
}

.chat-send {
    flex-shrink: 0;
    width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: var(--tg-theme-button-color, #2481cc);
    color: var(--tg-theme-button-text-color, #fff);
    font-size: 20px;
    cursor: pointer;
}

.chat-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--tg-theme-hint-color, #ddd);
}

.chat-header-text {
    flex: 1;
    min-width: 0;
}

.chat-header-title {
    font-weight: 600;
    font-size: 0.95rem;
    line-height: 1.25;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
}

.chat-header-user {
    font-size: 0.8rem;
    color: var(--tg-theme-hint-color, #888);
    margin-top: 1px;
}

.chat-close {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    padding: 0;
    font-size: 20px;
    color: var(--tg-theme-hint-color, #888);
    cursor: pointer;
}

.chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Разговор начинается от поля ввода и растёт вверх, как в мессенджерах.
   Раньше пара сообщений висела под шапкой, а под ними до самого низа была
   пустота. Отступ на первом элементе, а не justify-content: flex-end —
   с ним при переполнении верхние сообщения становятся недоступны прокрутке. */
.chat-messages > .chat-message:first-child,
.chat-messages > .chat-day:first-child {
    margin-top: auto;
}

.chat-empty {
    margin: auto;
    text-align: center;
    color: var(--tg-theme-hint-color, #888);
}

/* Дата стоит один раз в начале дня, а не в каждом сообщении. Невзрачная
   и по центру: это указатель, а не часть переписки. */
.chat-day {
    align-self: center;
    margin: 10px 0 6px;
    font-size: 0.72rem;
    color: var(--tg-theme-hint-color, #888);
}

/* Облачко и время — два этажа одной колонки. Внутри облачка время задавало
   ему ширину: слово «Да» занимало столько же места, сколько подпись. */
.chat-message {
    display: flex;
    flex-direction: column;
    max-width: 75%;
}

.chat-bubble {
    padding: 7px 12px;
    border-radius: 16px;
    overflow-wrap: anywhere;
}

/* Сообщения подряд от одного человека идут плотнее, смена автора заметна
   по увеличенному зазору */
.chat-message-own + .chat-message-other,
.chat-message-other + .chat-message-own {
    margin-top: 8px;
}

.chat-message-own {
    align-self: flex-end;
    align-items: flex-end;
}

.chat-message-own .chat-bubble {
    background: var(--tg-theme-button-color, #2481cc);
    color: var(--tg-theme-button-text-color, white);
    border-bottom-right-radius: 4px;
}

/* Своё сообщение узнаётся по цвету кнопки, чужому опереться не на что.
   Тонкая серая обводка держит границу облачка даже в темах, где вторичный
   фон почти не отличается от основного. */
.chat-message-other {
    align-self: flex-start;
    align-items: flex-start;
}

.chat-message-other .chat-bubble {
    background: var(--tg-theme-secondary-bg-color, #f0f0f0);
    color: var(--tg-theme-text-color, #000);
    border: 1px solid rgba(128, 128, 128, 0.25);
    border-bottom-left-radius: 4px;
}

/* Время под облачком, у внешнего края: у своих сообщений справа, у чужих
   слева. Небольшой отступ, чтобы не липло к самому краю экрана. */
.chat-message-time {
    margin-top: 2px;
    padding: 0 6px;
    /* Цифры читаются крупнее строчных букв того же кегля, поэтому подпись
       берём заметно мельче текста сообщения, а не на пару долей */
    font-size: 0.6rem;
    color: var(--tg-theme-hint-color, #888);
    white-space: nowrap;
}
