/* dashboard.css — Dashboard/SaaS-адаптация сайта (браузер, вне Telegram)
 * ПОВЕРХ существующих index.html/script.js/style.css. Ничего не дублирует:
 * это только сайдбар/топбар-раскладка для широкого экрана, включается
 * классом "is-browser" на <html> (см. script.js, сразу после IS_TELEGRAM).
 * Внутри Telegram Mini App и на мобильной ширине браузера — ровно тот же
 * вид, что был всегда (нижняя навигация, полноэкранные разделы).
 *
 * Почему так, а не отдельный сайт с нуля: script.js уже содержит рабочую,
 * проверенную логику (реальный рендер AI-отчёта, фильтры, избранное,
 * карта, GSAP-анимации) — переписывать её ради другой обёртки означало бы
 * держать два места с одной и той же бизнес-логикой, которые неизбежно
 * разойдутся. Здесь адаптирована ВЁРСТКА, а не логика.
 *
 * 🔥 ВАЖНО (найдено при доводке до "идеальной вёрстки", см. blueprint-план):
 * в style.css уже ДО этого файла существует своя обширная десктоп-адаптация
 * ("PHASE 6" в style.css, секции 6.1–6.3) — она центрирует .screen/#mainHeader/
 * #gHeader как "мобильную карточку на всю высоту" на ЛЮБОМ широком экране
 * (без привязки к is-browser — это касается и Telegram Desktop) и делает это
 * через margin/left/right/width с !important. Первая версия сайдбара в этом
 * файле не учла это и потеряла войну специфичности — правила ниже были
 * (visually) вообще без эффекта, сайдбар просто накладывался поверх
 * центрированного контента. Все правила, переопределяющие PHASE 6 конкретно
 * для is-browser + ≥1024px, теперь явно используют !important на селекторе
 * с более высокой специфичностью (html.is-browser #id перебивает #id при
 * равном !important) — тот же приём, что и в самом style.css (см. комментарий
 * там же про #mapModal).
 */

:root {
    /* TASK4 4.1 (DESIGN_MASTER_PROMPT.md §6.4): было 288px на любой ширине —
       теперь ширина зависит от окна: 72px иконный рейл на 1024–1535px,
       240px с подписями на ≥1536px. Значение потребляют только
       html.is-browser-селекторы ниже (в Mini App у html нет is-browser),
       поэтому сама переменная там ни на что не влияет. */
    --sidebar-w: 72px;
}
@media (min-width: 1536px) {
    :root { --sidebar-w: 240px; }
}

/* Сайдбар и метрик-стрип скрыты везде по умолчанию — появляются только ниже,
   под явным контекстом "браузер + широкий экран". (Без inline style="display:
   none" в index.html: там он побеждал бы медиа-запрос ниже без !important —
   та же ловушка специфичности, что и с сайдбаром/топбаром, см. комментарий
   в начале файла.) */
#sidebarNav, #desktopMetricStrip, #homePageBanner { display: none; }

/* ДОБАВЛЕНО (обратная связь 03.09.2026, "сделай категории не обязательными
   скроллингу, а просто помести все категории сразу"): строка категорий
   (#homeCategoryRow) в разметке — это flex-ряд с overflow-x-auto (Tailwind)
   без переноса, поэтому 8 пилюль-кнопок не помещаются по ширине и уходят в
   горизонтальный скролл — на мобильной ширине браузера "Прочее"/"Паркинг"
   были обрезаны и терялись, пока не проскроллишь. Правило НЕ внутри
   @media (min-width: 1024px), как обычно в этом файле — раньше здесь ничего
   не переопределялось для узкой ширины специально: и Telegram, и мобильный
   браузер делили один и тот же мобильный вид (см. шапку файла). Здесь это
   осознанно нарушается ТОЛЬКО для браузера (html.is-browser) — специально
   для мобильной ширины, а не только десктопа, — Mini App (html без класса
   is-browser) продолжает получать ту же прокручиваемую ленту, что и раньше,
   ни один селектор ниже не задевает его. Просто переносим кнопки на
   следующую строку вместо скролла — тот же .no-scrollbar/overflow-x-auto
   из разметки ничего не портит: скроллить уже нечего, когда всё помещается
   переносом. Тот же селектор действует и когда script.js позже переносит
   этот же узел в #homeFilterRail на широком экране (≥1280px, см. ниже по
   файлу) — там ряд просто переносится на несколько строк внутри узкой
   колонки рейла вместо скролла там же. */
html.is-browser #homeCategoryRow {
    flex-wrap: wrap;
    overflow-x: visible;
}

/* ДОБАВЛЕНО (обратная связь 05.09.2026, "категории одного размера, без
   смайликов, премиально"): смайлики убраны прямо из разметки (app_shell.html,
   .cat-btn/.fav-cat-btn/.g-cat-btn — все три ряда категорий идентичны,
   см. комментарий выше про #homeCategoryRow/#gCategoryRow). Без иконки-эмодзи
   и с "whitespace-nowrap" ширина каждой кнопки раньше считалась по длине
   собственного текста — "Все" (3 буквы) и "Коммерция" (9 букв) были заметно
   разной ширины, ряд выглядел рваным. Единая min-width (по самому длинному
   слову с запасом) + текст по центру — тот же приём, что уже определяет
   премиальность золотых активных кнопок в остальном интерфейсе, просто
   применённый к самой геометрии кнопки, а не только к цвету. Только десктоп
   (≥1024px) — на телефоне/в Mini App ряд остаётся компактным, как был. */
@media (min-width: 1024px) {
    html.is-browser .cat-btn,
    html.is-browser .fav-cat-btn,
    html.is-browser .g-cat-btn {
        min-width: 108px;
        text-align: center;
    }
}

/* ЧАСТИЧНО ОТКАЧЕНО (обратная связь 03.09.2026, "для браузера телефона
   сделай категории со скроллингом, как в Telegram, а не вываливай все
   сразу — на ПК-браузере оставь как есть"): перенос строк выше (просили
   сами же на предыдущем шаге) на телефоне съедал слишком много места под
   шапкой — категории вытесняли обзор на список лотов. На узкой ширине
   (<640px — телефон, единственная ширина, где вообще стоит вопрос
   "видно ли список сразу") возвращаем ИСХОДНОЕ поведение — тот же
   горизонтальный скролл, что и в самом Telegram Mini App (см. шапку
   файла: Mini App этот CSS-файл вообще не подключает, там #homeCategoryRow
   всегда был со скроллом, это не трогаем). На ПК-браузере (≥640px)
   правило выше как было — все категории сразу, переносом строк. Тот же
   селектор specificity, что и выше — при <640px эта, более поздняя по
   файлу @media-версия побеждает. */
@media (max-width: 639px) {
    html.is-browser #homeCategoryRow {
        flex-wrap: nowrap;
        overflow-x: auto;
    }
}

@media (min-width: 1024px) {
    html.is-browser #sidebarNav {
        display: flex;
        flex-direction: column;
        position: fixed;
        top: 0; left: 0; bottom: 0;
        width: var(--sidebar-w);
        padding: 20px 16px;
        background: #0a0e1a;
        border-right: 1px solid rgba(255,255,255,0.08);
        z-index: 100; /* ниже screen-login (10000, fixed inset-0 — полностью
                         перекрывает сайдбар на экране входа) и модалок */
    }

    .sidebar-brand {
        display: flex; align-items: center; gap: 9px;
        font-weight: 700; font-size: 18px; color: #fff;
        padding: 4px 8px 22px;
    }
    .sidebar-brand i { color: var(--accent); font-size: 24px; }
    .sidebar-brand .accent-text { color: var(--accent); }

    .sidebar-user {
        display: flex; align-items: center; gap: 12px;
        padding: 12px 10px; margin-bottom: 18px;
        background: rgba(255,255,255,0.04); border-radius: 12px;
    }
    .sidebar-user i { color: #94a3b8; font-size: 22px; }
    .sidebar-user-info { min-width: 0; }
    .sidebar-user-name { font-size: 14px; font-weight: 700; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .sidebar-balance { font-size: 12px; color: #E8B84B; display: flex; align-items: center; gap: 4px; }

    .sidebar-nav { display: flex; flex-direction: column; gap: 6px; flex: 1; }
    /* ИСПРАВЛЕНО (обратная связь 05.09.2026, "сайдбар побольше"): было
       10px/12px паддинг, 13px текст, 18px иконка, 40px мин-высота — сайдбар
       выглядел заметно мельче остального премиального интерфейса. */
    .sidebar-nav .nav-item {
        display: flex; align-items: center; gap: 14px;
        padding: 13px 14px; border-radius: 12px;
        color: #94a3b8; font-size: 14.5px; font-weight: 600;
        text-align: left; transition: background .15s ease, color .15s ease;
        min-height: 48px; /* тач-цель — UX-гайд по touch target/spacing */
    }
    .sidebar-nav .nav-item i { font-size: 20px; }
    .sidebar-nav .nav-item:hover { background: var(--bg-raised, rgba(255,255,255,0.05)); color: var(--text-primary, #fff); }
    /* TASK4 4.1 (DESIGN_MASTER_PROMPT.md §7.12): активный пункт — золотой
       маркер 3px слева + иконка ph-fill (она и так ph-fill в разметке),
       БЕЗ заливки фоном. Маркер — на СОБСТВЕННОМ левом краю пункта
       (left:0, ревью 4.1: left:-16px/-12px выносил его за padding-box
       #sidebarNav и рисовал точку 3×4px вместо полосы); top/bottom 12px —
       полоса 24px по центру пункта высотой 48px. */
    .sidebar-nav .nav-item { position: relative; }
    .sidebar-nav .nav-item.active { background: transparent; color: var(--accent); }
    /* height:auto/transform:none/border-radius:0 — сброс индикатора нижней
       навигации (style.css:494 .nav-item.active::before: width:22px;
       height:3px; translateX(-50%); radius), который без этого сужал полосу
       в точку 3×3 (найдено на зумах ревью 4.1b — top/left/width перекрывали
       его, а height/transform оставались). */
    .sidebar-nav .nav-item.active::before {
        content: ""; position: absolute; left: 0; top: 12px; bottom: 12px;
        width: 3px; height: auto; transform: none; border-radius: 0;
        background: var(--accent);
    }

    .sidebar-logout {
        display: flex; align-items: center; gap: 10px;
        padding: 10px 12px; border-radius: 10px; margin-top: 8px;
        color: #f87171; font-size: 13px; font-weight: 600;
        border-top: 1px solid rgba(255,255,255,0.06);
        min-height: 40px;
    }
    .sidebar-logout:hover { background: rgba(248,113,113,0.08); }

    /* Нижняя мобильная навигация больше не нужна — её роль играет сайдбар.
       (Эта !important ни с чем не воюет — display нигде больше не трогают.) */
    html.is-browser #bottomNav { display: none !important; }

    /* НАЙДЕНО при проверке вёрстки в Chrome (03.09.2026): #headerSpacer —
       мобильный приём, распорка под ВЫСОТУ #mainHeader, нужная только пока
       он "position: fixed" (перекрывает контент, если под ним нет места).
       window.onload в script.js безусловно выставляет ей
       "height = #mainHeader.offsetHeight + 20px" на КАЖДОЙ загрузке — и на
       мобильном, и на десктопе, — а #mainHeader несколькими правилами выше
       на десктопе уже переведён в position: relative (обычный поток).
       Результат: между шапкой/фильтрами и контентом (карточки/рекомендации)
       повисало ~200px пустого места, которое ничем не оправдано — сам
       контент и так корректно идёт следующим блоком в потоке. JS-логику не
       трогаем (мобильный сценарий использует её как есть) — просто гасим
       эффект на десктопе тем же приёмом, что и #bottomNav выше. */
    html.is-browser #headerSpacer { display: none !important; }

    /* ДОБАВЛЕНО (P1.3 аудита, 11.09.2026): ровно тот же баг, что описан в
       комментарии выше про #headerSpacer, — только для #gHeader/#gHeaderSpacer
       (шапка «Базы AI»). style.css переводит #gHeader в position:relative на
       той же ширине (≥640px, тот же общий селектор "#mainHeader, #gHeader"),
       но правило для #headerSpacer выше почему-то не продублировали для
       gHeaderSpacer — тот по-прежнему резервировал свою JS-высоту
       (watchHeaderSpacer('gHeader', 'gHeaderSpacer', ...) в script.js) ВТОРЫМ
       блоком поверх уже занявшего место в потоке #gHeader, тот же лишний
       зазор на «Базе AI» в браузере на ≥1024px. */
    html.is-browser #gHeaderSpacer { display: none !important; }

    /* 🔥 ИСПРАВЛЕНО: раньше здесь стояло `left: var(--sidebar-w)` без
       !important — style.css (PHASE 4, ~строка 480) уже держит
       #mainHeader/#gHeader через `left/right/margin-left/margin-right/
       max-width/width` ВСЕ с !important, и побеждал именно он: топбар
       визуально оставался на всю ширину экрана, наезжая на сайдбар.
       Переопределяем то же самое множество свойств тем же приёмом. */
    html.is-browser #mainHeader,
    html.is-browser #gHeader {
        left: var(--sidebar-w) !important;
        right: 0 !important;
        width: calc(100% - var(--sidebar-w)) !important;
        max-width: none !important;
        margin-left: 0 !important;
        margin-right: 0 !important;
    }

    /* 🔥 ИСПРАВЛЕНО: та же история с .screen — style.css центрирует его как
       карточку (margin-left/margin-right: auto !important, max-width:1280px)
       на любом экране ≥640px. Без !important здесь эта карточка просто
       накрывала сайдбар слева. Внутренний контент (#homeGrid и т.п.) уже
       ограничен своим max-w-7xl/mx-auto в Tailwind-разметке — сайдбар не
       заменяет этот внутренний потолок ширины, только освобождает место
       под себя контейнеру-родителю. */
    html.is-browser .screen {
        margin-left: var(--sidebar-w) !important;
        margin-right: 0 !important;
        width: calc(100% - var(--sidebar-w)) !important;
        max-width: none !important;
        border-left: none !important;
        border-right: none !important;
        box-shadow: none !important;
    }

    /* УДАЛЕНО (DESIGN_MASTER_PROMPT.md §5.4, обновление "сайт — не
       приложение"): здесь стоял большой блок html.is-browser #detailModal/
       #analysisModal{position:static;...} — превращал бывшие мобильные
       fixed-модалки в подобие "страницы" ЧИСТО ВИЗУАЛЬНО (те же классы
       .open/.modal-over-map/.hidden по-прежнему ставил/снимал JS,
       рассчитанный на модалку), плюс правило body:has(#detailModal.open)
       .screen{display:none}, прятавшее каталог под ней. На сайте ни
       #detailModal, ни #analysisModal больше не существуют вообще — лот и
       анализ теперь настоящие #screen-lot/#screen-analysis (тот же
       .screen-паттерн, что у home/favorites/..., без единого специального
       правила позиционирования: обычный блок в потоке документа, как и
       любой другой экран). Правило #actionButtonsContainer{position:static}
       тоже удалено — в partials/screens/lot.html эта кнопка с самого начала
       обычный блок, а не fixed-панель (той нужна была мобильная модалка).
       Оба класса .open/.modal-over-map остаются актуальны для Mini App
       (partials/modals/detail.html, shells/miniapp.html) — там стили лежат
       в style.css, вне html.is-browser, не тронуты. */

    /* НАЙДЕНО (D2, DESIGN_UPGRADE_PROMPT.md §5.6, липкая TL;DR-строка не
       прилипала на десктопе): #pdfContentArea несёt overflow-y-auto
       (Tailwind, из разметки) — задумано для Mini App/узкого браузера, где
       #analysisModal остаётся position:fixed и реально даёт этому блоку
       ограниченную высоту (flex:1 внутри flex-колонки фиксированной
       высоты), поэтому именно #pdfContentArea там и скроллится. Здесь же,
       на ≥1024px, #pdfContentArea живёт внутри #screen-analysis — обычного
       блока в потоке документа (§5.4, никаких position-хаков) — высота
       #pdfContentArea больше ничем не ограничена, она просто растягивается
       под весь контент, и скроллит вместо неё документ целиком. Но
       overflow-y:auto сам по себе (независимо от того, есть ли реальное
       переполнение) уже делает #pdfContentArea "ближайшим скролл-предком"
       для любого position:sticky внутри — sticky-потомок (#uiTldrStrip)
       привязывался к контейнеру, который на деле никогда не скроллится, и
       просто уезжал вместе со страницей. overflow-y:visible
       снимает с #pdfContentArea статус скролл-контейнера, sticky-потомки
       находят следующего реального — сам документ — и приклеиваются как
       надо. Визуально ничего не меняется: контент и так помещался внутри
       (реального переполнения не было, скроллбар никогда не появлялся). */
    html.is-browser #pdfContentArea {
        overflow-y: visible !important;
    }
    /* Со снятым overflow-y выше заголовок модалки ("Анализ", свой
       sticky top-0 z-10 в analysis.html) и #uiTldrStrip (тоже top-0, но
       z-20) сразу оба цепляются за один и тот же документный скролл и
       встают друг на друга — с более высоким z-index строка полностью
       закрывает заголовок. 65px — фактическая высота заголовка (py-4 +
       иконки), сдвигает строку строго под него, а не поверх. */
    html.is-browser #uiTldrStrip {
        top: 65px;
    }


    /* Заголовок "Auction Detective" внутри #mainHeader дублирует бренд,
       который уже есть в сайдбаре — на десктопе прячем, чтобы не было двух
       одинаковых логотипов подряд.
       ИСПРАВЛЕНО (проверка вёрстки в Chrome, 03.09.2026): селектор был
       "> h1:first-child", но в index.html этот заголовок — <h2> (строка
       ~258), не <h1>. Селектор никогда не совпадал, поэтому дублирующий
       логотип оставался на месте — сразу под ним ещё и растягивалась во всю
       ширину контента кнопка "Карта лотов" (тоже валидно, но выглядело как
       нагромождение). Совпадение и с h1, и с h2 — на случай, если тег ещё
       раз поменяют. */
    html.is-browser #mainHeader > h1:first-child,
    html.is-browser #mainHeader > h2:first-child { display: none; }

    /* ИСПРАВЛЕНО (обратная связь от 02.09.2026, "сетка концентрируется по
       середине, должна использовать всё свободное пространство"): раньше
       #homeGrid ограничивался Tailwind-классом max-w-7xl (1280px) и
       центрировался — на широком мониторе оставались пустые поля по бокам,
       а число колонок было жёстко зашито в разметке (xl:grid-cols-4, больше
       не становится ни на каком экране). auto-fill сам считает, сколько
       карточек шириной ≥340px помещается в реально доступную ширину — она
       занята вся, колонок ровно столько, сколько влезает, без пустых полей
       и без потолка в 4. !important бьёт тот же max-w-7xl (см. комментарий
       про специфичность в начале файла). */
    html.is-browser #homeGrid {
        /* TASK4 4.1 (DESIGN_MASTER_PROMPT.md §6.4): потолок max-w-7xl снят —
           контент текучий, без центрирования; два споривших правила
           (#homeGrid и #homeTableWrap, §6.4 «argues with itself») сведены
           к одной паре max-width:none без внутреннего потолка. Шаг сетки —
           auto-fill minmax(248px,1fr) (§6.4): колонок столько, сколько
           влезает; точные числа диапазонов — переопределениями сразу после
           основного @media-блока. Отступ между карточками — 16 (§6.3). */
        max-width: none !important;
        grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)) !important;
        gap: 16px;
    }
    /* ИСПРАВЛЕНО (обратная связь 02.09.2026, "тоже самое в виде таблицы"):
       #homeTableWrap нёс тот же max-w-7xl/mx-auto, что и сетка — таблица
       тоже упиралась в 1280px и висела по центру с пустыми полями. */
    html.is-browser #homeTableWrap {
        max-width: none !important;
        margin-left: 0 !important;
        margin-right: 0 !important;
    }

    /* ДОБАВЛЕНО (обратная связь 05.09.2026, "баннер Главная"): заголовок
       страницы над плитками баланса — тот же max-width/margin/padding, что
       и у #desktopMetricStrip чуть ниже, чтобы оба блока строго совпадали
       по левому/правому краю с сеткой лотов под ними. */
    #homePageBanner {
        display: block;
        max-width: 1280px;
        margin: 0 auto 20px;
        padding: 0 16px;
    }
    #homePageBanner h1 {
        font-size: 26px;
        font-weight: 700;
        color: #fff;
        letter-spacing: -0.01em;
        margin: 0 0 4px;
    }
    #homePageBanner p {
        font-size: 13.5px;
        color: #8b93a7;
        margin: 0;
    }

    /* D2 (DESIGN_UPGRADE_PROMPT.md §5.1, "метрик-стрип сливается с тулбаром
       одной тихой строкой"): раньше — самостоятельная секция из 3 крупных
       карточек-плиток на всю ширину колонки (см. git-историю). Теперь —
       тихая строка внутри #homeViewToggle (см. home.html), справа рядом со
       счётчиком, без фоновых карточек. Использует уже загруженные в память
       данные (userProfile), заполнение в script.js::updateProfileUI(), id
       не менялись. Только ≥1440px — на 1024–1439px тулбар и так плотный
       (переключатель площадок + счётчик), а эти же цифры уже есть в
       Профиле/сайдбаре. Не показывается в Mini App. */
    #desktopMetricStrip {
        display: none;
        align-items: center;
        gap: 18px;
    }
    #desktopMetricStrip .metric-tile {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        white-space: nowrap;
    }
    #desktopMetricStrip .metric-tile i {
        font-size: 14px;
        color: var(--accent);
        flex-shrink: 0;
    }
    #desktopMetricStrip .metric-value {
        font-size: 12.5px;
        font-weight: 600;
        color: var(--text-secondary);
        font-variant-numeric: tabular-nums;
    }

    /* Скор-ринг отчёта (#uiScoreRing) — по финтех-гайду главная метрика
       должна визуально доминировать; в мобильной вёрстке это плитка 56×56px
       рядом с иконкой кнопки, что теряется на просторной левой колонке
       двухколоночного отчёта (см. .report-grid в style.css, PHASE 6.2).
       Разметка/JS не трогаем (JS перезаписывает className целиком, но не
       трогает inline-стили) — просто укрупняем через ID-селектор outside
       Tailwind-классов, ровно как уже сделано для его gold-свечения выше
       в style.css (#uiScoreRing { filter: ... }). */
    html.is-browser #uiScoreRing {
        width: 84px !important;
        height: 84px !important;
        font-size: 28px !important;
    }
}

/* TASK4 4.1 (DESIGN_MASTER_PROMPT.md §6.4, TASK4 §1): 1024–1535px — узкий
   иконный рейл 72px (та же разметка a[data-nav]/#sidebarNav, только CSS):
   подписи скрыты, иконки по центру, тултип — нативный title атрибут ссылки
   (см. partials/chrome/sidebar.html), карточка пользователя — только
   аватар/инициал. Mini App не задет: селекторы живут под html.is-browser,
   а диапазон ≥1024px у телефона Mini App не бывает. */
@media (min-width: 1024px) and (max-width: 1535.98px) {
    html.is-browser #sidebarNav { padding: 20px 12px; }
    html.is-browser .sidebar-brand { justify-content: center; padding: 4px 0 22px; }
    html.is-browser .sidebar-brand span { display: none; }
    html.is-browser .sidebar-user { justify-content: center; padding: 12px 0; }
    html.is-browser .sidebar-user-info { display: none; }
    html.is-browser .sidebar-nav .nav-item { justify-content: center; padding-left: 0; padding-right: 0; }
    html.is-browser .sidebar-nav .nav-item span { display: none; }
}

/* TASK4 4.1 (DESIGN_MASTER_PROMPT.md §6.4 / TASK4 §1): диапазонные числа
   колонок сетки. Чистый auto-fill от minmax(248px) даёт на 1536px только
   3 колонки (после сайдбара 240 + рейла 264 + отступов остаётся ~990px —
   меньше 4×248+3×16), а на 2560px — 7; таблица §6.4 требует 4 на
   1536–1919 и 5–6 на ≥1920. Проверено на живых ширинах: 1920 → 5,
   1536 → 4, 1280 → 3. */
@media (min-width: 1536px) and (max-width: 1919.98px) {
    html.is-browser #homeGrid { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
}
@media (min-width: 2400px) {
    html.is-browser #homeGrid { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)) !important; }
}

/* D2 (DESIGN_UPGRADE_PROMPT.md §5.1): метрик-стрип в тулбаре показываем
   только на действительно просторном десктопе — на 1024–1439px тулбар и
   так занят переключателем вида + переключателем площадок + счётчиком,
   плюс эти же цифры уже видны в Профиле/сайдбаре, прятать не жалко. */
@media (min-width: 1440px) {
    #desktopMetricStrip {
        display: flex;
    }
}

/* --- Тело AI-отчёта (#analysisModal) ниже верхнего .report-grid-блока —
   раньше сценарии/риски/история/конкуренты/визуальные дефекты/анализ
   документов/юр.статус/вердикт/стратегия шли плоским одноколоночным
   потоком внутри уже широкой 1280px-рамки (см. #analysisModal в
   style.css, PHASE 6.2) — рамка широкая, а контент всё равно как на
   телефоне. .report-grid/.report-col сюда не годятся (сделаны под пару
   "герой+финмодель"), поэтому три новых класса под конкретные формы
   контента. Разметка/JS не трогались — только добавлены классы на уже
   существующие узлы (см. app_shell.html), где id остались прежними. ---*/
@media (min-width: 1024px) {
    /* Независимые карточки (сценарии доходности, риски, история торгов,
       конкуренты/аналоги) — раньше space-y-* стопкой, теперь сеткой;
       auto-fit не ломается при переменном количестве карточек (1-N). */
    html.is-browser .report-card-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
        gap: 12px;
    }
    /* Tailwind space-y-* добавляет margin-top каждому ребёнку кроме
       первого — внутри grid это лишний воздух между рядами, нейтрализуем. */
    html.is-browser .report-card-grid > * {
        margin-top: 0 !important;
    }

    /* Повествовательный текст (анализ документов/юр.статус — общий класс
       .expert-block__text, что делать после победы, итоговый вердикт,
       дисклеймер) — это ЧИТАЮТ, а не сканируют: ограничиваем ширину строки
       вместо того чтобы растягивать на все 1280px рамки. */
    html.is-browser .report-prose,
    html.is-browser .expert-block__text {
        max-width: 720px;
    }

    /* "Метка/число + объяснение" (стратегия торгов: stop-loss слева,
       обоснование+тактика справа). */
    html.is-browser .report-duo {
        display: grid;
        grid-template-columns: 260px 1fr;
        gap: 16px;
        align-items: start;
    }
    html.is-browser .report-duo > .report-duo__main {
        margin-top: 0 !important;
    }
    /* #uiGeoBlock — свой порядок детей (заголовок/карта/текст), заголовок
       занимает всю ширину первой строкой, карта слева от текста. */
    html.is-browser #uiGeoBlock.report-duo {
        grid-template-columns: 320px 1fr;
    }
    html.is-browser #uiGeoBlock.report-duo > h3 {
        grid-column: 1 / -1;
    }

    /* Визуальный анализ фото — было 2 колонки (мобильный размер), на
       широком экране 4 делает галерею компактнее без скролла. */
    html.is-browser #uiGalleryGrid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* --- Экран входа: на десктопе выглядит как страница, а не мобильная
   модалка, зависшая в углу большого тёмного экрана. Разметка та же (см.
   login.html #screen-login) — только просторнее и с рамкой-карточкой.
   Токены (D2, DESIGN_UPGRADE_PROMPT.md §5.7): bg-surface/border-subtle/
   radius-card/shadow-modal вместо смеси raw hex — тот же язык, что у модалок. */
@media (min-width: 1024px) {
    html.is-browser #screen-login .login-card {
        max-width: 420px;
        padding: 48px 40px;
        background: var(--bg-surface);
        border: 1px solid var(--border-subtle);
        border-radius: var(--radius-card);
        box-shadow: var(--shadow-modal);
    }
}

/* #loginShowcase/.showcase-* (двухколоночная маркетинговая витрина рядом с
   карточкой входа — эмодзи-заголовок, serif-хедлайн, 4 пункта с золотыми
   иконками в кружках) удалены вместе с разметкой в login.html (D2,
   DESIGN_UPGRADE_PROMPT.md §5.7, "Kill showcase noise" — витрина не
   переоформлена, а убрана: один спокойный блок на любом размере экрана
   вместо карточки + отдельной рекламной колонки). .login-facts ниже —
   её замена: три пункта «что внутри» с настоящими числами. */

/* --- Мобильный браузер (ширина < 1024px), вне Telegram: сайдбара нет,
   остаётся привычная нижняя навигация — но кнопка "Выход" в ней теперь
   реально разлогинивает (см. handleNavClose() в script.js), а не молчит. */

@media (prefers-reduced-motion: reduce) {
    .sidebar-nav .nav-item, .sidebar-logout { transition: none; }
}

/* --- Профиль → аккаунт-страница (платформенный план, фаза 1): на мобильном
   и в Telegram Mini App экран "Профиль" остаётся ровно тем, чем был —
   вертикальным стеком из трёх блоков (Обзор/Биллинг/О сервисе), потому что
   #profileAccountNav скрыт, а .profile-section без явного display ничего
   не прячет (все три просто идут подряд, как раньше единый список).
   На широком экране браузера те же три блока становятся вкладками:
   вертикальная навигация слева (тот же визуальный язык, что у #sidebarNav
   — тёмная плашка, золотой акцент на активном пункте) + один активный
   раздел справа, вместо длинной прокрутки через весь профиль. Разметка и
   все id внутри разделов (#profileAvatar, #balanceWeekly и т.д.) не
   менялись — см. index.html, script.js switchProfileSection(). */
#profileAccountNav { display: none; }

@media (min-width: 1024px) {
    html.is-browser #profileAccountNav {
        display: flex;
        flex-direction: column;
        gap: 4px;
        width: 220px;
        flex-shrink: 0;
        padding: 12px;
        background: #0a0e1a;
        border: 1px solid rgba(255,255,255,0.08);
        border-radius: 14px;
        height: fit-content;
    }
    .profile-account-nav-item {
        display: flex; align-items: center; gap: 12px;
        padding: 10px 12px; border-radius: 10px;
        color: #94a3b8; font-size: 13px; font-weight: 600;
        text-align: left; transition: background .15s ease, color .15s ease;
        min-height: 40px; /* тач-цель — как у .sidebar-nav .nav-item */
    }
    .profile-account-nav-item i { font-size: 18px; }
    .profile-account-nav-item:hover { background: rgba(255,255,255,0.05); color: #fff; }
    .profile-account-nav-item.active { background: rgba(232,184,75,0.12); color: #E8B84B; }

    /* #profileAccountNav и #profileContent — сиблинги внутри #screen-profile
       (см. index.html), не вложены друг в друга: сам #screen-profile
       становится строкой на десктопе. !important нужен по той же причине,
       что и у #sidebarNav/#mainHeader выше — style.css PHASE 6 уже задаёт
       .screen unconditional display/margin, не привязанные к is-browser. */
    html.is-browser #screen-profile.active {
        display: flex !important;
        align-items: flex-start;
        gap: 20px;
    }
    html.is-browser #profileContent { flex: 1; min-width: 0; }
    html.is-browser #profileContent .profile-section { display: none; }
    html.is-browser #profileContent .profile-section.active { display: block; }

    /* --- Профиль → Обзор/Биллинг/О сервисе (фаза 2, "только десктоп-вёрстка,
       без новых полей"): раньше все три раздела были одной узкой мобильной
       лентой, растянутой на всю ширину широкого пейна — карточки и строки
       "терялись" в пустом пространстве. Ни один блок/id/текст внутри не
       добавлен и не убран, только их взаимное расположение и читаемая
       ширина, тем же приёмом, что уже используется для .report-prose.
       ОТКАЧЕНО (аудит вёрстки, "в Обзоре справа много пустого места под
       Мои отчеты"): Обзор сначала получил отдельную 2-колоночную сетку
       (карточка баланса слева, "Мои отчеты" справа) — но с ровно двумя
       блоками, один из которых короче второго, это просто переносило ту
       же пустоту в правую колонку снизу. Единая узкая колонка, как у
       Биллинга/О сервисе, читается ровнее при таком объёме контента. */
    html.is-browser #profileContent .profile-section[data-section="billing"],
    html.is-browser #profileContent .profile-section[data-section="about"],
    html.is-browser #profileContent .profile-section[data-section="overview"] {
        max-width: 640px;
    }
}

/* --- Избранное → таблица (платформенный план, фаза 2): на мобильном и в
   Telegram — та же карточная лента + узкая панель фильтров по центру, что и
   всегда (#favTableWrap скрыт, #favFilterPanel/#favCatTabs без переопределений
   ничего не меняют). На широком экране браузера панель фильтров раскрывается
   на всю ширину, категории — из горизонтальной свайп-ленты в обычную
   вкладочную полосу (те же кнопки/обработчики, см. script.js setFavCategory —
   только визуально не лента-для-пальца), а #favGrid уступает место
   сортируемой таблице с чекбоксами для массовых действий. Ни один id/атрибут
   карточной версии не тронут — #favGrid как рендерился, так и рендерится
   (см. renderFavorites() в script.js), просто скрыт рядом с таблицей тем же
   приёмом, что и #bottomNav. */
#favTableWrap { display: none; }
/* ИСПРАВЛЕНО (аудит "контраст ниже нормы на самом мелком тексте", 05.09.2026):
   заголовки колонок/регион/дата/пустые состояния во всех трёх таблицах
   (#favArchiveTable здесь, #globalTable, #homeTable — ниже по файлу) были
   жёстко покрашены в #5c6579 — 3.29:1 на фоне #0a0e1a при 11-13px, ниже
   нормы WCAG AA (нужно 4.5:1). Заменено одним поиском-заменой на уже
   существующий токен var(--text-secondary) (#94a3b8, style.css) — 7.51:1,
   тот же цвет, что и вторичный текст в остальном приложении. */
/* ДОБАВЛЕНО (аудит интерфейса): та же табличная десктоп-версия для секции
   "Завершённые" (#favArchiveSection) — раньше там на любой ширине была
   только фиксированная карточная сетка с одной кнопкой "убрать все", без
   табличного вида и точечного массового выбора, которые уже есть у
   активного списка выше. */
#favArchiveTableWrap { display: none; }

@media (min-width: 1024px) {
    /* 1024–1279px: промежуточная ширина — постоянный рейл (ниже, ≥1280px)
       ещё не включается, панель фильтров остаётся горизontal-полосой сверху,
       просто на всю ширину вместо узкой карточки по центру. */
    html.is-browser #favFilterPanel {
        max-width: 100%;
    }
    html.is-browser #favFilterPanel .glass-panel {
        display: flex;
        align-items: center;
        gap: 20px;
        flex-wrap: wrap;
    }
    html.is-browser #favFilterPanel h2 { flex-shrink: 0; }
    html.is-browser #favFilterPanel .space-y-4 {
        display: flex;
        align-items: center;
        gap: 12px;
        flex: 1;
        flex-wrap: wrap;
    }
    html.is-browser #favFilterPanel .space-y-4 > * { margin: 0 !important; } /* снимает space-y-4 вертикальные отступы — тут ряд, не стек */
    html.is-browser #favCatTabs {
        overflow-x: visible;
        flex-wrap: wrap;
        flex: 1;
        min-width: 260px;
    }
    html.is-browser #favSiteToggle {
        min-width: 280px;
        flex-shrink: 0;
    }

    /* D2 (DESIGN_UPGRADE_PROMPT.md §5.2, "bulk bar становится плавающей
       нижней панелью действий при выборе > 0"): раньше бар массовых
       действий был обычной строкой НАД таблицей — при длинной таблице и
       выборе строк внизу списка кнопка "Убрать из избранного" уезжала за
       пределы экрана. position:sticky (не fixed — держится в рамках
       содержимого колонки, без ручного расчёта отступа под сайдбар/рейл,
       которым нужен другим fixed-элементам, см. #bottomNav) прижимает бар
       к низу видимой области, пока таблица прокручивается. Виден только
       когда есть выбор — .hidden/.flex переключает updateFavBulkBar(), эту
       логику не трогаем. */
    html.is-browser .fav-bulk-bar {
        position: sticky;
        bottom: 16px;
        z-index: 60;
        box-shadow: var(--shadow-modal);
        backdrop-filter: blur(12px);
    }

    html.is-browser #favGrid {
        display: none !important;
    }
    /* ИСПРАВЛЕНО (обратная связь 02.09.2026): #favGrid тоже больше не
       упирается в max-w-7xl, когда всё-таки видна (узкий десктоп, до того
       как рейл ниже возьмёт на себя роль фильтров) — тот же auto-fill приём,
       что и на Главной (см. #homeGrid выше). */
    html.is-browser #favContentCol,
    html.is-browser #favGrid,
    html.is-browser #favTableWrap,
    html.is-browser #favArchiveSection,
    html.is-browser #favArchiveGrid,
    html.is-browser #favArchiveTableWrap {
        max-width: none !important;
    }
    html.is-browser #favGrid {
        /* НАЙДЕНО (аудит "на 1440px в сетке только 2 колонки, хотя места
           хватает на 3"): при реальной доступной ширине контента (~869px на
           1440px — сайдбар 256px + рейл фильтров 300px) 340px давал ровно
           2 колонки, оставляя карточки крупнее и площе, чем нужно. 264px —
           ближе к уже используемому в .report-card-grid минимуму (280px),
           но с запасом, чтобы 3 колонки гарантированно помещались именно на
           1440px, а не балансировали на грани. */
        grid-template-columns: repeat(auto-fill, minmax(264px, 1fr)) !important;
    }

    /* Архив ("Завершённые") — тот же переход сетка→таблица, что у активного
       списка выше, независимо от того, свёрнут ли сам аккордеон (пусто —
       так пусто, JS не строит содержимое, пока свёрнуто, см. renderFavArchive()). */
    html.is-browser #favArchiveGrid {
        display: none !important;
    }
    html.is-browser #favArchiveTableWrap {
        display: block;
        margin-top: 12px;
    }

    html.is-browser #favTableWrap {
        display: block;
        margin-top: 20px;
    }
    html.is-browser #favTable,
    html.is-browser #favArchiveTable {
        width: 100%;
        table-layout: fixed;
        border-collapse: separate;
        border-spacing: 0;
        background: #0a0e1a;
        border: 1px solid rgba(255,255,255,0.08);
        border-radius: 14px;
        overflow: hidden;
    }
    html.is-browser #favTable thead th,
    html.is-browser #favArchiveTable thead th {
        text-align: left;
        font-size: 11px;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--text-secondary);
        padding: 12px 14px;
        border-bottom: 1px solid rgba(255,255,255,0.08);
        background: rgba(255,255,255,0.02);
    }
    html.is-browser #favTable thead th.sortable { cursor: pointer; user-select: none; }
    html.is-browser #favTable thead th.sortable:hover { color: #E8B84B; }
    html.is-browser #favTable .fav-th-check,
    html.is-browser #favArchiveTable .fav-th-check { width: 40px; }
    /* ИСПРАВЛЕНО (обратная связь 02.09.2026, "изображение слишком маленькое,
       увеличь лоты в 2 раза"): было 44px, как и .fav-th-photo/64px — теперь
       88px (ровно 2×), колонка-заголовок расширена под неё же. */
    html.is-browser #favTable .fav-th-photo,
    html.is-browser #favArchiveTable .fav-th-photo { width: 108px; }
    html.is-browser #favTable tbody tr,
    html.is-browser #favArchiveTable tbody tr {
        cursor: pointer;
        transition: background .15s ease;
        border-bottom: 1px solid rgba(255,255,255,0.05);
    }
    html.is-browser #favTable tbody tr:last-child,
    html.is-browser #favArchiveTable tbody tr:last-child { border-bottom: none; }
    html.is-browser #favTable tbody tr:hover,
    html.is-browser #favArchiveTable tbody tr:hover { background: rgba(255,255,255,0.03); }
    html.is-browser #favTable tbody td,
    html.is-browser #favArchiveTable tbody td { padding: 10px 14px; font-size: 13px; color: #e8eaf0; vertical-align: middle; }
    html.is-browser #favTable .fav-row-thumb,
    html.is-browser #favArchiveTable .fav-row-thumb {
        width: 88px; height: 88px; border-radius: 10px; object-fit: cover;
        max-width: none;
        border: 1px solid rgba(255,255,255,0.08);
    }
    html.is-browser #favTable .fav-row-title,
    html.is-browser #favArchiveTable .fav-row-title { font-weight: 600; width: 32%; }
    html.is-browser #favTable .fav-row-price,
    html.is-browser #favArchiveTable .fav-row-price {
        font-family: var(--font-mono, 'Manrope', sans-serif);
        font-variant-numeric: tabular-nums;
        color: var(--text-secondary); white-space: nowrap;
    }
    html.is-browser #favTable .fav-row-date,
    html.is-browser #favArchiveTable .fav-row-date { color: var(--text-secondary); font-size: 12px; white-space: nowrap; }
    html.is-browser #favTable .fav-table-empty,
    html.is-browser #favArchiveTable .fav-table-empty {
        text-align: center; padding: 32px 14px; color: var(--text-secondary); font-size: 13px;
    }
}

/* --- База AI → таблица (платформенный план, фаза 3): исследовательская база
   готовых отчётов — таблица данных вместо фото-витрины на широком экране
   браузера. Скор — не бейдж на карточке, а числовая колонка с мини-полосой
   прогресса в самой ячейке, как в финансовых дашбордах (см. тезис плана).
   На мобильном и в Telegram — #globalGrid как была, карточная лента; таблица
   скрыта (#globalTableWrap). Пагинация не менялась — тот же window.onscroll
   (см. script.js), он не завязан на грид/таблицу конкретно, а на высоту
   страницы, так что бесконечная подгрузка работает одинаково для обоих
   видов. Пейволл (#gPaywall) обрабатывает оба контейнера одинаково — см.
   loadGlobalLots(), класс "hidden" по-прежнему решает, скрыт ли контейнер
   даже на десктопе (нет доступа = не PRO/PREMIUM). */
#globalTableWrap { display: none; }

@media (min-width: 1024px) {
    html.is-browser #globalGrid { display: none !important; }

    /* ИСПРАВЛЕНО (обратная связь 02.09.2026, "сетка концентрируется по
       середине... тоже самое в виде таблицы"): #globalContentCol/#globalGrid/
       #globalTableWrap несли тот же max-w-7xl/mx-auto, что и на Главной —
       тот же приём full-width, auto-fill для сетки (на случай узкого
       десктопа, где #globalGrid ещё не скрыт правилом выше). */
    html.is-browser #globalContentCol,
    html.is-browser #globalGrid,
    html.is-browser #globalTableWrap {
        max-width: none !important;
        margin-left: 0 !important;
        margin-right: 0 !important;
    }
    html.is-browser #globalGrid {
        /* НАЙДЕНО (аудит "на 1440px в сетке только 2 колонки, хотя места
           хватает на 3"): при реальной доступной ширине контента (~869px на
           1440px — сайдбар 256px + рейл фильтров 300px) 340px давал ровно
           2 колонки, оставляя карточки крупнее и площе, чем нужно. 264px —
           ближе к уже используемому в .report-card-grid минимуму (280px),
           но с запасом, чтобы 3 колонки гарантированно помещались именно на
           1440px, а не балансировали на грани. */
        grid-template-columns: repeat(auto-fill, minmax(264px, 1fr)) !important;
    }

    html.is-browser #globalTableWrap:not(.hidden) {
        display: block;
    }
    html.is-browser #globalTable {
        width: 100%;
        table-layout: fixed;
        border-collapse: separate;
        border-spacing: 0;
        background: #0a0e1a;
        border: 1px solid rgba(255,255,255,0.08);
        border-radius: 14px;
        overflow: hidden;
    }
    html.is-browser #globalTable thead th {
        text-align: left;
        font-size: 11px;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--text-secondary);
        padding: 12px 14px;
        border-bottom: 1px solid rgba(255,255,255,0.08);
        background: rgba(255,255,255,0.02);
    }
    html.is-browser #globalTable thead th.sortable { cursor: pointer; user-select: none; }
    html.is-browser #globalTable thead th.sortable:hover { color: #E8B84B; }
    /* §5.1: миниатюра строки — 48px (было 88px/108px-колонка, см. общий
       .lot-row-thumb в блоке "ЕДИНАЯ СТРОКА ЛОТА" выше в файле) — колонку
       под <th> сужаем следом. */
    html.is-browser #globalTable .global-th-photo { width: 76px; }
}

/* --- Главная (платформенный план, фаза 4): переключатель "Сетка / Таблица"
   для сравнения 20+ лотов разом. На мобильном/в Telegram кнопки скрыты и
   #homeTable вообще не показывается — homeViewMode всегда 'grid' (см.
   script.js), .hidden-by-view ниже намеренно живёт в той же ≥1024px+
   is-browser области, что и всё остальное здесь, так что гипотетический
   вызов setHomeViewMode() на мобильном (кнопки для этого физически скрыты)
   не смог бы спрятать сетку. */
#homeViewToggle { display: none; }
#homeTableWrap { display: none; }

@media (min-width: 1024px) {
    html.is-browser #homeViewToggle {
        display: flex;
        gap: 6px;
        /* ИСПРАВЛЕНО (обратная связь 03.09.2026, "переключатель сетка/таблица
           остался в том же месте, где уже выглядит не гармонично"): margin
           0 auto центрировал переключатель, пока метрик-стрип и карусель
           рекомендаций (см. правку выше) стали прижаты к левому краю —
           получалось три соседних блока с разным выравниванием. */
        margin: 0 0 12px;
    }
    html.is-browser .home-view-btn {
        display: flex; align-items: center; gap: 6px;
        padding: 8px 14px; border-radius: 10px;
        font-size: 12px; font-weight: 700;
        background: rgba(255,255,255,0.04);
        border: 1px solid rgba(255,255,255,0.08);
        color: #94a3b8;
        transition: background .15s ease, color .15s ease;
    }
    html.is-browser .home-view-btn:hover { color: #fff; }
    html.is-browser .home-view-btn.active { background: rgba(232,184,75,0.14); color: #E8B84B; border-color: rgba(232,184,75,0.3); }

    html.is-browser #homeGrid.hidden-by-view { display: none !important; }
    html.is-browser #homeTableWrap:not(.hidden-by-view) { display: block; }

    html.is-browser #homeTable {
        width: 100%;
        table-layout: fixed;
        border-collapse: separate;
        border-spacing: 0;
        background: #0a0e1a;
        border: 1px solid rgba(255,255,255,0.08);
        border-radius: 14px;
        overflow: hidden;
    }
    html.is-browser #homeTable thead th {
        text-align: left;
        font-size: 11px;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--text-secondary);
        padding: 12px 14px;
        border-bottom: 1px solid rgba(255,255,255,0.08);
        background: rgba(255,255,255,0.02);
    }
    /* ИСПРАВЛЕНО (обратная связь 05.09.2026, "лоты в таблице побольше,
       картинки слишком маленькие"): было 108px/88px (уже увеличено один раз
       02.09.2026 с исходных 64px) — увеличиваем ещё раз, до 140px/120px. */
    html.is-browser #homeTable .home-th-photo { width: 140px; }
    html.is-browser #homeTable tbody tr {
        cursor: pointer;
        transition: background .15s ease;
        border-bottom: 1px solid rgba(255,255,255,0.05);
    }
    html.is-browser #homeTable tbody tr:last-child { border-bottom: none; }
    html.is-browser #homeTable tbody tr:hover { background: rgba(255,255,255,0.03); }
    html.is-browser #homeTable tbody td { padding: 14px; font-size: 13px; color: #e8eaf0; vertical-align: middle; }
    html.is-browser #homeTable .home-row-thumb {
        width: 120px; height: 120px; border-radius: 12px; object-fit: cover;
        max-width: none;
        border: 1px solid rgba(255,255,255,0.08);
    }
    /* ИСПРАВЛЕНО (обратная связь 02.09.2026): обрезка длинного заголовка —
       см. .row-title-ellipsis ниже, span уже обёрнут в renderHomeTableRows()
       (script.js) с полным текстом в title="". */
    html.is-browser #homeTable .home-row-title { font-weight: 600; width: 26%; }
    /* ИСПРАВЛЕНО (обратная связь 05.09.2026, "цену сделай больше и выдели
       цветом"): была тем же серым (#94a3b8), что и весь остальной текст
       строки, — цена (главное число, по которому инвестор сканирует список)
       ничем не отличалась от второстепенных колонок. Золотой акцент — тот
       же, что у активных категорий/кнопок, крупнее и жирнее шрифта ячейки. */
    html.is-browser #homeTable .home-row-price {
        font-family: var(--font-mono, 'Manrope', sans-serif);
        font-variant-numeric: tabular-nums;
        color: var(--accent); white-space: nowrap;
        font-size: 16px; font-weight: 700;
    }
    html.is-browser #homeTable .home-row-region { color: var(--text-secondary); font-size: 12px; white-space: nowrap; }
    html.is-browser #homeTable .home-row-site { font-size: 9px; padding: 3px 8px; }
    html.is-browser #homeTable .home-table-empty {
        text-align: center; padding: 32px 14px; color: var(--text-secondary); font-size: 13px;
    }
}

/* --- Главная → постоянная левая панель фильтров. ИЗМЕНЕНО (P3.2 аудита,
   12.09.2026): раньше здесь был JS-перенос узла (layoutDesktopFilterRail()
   двигал #filterPanel/#homeSearchWrap/#homeCategoryRow/#savedFiltersBtn из
   #mainHeader сюда) — теперь это статическая колонка
   (partials/screens/home_desktop.html), мобильные узлы остаются на месте в
   #mainHeader и просто скрыты ниже по файлу на этой же ширине. #mainHeader
   остаётся полноширинной (относительно сайдбара) шапкой сверху — рейл
   начинается ПОД ней (top выставляется в JS через header.offsetHeight, здесь
   только запасное значение на случай, если JS ещё не отработал). */
#homeFilterRail { display: none; }

@media (min-width: 1280px) {
    /* ИСПРАВЛЕНО (аудит "фильтры недоступны на ноутбуке", 05.09.2026 — см.
       развёрнутый комментарий у #homeFilterRail в app_shell.html). Было:
       весь рейл — один `overflow-y: auto` блок, кнопки "Применить"/"Сохра-
       нить" — последние дети прокручиваемой формы. При высоте окна ~768px
       форма (регион/тип/сортировка/цена/динамические фильтры категории) уже
       не помещалась целиком, а обычный оверлейный скроллбар (1-2px) не давал
       заметить это на глаз — кнопки просто пропадали из виду.
       ПЕРВАЯ ПОПЫТКА ЧИНИТЬ (найдена и отброшена тем же прогоном, до публи-
       кации): sticky-подвал ВНУТРИ той же прокручиваемой формы. Не сработало
       по другой причине — при небольшом остатке прокрутки (форма лишь
       немного длиннее рейла) прилипший футер вставал поверх ЕЩЁ НЕ прокру-
       ченного поля "Цена"/кнопок сортировки: на замере оба рендерились в
       одном диапазоне 581-728px по Y (getBoundingClientRect()), кнопки
       сортировки просто исчезали под непрозрачным фоном подвала — уже на
       старте, без единой прокрутки.
       РЕШЕНИЕ: рейл — flex-колонка из двух РАЗНЫХ по природе частей:
       #homeFilterRailScroll (flex:1, сама форма, прокручивается) и
       #filterPanelActions (напрямую в рейле, минуя прокрутку — см. её же
       вынос из #filterPanel в app_shell.html и layoutDesktopFilterRail() в
       script.js). Кнопки физически не участвуют в скролле формы — им
       структурно не над чем "прилипать" и нечего "закрывать" собой. */
    html.is-browser #homeFilterRail {
        display: flex;
        flex-direction: column;
        position: fixed;
        left: var(--sidebar-w);
        top: 260px; /* запасное значение — JS выставляет точную высоту #mainHeader */
        bottom: 0;
        /* TASK4 4.1 (DESIGN_MASTER_PROMPT.md §6.4): ширина рейла 264px
           (было 280px — вне шкалы; контентный отступ ниже заменён на
           264+24 = 288px, §6.3 «край страницы — 24»). */
        width: 264px;
        background: #0a0e1a;
        border-right: 1px solid rgba(255,255,255,0.08);
        z-index: 90; /* ниже #mainHeader/#sidebarNav (100) и модалок, выше обычного контента */
    }
    html.is-browser #homeFilterRailScroll {
        flex: 1 1 auto;
        min-height: 0; /* без этого flex-ребёнок не сжимается меньше своего контента и не скроллится вовсе */
        overflow-y: auto;
        padding: 20px 16px 16px;
    }
    /* ИЗМЕНЕНО (P3.2 аудита, 12.09.2026): #filterPanelActionsDesktop — своя
       статическая кнопка (см. home_desktop.html::render_actions()), не
       #filterPanelActions (тот несёт мобильную collapse-логику, см.
       комментарий в style.css — по умолчанию свёрнут). max-height/opacity/
       overflow-переопределения из старой версии здесь не нужны: кнопки
       никогда не стартуют свёрнутыми. */
    html.is-browser #homeFilterRail > #filterPanelActionsDesktop {
        flex: 0 0 auto; /* никогда не сжимается и не участвует в overflow-y:auto соседа — обычный, не sticky, элемент */
        padding: 12px 16px 20px;
        border-top: 1px solid rgba(255,255,255,0.08);
    }

    /* УБРАНО (P3.2 аудита): правила html.is-browser #homeFilterRail
       .filter-panel-inline.desktop-rail-open / #homeSearchWrap /
       #homeCategoryRow / #savedFiltersBtn были частью DOM-relocation —
       стилизовали УЖЕ ПЕРЕНЕСЁННЫЕ script.js мобильные узлы внутри рейла.
       Десктопная колонка теперь статическая, со своими id
       (homeSearchWrapDesktop/homeCategoryRowDesktop/...) и нужные отступы
       уже в самой разметке (см. home_desktop.html) — переопределять через
       дескендант-селекторы по старым id незачем, они больше никогда не
       окажутся внутри рейла. */

    /* Кнопка "открыть/закрыть фильтры" больше не нужна — панель всегда
       открыта в рейле слева. Сама функция toggleFilters() не трогается
       (мобильный сценарий использует её как раньше), кнопка просто скрыта. */
    html.is-browser #filterToggleBtn { display: none; }

    /* ДОБАВЛЕНО (P3.2 аудита, 12.09.2026): раньше эти узлы на широком экране
       физически ПЕРЕЕЗЖАЛИ (в рейл или в #homeViewToggle) — сам факт переезда
       и прятал их в #mainHeader. Теперь они остаются на месте (десктопная
       колонка — статическая копия, не перенос), поэтому без явного
       display:none они висели бы ВТОРЫМ, лишним набором поиска/кнопки
       уведомлений/категорий/переключателя площадок прямо в шапке одновременно
       с рейлом слева. #filterPanel отдельно прятать не нужно — он и так
       остаётся свёрнутым по умолчанию (.filter-panel-inline без .open, см.
       style.css), никто больше не добавляет ему класс .open на широком
       экране. */
    html.is-browser #mainHeader #homeSearchWrap,
    html.is-browser #mainHeader #savedFiltersBtn,
    html.is-browser #mainHeader #homeCategoryRow,
    html.is-browser #mainHeader #homeSiteSwitch {
        display: none;
    }

    /* Контент сдвигается вправо на ширину рейла + отступ — сам #mainHeader
       (шапка сверху) в этот сдвиг не входит, он остаётся во всю ширину
       рядом с сайдбаром. #scenarioChipsRow — ДОБАВЛЕНО (D5, DESIGN_UPGRADE_
       PROMPT.md §6): без этого правила чипы "Мои сценарии" рендерились под
       фиксированным рейлом (тот же z-index:90 перекрывает контент без
       собственного сдвига) — виден был только хвост текста, торчащий из-под
       правого края рейла (280px+var(--sidebar-w)). */
    html.is-browser #homeViewToggle,
    html.is-browser #homeGrid,
    html.is-browser #homeTableWrap,
    html.is-browser #homePageBanner,
    html.is-browser #recommendationsWrapper,
    html.is-browser #scenarioChipsRow,
    html.is-browser #onboardingChecklist {
        /* TASK4 4.1: 288px = рейл 264px + зазор 24px (§6.3). Отсчитывается
           от .screen (тот уже начинается после сайдбара), как и рейл —
           поэтому одно значение верно на любой ширине сайдбара. */
        padding-left: 288px !important;
    }

    /* НАЙДЕНО при живой проверке сайта в Chrome (03.09.2026): у
       #recommendationsWrapper (Tailwind max-w-7xl mx-auto в разметке) своё
       собственное центрирование внутри родителя НЕ снималось — вместе с
       padding-left:300px это давало ровно тот же баг, на который жаловался
       пользователь для сетки/таблицы: блок "плавает" по центру оставшегося
       пространства, а не начинается вплотную к сетке лотов под ним. margin:0
       выравнивает блок по левому краю (в один визуальный столбец с
       #homeGrid/#homeTableWrap), сама ширина (max-w-7xl) не менялась — это
       не список лотов, тянуть карусель на всю ширину экрана не нужно.
       #desktopMetricStrip раньше был в этом же списке (собственная секция
       со своим центрированием) — с D2 он переехал ВНУТРЬ #homeViewToggle
       (см. home.html), поэтому больше не нуждается в отдельном сбросе
       margin: позиционирование теперь только от родителя. */
    html.is-browser #homePageBanner,
    html.is-browser #recommendationsWrapper,
    html.is-browser #scenarioChipsRow,
    html.is-browser #onboardingChecklist {
        margin-left: 0 !important;
        margin-right: 0 !important;
    }

    /* ИСПРАВЛЕНО (обратная связь 05.09.2026, "рекомендации расширь до конца
       края, справа много места"): #recommendationsWrapper держал Tailwind
       max-w-7xl (1280px) из решения выше (03.09.2026) — на широком мониторе
       карусель и стрелка прокрутки упирались в невидимую границу задолго до
       настоящего края экрана, хотя сетка лотов под ней уже тянется во всю
       ширину (см. #homeGrid, max-width:none чуть выше по файлу). В отличие
       от #desktopMetricStrip (3 плитки баланса — растягивать их на весь
       экран незачем и не просили), карусель рекомендаций — это список,
       который логично тянуть на ту же ширину, что и сетку/таблицу под ним. */
    html.is-browser #recommendationsWrapper {
        max-width: none !important;
    }

    /* ИЗМЕНЕНО (P3.2 аудита, 12.09.2026): #homeViewToggle раньше был
       justify-between ровно на 2 детей (кнопки | счётчик) — с десктопной
       копией переключателя площадок (#homeSiteSwitchDesktop, статическая, не
       перенесённая — см. home_desktop.html) между ними middle-элемент лёг
       бы посередине с равными отступами от соседей, визуально "оторванным"
       от кнопок вида, к которым он ближе по смыслу. flex-start возвращает
       обычную слева-направо раскладку, margin-left:auto на счётчике
       сохраняет прежнее прижатие вправо. */
    html.is-browser #homeViewToggle {
        justify-content: flex-start;
    }
    html.is-browser #homeViewToggle #homeLotsCounter {
        margin-left: auto;
    }
    /* ИЗМЕНЕНО (P3.2 аудита): было #homeSiteSwitch (переехавший узел, нёс
       мобильный mb-3 — отступ до строки категорий под ним в #mainHeader,
       здесь лишний) — теперь #homeSiteSwitchDesktop, своя статическая копия
       без mb-3 вообще (см. её разметку), gap оставлен тем же переопределением. */
    html.is-browser #homeViewToggle #homeSiteSwitchDesktop {
        gap: 10px;
    }
    /* ИСПРАВЛЕНО (обратная связь 05.09.2026, "свитч сжался, сделай красивым
       и понятным"): .site-switch-pill и её кнопки (.site-btn) несут flex-1
       (нужен в узком 280px рейле — заполнить всю ширину). Первая попытка
       (flex:0 0 auto только на .site-switch-pill) убрала растягивание
       пилюли, но flex-1 НА КНОПКАХ внутри теперь уже НЕ растянутого
       родителя дал обратный эффект — без внешнего давления flex-1
       схлопывает элементы к минимальной ширине контента, отсюда и жалоба
       "текст слип". Возвращаем кнопкам обычные горизонтальные паддинги
       вместо flex-grow — они и держат разборчивую ширину независимо от
       родителя. */
    html.is-browser #homeViewToggle #homeSiteSwitchDesktop .site-switch-pill {
        flex: 0 0 auto;
        width: auto;
        gap: 2px;
    }
    html.is-browser #homeViewToggle #homeSiteSwitchDesktop .site-switch-pill .site-btn {
        flex: 0 0 auto;
        padding-left: 14px;
        padding-right: 14px;
        white-space: nowrap;
    }

    /* УБРАНО (P3.2 аудита): html.is-browser #homeViewToggle #mapToggleBtn /
       .map-toggle-label — переопределяли ширину и показывали подпись у УЖЕ
       ПЕРЕНЕСЁННОЙ script.js мобильной кнопки карты (компактный круг →
       пилюля с подписью). Десктопная копия
       (home_desktop.html::render_site_switch()) без id, со своей шириной
       "по содержимому" и видимой подписью сразу в разметке (pl-3 pr-3.5, см.
       её же комментарий там) — оригинальный #mapToggleBtn в #mainHeader
       никогда не покидает мобильную вёрстку, переопределять там нечего. */
}

/* ДОБАВЛЕНО (обратная связь 05.09.2026, "от Главной до Сетка/Таблица не
   должно скроллиться, скролл только у самого списка"; перенесено сюда из
   @media(min-width:1280px) коммитом TASK4 4.1b): #screen-home — flex-колонка
   на всю высоту окна: #mainHeader и #homeStickyHeader — несжимаемые "шапки"
   (flex:0 0 auto), #homeScrollArea — единственный растягивающийся ребёнок со
   своим overflow-y:auto. Тот же приём, что у #homeFilterRail/
   #homeFilterRailScroll (flex:1 + min-height:0). ИЗМЕНЕНО (TASK4 4.1b,
   ревью 4.1 п.2): порог снижен с 1280px до 1024px — иначе на 1024–1279
   (диапазон drawer-а, TASK4 §1) страница скроллилась целиком и
   scrollHeight ≠ innerHeight; брейкпоинт в checkInfiniteScroll()
   (script.js) синхронизирован тем же коммитом. */
@media (min-width: 1024px) {
    html.is-browser body {
        /* TASK4 4.1b, ревью 4.1 п.2: style.css:899 держит
           body { padding-bottom: 96px } — наследие "старой" полноширинной
           нижней панели (см. комментарий там же). На ≥1024 сайта нижней
           навигации нет (#bottomNav display:none выше), документ и так
           заперт в 100vh-рамке #screen-home — эти 96px торчали мёртвой
           полосой ПОД приложением (scrollHeight 996 при innerHeight 900).
           Здесь, а не в style.css: правило осознанно только для сайта
           ≥1024 — Mini App и мобильный браузер <1024 продолжают
           резервировать место под #bottomNav. */
        padding-bottom: 0 !important;
    }
    html.is-browser #screen-home.active {
        /* !important обязателен: index.html/workspace.html рендерят
           style="display: block" ИНЛАЙНОМ на этом узле (см. active_screen
           в app_shell.html) — инлайн-стиль побеждает любое внешнее правило
           без !important независимо от специфичности селектора. */
        display: flex !important;
        flex-direction: column;
        height: 100vh;
        overflow: hidden;
    }
    html.is-browser #screen-home.active > #mainHeader { flex: 0 0 auto; }
    html.is-browser #homeStickyHeader { flex: 0 0 auto; }
    html.is-browser #homeScrollArea {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
    }
}

/* TASK4 4.1 (DESIGN_MASTER_PROMPT.md §6.4/§7.11, TASK4 §1): 1024–1279px —
   постоянного рейла нет; фильтры открываются как ЛЕВАЯ ВЫДВИЖНАЯ ПАНЕЛЬ
   (drawer) кнопкой «Фильтры (N)» в тулбаре — сама кнопка и её JS приходят
   коммитом 4.2 (тулбар), здесь только механика показа по классу.
   top:0 !important — inline top от layoutDesktopFilterRail() рассчитан на
   постоянный рейл под шапкой; выдвижная панель занимает всю высоту окна.
   Тень разрешена: §6.3 — тени только у плавающих слоёв (dropdown, toast,
   drawer). */
@media (min-width: 1024px) and (max-width: 1279.98px) {
    html.is-browser #homeFilterRail.drawer-open {
        display: flex;
        flex-direction: column;
        position: fixed;
        left: var(--sidebar-w);
        top: 0 !important;
        bottom: 0;
        width: 264px;
        background: var(--bg-surface);
        border-right: 1px solid var(--border-subtle);
        box-shadow: var(--shadow-md);
        z-index: 95; /* выше контента, ниже модалок */
        padding-top: 16px;
    }
    html.is-browser #homeFilterRail.drawer-open #homeFilterRailScroll {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        padding: 4px 16px 16px;
    }
}

/* ДОБАВЛЕНО (обратная связь 03.09.2026, "не знаю как мне скроллить
   рекомендации"): карусель #recommendationsGrid прокручивается свайпом на
   мобильном/Telegram (overflow-x-auto), но на десктопе без тачпада это не
   очевидно — не было визуальной подсказки. Стрелки уже есть в разметке
   (index.html, #recsArrows) со скрытым по умолчанию "hidden flex" — здесь
   они показываются только в браузерной версии, начиная с того же порога
   (≥1024px), с которого вообще появляется десктопный layout. */
@media (min-width: 1024px) {
    html.is-browser #recsArrows.hidden {
        display: flex !important;
    }
}

/* --- Общее: обрезка длинного заголовка лота в табличных представлениях всех
   трёх вкладок (по обратной связи 02.09.2026, "текст лота с длинным
   названием должно проходить по допустимому стандарту, а не выводить
   абсолютно весь заголовок") — одно правило на все три таблицы (Главная/
   Избранное/База AI), полный текст остаётся доступен через нативный
   title="..." (см. renderHomeTableRows/renderFavTable/renderGlobalTableRows
   в script.js — <span class="row-title-ellipsis"> уже там). Ячейки-родители
   у всех трёх таблиц теперь процентной ширины (.home-row-title/.fav-row-title/
   .lot-row-cell--title, см. выше) + table-layout:fixed на самих таблицах — без
   этого overflow:hidden/text-overflow:ellipsis ничего не обрезали бы, т.к.
   ячейка тянулась бы под контент. */
html.is-browser .row-title-ellipsis {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    /* min-width:0 — обязателен теперь, когда родитель (.lot-row-cell--title,
       см. блок "ЕДИНАЯ СТРОКА ЛОТА" ниже) стал flex-контейнером: у flex-
       элементов min-width по умолчанию auto (= ширина контента), а не 0,
       поэтому overflow:hidden/ellipsis выше молча не работал — заголовок
       рендерился на полную длину и наезжал на соседние колонки. min-width:0
       на самом <td>/.lot-row-cell--title этого не чинит — ограничение нужно
       именно на flex-элементе, который переполняет. */
    min-width: 0;
    width: 100%;
}

/* =====================================================================
   §5.1 DESIGN_MASTER_PROMPT.md — ЕДИНАЯ СТРОКА ЛОТА (Избранное/База AI/Мои
   анализы). Раньше это были три разные разметки: два разных <table>
   (высота строки ~108px, миниатюра 88×88, радиус 10px — ни то, ни другое
   не входит в шкалу токенов §3) и flex-строка Моих анализов с точкой-
   индикатором вместо бейджа вердикта. renderLotRow() в script.js теперь
   строит все три из одних и тех же .lot-row-cell — здесь единственное
   место, где описан их внешний вид. Работает и для <tr> (Избранное/
   База AI, .lot-row-cell лежит внутри <td> — <table>/<thead> в партиалах
   не менялись, ширину колонок по-прежнему держат .fav-th-photo/
   .global-th-photo и т.п. на <th>) и для <div> (Мои анализы).

   Высота строки — ровно §5.1 ("~64px"): 8px вертикальный паддинг + 48px
   миниатюра. Радиус миниатюры/бейджей — var(--radius-ctl) (8px, §3), не
   14px/10px, как было раньше. Разделители — только hairline (border-bottom
   1px var(--border-subtle)), без зебры; hover — var(--bg-raised), тоже
   без пятой раскраски. */
html.is-browser .lot-row {
    cursor: default;
    border-bottom: 1px solid var(--border-subtle, rgba(255,255,255,0.08));
}
html.is-browser tr.lot-row { transition: background .15s var(--ease, ease); }
html.is-browser tr.lot-row:last-child,
html.is-browser div.lot-row:last-child { border-bottom: none; }
html.is-browser .lot-row--clickable { cursor: pointer; }
html.is-browser tr.lot-row.lot-row--clickable:hover,
html.is-browser div.lot-row.lot-row--clickable:hover {
    background: var(--bg-raised, rgba(255,255,255,0.03));
}
/* Мои анализы (div-строка) — та же геометрия, что и <tr>/<td> у остальных
   двух вкладок, просто через flex вместо табличной раскладки. */
html.is-browser div.lot-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 14px;
}
html.is-browser .lot-row-cell { display: flex; align-items: center; min-width: 0; }
html.is-browser tr.lot-row > td { padding: 0; vertical-align: middle; }
html.is-browser tr.lot-row > td .lot-row-cell { padding: 10px 14px; height: 64px; box-sizing: border-box; }
html.is-browser .lot-row-cell--checkbox { flex: 0 0 auto; justify-content: center; }
html.is-browser .lot-row-cell--thumb { flex: 0 0 auto; }
html.is-browser .lot-row-thumb {
    width: 48px; height: 48px; border-radius: var(--radius-ctl, 8px);
    object-fit: cover; border: 1px solid var(--border-subtle, rgba(255,255,255,0.08));
}
html.is-browser .lot-row-cell--title { flex: 1 1 auto; min-width: 0; flex-direction: column; align-items: flex-start; gap: 2px; }
html.is-browser div.lot-row .lot-row-cell--title { font-weight: 600; }
html.is-browser .lot-row-meta { font-size: 10px; color: var(--text-tertiary, #5F6B7C); }
html.is-browser .lot-row-cell--region { flex: 0 0 100px; color: var(--text-secondary); font-size: 12px; }
html.is-browser .lot-row-cell--price {
    flex: 0 0 110px; font-family: var(--font-mono, 'JetBrains Mono', monospace);
    font-variant-numeric: tabular-nums; color: var(--accent); font-size: 14px; font-weight: 700; white-space: nowrap;
}
html.is-browser .lot-row-cell--score { flex: 0 0 96px; gap: 8px; }
html.is-browser .lot-row-score-num {
    font-family: var(--font-mono, 'JetBrains Mono', monospace);
    font-variant-numeric: tabular-nums; font-weight: 700; font-size: 13px; width: 24px; flex-shrink: 0;
}
html.is-browser .lot-row-score-bar {
    display: block; width: 48px; height: 5px; border-radius: 3px;
    background: rgba(255,255,255,0.08); overflow: hidden; flex-shrink: 0;
}
html.is-browser .lot-row-score-bar-fill { display: block; height: 100%; border-radius: 3px; }
html.is-browser .lot-row-score-num.score-good { color: var(--status-pos, #34C77B); }
html.is-browser .lot-row-score-bar-fill.score-good { background: var(--status-pos, #34C77B); }
html.is-browser .lot-row-score-num.score-mid { color: var(--status-warn, #E5A50A); }
html.is-browser .lot-row-score-bar-fill.score-mid { background: var(--status-warn, #E5A50A); }
html.is-browser .lot-row-score-num.score-bad { color: var(--status-neg, #E5484D); }
html.is-browser .lot-row-score-bar-fill.score-bad { background: var(--status-neg, #E5484D); }
html.is-browser .lot-row-score-num.score-none { color: var(--text-tertiary, #5F6B7C); }
html.is-browser .lot-row-cell--verdict { flex: 0 0 auto; white-space: nowrap; }
html.is-browser .lot-row-cell--date { flex: 0 0 90px; color: var(--text-secondary); font-size: 12px; white-space: nowrap; }
html.is-browser .lot-row-cell--actions { flex: 0 0 auto; gap: 6px; }
html.is-browser .lot-row-empty {
    text-align: center; padding: 32px 14px; color: var(--text-secondary); font-size: 13px;
}
/* table-layout:fixed (Избранное/База AI) берёт ширину колонки из самого
   <td>, а не из вложенного flex-элемента .lot-row-cell (тот в <td> не
   flex-контейнер) — те же значения, что и flex-basis выше, просто
   применённые к <td>. .lot-row-td--title сознательно без width: она одна
   растягивается на весь остаток (table-layout:fixed отдаёт ей то, что не
   разобрали остальные колонки), как раньше .fav-row-title/.global-row-title. */
html.is-browser tr.lot-row .lot-row-td--region { width: 100px; }
html.is-browser tr.lot-row .lot-row-td--price { width: 110px; }
html.is-browser tr.lot-row .lot-row-td--score { width: 96px; }
html.is-browser tr.lot-row .lot-row-td--verdict { width: 215px; }
html.is-browser tr.lot-row .lot-row-td--date { width: 90px; }
html.is-browser tr.lot-row .lot-row-td--actions { width: 76px; }
/* table-layout:fixed берёт ширину колонки из ПЕРВОЙ строки таблицы (это
   <thead>, не <tbody> — <tbody> у обеих таблиц пуст на момент первого
   layout'а, наполняется JS'ом уже после) — без width на самих <th> все
   правила выше на <td> молча игнорируются браузером, и колонки делятся
   поровну. <thead>/<th> в партиалах не менялись (вне списка файлов этой
   задачи) — ширина навешена отсюда, по позиции колонки (nth-child), а не
   по классу. Порядок — см. её же комментарий у responsive-блока ниже:
   global.html: photo/Лот/Цена/Инвестскор/Вердикт/Дата анализа/Регион;
   favorites.html: checkbox/photo/Лот/Цена/Статус анализа/Добавлено. */
html.is-browser #globalTable thead th:nth-child(3) { width: 110px; }
html.is-browser #globalTable thead th:nth-child(4) { width: 96px; }
html.is-browser #globalTable thead th:nth-child(5) { width: 215px; }
html.is-browser #globalTable thead th:nth-child(6) { width: 90px; }
html.is-browser #globalTable thead th:nth-child(7) { width: 100px; }
html.is-browser #favTable thead th:nth-child(4) { width: 110px; }
html.is-browser #favTable thead th:nth-child(5) { width: 215px; }
html.is-browser #favTable thead th:nth-child(6) { width: 90px; }
/* Фаза 4 (сравнение, Мои анализы): подсветка выбранной строки и приглушение
   недоступных для выбора — то же поведение, что было раньше, просто на
   новой общей .lot-row вместо .analysis-row. */
html.is-browser div.lot-row.lot-row--selected {
    background: rgba(168,85,247,0.10); border-bottom-color: rgba(168,85,247,0.3);
}
html.is-browser div.lot-row.lot-row--unselectable { opacity: 0.4; cursor: default; }

/* §5.1 п.5: <1280px — второстепенные колонки (регион у Базы AI, дата у всех
   трёх) уходят, чтобы заголовок/цена/вердикт не теснились на среднем окне
   браузера; ниже 1024px Избранное/База AI и так переключаются на карточки
   (см. #favTableWrap/#globalTableWrap выше), а Мои анализы отдельного
   карточного вида не имеют — их строка остаётся, просто без пары колонок. */
@media (max-width: 1280px) {
    html.is-browser .lot-row-cell--region,
    html.is-browser .lot-row-cell--date,
    html.is-browser tr.lot-row .lot-row-td--region,
    html.is-browser tr.lot-row .lot-row-td--date { display: none; }
    /* <thead> — не JS-разметка (не в списке файлов этой задачи), поэтому
       прячем сами <th> позиционно (nth-child), а не по классу: global.html —
       photo/Лот/Цена/Инвестскор/Вердикт/Дата анализа(6)/Регион(7);
       favorites.html — checkbox/photo/Лот/Цена/Статус анализа/Добавлено(6). */
    html.is-browser #globalTable thead th:nth-child(6),
    html.is-browser #globalTable thead th:nth-child(7),
    html.is-browser #favTable thead th:nth-child(6) { display: none; }
}

/* Мои анализы (div-строка) — в отличие от Избранного/Базы AI, у неё нет
   отдельного карточного вида на узком экране (см. её же комментарий выше —
   их <table> ниже 1024px просто скрывается CSS'ом, а #screen-analyses
   остаётся единственным видом всегда, в т.ч. на мобильном браузере сайта,
   где !IS_TELEGRAM тоже true). Фиксированные flex-basis у цены/скора/
   вердикта (см. .lot-row-cell--price и т.д. выше), рассчитанные под
   табличные колонки ≥1024px, на телефоне попросту не помещаются в одну
   строку. flex-wrap переносит то, что не влезло, на вторую строку —
   без наложения элементов друг на друга, просто увеличивается высота
   строки (для узкого экрана это нормально, §5.1 "~64px" — требование
   для табличного вида, не для этого запасного мобильного потока). */
@media (max-width: 767px) {
    html.is-browser div.lot-row {
        flex-wrap: wrap;
        row-gap: 6px;
    }
    html.is-browser div.lot-row .lot-row-cell--title { flex-basis: 140px; }
}

/* --- Общее: карточки лотов (список — Избранное/архив используют этот
   вариант, где фото стоит СЛЕВА от текста в ряд) — увеличение фото лота в
   2 раза (по обратной связи 02.09.2026, "изображение лотов слишком
   маленькое... в целом нужно немного увеличить лоты в 2 раза"). Было
   w-20 h-20 (80px) — теперь 160px. Класс уже висит на существующем узле
   (createCard() в script.js), разметка карточек не менялась. Порог ≥1024px —
   на узком окне браузера (не Telegram) те же 160px ломали карточку, фото
   занимало половину экрана — оставлены прежние 80px.
   ИСПРАВЛЕНО (обратная связь 03.09.2026, "изображение не соответствует
   размеру карточки, выглядит не гармонично"): это правило конфликтовало с
   более старым и более специфичным style.css-правилом
   "#homeGrid.grid > .glass-card > div:first-child" (≥640px, действует и в
   Telegram Desktop) — на широкой сетке (Главная/Избранное-карточки/База AI)
   карточка лота переключается в ВЕРТИКАЛЬНЫЙ вид (фото на всю ширину сверху,
   текст под ним), а не в ряд. !important здесь перебивал ту вёрстку, сажая
   квадрат 160×160 в угол широкой карточки с пустым местом справа — это и
   выглядело "не гармонично". Ниже отдельным, более специфичным правилом
   (после этого) возвращена вёрстка "на всю ширину" для сеточного вида — оно
   и увеличивает фото (140px → 220px высотой), и не спорит с этим общим
   160×160, которое остаётся верным для рядных карточек вне сетки (архив
   Избранного и т.п., см. #favArchiveGrid). */
@media (min-width: 1024px) {
    html.is-browser .lot-card-thumb {
        width: 160px !important;
        height: 160px !important;
        min-width: 160px !important;
    }
    html.is-browser .lot-card-body {
        height: 160px !important;
    }

    /* Карточки лотов В СЕТОЧНОМ виде (Главная/Избранное/База AI, класс .grid
       уже стоит на контейнере — см. style.css "6. Карточки лота в сетке")
       — здесь карточка вертикальная, фото должно оставаться на всю ширину
       карточки, а не превращаться в квадрат слева. Тот же принцип
       увеличения (было 140px, показалось мелким — теперь 220px), но без
       фиксированной ширины/квадрата. Селектор точнее и стоит ниже по
       каскаду, поэтому выигрывает у общего правила выше без доп. !important
       на ширине (только переопределяем то, что реально нужно). */
    html.is-browser #homeGrid.grid > .glass-card.lot-card > .lot-card-thumb,
    html.is-browser #favGrid.grid > .glass-card.lot-card > .lot-card-thumb,
    html.is-browser #globalGrid.grid > .glass-card.lot-card > .lot-card-thumb {
        width: 100% !important;
        height: 220px !important;
        min-width: 0 !important;
    }
    html.is-browser #homeGrid.grid > .glass-card.lot-card > .lot-card-body,
    html.is-browser #favGrid.grid > .glass-card.lot-card > .lot-card-body,
    html.is-browser #globalGrid.grid > .glass-card.lot-card > .lot-card-body {
        height: auto !important;
    }
}

/* --- Избранное → постоянная левая панель фильтров (по обратной связи
   02.09.2026: "насчет фильтров, мне нравится как выглядит и как расположен
   бар [на Главной], тоже самое хочу видеть в избранных и базе ai"). У
   Избранного нет своей fixed-шапки (в отличие от #mainHeader/#gHeader), в
   которую нужно было бы лезть через JS-перенос узла, как на Главной/Базе
   AI — #favFilterPanel и так обычный блочный сосед #favContentCol внутри
   #screen-favorites, поэтому здесь чистый CSS: делаем #screen-favorites
   флекс-строкой из двух колонок. Ниже 1280px остаётся горизонтальная
   полоса (см. блок @media (min-width: 1024px) выше) — этот блок её
   переопределяет обратно в вертикальный вид, визуально повторяющий
   #homeFilterRail (тот же фон/бордер/паддинг/ширина 280px). */
@media (min-width: 1280px) {
    /* ВАЖНО: селектор с .active — иначе !important на display:flex бил бы
       инлайновый display:none, которым switchScreen() прячет НЕактивные
       экраны (баг найден на тестах 02.09.2026: уйдя с "Избранное" на любой
       другой экран, эта секция оставалась видна поверх него). .active
       вешается/снимается тем же switchScreen(), так что правило включается
       и выключается синхронно с реальной видимостью экрана. */
    html.is-browser #screen-favorites.active {
        display: flex !important;
        align-items: flex-start;
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
    html.is-browser #favFilterPanel {
        width: 280px;
        max-width: 280px !important;
        flex-shrink: 0;
        margin: 0 !important;
        align-self: stretch;
    }
    html.is-browser #favFilterPanel .glass-panel {
        display: block !important;
        height: 100%;
        background: #0a0e1a;
        border: none !important;
        border-right: 1px solid rgba(255,255,255,0.08) !important;
        border-radius: 0 !important;
        padding: 20px 16px 40px !important;
    }
    /* Возврат к вертикальному стеку — блок @media(1024px) выше превращал
       .space-y-4 в горизонтальный ряд для промежуточной ширины, здесь это
       больше не нужно, панель снова колонка, как в мобильной версии. */
    html.is-browser #favFilterPanel .space-y-4 {
        display: block !important;
    }
    html.is-browser #favFilterPanel .space-y-4 > * {
        margin: 0 !important;
    }
    html.is-browser #favFilterPanel .space-y-4 > * + * {
        margin-top: 16px !important;
    }
    html.is-browser #favCatTabs {
        flex-wrap: wrap;
        overflow-x: visible;
        min-width: 0 !important;
    }
    html.is-browser #favSiteToggle {
        min-width: 0 !important;
    }
    /* Строка сортировки (без своего id) — та же проблема, что и у категорий:
       overflow-x-auto без переноса обрезала кнопки "Дешевле"/"Дороже" в
       узкой колонке 280px. */
    html.is-browser #favFilterPanel .space-y-4 > .overflow-x-auto {
        flex-wrap: wrap;
        overflow-x: visible;
    }

    html.is-browser #favContentCol {
        flex: 1;
        min-width: 0;
        padding-left: 24px;
        padding-top: 16px;
    }
}

/* --- База AI → постоянная левая панель фильтров, тот же приём, что и на
   Главной (см. #homeFilterRail выше). ИЗМЕНЕНО (P3.1 аудита, 11.09.2026):
   раньше здесь был JS-перенос узла (layoutGlobalFilterRail() двигал
   #gFilterPanel/#gSearchWrap/#gSiteSwitch/#gCategoryRow из #gHeader сюда) —
   теперь это статическая колонка (partials/screens/global_desktop.html),
   мобильные узлы остаются на месте в #gHeader и просто скрыты ниже по
   файлу на этой же ширине. */
#globalFilterRail { display: none; }

@media (min-width: 1280px) {
    /* Та же flex-колонка из прокручиваемой зоны + обычного (не sticky)
       подвала, что и у #homeFilterRail — см. её развёрнутый комментарий там
       же (dashboard.css) про то, почему sticky-подвал внутри общей
       прокрутки не работает при малом остатке скролла. */
    html.is-browser #globalFilterRail {
        display: flex;
        flex-direction: column;
        position: fixed;
        left: var(--sidebar-w);
        top: 260px; /* запасное значение — JS выставляет точную высоту #gHeader */
        bottom: 0;
        width: 280px;
        background: #0a0e1a;
        border-right: 1px solid rgba(255,255,255,0.08);
        z-index: 90;
    }
    html.is-browser #globalFilterRailScroll {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        padding: 20px 16px 16px;
    }
    /* ИЗМЕНЕНО (P3.1 аудита, 11.09.2026): #gFilterPanelActionsDesktop — своя
       статическая кнопка (см. global_desktop.html::render_actions()), не
       #gFilterPanelActions (тот несёт мобильную collapse-логику, см.
       комментарий в style.css — по умолчанию свёрнут). max-height/opacity/
       overflow-переопределения из старой версии этого правила здесь не
       нужны: кнопка никогда не стартует свёрнутой. */
    html.is-browser #globalFilterRail > #gFilterPanelActionsDesktop {
        flex: 0 0 auto;
        padding: 12px 16px 20px;
        border-top: 1px solid rgba(255,255,255,0.08);
    }

    /* УБРАНО (P3.1 аудита): правила html.is-browser #globalFilterRail
       .filter-panel-inline.desktop-rail-open / #gSearchWrap / #gCategoryRow
       были частью DOM-relocation — стилизовали УЖЕ ПЕРЕНЕСЁННЫЕ script.js
       мобильные узлы внутри рейла. Десктопная колонка теперь статическая, со
       своими id (gSearchWrapDesktop/gCategoryRowDesktop) и нужные отступы/
       перенос строк уже в самой разметке (mb-4/flex-wrap как Tailwind-классы,
       см. global_desktop.html) — переопределять через дескендант-селекторы
       по старым id незачем, они больше никогда не окажутся внутри рейла. */

    /* Кнопка-тумблер фильтров в шапке больше не нужна — панель всегда
       открыта в рейле слева, сама toggleGFilters() не трогается (мобильный
       сценарий использует её как раньше). */
    html.is-browser #gFilterToggleBtn { display: none; }

    /* ДОБАВЛЕНО (P3.1 аудита, 11.09.2026): раньше эти три узла на широком
       экране физически ПЕРЕЕЗЖАЛИ в рейл (см. старый комментарий у
       #globalFilterRail выше) — сам факт переезда и прятал их в #gHeader.
       Теперь они остаются на месте (десктопная колонка — статическая
       копия, не перенос), поэтому без явного display:none они висели бы
       ВТОРЫМ, лишним рядом поиска/площадок/категорий прямо под заголовком
       "База готовых отчетов" одновременно с рейлом слева. #gFilterPanel
       (тип аукциона + сортировка) отдельно прятать не нужно — он и так
       остаётся свёрнутым по умолчанию (.filter-panel-inline без .open,
       см. style.css), никто больше не добавляет ему класс .open на
       широком экране. */
    html.is-browser #gHeader #gSearchWrap,
    html.is-browser #gHeader #gSiteSwitch,
    html.is-browser #gHeader #gCategoryRow {
        display: none;
    }

    /* Контент сдвигается вправо на ширину рейла + отступ, #gHeader (шапка
       сверху с поиском) в этот сдвиг не входит — остаётся во всю ширину. */
    html.is-browser #globalContentCol {
        padding-left: 300px !important;
    }
}
