
/* ============================================================
   СТРАНИЦА «УРОКИ ПО VFX ДЛЯ ПАТРОНОВ» timesavervfx.com/exclusive/
   Встраиваемый фрагмент. Токены наследуются из .tsv-root
   (design/tokens.css) — внутри ничего глобального не объявляем.
   Все селекторы заскоуплены под .tsv-excl, включая ресет и медиа.

   Семь секций: герой → три полки → галерея уроков в пяти
   группах → где открыть (CTA 1) → что открывается вместе
   с уроками → FAQ → спасибо (CTA 2).

   Главный приём страницы — галерея из 30 карточек с фильтром
   по темам. У каждой карточки своя обложка и свои три ссылки
   на площадки, которые раскрываются нативным <details> прямо
   в карточке: без JS галерея работает целиком, фильтр просто
   не показывается.

   Обложки СВОИ: скачаны с серверов YouTube один раз, приведены
   к 16:9, пережаты в WebP 480px и лежат в assets/img. Со страницы
   посетителя к i.ytimg.com не уходит ни одного запроса — его IP
   третьей стороне не передаётся, а превью он всё равно видит.
   Эмбедов ноль, iframe ноль.

   Заголовок первого уровня стилизован ПО КЛАССУ .tsv-excl-h1,
   а не по тегу: если тема хоста выводит свой заголовок, наш
   понижается до h2 правкой в один символ.

   Кнопок ровно две, тексты разные, обе ведут на Boosty. Сумм
   подписки нет нигде — они живут на площадках и меняются.
   Логотипов площадок нет, только названия словами.
   Прерываний фона ноль, full-bleed полосы нет.
   Микроразметка в фрагменте не живёт: визуальный редактор
   WordPress вырезает её из контента, она ставится SEO-плагином.
   ============================================================ */

.tsv-excl *, .tsv-excl *::before, .tsv-excl *::after { box-sizing: border-box; }

.tsv-excl {
    position: relative;
    /* обёртка несёт свой фон и цвет: страница-хост может быть светлой */
    background: var(--tsv-bg);
    color: var(--tsv-fg);
    font-family: var(--tsv-sans);
    font-size: 16px;
    line-height: 1.6;
}

.tsv-excl h1,
.tsv-excl h2,
.tsv-excl h3,
.tsv-excl p { margin: 0; }
.tsv-excl ul, .tsv-excl ol { margin: 0; padding: 0; list-style: none; }
.tsv-excl a { color: inherit; }

/* Фокус с клавиатуры — обязателен на всех ссылках, кнопках и summary */
.tsv-excl a:focus-visible,
.tsv-excl button:focus-visible,
.tsv-excl summary:focus-visible {
    outline: 2px solid var(--tsv-accent-bright);
    outline-offset: 2px;
}

/* ---------- Общая типографика ---------- */
.tsv-excl .tsv-excl-kicker {
    display: block;
    margin: 0 0 10px;
    font-family: var(--tsv-mono);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 2.5px;
    text-transform: uppercase;
    color: var(--tsv-accent-bright);
}
.tsv-excl h2 {
    font-size: var(--fs-2xl);
    font-weight: 800;
    letter-spacing: -0.015em;
    line-height: 1.2;
    color: var(--tsv-fg);   /* градиентной вставки в h2 нет ни в одной секции */
}
.tsv-excl .tsv-excl-lead-sec {
    max-width: 680px;
    margin: 12px 0 0;
    font-size: 17px;
    line-height: 1.6;
    color: var(--tsv-fg-dim);
}

/* Два регистра тихих строк: soft — 13px вторичная,
   mute — 13px совсем тихая приписка */
.tsv-excl .tsv-excl-soft {
    margin: 14px 0 0;
    font-size: 13.5px;
    line-height: 1.6;
    color: var(--tsv-fg-dim);
}
.tsv-excl .tsv-excl-mute {
    margin: 10px 0 0;
    font-size: 13px;
    line-height: 1.6;
    color: var(--tsv-fg-mute);
}

/* Текстовые ссылки внутри предложений — везде одинаковые */
.tsv-excl .tsv-excl-lead-sec a,
.tsv-excl .tsv-excl-shelf a,
.tsv-excl .tsv-excl-gain a,
.tsv-excl .tsv-excl-soft a,
.tsv-excl .tsv-excl-mute a,
.tsv-excl .tsv-excl-faq-body a,
.tsv-excl .tsv-excl-final-text a {
    color: var(--tsv-accent-bright);
    text-decoration: underline;
    text-decoration-color: var(--tsv-accent-soft);
    text-underline-offset: 3px;
    transition: text-decoration-color var(--dur-base) var(--ease-out);
}

/* Самостоятельная ссылка на площадку: тап-таргет не меньше 44px
   по высоте. Внутри предложений такие ссылки не используются —
   раздвигать строку текста ради тап-таргета нельзя. */
.tsv-excl .tsv-excl-plat {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 2px;
    vertical-align: middle;
    font-weight: var(--fw-semibold);
    color: var(--tsv-accent-bright);
    text-decoration: underline;
    text-decoration-color: var(--tsv-accent-soft);
    text-underline-offset: 3px;
    transition: text-decoration-color var(--dur-base) var(--ease-out);
}
.tsv-excl .tsv-excl-sep {
    display: inline-block;
    padding: 0 6px;
    color: var(--tsv-fg-mute);
}

/* ---------- Секции и колонка чтения ---------- */
.tsv-excl .tsv-excl-section { padding: 48px 24px; }
.tsv-excl .tsv-excl-inner {
    max-width: 1040px;
    margin-inline: auto;
}
.tsv-excl .tsv-excl-head { margin: 0 0 24px; }

/* Ленивый рендер: браузер не считает то, что ниже экрана.
   На герое content-visibility НЕ ставим — это первый экран. */
.tsv-excl .tsv-excl-section  { content-visibility: auto; }
/* Числа — замеренные высоты секций на 1280px, а не догадки:
   заниженный интринсик заставляет скроллбар прыгать при первом
   проходе по длинному списку. */
.tsv-excl .tsv-excl-s-shelf  { contain-intrinsic-size: auto 800px; }
/* Галерея выше прежней описи втрое: 30 карточек с обложками 16:9
   вместо 30 строк текста. Числа были замерены на живой странице
   при 39 карточках — 5508px на 1280 и 1440 (три колонки), 7494px
   на 768 (две), 13431px на 390 (одна). После удаления девяти
   устаревших уроков пересчитаны по высоте ряда, а не перезамерены:
   10 рядов вместо 13, 15 вместо 20, 30 вместо 39. Занижать нельзя:
   скроллбар прыгает при первом проходе, поэтому округлено вверх. */
.tsv-excl .tsv-excl-s-list   { contain-intrinsic-size: auto 4300px; }
.tsv-excl .tsv-excl-s-where  { contain-intrinsic-size: auto 720px; }
.tsv-excl .tsv-excl-s-more   { contain-intrinsic-size: auto 720px; }
.tsv-excl .tsv-excl-s-faq    { contain-intrinsic-size: auto 700px; }
.tsv-excl .tsv-excl-s-final  { contain-intrinsic-size: auto 620px; }

/* ---------- Кнопка: pill с градиентом, без иконок и стрелок ---------- */
.tsv-excl .tsv-excl-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 14px 28px;   /* 45px по высоте: тап-таргет не меньше 44px */
    border-radius: 999px;
    border: 1px solid transparent;
    background: linear-gradient(135deg, #a884ec 0%, #7a54cf 100%);
    color: #ffffff;
    font-family: inherit;
    font-size: 15px;
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
    box-shadow: 0 10px 26px -14px rgba(122, 84, 207, 0.85);
    transition: filter var(--dur-base) var(--ease-out),
                transform var(--dur-base) var(--ease-out);
}

/* ============================================================
   1. ГЕРОЙ — content-visibility НЕ ставим, это первый экран.
   Ни картинки, ни кнопки: кнопка ведёт на чужой сайт, и человек
   ушёл бы раньше, чем узнал, ради чего идёт.
   ============================================================ */
.tsv-excl .tsv-excl-hero { padding: 60px 24px 44px; }
.tsv-excl .tsv-excl-hero-inner {
    max-width: 1040px;
    margin-inline: auto;
}
.tsv-excl .tsv-excl-h1 {
    max-width: 760px;
    font-size: clamp(30px, 4.6vw, 46px);
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.14;
}
/* Градиентная вставка используется на всей странице ровно один раз — здесь */
.tsv-excl .tsv-excl-h1 em {
    font-style: normal;
    background: linear-gradient(135deg, var(--tsv-accent-bright), #e9d4ff);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
}
.tsv-excl .tsv-excl-lead {
    max-width: 680px;
    margin: 16px 0 0;
    font-size: 18px;
    line-height: 1.6;
    color: var(--tsv-fg-dim);
}
/* Про подписку сказано в первом экране, а не мелким шрифтом в FAQ:
   человек, который узнал про регулярный платёж на четвёртом экране,
   чувствует, что его вели. */
.tsv-excl .tsv-excl-facts {
    max-width: 680px;
    margin: 20px 0 0;
    font-family: var(--tsv-mono);
    font-size: 12.5px;
    line-height: 1.6;
    letter-spacing: 0.08em;
    color: var(--tsv-fg-mute);
    text-wrap: balance;
}

/* ============================================================
   2. ТРИ ПОЛКИ — где что лежит. Ни карточек, ни трёх колонок:
   это не сравнение тарифов, а объяснение устройства.
   ============================================================ */
.tsv-excl .tsv-excl-shelf {
    max-width: 720px;
    padding: 16px 0 16px 20px;
    border-left: 2px solid var(--tsv-border);
    font-size: 15.5px;
    line-height: 1.65;
    color: var(--tsv-fg-dim);
}
.tsv-excl .tsv-excl-shelf + .tsv-excl-shelf { margin-top: 8px; }
.tsv-excl .tsv-excl-shelf strong {
    font-size: 16px;
    font-weight: var(--fw-semibold);
    color: var(--tsv-fg);
}
/* Третья полка — та, ради которой страница */
.tsv-excl .tsv-excl-shelf--this { border-left-color: var(--tsv-accent); }

/* ============================================================
   3. ГАЛЕРЕЯ УРОКОВ — главная секция.

   Четыре группы, тридцать карточек. Карточка = своя обложка
   16:9 плюс название; ссылки на площадки раскрываются внутри
   карточки нативным <details>, поэтому работают и без скрипта.

   Фильтр по темам показывает одну группу. Группы разложены
   не марджинами, а flex-колонкой с gap: скрытый через [hidden]
   элемент не создаёт зазора, и после фильтра сверху не остаётся
   пустоты от невидимых соседей.
   ============================================================ */
.tsv-excl .tsv-excl-list {
    display: flex;
    flex-direction: column;
    gap: 44px;
}

/* ---------- Панель фильтров ---------- */
.tsv-excl .tsv-excl-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 30px;
    scroll-margin-top: 20px;
}
/* Без этого правила display:flex перебил бы атрибут hidden
   и панель показалась бы даже при выключенном JS */
.tsv-excl .tsv-excl-filters[hidden] { display: none; }
.tsv-excl .tsv-excl-filters-label {
    margin-right: 4px;
    font-family: var(--tsv-mono);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 2.5px;
    text-transform: uppercase;
    color: var(--tsv-fg-mute);
}
.tsv-excl .tsv-excl-chip {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    min-height: 44px;          /* тап-таргет */
    padding: 0 16px;
    border: 1px solid var(--tsv-border);
    border-radius: 999px;
    background: transparent;
    color: var(--tsv-fg-dim);
    font-family: inherit;
    font-size: 14.5px;
    font-weight: var(--fw-medium);
    line-height: 1.2;
    text-align: left;
    cursor: pointer;
    transition: border-color var(--dur-base) var(--ease-out),
                background-color var(--dur-base) var(--ease-out),
                color var(--dur-base) var(--ease-out);
}
.tsv-excl .tsv-excl-chip-n {
    font-family: var(--tsv-mono);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--tsv-fg-mute);
    transition: color var(--dur-base) var(--ease-out);
}
.tsv-excl .tsv-excl-chip[aria-pressed="true"] {
    border-color: var(--tsv-accent);
    background: var(--tsv-accent-soft);
    color: var(--tsv-fg);
}
.tsv-excl .tsv-excl-chip[aria-pressed="true"] .tsv-excl-chip-n { color: var(--tsv-accent-bright); }

/* ---------- Группа ---------- */
.tsv-excl .tsv-excl-group[hidden] { display: none; }
.tsv-excl .tsv-excl-group-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
}
.tsv-excl .tsv-excl-group h3 {
    font-size: 21px;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.01em;
    color: var(--tsv-fg);
}
.tsv-excl .tsv-excl-group-count {
    flex: 0 0 auto;
    font-family: var(--tsv-mono);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 2.5px;
    text-transform: uppercase;
    color: var(--tsv-fg-mute);
}
.tsv-excl .tsv-excl-group-note {
    max-width: 620px;
    margin: 8px 0 14px;
    font-size: 14px;
    line-height: 1.55;
    color: var(--tsv-fg-mute);
}
/* ---------- Сетка карточек ----------
   Колонки считает auto-fill, а не брейкпоинты: жёсткая раскладка
   давала между 700 и 899px либо три колонки по 220px, либо одну
   по 660px — в первом случае не читается текст на обложке,
   во втором карточка занимает пол-экрана. Контейнер ограничен
   1040px, поэтому колонок никогда не больше трёх.

   align-items: start обязателен: раскрытая карточка растёт вниз,
   и без него соседи по строке тянулись бы вместе с ней. */
.tsv-excl .tsv-excl-gal {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    align-items: start;
    gap: 22px 18px;
    margin-top: 16px;
}

/* ---------- Карточка ---------- */
.tsv-excl .tsv-excl-card-in {
    overflow: hidden;                       /* обложка скругляется по углам карточки */
    border: 1px solid var(--tsv-border);
    border-radius: var(--tsv-radius);
    background: var(--tsv-bg-elev);
    transition: border-color var(--dur-base) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out);
}
/* Кликабельна вся карточка целиком, а не подпись под ней */
.tsv-excl .tsv-excl-card-sum {
    display: block;
    list-style: none;
    cursor: pointer;
}
.tsv-excl .tsv-excl-card-sum::-webkit-details-marker { display: none; }
/* Отрицательный offset: обводка внутри карточки, иначе overflow:hidden
   срезал бы её у самой рамки */
.tsv-excl .tsv-excl-card-sum:focus-visible {
    outline: 2px solid var(--tsv-accent-bright);
    outline-offset: -2px;
}

/* Обложка. Своя, из assets/img — к i.ytimg.com со страницы
   посетителя не уходит ни одного запроса. Градиент под картинкой
   работает заглушкой, если файл почему-то не отдался. */
.tsv-excl .tsv-excl-shot {
    display: block;
    overflow: hidden;
    height: auto;
    aspect-ratio: 16 / 9;
    background: linear-gradient(135deg, #1b1533 0%, #241c40 100%);
}
.tsv-excl .tsv-excl-shot img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    transition: transform var(--dur-slow) var(--ease-out);
}
.tsv-excl .tsv-excl-card-name {
    display: block;
    padding: 14px 16px 0;
    font-size: 15.5px;
    font-weight: var(--fw-semibold);
    line-height: 1.4;
    color: var(--tsv-fg);
    overflow-wrap: break-word;
}
/* Строка-подсказка: она же и тап-таргет 44px, и место шеврона */
.tsv-excl .tsv-excl-card-hint {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-height: 44px;
    padding: 0 16px;
    font-family: var(--tsv-mono);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--tsv-fg-mute);
    transition: color var(--dur-base) var(--ease-out);
}
.tsv-excl .tsv-excl-card-hint::after {
    content: "";
    flex: 0 0 auto;
    width: 7px;
    height: 7px;
    margin-bottom: 3px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform 180ms var(--ease-out);
}
.tsv-excl .tsv-excl-card-in[open] { border-color: var(--tsv-accent-dim); }
.tsv-excl .tsv-excl-card-in[open] .tsv-excl-card-hint { color: var(--tsv-accent-bright); }
.tsv-excl .tsv-excl-card-in[open] .tsv-excl-card-hint::after {
    margin-top: 3px;
    margin-bottom: 0;
    transform: rotate(225deg);
}

/* ---------- Три ссылки урока ----------
   Boosty назван главным не подписью, а видом строки. У Patreon
   оговорка про российские карты стоит прямо в строке: человек
   читает её ровно в тот момент, когда выбирает, куда идти.
   Логотипов площадок нет ни одного — только названия словами. */
.tsv-excl .tsv-excl-card-links {
    padding: 12px;
    border-top: 1px solid var(--tsv-border);
}
.tsv-excl .tsv-excl-go {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 2px 14px;
    min-height: 44px;          /* тап-таргет */
    padding: 8px 14px;
    border: 1px solid var(--tsv-border);
    border-radius: var(--tsv-radius-sm);
    color: var(--tsv-fg-dim);
    text-decoration: none;
    transition: border-color var(--dur-base) var(--ease-out),
                background-color var(--dur-base) var(--ease-out),
                color var(--dur-base) var(--ease-out);
}
.tsv-excl .tsv-excl-go + .tsv-excl-go { margin-top: 6px; }
.tsv-excl .tsv-excl-go-name {
    font-size: 15px;
    font-weight: var(--fw-semibold);
}
.tsv-excl .tsv-excl-go-note {
    font-size: 12px;
    line-height: 1.35;
    color: var(--tsv-fg-mute);
}
.tsv-excl .tsv-excl-go--main {
    border-color: var(--tsv-accent-dim);
    background: var(--tsv-accent-soft);
    color: var(--tsv-fg);
}
.tsv-excl .tsv-excl-go--main .tsv-excl-go-name { color: var(--tsv-accent-bright); }

.tsv-excl .tsv-excl-list-after {
    max-width: 820px;
    margin-top: 30px;
    padding-top: 22px;
    border-top: 1px solid var(--tsv-border-soft);
}
.tsv-excl .tsv-excl-list-after .tsv-excl-soft { margin-top: 0; }
.tsv-excl .tsv-excl-list-after .tsv-excl-soft + .tsv-excl-soft { margin-top: 10px; }

/* ============================================================
   4. ГДЕ ОТКРЫТЬ — строка-решатель, а не таблица сравнения.
   Каждая строка начинается с условия про читателя: человек
   ничего не сравнивает, он узнаёт свой случай.
   ============================================================ */
.tsv-excl .tsv-excl-pick {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: 8px 24px;
    max-width: 760px;
    padding: 15px 0;
    border-top: 1px solid var(--tsv-border-soft);
}
.tsv-excl .tsv-excl-pick-if {
    font-size: 15.5px;
    line-height: 1.55;
    color: var(--tsv-fg-dim);
}
.tsv-excl .tsv-excl-pick-to {
    font-size: 16px;
    line-height: 1.55;
    color: var(--tsv-fg-dim);
}
/* Названия площадок здесь — обычный текст, а не ссылки:
   ссылки живут под кнопкой, одним местом ниже. Логотипов нет. */
.tsv-excl .tsv-excl-pick-to strong {
    font-weight: var(--fw-semibold);
    color: var(--tsv-fg);
}
.tsv-excl .tsv-excl-cta { margin-top: 28px; }
.tsv-excl .tsv-excl-alt {
    margin: 4px 0 0;
    font-size: 13.5px;
    line-height: 1.6;
    color: var(--tsv-fg-mute);
}

/* ============================================================
   5. КРОМЕ УРОКОВ — четыре пункта хайрлайнами.
   Ни иконок, ни галочек, ни двух колонок.
   ============================================================ */
.tsv-excl .tsv-excl-gain {
    max-width: 760px;
    padding: 16px 0;
    border-top: 1px solid var(--tsv-border);
    font-size: 15.5px;
    line-height: 1.65;
    color: var(--tsv-fg-dim);
}
.tsv-excl .tsv-excl-gain strong {
    font-size: 16px;
    font-weight: var(--fw-semibold);
    color: var(--tsv-fg);
}

/* ============================================================
   6. ЧАСТЫЕ ВОПРОСЫ — нативные details, первый open.
   Ответы лежат в HTML и у свёрнутого details: подгрузка
   по клику через JS запрещена. Высоту не анимируем.
   ============================================================ */
.tsv-excl .tsv-excl-faq { max-width: 820px; }
.tsv-excl .tsv-excl-faq details {
    border: 1px solid var(--tsv-border);
    border-radius: var(--tsv-radius-sm);
    transition: border-color var(--dur-base) var(--ease-out);
}
.tsv-excl .tsv-excl-faq details + details { margin-top: 8px; }
.tsv-excl .tsv-excl-faq details[open] { background: var(--tsv-bg-elev); }
.tsv-excl .tsv-excl-faq summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    min-height: 44px;
    padding: 14px 16px;
    cursor: pointer;
    list-style: none;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--tsv-fg);
}
.tsv-excl .tsv-excl-faq summary::-webkit-details-marker { display: none; }
.tsv-excl .tsv-excl-faq summary::after {
    content: "";
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    margin-bottom: 4px;
    border-right: 2px solid var(--tsv-fg-mute);
    border-bottom: 2px solid var(--tsv-fg-mute);
    transform: rotate(45deg);
    transition: transform 180ms var(--ease-out);
}
.tsv-excl .tsv-excl-faq details[open] summary::after {
    margin-bottom: 0;
    margin-top: 4px;
    transform: rotate(225deg);
}
.tsv-excl .tsv-excl-faq-body {
    padding: 0 16px 16px;
    font-size: 15px;
    line-height: 1.65;
    color: var(--tsv-fg-dim);
}

/* ============================================================
   7. СПАСИБО — чистая framed-карточка без фоновой картинки
   и без сетки-клеточки (правило владельца).
   ============================================================ */
.tsv-excl .tsv-excl-final {
    max-width: 760px;
    margin: 0 auto;
    padding: 40px 32px;
    background: var(--tsv-bg-elev);
    border: 1px solid var(--tsv-border-soft);
    border-radius: var(--tsv-radius-lg);
}
.tsv-excl .tsv-excl-final-text {
    margin-top: 12px;
    font-size: 16px;
    line-height: 1.6;
    color: var(--tsv-fg-dim);
}
.tsv-excl .tsv-excl-final .tsv-excl-btn { margin-top: 24px; }
.tsv-excl .tsv-excl-links {
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--tsv-border);
}
.tsv-excl .tsv-excl-links .tsv-excl-mute { margin-top: 0; }
.tsv-excl .tsv-excl-links .tsv-excl-mute + .tsv-excl-mute { margin-top: 6px; }
.tsv-excl .tsv-excl-links .tsv-excl-plat { font-weight: var(--fw-regular); }

/* ============================================================
   Наведение — только там, где есть настоящий курсор.
   ============================================================ */
@media (hover: hover) and (pointer: fine) {
    .tsv-excl .tsv-excl-btn:hover {
        filter: brightness(1.06);
        transform: translateY(-1px);
    }
    .tsv-excl .tsv-excl-faq details:hover { border-color: var(--tsv-border-soft); }

    .tsv-excl .tsv-excl-chip:hover {
        border-color: var(--tsv-accent-dim);
        color: var(--tsv-fg);
    }
    /* Тень: радиус 30px, spread отрицательный — свет не расползается */
    .tsv-excl .tsv-excl-card-in:hover {
        border-color: var(--tsv-accent-dim);
        box-shadow: 0 14px 30px -20px rgba(0, 0, 0, 0.9);
    }
    .tsv-excl .tsv-excl-card-sum:hover .tsv-excl-shot img { transform: scale(1.04); }
    .tsv-excl .tsv-excl-card-sum:hover .tsv-excl-card-hint { color: var(--tsv-accent-bright); }
    .tsv-excl .tsv-excl-go:hover {
        border-color: var(--tsv-accent);
        color: var(--tsv-fg);
    }

    .tsv-excl .tsv-excl-lead-sec a:hover,
    .tsv-excl .tsv-excl-shelf a:hover,
    .tsv-excl .tsv-excl-gain a:hover,
    .tsv-excl .tsv-excl-soft a:hover,
    .tsv-excl .tsv-excl-mute a:hover,
    .tsv-excl .tsv-excl-faq-body a:hover,
    .tsv-excl .tsv-excl-final-text a:hover,
    .tsv-excl .tsv-excl-plat:hover { text-decoration-color: var(--tsv-accent-bright); }
}

/* ============================================================
   Движение. Единственная анимация страницы — появление карточек
   после переключения фильтра.

   Скролл-ревила на странице нет намеренно. Карточки — единственное
   содержание секции, и прятать их под opacity в ожидании наблюдателя
   нельзя: при свёрнутой вкладке браузер не выполняет шаги рендеринга,
   IntersectionObserver не срабатывает, и галерея осталась бы пустой.

   Здесь такого риска нет: класс tsv-excl-shown вешается в обработчике
   клика, то есть в момент, когда скрипт заведомо жив. Нет скрипта —
   нет и класса, карточки просто нарисованы.
   ============================================================ */
@keyframes tsv-excl-rise {
    from { opacity: 0; transform: translateY(9px); }
    to   { opacity: 1; transform: none; }
}
/* Ни fill-mode, ни animation-delay здесь нет — и это главное
   в этом правиле, а не сама анимация.

   С `both` карточка держала бы opacity: 0 всё время, пока анимация
   не проигралась. А не проиграться она может: секция накрыта
   content-visibility: auto, и в пропущенном из рендера поддереве
   браузер анимации не выполняет. Достаточно отфильтровать и увести
   секцию за экран — и группа осталась бы пустой.

   Без fill-mode вне анимации действует обычный стиль, то есть
   карточка видна. Анимация может не проиграться вовсе — потеряется
   только появление, но не содержимое. По той же причине снята
   лесенка задержек: в паузе до старта карточка была бы видна,
   а потом скачком гасла до нуля. */
.tsv-excl .tsv-excl-group.tsv-excl-shown .tsv-excl-card {
    animation: tsv-excl-rise 280ms var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
    .tsv-excl *,
    .tsv-excl *::before,
    .tsv-excl *::after {
        animation: none !important;
        transition: none !important;
    }
}

/* ============================================================
   Брейкпоинты
   ============================================================ */
@media (max-width: 1099px) {
    .tsv-excl .tsv-excl-gal { gap: 20px 16px; }
}
@media (max-width: 899px) {
    /* Планшет: колонок две, секция вытягивается — интринсик держим
       в медиа-выборке, иначе на первом проходе прыгает скроллбар */
    .tsv-excl .tsv-excl-s-list { contain-intrinsic-size: auto 5700px; }
}
@media (max-width: 760px) {
    /* Строка-решатель складывается: условие сверху, площадка снизу */
    .tsv-excl .tsv-excl-pick {
        grid-template-columns: minmax(0, 1fr);
        gap: 4px;
    }
}
@media (max-width: 699px) {
    .tsv-excl .tsv-excl-section { padding: 36px 16px; }
    .tsv-excl .tsv-excl-hero { padding: 40px 16px 32px; }

    /* Мобильные интринсики держим в медиа-выборке, иначе прыгает скроллбар */
    .tsv-excl .tsv-excl-s-shelf { contain-intrinsic-size: auto 1200px; }
    .tsv-excl .tsv-excl-s-list  { contain-intrinsic-size: auto 10400px; }
    .tsv-excl .tsv-excl-s-where { contain-intrinsic-size: auto 1000px; }
    .tsv-excl .tsv-excl-s-more  { contain-intrinsic-size: auto 1100px; }
    .tsv-excl .tsv-excl-s-faq   { contain-intrinsic-size: auto 1000px; }
    .tsv-excl .tsv-excl-s-final { contain-intrinsic-size: auto 880px; }

    .tsv-excl .tsv-excl-h1 { font-size: 30px; }
    .tsv-excl .tsv-excl-lead { font-size: 16px; }
    .tsv-excl h2 { font-size: 26px; }
    .tsv-excl .tsv-excl-lead-sec { font-size: 16px; }

    /* Счётчик группы уезжает под заголовок: на 390px две строки
       в одну баз-линию не помещаются и рвут заголовок */
    .tsv-excl .tsv-excl-group-head {
        display: block;
    }
    .tsv-excl .tsv-excl-group-count {
        display: block;
        margin-top: 6px;
    }
    .tsv-excl .tsv-excl-group-note { margin-top: 10px; }

    /* На телефоне колонка остаётся одна сама собой: 260px минимума
       во вторую не помещаются. Здесь только зазоры и кегль. */
    .tsv-excl .tsv-excl-gal { gap: 16px; }
    .tsv-excl .tsv-excl-list { gap: 36px; }
    .tsv-excl .tsv-excl-filters { margin-bottom: 24px; }
    .tsv-excl .tsv-excl-chip { padding: 0 14px; font-size: 14px; }
    .tsv-excl .tsv-excl-card-name { font-size: 16px; }

    /* Кнопки на всю ширину */
    .tsv-excl .tsv-excl-btn { display: flex; width: 100%; min-height: 48px; }

    .tsv-excl .tsv-excl-final { padding: 32px 20px; }
}
