/* Discovery («Маркетплейс») — отдельный лист, без карты и landing.css.
   Токены берутся из variables.css + css/_palette_refresh_2026.css (--bg-*,
   --text-*, --border-*, --primary*, --info*, --warning*, --radius-*,
   --shadow-*). Literal hex здесь запрещён (design task 02): цвет типа
   карточки — через семантические алиасы ниже, которые указывают на
   канонические токены. Normal document scroll, один столбец на телефоне,
   два на планшете, три на десктопе (ТЗ §16.1).

   ПАЛИТРА (08.09). Страница выглядела холодной при верной структуре, и
   первый диагноз был неверным: «канонические токены — это индиго
   #4f46e5 и серый #f9fafb, значит Editorial Calm сюда не переносится».
   На деле палитра издания в репозитории ЕСТЬ и совпадает с
   design_reference значение-в-значение: `css/_palette_refresh_2026.css`
   (--primary #1F3D2B, --info #2C5282, --warning #8C5A1A, бумажные
   поверхности #FBFAF7/#F4F1EA, тёплые границы и тени). Не работала она
   потому, что `base.html` этот лист НЕ подключает — он стоял ровно в
   пяти шаблонах (админка и четыре страницы оплаты), причём собственная
   шапка файла утверждала обратное. Классический «registered ≠ called»
   (правило #17): слой существовал и не доезжал.

   Поэтому здесь литералов по-прежнему нет, а лист палитры подключён в
   `templates/discovery/_layout.html` в блоке `styles` — то есть ПОСЛЕ
   variables.css, иначе переопределение проигрывает по порядку
   (`block head` в base.html объявлен ДО variables.css). Связку стережёт
   tests/discovery/test_marketplace_visual.py. */

/* ── Шрифт витрины (09.09) ────────────────────────────────────────────
   Лист УЖЕ объявлял `font-family: Inter, system-ui, …` на `.dsc-page`, но
   самого Inter в проекте не было: ни файла, ни `@font-face`, ни ссылки на
   внешний хостинг. Значит объявление всегда разрешалось во ВТОРОЙ пункт
   списка — системный шрифт ОС посетителя. Это «registered ≠ called»
   (правило #17), применённое к гарнитуре: имя записано, читателя нет.
   Доказано замером на живой странице, а не чтением: `document.fonts`
   содержал только Literata и JetBrains Mono, а ширина заголовка совпадала
   с принудительным system-ui и отличалась от Inter.

   Хостим сами, как Literata и JetBrains Mono (см. gd-fonts.css): на
   RU-сервере внешние шрифтовые CDN недоступны, и ссылка на них дала бы
   ровно тот же молчаливый фоллбэк, только с задержкой. Один файл на всё
   семейство — переменное начертание 100-900. `font-display: swap`: текст
   читается сразу, замена происходит по загрузке.

   Область — только витрина. `variables.css --font-sans` тоже называет
   Inter для всего продукта и тоже сейчас разрешается в системный шрифт;
   включать его продуктово — отдельное решение владельца, потому что
   «Калька» намеренно набрана Literata. */
@font-face {
  font-family: "Inter";
  /* Подмножество RU+EN, ось веса 400–700, оптическая ось сохранена (её
     закрепление меняло метрики заголовков): полный InterVariable.woff2
     весил 344 КБ и был 44% байт витрины на телефоне (замер 22.09).
     Сборка — scripts/build_font_subsets.py. */
  src: url("../fonts/Inter-cyrlat.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

.dsc-page {
  /* Цвет типа: сообщество — primary (глубокий зелёный), проект — info
     (приглушённый navy), место — warning (охра). Берём базовый шаг, а не
     `-dark`: в палитре издания базовый и есть цвет референса, и он даёт
     ≥4.9:1 и на бумаге, и на своей плашке. Плашки — самый светлый шаг. */
  --dsc-community: var(--primary);
  --dsc-community-tint: var(--primary-lightest);
  --dsc-project: var(--info);
  --dsc-project-tint: var(--info-lightest);
  --dsc-place: var(--warning);
  --dsc-place-tint: var(--warning-lightest);
  --dsc-accent: var(--dsc-community);
  --dsc-tint: var(--dsc-community-tint);
  --dsc-ease: cubic-bezier(.2, .6, .2, 1);
  --dsc-motion-fast: 120ms;
  --dsc-motion-base: 180ms;

  /* Радиусы витрины. Значения зеркалят variables.css:129-133 и объявлены
     здесь, потому что Калька (kalka-bridge.css:170-174) переопределяет эти
     же токены в `var(--gd-radius)` = 0. Витрина живёт по своему референсу
     (решение владельца 09.09, вариант А), поэтому возвращает их себе — но
     только внутри `.dsc-page`, остальной продукт остаётся на Кальке.
     Расхождение с variables.css поймает
     tests/discovery/test_marketplace_cascade.py. */
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-full: 9999px;

  max-width: 1200px;
  margin: 0 auto;
  padding: 16px 20px 72px;
  color: var(--text-primary);
  font-size: 1rem;
  line-height: 1.5;
}
.dsc-visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.dsc-eyebrow {
  margin: 0 0 10px; color: var(--primary);
  font-size: .75rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
}

/* Шапка §7.1 п.1: имя продукта и переключатель слева, город и вход справа.
   На узком экране обе половины остаются в одной строке (wrap внутри каждой),
   поэтому вход не уезжает под сгиб — это единственный способ войти со
   страницы, куда приходят по прямой ссылке. */
.dsc-topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; padding: 8px 0 20px;
}
.dsc-topbar__brand,
.dsc-topbar__right { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
/* Словесный знак: собственной картинки-логотипа в проекте нет (см. комментарий
   в templates/discovery/_layout.html), поэтому имя — это текст. */
.dsc-brand {
  font-weight: 700; font-size: 1.05rem; letter-spacing: -.01em;
  color: inherit; text-decoration: none; white-space: nowrap;
}
.dsc-brand:hover { color: var(--primary); }
/* Переключатель «Карта | Маркетплейс» — общий компонент
   static/css/components/mode-switcher.css (design task 01). */
.dsc-city { display: flex; flex-direction: column; line-height: 1.2; }
.dsc-city__label { font-size: .75rem; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
.dsc-city__name { font-weight: 600; text-decoration: none; color: inherit; font-size: 1.05rem; }
/* Вход/профиль. min-height 44px — тот же палец, что и у .dsc-btn: ссылка
   мелким текстом в углу на телефоне не нажимается. */
.dsc-auth {
  display: inline-flex; align-items: center; min-height: 44px; padding: 8px 16px;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  color: inherit; text-decoration: none; font-size: .95rem; white-space: nowrap;
}
.dsc-auth:hover { border-color: var(--primary); color: var(--primary); }
.dsc-auth--login { border-color: var(--primary); color: var(--primary); font-weight: 600; }
.dsc-auth--login:hover { background: var(--primary); color: var(--text-inverse, var(--white)); }
.dsc-auth:focus-visible,
.dsc-brand:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; }

/* ── Первый экран: тезис, поиск с городом, три намерения ─────────────── */
/* Первый экран лежит на тёплой полосе, а не на белом: в референсе это
   отдельная поверхность `.hero-surface` с фоном --bg-secondary и нижней
   границей. Полоса растянута на ширину контейнера компенсацией бокового
   padding'а страницы (20px) — без 100vw, чтобы не завести горизонтальный
   скролл на 320px, который запрещён ТЗ §16.1. */
.dsc-hero {
  display: grid; gap: 20px;
  margin-inline: -20px; padding: 24px 20px 28px;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border); margin-bottom: 24px;
}
.dsc-hero__top { display: grid; grid-template-columns: 1fr; gap: 12px; align-items: end; }
@media (min-width: 900px) {
  .dsc-hero__top { grid-template-columns: minmax(0, 1.45fr) minmax(280px, .7fr); gap: clamp(32px, 6vw, 78px); }
}
.dsc-hero__title {
  max-width: 800px; margin: 0;
  font-size: clamp(1.9rem, 4.2vw, 3.375rem); font-weight: 700; letter-spacing: -.04em; line-height: 1.02;
  text-wrap: balance;
}
.dsc-hero__lead { max-width: 520px; margin: 0; color: var(--text-secondary); font-size: 1.05rem; }

.dsc-search {
  display: grid; grid-template-columns: 1fr; gap: 12px; align-items: end;
  padding: 12px; border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--bg-primary); box-shadow: var(--shadow-sm);
}
@media (min-width: 640px) {
  .dsc-search { grid-template-columns: minmax(0, 2fr) minmax(190px, .8fr) auto; }
  .dsc-search--city { grid-template-columns: minmax(0, 1fr) auto; }
}
.dsc-search__field { display: grid; min-width: 0; gap: 6px; }
.dsc-search__label { color: var(--text-secondary); font-size: .85rem; font-weight: 600; }
.dsc-search__control {
  display: flex; min-height: 50px; align-items: center; gap: 10px; padding: 0 12px;
  border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-primary);
}
.dsc-search__control:focus-within { border-color: var(--primary); }
.dsc-search__control svg { flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; color: var(--text-muted); }
.dsc-search__input {
  width: 100%; min-width: 0; min-height: 44px; border: 0; background: transparent;
  color: var(--text-primary); font-size: 1rem; font-weight: 400;
}
.dsc-search__input:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.dsc-search__input::placeholder { color: var(--text-muted); }
/* Город живёт в той же оболочке, что и поиск: рамку, фон и высоту рисует
   `.dsc-search__control`, сам `select` — только текст. Нативная стрелка ОС
   снята (`appearance: none`) и заменена нашим шевроном: рядом с иконкой лупы
   системная стрелка читается как чужой элемент. */
.dsc-search__control--select { padding-right: 10px; }
.dsc-search__select {
  width: 100%; min-width: 0; padding: 0; border: 0; background: transparent;
  color: var(--text-primary); font-size: 1rem; font-weight: 400;
  appearance: none; -webkit-appearance: none;
}
.dsc-search__select:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.dsc-search__chevron {
  flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; color: var(--text-muted);
  pointer-events: none;
}
/* Кнопка ряда — той же высоты, что поля. Замер 15.09 (chromium, прод-каскад):
   объявленный здесь `min-height: 50px` не доезжал (приходило 44px от общего
   компонента кнопки), и «Найти» была на 4px ниже соседних полей. Высота
   закреплена в контр-слое ниже — там, где её не перебить. */
.dsc-search__submit { min-height: 50px; padding-inline: 24px; }

/* Намерений четыре: «Найти» + три типа §15.1 (клуб/сообщество, проект,
   место). На среднем экране — 2×2, на широком — в ряд; жёсткие три колонки
   оставляли бы четвёртую карточку одну на строке. */
.dsc-intents { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
@media (min-width: 1024px) { .dsc-intents { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.dsc-intent {
  display: grid; min-width: 0; min-height: 66px; grid-template-columns: 40px minmax(0, 1fr) auto;
  gap: 12px; align-items: center; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--bg-primary); color: var(--text-primary); text-decoration: none; text-align: left;
}
.dsc-intent:hover { border-color: var(--dsc-accent); }
.dsc-intent:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; }
.dsc-intent__icon {
  display: grid; width: 40px; height: 40px; place-items: center;
  border-radius: var(--radius-md); background: var(--dsc-tint); color: var(--dsc-accent);
}
.dsc-intent__icon svg { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.dsc-intent__text strong, .dsc-intent__text small { display: block; }
.dsc-intent__text strong { margin-bottom: 2px; font-size: 1rem; line-height: 1.25; }
.dsc-intent__text small { color: var(--text-muted); font-size: .8rem; line-height: 1.3; }
/* Стрелка — декор через CSS, не текст ссылки (a11y-гейт icon-only). */
.dsc-intent::after { content: "→"; color: var(--dsc-accent); font-size: 1.25rem; }
.dsc-intent--off::after { content: none; }
.dsc-intent--primary { border-color: var(--primary); background: var(--primary); color: var(--text-inverse, var(--white)); }
.dsc-intent--primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); }
.dsc-intent--primary .dsc-intent__icon { background: color-mix(in srgb, var(--white) 16%, transparent); color: var(--text-inverse, var(--white)); }
.dsc-intent--primary .dsc-intent__text small, .dsc-intent--primary::after { color: color-mix(in srgb, var(--white) 78%, transparent); }
.dsc-intent[data-kind="community"] { --dsc-accent: var(--dsc-community); --dsc-tint: var(--dsc-community-tint); }
.dsc-intent[data-kind="project"] { --dsc-accent: var(--dsc-project); --dsc-tint: var(--dsc-project-tint); }
.dsc-intent[data-kind="place"] { --dsc-accent: var(--dsc-place); --dsc-tint: var(--dsc-place-tint); }
.dsc-intent--off { cursor: not-allowed; background: var(--bg-secondary); grid-template-columns: 40px minmax(0, 1fr); }
.dsc-intent--off:hover { border-color: var(--border); }
.dsc-intent--off .dsc-intent__text strong { color: var(--text-secondary); }
@media (max-width: 639px) {
  .dsc-intent, .dsc-intent--off { grid-template-columns: minmax(0, 1fr); gap: 4px; padding: 12px; }
  .dsc-intent__icon, .dsc-intent::after { display: none; }
}

/* Кнопки */
.dsc-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 44px; padding: 10px 18px; border-radius: var(--radius-md); font-size: 1rem;
  border: 1px solid var(--border); background: var(--bg-primary);
  color: inherit; text-decoration: none; cursor: pointer;
}
.dsc-btn--primary { background: var(--primary); border-color: transparent; color: var(--text-inverse, var(--white)); }
.dsc-btn--primary:hover { background: var(--primary-dark); }
.dsc-btn--ghost { background: transparent; }
.dsc-btn--sm { padding: 4px 10px; font-size: var(--font-size-sm, 0.875rem); }
/* Строка события в карточке места: текст слева, CTA «Иду» справа (PR-M4 RSVP). */
.dsc-event { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.dsc-event form { margin: 0; }
.dsc-btn--danger { border-color: var(--danger); color: var(--danger); }
.dsc-btn:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; }
.dsc-cta-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }

/* ── Результаты: заголовок, сортировка, разделы ───────────────────────── */
.dsc-results { scroll-margin-top: 16px; }
.dsc-toolbar { display: flex; justify-content: space-between; align-items: flex-end; gap: 16px; flex-wrap: wrap; margin-bottom: 14px; }
.dsc-results__title { margin: 0 0 6px; font-size: clamp(1.4rem, 2.6vw, 1.9rem); letter-spacing: -.03em; line-height: 1.1; }
.dsc-count { margin: 0; color: var(--text-secondary); font-weight: 500; }
.dsc-sort { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.dsc-sort select { min-height: 40px; font-size: 1rem; padding: 6px 10px; border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--bg-primary); color: inherit; }

.dsc-facets { display: flex; gap: 8px; flex-wrap: wrap; padding: 4px 0 18px; }
.dsc-chip {
  --dsc-accent: var(--text-primary); --dsc-tint: var(--bg-secondary);
  display: inline-flex; align-items: center; min-height: 36px; padding: 6px 14px;
  border-radius: var(--radius-full); border: 1px solid var(--border);
  text-decoration: none; color: var(--text-primary); font-size: .95rem; background: var(--bg-primary);
}
.dsc-chip[data-category="community"] { --dsc-accent: var(--dsc-community); --dsc-tint: var(--dsc-community-tint); }
.dsc-chip[data-category="project"] { --dsc-accent: var(--dsc-project); --dsc-tint: var(--dsc-project-tint); }
.dsc-chip[data-category="place"] { --dsc-accent: var(--dsc-place); --dsc-tint: var(--dsc-place-tint); }
.dsc-chip--sub { font-size: .875rem; }
.dsc-chip:hover { border-color: var(--dsc-accent); background: var(--dsc-tint); color: var(--dsc-accent); }
.dsc-chip:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; }
.dsc-chip.is-active { background: var(--dsc-accent); color: var(--text-inverse, var(--white)); border-color: transparent; }
.dsc-chip.is-active:hover { color: var(--text-inverse, var(--white)); background: var(--dsc-accent); }

/* ── Bottom sheet фильтров без JS (§16.1) ─────────────────────────────
   Лист живёт на :target: ссылка #dsc-filters открывает, #dsc-results
   закрывает, back-кнопка возвращает состояние. На desktop — обычный блок. */
.dsc-sheet__head { display: none; }
.dsc-sheet__open { display: none; }
.dsc-sheet__panel { display: block; }
@media (max-width: 1023px) {
  .dsc-sheet__open { display: inline-flex; align-self: start; }
  .dsc-sheet { display: none; }
  .dsc-sheet:target { display: block; }
  .dsc-sheet:target .dsc-sheet__panel {
    position: fixed; inset: auto 0 0 0; z-index: 30; max-height: 82vh; overflow: auto;
    padding: 12px 16px calc(16px + env(safe-area-inset-bottom));
    background: var(--bg-primary); border-top: 1px solid var(--border);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0; box-shadow: var(--shadow-md);
  }
  .dsc-sheet:target::before { content: ""; position: fixed; inset: 0; z-index: 29; background: var(--bg-overlay); }
  .dsc-sheet__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
  .dsc-sheet__title { margin: 0; font-weight: 600; }
  .dsc-sheet .dsc-facets { padding-bottom: 8px; }
}
@media (max-width: 767px) {
  /* Липкий поиск на списке; touch target ≥ 44 (§16.1) */
  .dsc-search--sticky { position: sticky; top: 8px; z-index: 20; }
  .dsc-chip { min-height: 44px; }
  .dsc-btn { min-height: 44px; }
  .dsc-check { min-height: 44px; }
  .dsc-sort select { min-height: 44px; }
}

/* ── Каталог в две колонки (композиция референса, design task 02) ─────
   В `design_reference/styles.css:658` каталог задан так:
     .catalogue-layout { grid-template-columns: 236px minmax(0, 1fr) }
     .filters-panel    { position: sticky; top: 76px }
     @media (max-width: 1023px) { .filters-panel { display: none } }
   То есть фильтры на десктопе — постоянная липкая колонка слева, а нижняя
   шторка достаётся узким экранам. У нас лист лежал одной колонкой над
   выдачей на любой ширине: на телефоне это шторка (§16.1), а на десктопе
   просто блок сверху — фильтр, до которого надо прокрутить страницу вверх.

   Ниже 1024px колонка складывается обратно, и всё мобильное поведение
   (шторка на :target, кнопка «Фильтры и разделы», фиксация снизу) остаётся
   ровно тем же — правила выше не тронуты. Замер обеих раскладок в браузере:
   tests/discovery/test_catalog_is_two_columns.py. */
.dsc-catalog { display: grid; grid-template-columns: minmax(0, 1fr); }
/* Строка референса, которую легко потерять: `.results { min-width: 0 }`
   (design_reference/styles.css:704). `minmax(0, 1fr)` ограничивает ТРЕК, а не
   сам элемент — у грид-элемента `min-width: auto`, и одного неразрывного
   токена в выдаче (длинная ссылка в `.dsc-note`, текст ошибки провайдера)
   хватает, чтобы колонка распёрла страницу. Замер без этой строки: при окне
   1280px `scrollWidth` = 1537. Карточки защищены сами, `.dsc-pager`,
   `.dsc-note` и `.dsc-state--error` — нет.

   Одного `min-width: 0` при этом мало, и это тоже измерено: элемент
   перестаёт распирать ТРЕК, но сам текст всё равно рисуется за границей
   бокса — страница на 1280px получалась шириной 2357px. Поэтому рядом
   `overflow-wrap: anywhere`: длинный токен переносится, а не выезжает.
   Требование «нет горизонтального скролла на 320px» (§16.1) держится
   правилом, а не удачным содержимым. */
.dsc-catalog__main { min-width: 0; overflow-wrap: anywhere; }
@media (min-width: 1024px) {
  /* Ширина колонки и зазор — значения референса дословно (236px и
     clamp(28px, 4vw, 52px)), чтобы «перенести композицию» означало перенос,
     а не пересказ. `align-items: start` добавлено: без него колонка
     фильтров растянулась бы по высоте выдачи и липкость стала бы мнимой. */
  .dsc-catalog { grid-template-columns: 236px minmax(0, 1fr); gap: clamp(28px, 4vw, 52px); align-items: start; }
  /* Липкость — смысл колонки: при длинной выдаче фильтры остаются на
     экране. `top` небольшой, потому что шапка витрины НЕ липкая (в отличие
     от референса, где она sticky на 56px и панель отступает на 76px). */
  /* `max-height` + прокрутка — не украшение, а условие достижимости.
     `position: sticky` с одним `top` прижимает ВЕРХ элемента: если колонка
     выше окна, до её низа не добраться прокруткой НИКОГДА. У нас в панели 13
     чипсов и форма сортировки в столбик — замер даёт 916px, и на ноутбуке
     1280×768 последние подтипы мест и кнопка «Применить» становятся
     недостижимы навсегда. В референсе этого не видно: там 8 строк чекбоксов.
     То есть дословно перенести ЗНАЧЕНИЯ было правильно, а дословно перенести
     ПОВЕДЕНИЕ — недостаточно, потому что содержимое у нас другое. */
  .dsc-sheet { position: sticky; top: 12px; max-height: calc(100vh - 24px); overflow-y: auto; }
  .dsc-sheet__panel { padding: 16px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-primary); }
  /* Заголовок листа на десктопе нужен (это отдельная колонка, её надо
     назвать), а «Закрыть» — нет: закрывать нечего, шторки здесь нет. */
  .dsc-sheet__head { display: block; margin-bottom: 12px; }
  .dsc-sheet__close { display: none; }
  .dsc-sheet__title { margin: 0; font-weight: 700; font-size: .95rem; }
  .dsc-sheet .dsc-sort { flex-direction: column; align-items: stretch; }
  .dsc-sheet .dsc-facets { padding: 12px 0 0; }
}

/* ── Сетка карточек ──────────────────────────────────────────────────── */
.dsc-grid { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .dsc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .dsc-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.dsc-card {
  position: relative; display: flex; min-width: 0; height: 100%; overflow: hidden; flex-direction: column;
  border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-primary);
}
.dsc-card[data-kind="community"] { --dsc-accent: var(--dsc-community); --dsc-tint: var(--dsc-community-tint); }
.dsc-card[data-kind="project"] { --dsc-accent: var(--dsc-project); --dsc-tint: var(--dsc-project-tint); }
.dsc-card[data-kind="place"] { --dsc-accent: var(--dsc-place); --dsc-tint: var(--dsc-place-tint); }
/* Подъём и потепление рамки при наведении — как в референсе: рамка не
   уходит в полный акцент, а смешивается с обычной, иначе сетка «мигает». */
.dsc-card { transition: border-color var(--dsc-motion-fast) var(--dsc-ease), transform var(--dsc-motion-fast) var(--dsc-ease); }
.dsc-card:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--dsc-accent) 58%, var(--border)); }
@media (prefers-reduced-motion: reduce) {
  .dsc-card, .dsc-card__photo { transition: none; }
  .dsc-card:hover { transform: none; }
}
.dsc-card:has(.dsc-card__link:focus-visible) { border-color: var(--dsc-accent); outline: 3px solid var(--primary); outline-offset: 2px; }

/* Обложка 16:9: цвет типа и литера лежат ПОД фото — без JS и без файла
   карточка остаётся различимой; полоска типа снизу, статус — плашкой. */
.dsc-card__visual {
  position: relative; display: flex; aspect-ratio: 16 / 9; align-items: center; justify-content: center;
  margin: 0; overflow: hidden; border-bottom: 1px solid var(--border-light);
  background: var(--dsc-tint); color: var(--dsc-accent);
}
.dsc-card__visual::after {
  position: absolute; z-index: 3; right: 0; bottom: 0; left: 0; height: 4px;
  background: var(--dsc-accent); content: "";
}
.dsc-card__letter { position: relative; z-index: 0; font-size: clamp(2.75rem, 5vw, 4.5rem); font-weight: 700; letter-spacing: -.08em; line-height: 1; }
.dsc-card__photo {
  position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
}
/* Фото живёт приглушённым и «оживает» при наведении — приём референса,
   который и делает сетку спокойной. Приглушение общее для реальных обложек
   и категорийных подложек; различие «реальное фото / иллюстрация» несёт
   модификатор --fallback на самом визуале, а не сила фильтра. */
.dsc-card__photo {
  filter: saturate(.88) contrast(.98);
  transition: filter var(--dsc-motion-base) var(--dsc-ease), transform 320ms var(--dsc-ease);
}
.dsc-card:hover .dsc-card__photo { filter: saturate(1) contrast(1); transform: scale(1.025); }
.dsc-card__visual--fallback::before {
  position: absolute; z-index: 2; inset: 0; content: ""; pointer-events: none;
  background: linear-gradient(180deg, transparent 45%, color-mix(in srgb, var(--dsc-accent) 45%, transparent) 125%);
}
.dsc-card__status {
  position: absolute; z-index: 4; bottom: 14px; left: 14px; display: inline-flex; min-height: 28px; align-items: center;
  padding: 5px 9px; border: 1px solid color-mix(in srgb, var(--dsc-accent) 28%, transparent);
  border-radius: var(--radius-full); background: color-mix(in srgb, var(--bg-primary) 92%, transparent);
  color: var(--dsc-accent); box-shadow: var(--shadow-sm); font-size: .8rem; font-weight: 700; line-height: 1.1;
}
.dsc-card__status::before { width: 6px; height: 6px; margin-right: 6px; border-radius: var(--radius-full); background: currentColor; content: ""; }

.dsc-card__content { display: flex; flex: 1; flex-direction: column; padding: 16px 18px 18px; }
.dsc-card__type { margin: 0 0 10px; color: var(--dsc-accent); font-size: .75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
/* Сид-карточка ждёт владельца (ТЗ 14.09 A-5): плашка поверх кликабельной обёртки карточки,
   иначе её ссылку перекрывает ::after у .dsc-card__link. */
.dsc-card__seed { position: relative; z-index: 1; margin: 8px 0 0; padding: 6px 10px; border-left: 3px solid var(--dsc-accent); background: var(--bg-secondary); color: var(--text-secondary); font-size: .8rem; line-height: 1.35; }
.dsc-card__seed a { color: inherit; text-decoration: underline; }
.dsc-detail__seed { margin-top: 10px; }
.dsc-card__title { margin: 0; font-size: 1.25rem; letter-spacing: -.02em; line-height: 1.15; overflow-wrap: anywhere; text-wrap: balance; }
.dsc-card__link { color: inherit; text-decoration: none; }
.dsc-card__link::after { position: absolute; inset: 0; content: ""; }
/* Кольцо фокуса — на самой ссылке (не гасим) И на карточке через :has(). */
.dsc-card__link:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.dsc-card__summary {
  display: -webkit-box; overflow: hidden; margin: 10px 0 0; color: var(--text-secondary); font-size: .95rem;
  -webkit-box-orient: vertical; -webkit-line-clamp: 2;
}
.dsc-card__tags, .dsc-card__facts { list-style: none; margin: 0; padding: 0; }
.dsc-card__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.dsc-tag {
  display: inline-flex; min-height: 28px; align-items: center; padding: 0 9px;
  border: 1px solid var(--border-light); border-radius: var(--radius-full); background: var(--bg-tertiary);
  color: var(--text-secondary); font-size: .8rem; font-weight: 600;
}
.dsc-card__facts { display: grid; gap: 6px; margin-top: auto; padding-top: 12px; color: var(--text-muted); font-size: .85rem; }
.dsc-card__facts:empty { display: none; }
.dsc-card__facts li + li { border-top: 1px solid var(--border-light); padding-top: 6px; }
/* Соцссылки карточки: отдельные кликабельные чипы поверх перехода в карточку. */
.dsc-card__links { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; position: relative; z-index: 2; }
.dsc-link {
  display: inline-flex; min-height: 32px; align-items: center; gap: 6px; padding: 0 10px;
  border: 1px solid var(--border-light); border-radius: var(--radius-full); background: var(--bg-primary);
  color: var(--text-primary); font-size: .8rem; font-weight: 600; text-decoration: none;
}
.dsc-link::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--text-muted); }
.dsc-link--telegram::before { background: var(--info); }
.dsc-link--vk::before { background: var(--primary); }
.dsc-link:hover, .dsc-link:focus-visible { border-color: var(--dsc-accent); color: var(--dsc-accent); }
.dsc-card__cta {
  display: flex; min-height: 40px; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border-light);
  color: var(--dsc-accent); font-weight: 700;
}
.dsc-card__cta span { font-size: 1.25rem; }
.dsc-fresh::before { content: "●"; margin-right: 4px; }
.dsc-fresh--ok::before { color: var(--success); }
.dsc-fresh--stale::before { color: var(--warning-dark); }

/* ── Кросс-срезы (§7.1 п.5) ──────────────────────────────────────────
   Полоса — витрина, а не список: на узком экране горизонтальная лента с
   snap, на широком — три карточки в ряд. Своей рамки и своего радиуса у
   полосы нет намеренно: рамку несёт карточка, а лишний скруглённый
   контейнер пришлось бы отдельно выводить из-под обнуления геометрии
   Калькой (см. блок исключений витрины ниже) — меньше поверхностей,
   меньше расхождений. */
.dsc-rails { display: flex; flex-direction: column; gap: clamp(28px, 5vw, 44px); margin: 8px 0 clamp(32px, 6vw, 56px); }
.dsc-rail__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.dsc-rail__title { margin: 0; font-size: clamp(1.15rem, 2.2vw, 1.5rem); letter-spacing: -.02em; line-height: 1.15; }
.dsc-rail__hint { margin: 4px 0 0; color: var(--text-secondary); font-size: .95rem; }
.dsc-rail__list {
  list-style: none; margin: 0; padding: 0 4px 4px 0;
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(260px, 78%);
  gap: 16px; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity; scrollbar-width: thin;
}
.dsc-rail__list > * { scroll-snap-align: start; }
@media (min-width: 640px) { .dsc-rail__list { grid-auto-columns: minmax(280px, 46%); } }
@media (min-width: 1024px) {
  /* На широком экране лента перестаёт быть лентой: карточки встают в ряд,
     горизонтальной прокрутки нет. Ни одна карточка при этом не прячется:
     полоса всегда показывает ВЕСЬ свой набор (его размер задаёт
     SECTION_LIMIT), а сколько осталось за ней — говорит счётчик у «Все».
     Скрыть лишнее через display:none значило бы урезать выдачу молча. */
  .dsc-rail__list { grid-auto-flow: row; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-columns: auto; overflow-x: visible; }
}
.dsc-rail__state { margin: 0; color: var(--text-secondary); }
.dsc-rail__state--error { color: var(--danger-dark); }

/* Состояния */
.dsc-state { border-radius: var(--radius-lg); padding: 18px 20px; margin: 12px 0; }
.dsc-state--empty { background: var(--bg-secondary); }
.dsc-state--error { background: var(--danger-lightest); color: var(--danger-dark); }
.dsc-state--ok { background: var(--success-lightest); color: var(--success-dark); }
.dsc-state h2 { margin: 0 0 6px; font-size: 1.1rem; }
.dsc-empty {
  display: grid; grid-template-columns: 1fr; gap: 24px; align-items: center;
  padding: clamp(28px, 6vw, 64px); border: 1px dashed var(--border);
}
@media (min-width: 640px) { .dsc-empty { grid-template-columns: auto 1fr; gap: 32px; } }
.dsc-empty__mark { color: var(--border); font-size: clamp(5rem, 15vw, 10rem); font-weight: 700; letter-spacing: -.08em; line-height: .8; }
.dsc-empty h2 { font-size: clamp(1.4rem, 3vw, 1.9rem); }
.dsc-empty p { color: var(--text-secondary); }
.dsc-note { font-size: .9rem; color: var(--text-secondary); }
.dsc-muted { color: var(--text-muted); }
.dsc-pager { display: flex; gap: 12px; align-items: center; justify-content: center; margin: 24px 0; flex-wrap: wrap; }

/* ── Карточка (detail) ───────────────────────────────────────────────── */
.dsc-detail[data-kind="community"] { --dsc-accent: var(--dsc-community); --dsc-tint: var(--dsc-community-tint); }
.dsc-detail[data-kind="project"] { --dsc-accent: var(--dsc-project); --dsc-tint: var(--dsc-project-tint); }
.dsc-detail[data-kind="place"] { --dsc-accent: var(--dsc-place); --dsc-tint: var(--dsc-place-tint); }
.dsc-crumbs { display: flex; gap: 8px; font-size: .9rem; margin-bottom: 16px; }
.dsc-crumbs a { color: inherit; }
.dsc-detail__hero {
  display: grid; grid-template-columns: 1fr; gap: 24px; align-items: center; margin-bottom: 28px;
}
@media (min-width: 900px) {
  .dsc-detail__hero { grid-template-columns: minmax(280px, .9fr) minmax(0, 1.2fr); gap: clamp(32px, 6vw, 80px); }
}
.dsc-detail__visual {
  position: relative; overflow: hidden; aspect-ratio: 3 / 2;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--dsc-tint); color: var(--dsc-accent);
}
.dsc-detail__visual::after { position: absolute; z-index: 3; right: 0; bottom: 0; left: 0; height: 6px; background: var(--dsc-accent); content: ""; }
.dsc-detail__letter { position: relative; z-index: 0; font-size: clamp(5rem, 14vw, 10rem); font-weight: 700; letter-spacing: -.1em; line-height: 1; }
.dsc-detail__cover { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.dsc-detail__cover--generic { filter: saturate(.9) contrast(.98); }
.dsc-detail__visual--fallback::before {
  position: absolute; z-index: 2; inset: 0; content: ""; pointer-events: none;
  background: linear-gradient(180deg, transparent 45%, color-mix(in srgb, var(--dsc-accent) 40%, transparent) 125%);
}
.dsc-detail__intro .dsc-card__type { margin-bottom: 12px; }
.dsc-detail__title { font-size: clamp(1.75rem, 3.6vw, 2.75rem); letter-spacing: -.04em; line-height: 1.08; margin: 0 0 12px; text-wrap: balance; }
.dsc-detail__lead { max-width: 60ch; margin: 0 0 16px; color: var(--text-secondary); font-size: clamp(1.05rem, 1.6vw, 1.2rem); }
.dsc-detail__grid { display: grid; gap: 24px; grid-template-columns: 1fr; }
@media (min-width: 900px) { .dsc-detail__grid { grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); } }
.dsc-section { padding: 16px 0; border-top: 1px solid var(--border-light); }
.dsc-section h2 { font-size: 1.1rem; margin: 0 0 8px; }
.dsc-section h3 { font-size: 1rem; margin: 14px 0 4px; }
.dsc-section--cta { background: var(--bg-secondary); border: 0; border-radius: var(--radius-lg); padding: 16px 18px; }
.dsc-prose { white-space: pre-line; max-width: 65ch; }
.dsc-telegram-link { overflow-wrap: anywhere; }
.dsc-links { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.dsc-city-list { list-style: none; padding: 0; margin: 0; columns: 2; column-gap: 24px; }
.dsc-city-list li { break-inside: avoid; padding: 4px 0; }

/* Секции detail (ТЗ §7.3/7.4): дорожная карта, пространства, связанные карточки, sticky CTA */
.dsc-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; counter-reset: step; }
.dsc-step { display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 10px; align-items: baseline; counter-increment: step; }
.dsc-step::before { content: counter(step); display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: var(--radius-full); border: 1px solid var(--border); font-size: .8rem; color: var(--text-secondary); }
.dsc-step--done::before, .dsc-step--completed::before { background: var(--success-lightest); color: var(--success-dark); border-color: transparent; }
.dsc-step__meta { display: block; color: var(--text-muted); font-size: .85rem; }
.dsc-spaces { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.dsc-space { display: grid; min-width: 0; gap: 6px; padding: 14px; border: 1px solid var(--border-light); border-radius: var(--radius-md); }
.dsc-space__meta, .dsc-space__eq { color: var(--text-muted); font-size: .85rem; }
/* Снимок занимает ширину зала; остальные доступны прокруткой и клавиатурой.
   Ссылка открывает оригинал без зависимости от JS. */
.dsc-space__photos { display: flex; min-width: 0; gap: 12px; overflow-x: auto;
  scroll-snap-type: x mandatory; margin-bottom: 8px; padding-bottom: 8px; }
.dsc-space__photo-link { display: block; flex: 0 0 92%; min-width: 0; scroll-snap-align: start; }
.dsc-space__photo-link:only-child { flex-basis: 100%; }
.dsc-space__photo-link:focus-visible { outline: 3px solid var(--primary); outline-offset: -3px; }
.dsc-space__photo { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover;
  border-radius: var(--radius-sm); background: var(--surface-2); }
/* Бронь зала (§15.3): форма раскрывается без JS через <details> */
.dsc-space > .dsc-btn, .dsc-space > .dsc-status { justify-self: start; margin-top: 6px; }
.dsc-space__book { margin-top: 6px; }
.dsc-space__book > summary { list-style: none; display: inline-flex; cursor: pointer; }
.dsc-space__book > summary::-webkit-details-marker { display: none; }
.dsc-space__book > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.dsc-space__book[open] > summary { margin-bottom: 4px; }
.dsc-space__book .dsc-form { margin-top: 8px; gap: 10px; }
.dsc-form__row { display: grid; gap: 10px; grid-template-columns: 1fr; }
@media (min-width: 560px) { .dsc-form__row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.dsc-related { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .dsc-related { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.dsc-related__item { --dsc-accent: var(--dsc-community); --dsc-tint: var(--dsc-community-tint); }
.dsc-related__item[data-kind="project"] { --dsc-accent: var(--dsc-project); --dsc-tint: var(--dsc-project-tint); }
.dsc-related__item[data-kind="place"] { --dsc-accent: var(--dsc-place); --dsc-tint: var(--dsc-place-tint); }
.dsc-related__link { display: grid; gap: 2px; padding: 12px 14px; border: 1px solid var(--border); border-left: 4px solid var(--dsc-accent); border-radius: var(--radius-md); color: inherit; text-decoration: none; background: var(--bg-primary); }
.dsc-related__link:hover { border-color: var(--dsc-accent); }
.dsc-related__link:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; }
.dsc-related__link .dsc-card__type { margin: 0; }
.dsc-related__title { font-weight: 600; }
.dsc-related__rel { color: var(--text-muted); font-size: .85rem; }
/* Sticky CTA: только на телефоне, невысокая полоса (F-11: оверлей ≪ 40% экрана). */
.dsc-sticky-actions { display: none; }
@media (max-width: 768px) {
  .dsc-sticky-actions {
    position: fixed; z-index: 30; left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    display: flex; gap: 8px;
  }
  .dsc-sticky-cta {
    display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 48px;
    flex: 1 1 0; min-width: 0; padding: 8px; text-align: center; line-height: 1.25;
    border-radius: var(--radius-md); background: var(--primary); color: var(--text-inverse, var(--white));
    text-decoration: none; font-weight: 600; box-shadow: var(--shadow-md);
  }
  .dsc-sticky-cta--analysis { background: var(--bg-primary); color: var(--primary); border: 1px solid var(--primary); }
  .dsc-sticky-cta:focus-visible { outline: 3px solid var(--primary); outline-offset: 3px; }
  .dsc-sticky-cta::after { content: "↓"; }
  .dsc-detail { padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px)); }
}

/* Формы заявок */
.dsc-form-page { max-width: 720px; }
.dsc-form-page--wide { max-width: 960px; }
.dsc-form { display: flex; flex-direction: column; gap: 16px; margin-top: 16px; }
.dsc-field { display: flex; flex-direction: column; gap: 6px; }
.dsc-field > span { font-weight: 500; }
.dsc-field input, .dsc-field select, .dsc-field textarea {
  font-size: 1rem; padding: 10px 12px; border-radius: var(--radius-md); min-height: 44px;
  border: 1px solid var(--border); background: var(--bg-primary); color: inherit;
}
.dsc-field small { color: var(--text-muted); }
.dsc-consent { border: 1px solid var(--border-light); border-radius: var(--radius-lg); padding: 12px 16px; display: flex; flex-direction: column; gap: 10px; }
.dsc-consent label { display: flex; gap: 10px; align-items: flex-start; }
.dsc-consent input { width: 20px; height: 20px; margin-top: 2px; flex: none; }

/* Мои заявки / очередь */
.dsc-app-list { list-style: none; padding: 0; margin: 16px 0; display: flex; flex-direction: column; gap: 14px; }
.dsc-app { border: 1px solid var(--border-light); border-radius: var(--radius-lg); padding: 16px 18px; }
.dsc-app__head { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.dsc-app__title { margin: 0; font-size: 1.15rem; flex: 1 1 auto; }
.dsc-app__note { background: var(--bg-secondary); padding: 8px 12px; border-radius: var(--radius-md); }
.dsc-editorial-scope { margin-top: 16px; padding: 12px 16px; border: 1px solid var(--border-light); border-radius: var(--radius-md); overflow-wrap: anywhere; }
.dsc-editorial-scope summary { cursor: pointer; min-height: 32px; font-weight: 600; }
.dsc-editorial-scope input, .dsc-editorial-scope select, .dsc-editorial-scope textarea { box-sizing: border-box; max-width: 100%; min-width: 0; width: 100%; }
.dsc-status { font-size: .8rem; padding: 4px 10px; border-radius: var(--radius-full); background: var(--bg-secondary); }
.dsc-status--approved { background: var(--success-lightest); color: var(--success-dark); }
.dsc-status--rejected { background: var(--danger-lightest); color: var(--danger-dark); }
.dsc-status--needs_changes { background: var(--warning-lightest); color: var(--warning-dark); }
.dsc-decide { display: grid; gap: 10px; margin-top: 12px; }
.dsc-decide form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.dsc-decide input[type="text"], .dsc-decide select { flex: 1 1 220px; min-height: 40px; padding: 6px 10px; border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--bg-primary); color: inherit; font-size: .95rem; }

@media (prefers-reduced-motion: no-preference) {
  .dsc-card, .dsc-intent { transition: transform .15s var(--dsc-ease), border-color .15s var(--dsc-ease); }
  .dsc-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
  .dsc-intent:hover { transform: translateY(-1px); }
  .dsc-card__cta span { transition: transform .18s var(--dsc-ease); }
  .dsc-card:hover .dsc-card__cta span { transform: translateX(3px); }
}

/* PR-M5: следить / приглашения владельца / апелляции */
.dsc-follow { margin-top: .75rem; }
.dsc-invites { margin-top: .75rem; }
.dsc-invites summary { cursor: pointer; font-weight: 600; }
.dsc-inline-form { display: inline; }
.dsc-invite-link { word-break: break-all; font-size: .85em; }
.dsc-status--appealed { background: var(--warning-lightest); color: var(--warning-dark); }
.dsc-status--draft { background: var(--bg-tertiary); color: var(--text-secondary); }
/* Доказательства владения (§15.2) */
.dsc-evidence { margin-top: 10px; padding: 10px 12px; border: 1px solid var(--border-light); border-radius: var(--radius-md); display: grid; gap: 8px; }
.dsc-evidence__title { margin: 0; font-weight: 600; }
.dsc-evidence__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.dsc-form--inline { margin-top: 4px; gap: 8px; }
.dsc-status--ev-verified { background: var(--success-lightest); color: var(--success-dark); }
.dsc-status--ev-pending { background: var(--warning-lightest); color: var(--warning-dark); }
.dsc-status--ev-failed, .dsc-status--ev-expired { background: var(--danger-lightest); color: var(--danger-dark); }
.dsc-status--overdue { background: var(--danger-lightest); color: var(--danger-dark); }
.dsc-status--rejected_final { background: var(--danger-lightest); color: var(--danger-dark); }
.dsc-check { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; }

/* ── Витрина под Калькой: своя геометрия и типографика ────────────────
   ПОВОД (09.09, прод). Владелец: «дизайн маркетплейса старый». Проверка
   браузером на ТОМ ЖЕ каскаде показала, что цвет как раз доехал
   (--primary #1F3D2B, бумажные фоны), а изменились форма и шрифт:
   Калька включена на проде и ставит `border-radius: 0 !important` на `*`
   (kalka-components.css, исключены только карты), а тело переводит на
   серифную Literata. Карточки стали квадратными, текст — серифным; для
   человека это и есть «не тот дизайн».

   Решение владельца — вариант А: публичная витрина живёт по своему
   референсу, как уже живут карты. Кальку НЕ трогаем: правка целиком
   здесь, откат — снятие этого блока.

   Механика. Правило Кальки имеет вес (0,3,0) с `!important`. Селекторы
   ниже добраны до (0,4,0) тем же приёмом, что применяет сама Калька для
   своих исключений: тремя `:not(.gd-void)` — класса `.gd-void` в проекте
   нет, он существует только как гиря. Пересечений со спиннерами Кальки
   (тоже (0,4,0)) нет: в разметке витрины нет ни одного класса со
   `spin`/`loader` — проверено грепом.

   Значения не выдуманы: это ровно те токены, которые правила выше уже
   назначают этим же элементам. Меняя радиус компонента, поменяйте и здесь —
   расхождение поймает tests/discovery/test_marketplace_cascade.py. */
.dsc-page .dsc-search:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-card:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-state:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-detail__visual:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-section--cta:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-consent:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-app:not(.gd-void):not(.gd-void):not(.gd-void) {
  border-radius: var(--radius-lg) !important;
}
.dsc-page .dsc-search__control:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-search__select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-intent:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-intent__icon:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-btn:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-sort select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-space:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-related__link:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-sticky-cta:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-app__note:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-evidence:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field input:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field textarea:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-decide input[type="text"]:not(.gd-void):not(.gd-void),
.dsc-page .dsc-decide select:not(.gd-void):not(.gd-void):not(.gd-void) {
  border-radius: var(--radius-md) !important;
}
.dsc-page .dsc-chip:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-tag:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-status:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-card__status:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-card__status:not(.gd-void):not(.gd-void):not(.gd-void)::before,
.dsc-page .dsc-step:not(.gd-void):not(.gd-void):not(.gd-void)::before {
  border-radius: var(--radius-full) !important;
}
/* Колонка фильтров на десктопе — панель с рамкой, значит и со скруглением.
   Мобильная шторка ниже перебивает это правило по специфичности (там
   участвует ещё и `:target`), поэтому у неё по-прежнему скруглены только
   верхние углы. */
.dsc-page .dsc-sheet__panel:not(.gd-void):not(.gd-void):not(.gd-void) {
  border-radius: var(--radius-lg) !important;
}
/* Нижняя шторка фильтров: скруглены только верхние углы. */
.dsc-page .dsc-sheet:target .dsc-sheet__panel:not(.gd-void):not(.gd-void) {
  border-radius: var(--radius-lg) var(--radius-lg) 0 0 !important;
}
/* Типографика витрины — гротеск. Серифом в референсе набрана ТОЛЬКО
   оболочка карты (design task 03), у Маркетплейса его нет нигде.
   `!important` не нужен: класс (0,1,0) сильнее правила на теле. */
.dsc-page {
  font-family: Inter, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
}

/* Формы витрины: гарнитура страницы, обычный регистр.
   Правило на `.dsc-page` выше формы НЕ покрывает: браузер не наследует
   типографику в input/select/button — их набирают общие компоненты через
   токены, которые Калька подменила. Отсюда `inherit` и та же лесенка
   специфичности, что у радиусов.
   Верхний регистр и разрядка — тоже её: у Кальки это язык служебных
   подписей. На кнопке «Найти» и в выборе города они читаются как чужой
   стиль, поэтому снимаются здесь и ТОЛЬКО здесь: собственные
   капитель-элементы витрины (`.dsc-eyebrow`, `.dsc-card__type`,
   `.dsc-city__label`) формами не являются и не затронуты. */
.dsc-page .dsc-search__input:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-search__select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-btn:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-sort select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field input:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field textarea:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-decide input[type="text"]:not(.gd-void):not(.gd-void),
.dsc-page .dsc-decide select:not(.gd-void):not(.gd-void):not(.gd-void) {
  font-family: inherit !important;
  text-transform: none !important;
  letter-spacing: normal !important;
}
/* Поля — 1rem: под Калькой приходит 15px, а всё, что меньше 16px, заставляет
   iOS увеличивать страницу при фокусе. Список ПОЛНЫЙ: раньше здесь стояли
   только два поля первого экрана, и замер 15.09 показал у `.dsc-field input`
   ровно те же 15px — то есть класс был починен в одном экземпляре (#31.5). */
.dsc-page .dsc-search__input:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-search__select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field input:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field textarea:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-sort select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-decide input[type="text"]:not(.gd-void):not(.gd-void),
.dsc-page .dsc-decide select:not(.gd-void):not(.gd-void):not(.gd-void) {
  font-size: 1rem !important;
}

/* ПОВЕРХНОСТЬ ФОРМ: рамка, фон, цвет, межстрочный.
   Замер 15.09 (chromium, прод-каскад — порядок листов из
   tests/discovery/test_marketplace_cascade.py) показал у полей витрины:
     .dsc-search__input — рамка 1px rgb(126,133,124), радиус 0, фон rgb(246,247,244);
     .dsc-field input   — рамка того же чужого цвета, фон чужой, межстрочный 22.5px.
   Контр-слой выше перекрывал у них ТОЛЬКО гарнитуру и регистр, поэтому
   внутри скруглённой карточки поиска сидело поле с чужой прямоугольной
   рамкой. Именно это владелец 15.09 назвал «поисковая строка в другом
   стиле». Свойства перечислены полным набором, а не по одному: перекрывать
   «то, что заметили», — верный способ вернуться сюда в третий раз. */
.dsc-page .dsc-search__input:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-search__select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field input:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-field textarea:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-sort select:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-decide input[type="text"]:not(.gd-void):not(.gd-void),
.dsc-page .dsc-decide select:not(.gd-void):not(.gd-void):not(.gd-void) {
  border: 1px solid var(--border) !important;
  background: var(--bg-primary) !important;
  color: var(--text-primary) !important;
  line-height: 1.5 !important;
}
/* Исключение — поля ВНУТРИ оболочки `.dsc-search__control`: рамку, фон и
   высоту там рисует оболочка, а поле обязано быть прозрачным, иначе выходит
   рамка в рамке. Специфичность (0,5,0) выше общего правила (0,4,0). */
.dsc-page .dsc-search__control > .dsc-search__input:not(.gd-void):not(.gd-void),
.dsc-page .dsc-search__control > .dsc-search__select:not(.gd-void):not(.gd-void) {
  border: 0 !important;
  background: transparent !important;
  appearance: none !important;
  -webkit-appearance: none !important;
}
/* Ряд поиска — одной высоты. Замер: у кнопки приходило min-height 44px от
   общего компонента, поля были 50px, и «Найти» сидела на 4px ниже соседей. */
.dsc-page .dsc-search__control:not(.gd-void):not(.gd-void):not(.gd-void),
.dsc-page .dsc-search__submit:not(.gd-void):not(.gd-void):not(.gd-void) {
  min-height: 50px !important;
}
/* Дополнение №5 §3: вход в очередь проверки для модератора — в шапке витрины. */
.dsc-auth--review { font-weight: 700; }

/* «Глубокий анализ» сообщества (static/js/discovery-community-analysis.js).
   Цвета типов графа — из общей палитры графа знаний (shared/kb-graph-palette.js,
   схема «Аврора», как у Горожанина и Атласа): JS ставит их в --sw у меток и в
   группы vis-network. Токены ниже — запасной путь, если палитра не загрузилась.
   Тип различим и без цвета — у каждого своя форма узла и подпись в легенде.
   Порядок панели: краткий вывод → разделы → граф → источники. Всё в сетке с
   minmax(0, …) и переносом слов: на 390 px нет горизонтальной прокрутки. */
.dsc-analysis {
  --dsc-graph-community: var(--dsc-community);
  --dsc-graph-person: var(--accent);
  --dsc-graph-role: var(--primary-dark);
  --dsc-graph-event: var(--warning-dark);
  --dsc-graph-meaning: var(--info);
  --dsc-graph-resource: var(--success-dark);
  --dsc-graph-place: var(--dsc-place);
  --dsc-graph-organization: var(--dsc-project);
  --dsc-graph-partner: var(--text-secondary);
  min-width: 0;
}
.dsc-analysis__ai {
  display: inline-block; margin-left: 6px; padding: 1px 8px; vertical-align: middle;
  border: 1px solid var(--border); border-radius: var(--radius-full);
  font-size: .75rem; font-weight: 700; letter-spacing: .06em; color: var(--text-secondary);
}
.dsc-analysis__status { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 24px; }
.dsc-analysis__detail { flex: 1 1 100%; font-size: .8125rem; }
.dsc-analysis__detail pre { margin: 4px 0 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.dsc-analysis__body { min-width: 0; overflow-wrap: anywhere; }
.dsc-analysis { scroll-margin-top: 16px; }
.dsc-analysis__actions { scroll-margin-bottom: 100px; }

/* Краткий вывод */
.dsc-analysis__lead {
  margin: 12px 0 14px; padding: 18px 20px; border-radius: var(--radius-lg);
  background: linear-gradient(135deg, var(--dsc-community-tint), var(--bg-primary) 70%);
  border: 1px solid var(--border-light); box-shadow: var(--shadow-sm);
}
.dsc-analysis__lead-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 6px 12px; }
.dsc-analysis__lead-head h3 {
  margin: 0; font-size: .8rem; letter-spacing: .08em; text-transform: uppercase; color: var(--dsc-accent);
}
.dsc-analysis__approval { font-size: .8125rem; font-weight: 600; color: var(--text-secondary); }
.dsc-analysis__approval--ok { color: var(--success-dark); }
.dsc-analysis__verdict { margin: 8px 0 4px; font-size: 1.125rem; line-height: 1.55; color: var(--text-primary); }
.dsc-analysis__metrics {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 140px), 1fr));
  gap: 8px; margin: 14px 0 0;
}
.dsc-analysis__metric {
  display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: 10px 12px;
  border-radius: var(--radius-md); background: var(--bg-primary); border: 1px solid var(--border-light);
}
.dsc-analysis__metric strong { font-size: 1.05rem; color: var(--text-primary); overflow-wrap: anywhere; }
.dsc-analysis__metric span { font-size: .8125rem; color: var(--text-muted); }
.dsc-analysis__note { margin: 12px 0 0; padding: 8px 12px; border-radius: var(--radius-md); font-size: .875rem; }
.dsc-analysis__note--warn { background: var(--warning-lightest); color: var(--warning-dark); border: 1px solid var(--warning); }
.dsc-analysis__feeds-title { margin: 0 0 4px; font-weight: 600; }
.dsc-analysis__feeds { margin: 0 0 6px; padding-left: 18px; }
.dsc-analysis__feeds li { margin: 2px 0; overflow-wrap: anywhere; }
.dsc-analysis__group {
  flex-basis: 100%; margin-top: 12px; padding: 10px 12px; border-radius: var(--radius-md);
  background: var(--bg-secondary); border: 1px solid var(--border-light);
}
.dsc-analysis__group-title { margin: 0 0 4px; font-size: .95rem; }
.dsc-analysis__group-status { margin: 0 0 8px; overflow-wrap: anywhere; }
.dsc-analysis__group .dsc-muted { margin: 6px 0 0; font-size: .8125rem; }
.dsc-analysis__group-link { margin: 6px 0 0; font-size: .875rem; overflow-wrap: anywhere; }
.dsc-analysis__disclaimer { margin: 10px 0 0; font-size: .8125rem; }

/* Оглавление */
.dsc-analysis__toc { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 14px; }
.dsc-analysis__toc-link {
  padding: 4px 10px; border-radius: var(--radius-full); border: 1px solid var(--border);
  background: var(--bg-primary); color: var(--text-secondary); font-size: .8125rem; text-decoration: none;
}
.dsc-analysis__toc-link:hover, .dsc-analysis__toc-link:focus-visible {
  border-color: var(--dsc-accent); color: var(--dsc-accent);
}

/* Разделы */
/* Две колонки — по ширине САМОЙ панели, а не окна: на карточке она живёт в
   основной колонке (~760 px и на 1920), где две колонки дали бы узкие
   карточки с переносом через слово. */
.dsc-analysis__body { container-type: inline-size; }
.dsc-analysis__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
@container (min-width: 900px) {
  .dsc-analysis__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dsc-analysis__card[data-section="dynamics"], .dsc-analysis__card[data-section="suggestions"] { grid-column: 1 / -1; }
}
.dsc-analysis__section { min-width: 0; padding: 12px 0; border-top: 1px solid var(--border-light); scroll-margin-top: 80px; }
.dsc-analysis__card {
  padding: 14px 16px; border: 1px solid var(--border-light); border-radius: var(--radius-lg);
  background: var(--bg-primary);
}
.dsc-analysis__section h3 { margin: 0 0 6px; font-size: 1.05rem; }
.dsc-analysis__section h4 { margin: 10px 0 4px; font-size: .95rem; }
.dsc-analysis__summary { margin: 0 0 6px; line-height: 1.55; }
.dsc-analysis__claims { margin: 6px 0 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.dsc-analysis__claim {
  margin: 0; padding: 8px 10px 8px 12px; border-left: 3px solid var(--dsc-community-tint);
  background: var(--bg-secondary); border-radius: 0 var(--radius-md) var(--radius-md) 0; overflow-wrap: anywhere;
}
.dsc-analysis__claim-text { margin: 0; }
.dsc-analysis__claim-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin-top: 6px; font-size: .8125rem; }
.dsc-analysis__conf { padding: 1px 8px; border-radius: var(--radius-full); font-weight: 600; background: var(--bg-tertiary); color: var(--text-secondary); }
.dsc-analysis__conf--high { background: var(--success-lightest); color: var(--success-dark); }
.dsc-analysis__conf--medium { background: var(--primary-lightest); color: var(--primary-dark); }
.dsc-analysis__conf--low { background: var(--warning-lightest); color: var(--warning-dark); }
.dsc-analysis__ref {
  padding: 1px 8px; border-radius: var(--radius-full); border: 1px solid var(--border);
  color: var(--text-secondary); text-decoration: none; background: var(--bg-primary); max-width: 100%;
}
a.dsc-analysis__ref:hover, a.dsc-analysis__ref:focus-visible { border-color: var(--dsc-accent); color: var(--dsc-accent); }

/* Ритм ленты: столбики по неделям; неделя вне выборки — штриховка, не ноль */
.dsc-analysis__rhythm { margin: 4px 0 10px; }
.dsc-analysis__bars {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); align-items: end;
  gap: 3px; height: 72px; padding: 6px 0 0; border-bottom: 1px solid var(--border);
}
.dsc-analysis__bar {
  display: block; height: var(--h, 2%); min-height: 2px; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  background: linear-gradient(180deg, var(--dsc-community), var(--primary-dark));
}
.dsc-analysis__bar--gap {
  background: repeating-linear-gradient(45deg, var(--border-light) 0 4px, transparent 4px 8px);
}
.dsc-analysis__axis { display: flex; justify-content: space-between; gap: 8px; margin-top: 4px; font-size: .75rem; color: var(--text-muted); }
.dsc-analysis__rhythm figcaption { margin-top: 4px; font-size: .8125rem; }

/* Граф — тот же визуальный язык, что Атлас знаний: «бумага» страницы с
   лёгкой точечной сеткой; цвета узлов под этот фон выбирает общая палитра
   (светлая «Бумага» / тёмная «Аврора» — по фактической яркости фона). */
.dsc-analysis__graph-box { margin-top: 16px; }
.dsc-analysis__graph-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.dsc-analysis__graph-head h3 { margin: 0; }
.dsc-analysis__graph-hint { margin: 6px 0 0; font-size: .8125rem; }
.dsc-analysis__toggle { display: flex; gap: 6px; }
.dsc-analysis__toggle .dsc-btn[aria-pressed="true"] {
  background: var(--dsc-tint); border-color: var(--dsc-accent); color: var(--dsc-accent);
}
.dsc-analysis__legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 8px 0 10px; padding: 0; list-style: none; }
.dsc-analysis__legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: .85rem; }
.dsc-analysis__swatch {
  flex: 0 0 auto; width: 12px; height: 12px; border-radius: var(--radius-full);
  background: var(--sw, var(--text-muted)); box-shadow: 0 0 0 1px rgba(0, 0, 0, .15);
}
.dsc-analysis__swatch--community { background: var(--sw, var(--dsc-graph-community)); }
.dsc-analysis__swatch--person { background: var(--sw, var(--dsc-graph-person)); }
.dsc-analysis__swatch--role { background: var(--sw, var(--dsc-graph-role)); }
.dsc-analysis__swatch--event { background: var(--sw, var(--dsc-graph-event)); }
.dsc-analysis__swatch--meaning { background: transparent; border: 2px dashed var(--sw, var(--dsc-graph-meaning)); box-shadow: none; }
.dsc-analysis__swatch--resource { background: var(--sw, var(--dsc-graph-resource)); }
.dsc-analysis__swatch--place { background: var(--sw, var(--dsc-graph-place)); }
.dsc-analysis__swatch--organization { background: var(--sw, var(--dsc-graph-organization)); }
.dsc-analysis__swatch--partner { background: var(--sw, var(--dsc-graph-partner)); }
.dsc-analysis__graph {
  width: 100%; height: min(66vh, 560px);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background-color: var(--bg-primary);
  background-image: radial-gradient(circle at 1px 1px, color-mix(in srgb, var(--text-primary) 8%, transparent) 1px, transparent 0);
  background-size: 22px 22px;
}
.dsc-analysis__graph + .dsc-analysis__list + .dsc-analysis__legend { margin-top: 10px; }
.dsc-analysis__list-head { display: flex; align-items: center; gap: 8px; }
.dsc-analysis__nodes, .dsc-analysis__edges { margin: 6px 0; padding-left: 20px; }
.dsc-analysis__nodes > li { margin: 4px 0; }
.dsc-analysis__edges { font-size: .9rem; color: var(--text-secondary); }

/* Источники */
.dsc-analysis__sources-box { margin-top: 16px; }
.dsc-analysis__posts summary { cursor: pointer; font-weight: 600; }
.dsc-analysis__post-list { margin: 8px 0 0; padding-left: 22px; display: grid; gap: 8px; }
.dsc-analysis__post-head { font-size: .8125rem; font-weight: 600; }
.dsc-analysis__post-text { margin: 2px 0 0; font-size: .875rem; color: var(--text-secondary); overflow-wrap: anywhere; }
.dsc-analysis__sources, .dsc-analysis__ethics { margin: 10px 0 0; font-size: .875rem; overflow-wrap: anywhere; }
.dsc-analysis__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
/* «Куда расти»: компактные рекомендации + мини-карта связей (discovery-growth.js).
   Цвета — только токены витрины: место — --dsc-place, сообщество —
   --dsc-community; обе темы берут их из variables.css, своих цветов нет. */
.dsc-growth { margin-top: 16px; }
.dsc-growth__profile, .dsc-growth__foot { margin: 4px 0 0; font-size: .8125rem; color: var(--text-muted); }
.dsc-growth__block { margin-top: 14px; }
.dsc-growth__block h4 { margin: 0 0 8px; font-size: .95rem; }
.dsc-growth__list { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 760px) { .dsc-growth__list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.dsc-rec {
  display: flex; gap: 10px; align-items: flex-start; min-width: 0; padding: 8px;
  border: 1px solid var(--border-light); border-radius: var(--radius-md);
  background: var(--bg-primary); transition: border-color var(--dsc-motion-fast) var(--dsc-ease),
    box-shadow var(--dsc-motion-fast) var(--dsc-ease);
}
.dsc-rec.is-hot { border-color: var(--dsc-community); box-shadow: 0 0 0 2px var(--dsc-community-tint); }
.dsc-rec[data-kind="place"].is-hot { border-color: var(--dsc-place); box-shadow: 0 0 0 2px var(--dsc-place-tint); }
.dsc-rec__media {
  position: relative; flex: 0 0 56px; width: 56px; height: 56px; overflow: hidden;
  border-radius: var(--radius-md); background: var(--dsc-community-tint); display: grid; place-items: center;
}
.dsc-rec[data-kind="place"] .dsc-rec__media { background: var(--dsc-place-tint); }
.dsc-rec__letter { font-weight: 700; font-size: 1.25rem; color: var(--dsc-community); }
.dsc-rec[data-kind="place"] .dsc-rec__letter { color: var(--dsc-place); }
.dsc-rec__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.dsc-rec__body { flex: 1 1 auto; min-width: 0; }
.dsc-rec__title {
  display: block; font-weight: 600; font-size: .9rem; line-height: 1.25; color: var(--text-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
a.dsc-rec__title:hover { text-decoration: underline; }
.dsc-rec__meta, .dsc-rec__why { margin: 1px 0 0; font-size: .78rem; line-height: 1.3; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dsc-rec__why { color: var(--text-secondary); }
.dsc-rec__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin-top: 6px; }
.dsc-rec__actions .dsc-btn--sm { padding: 2px 8px; font-size: .78rem; min-height: 28px; }
.dsc-rec__alt { font-size: .75rem; color: var(--text-secondary); }
.dsc-rec__status { margin: 4px 0 0; font-size: .75rem; color: var(--success-dark, var(--text-secondary)); }
.dsc-rec__status:empty { display: none; }
.dsc-rec__status--muted { color: var(--text-muted); }
.dsc-rec__compose { margin-top: 8px; display: grid; gap: 6px; }
.dsc-rec__label { font-size: .78rem; font-weight: 600; }
.dsc-rec__text { width: 100%; box-sizing: border-box; font: inherit; font-size: .85rem; padding: 6px 8px;
  border: 1px solid var(--border-light); border-radius: var(--radius-md); background: var(--bg-primary); color: var(--text-primary); }
.dsc-rec__hint { margin: 0; font-size: .75rem; color: var(--text-muted); }
.dsc-rec__error { margin: 0; font-size: .78rem; color: var(--danger, var(--text-primary)); }
.dsc-rec__error:empty { display: none; }
.dsc-rec__row { display: flex; gap: 6px; }

/* Мини-карта: подложка MapLibre + свой SVG-слой стрелок поверх. */
.dsc-gmap { margin-top: 10px; }
.dsc-gmap__stage { position: relative; height: 260px; border-radius: var(--radius-lg); overflow: hidden;
  border: 1px solid var(--border-light); background: var(--bg-secondary); }
/* Специфичность выше `.maplibregl-map { position: relative }` из
   maplibre-gl.css, который подгружается позже: иначе холст терял высоту
   и точки ложились за нижний край. */
.dsc-gmap__stage > .dsc-gmap__canvas, .dsc-gmap__stage > .dsc-gmap__layer {
  position: absolute; inset: 0; width: 100%; height: 100%; }
.dsc-gmap__layer { pointer-events: none; }
.dsc-gmap__svg { display: block; overflow: visible; }
.dsc-gmap__arc { fill: none; stroke-width: 2.25; stroke-linecap: round; opacity: .85; }
.dsc-gmap__link--place .dsc-gmap__arc { stroke: var(--dsc-place); }
.dsc-gmap__link--partner .dsc-gmap__arc { stroke: var(--dsc-community); stroke-dasharray: 6 4; }
.dsc-gmap__head--place { fill: var(--dsc-place); }
.dsc-gmap__head--partner { fill: var(--dsc-community); }
.dsc-gmap__hit { fill: none; stroke: transparent; stroke-width: 16; pointer-events: stroke; cursor: pointer; }
.dsc-gmap__link .dsc-gmap__pt { pointer-events: all; cursor: pointer; }
.dsc-gmap__link.is-hot .dsc-gmap__arc { stroke-width: 4; opacity: 1; }
.dsc-gmap__pt { stroke: var(--bg-primary); stroke-width: 2; }
.dsc-gmap__pt--place { fill: var(--dsc-place); }
.dsc-gmap__pt--partner { fill: var(--dsc-community); }
.dsc-gmap__pt--home { fill: var(--dsc-community); }
.dsc-gmap__halo { fill: var(--dsc-community-tint); opacity: .85; }
.dsc-gmap__label { font-size: 11px; font-weight: 600; fill: var(--text-primary); paint-order: stroke;
  stroke: var(--bg-primary); stroke-width: 3px; stroke-linejoin: round; }
.dsc-gmap__legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 6px 0 0; font-size: .75rem; color: var(--text-muted); }
.dsc-gmap__key::before { content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 5px;
  border-radius: var(--radius-full); vertical-align: -1px; background: var(--dsc-community); }
.dsc-gmap__key--place::before { background: var(--dsc-place); }
.dsc-gmap__key--partner::before { width: 14px; height: 0; border-radius: 0; background: none;
  border-top: 2px dashed var(--dsc-community); vertical-align: 3px; }
.dsc-gmap__gap { margin: 4px 0 0; font-size: .75rem; color: var(--text-muted); }
.dsc-gmap__fallback { position: absolute; inset: 0; display: grid; place-content: center; gap: 8px; padding: 16px; text-align: center; }
@media (max-width: 480px) {
  .dsc-analysis__actions .dsc-btn { flex: 1 1 100%; }
  .dsc-analysis__lead { padding: 14px; }
  .dsc-analysis__verdict { font-size: 1.02rem; }
  .dsc-analysis__card { padding: 12px; }
  .dsc-analysis__bars { gap: 2px; }
  .dsc-gmap__stage { height: 220px; }
}

/* Видео-истории карточки (discovery-stories.js): кружки вверху карточки и
   плеер. Кольцо — цвета вида карточки (токены витрины), сцена плеера — тёмная
   в обеих темах, как у любого видеоплеера (--gray-900 из variables.css). */
.dsc-stories { margin: 4px 0 18px; }
.dsc-stories__ring { list-style: none; margin: 0; padding: 4px 2px 6px; display: flex; gap: 14px;
  overflow-x: auto; scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch; }
.dsc-story { display: grid; justify-items: center; gap: 4px; width: 76px; padding: 0; border: 0;
  background: none; color: var(--text-primary); cursor: pointer; scroll-snap-align: start; font: inherit; }
.dsc-story__ring { display: grid; place-items: center; width: 68px; height: 68px; border-radius: var(--radius-full);
  background: conic-gradient(from 210deg, var(--dsc-community), var(--dsc-place), var(--dsc-community)); }
.dsc-detail[data-kind="place"] .dsc-story__ring { background: conic-gradient(from 210deg, var(--dsc-place), var(--dsc-community), var(--dsc-place)); }
.dsc-story__face { display: grid; place-items: center; width: 62px; height: 62px; border-radius: var(--radius-full); overflow: hidden;
  background: var(--dsc-tint); border: 2px solid var(--bg-primary); }
.dsc-story__face img { width: 100%; height: 100%; object-fit: cover; }
.dsc-story__letter, .dsc-story__plus { font-weight: 700; font-size: 1.35rem; color: var(--dsc-accent); }
.dsc-story__cap { max-width: 76px; font-size: .72rem; line-height: 1.2; text-align: center; color: var(--text-secondary);
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.dsc-story--hidden .dsc-story__ring { background: var(--border-light); }
.dsc-story--hidden .dsc-story__face { opacity: .55; }
.dsc-story--add .dsc-story__ring { background: none; border: 2px dashed var(--border); }
.dsc-story:focus-visible { outline: 3px solid var(--primary); outline-offset: 3px; border-radius: var(--radius-lg); }

.dsc-sv-open, .dsc-sv-open body { overflow: hidden; }
.dsc-sv { position: fixed; inset: 0; z-index: var(--z-modal, 2600); display: grid; place-items: center;
  background: var(--bg-overlay); }
.dsc-sv__frame { position: relative; width: 100vw; height: 100dvh; background: var(--gray-900); color: var(--white);
  display: grid; grid-template-rows: auto auto 1fr auto; overflow: hidden; }
@media (min-width: 769px) {
  .dsc-sv__frame { width: auto; height: min(88vh, 860px); aspect-ratio: 9 / 16; border-radius: var(--radius-lg); }
}
.dsc-sv__bars { display: flex; gap: 4px; padding: 10px 12px 0; }
.dsc-sv__bar { flex: 1; height: 3px; border-radius: var(--radius-full); overflow: hidden; background: color-mix(in srgb, var(--white) 30%, transparent); }
.dsc-sv__fill { display: block; height: 100%; width: 0; background: var(--white); }
.dsc-sv__top { display: flex; align-items: flex-start; gap: 8px; padding: 8px 12px; }
.dsc-sv__text { flex: 1; min-width: 0; }
.dsc-sv__cap { margin: 0; font-weight: 600; font-size: .95rem; overflow-wrap: anywhere; }
.dsc-sv__meta { margin: 2px 0 0; font-size: .75rem; opacity: .8; }
.dsc-sv__close { flex: 0 0 auto; width: 44px; height: 44px; border: 0; border-radius: var(--radius-full); font-size: 1.6rem; line-height: 1;
  background: color-mix(in srgb, var(--white) 16%, transparent); color: var(--white); cursor: pointer; }
.dsc-sv__media { position: relative; min-height: 0; display: grid; place-items: center; touch-action: pan-y; }
.dsc-sv__video, .dsc-sv__embed { width: 100%; height: 100%; object-fit: contain; border: 0; background: var(--gray-900); }
.dsc-sv__link { display: grid; gap: 12px; justify-items: center; padding: 24px; text-align: center; }
.dsc-sv__note { margin: 0; font-size: .9rem; opacity: .9; }
.dsc-sv__nav { position: absolute; top: 50%; transform: translateY(-50%); width: 44px; height: 64px; border: 0;
  font-size: 2rem; color: var(--white); background: color-mix(in srgb, var(--gray-900) 35%, transparent); cursor: pointer; }
.dsc-sv__nav--prev { left: 0; border-radius: 0 var(--radius-md) var(--radius-md) 0; }
.dsc-sv__nav--next { right: 0; border-radius: var(--radius-md) 0 0 var(--radius-md); }
.dsc-sv__nav:disabled { opacity: .3; cursor: default; }
.dsc-sv__tools { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; padding: 10px 12px 14px; }
.dsc-sv__tools:empty { display: none; }
.dsc-sv__tool { min-height: 44px; padding: 6px 12px; border-radius: var(--radius-full); border: 1px solid color-mix(in srgb, var(--white) 40%, transparent);
  background: transparent; color: var(--white); font: inherit; font-size: .85rem; cursor: pointer; }
.dsc-sv__tool--danger { border-color: var(--danger, var(--white)); }
.dsc-sv__close:focus-visible, .dsc-sv__nav:focus-visible, .dsc-sv__tool:focus-visible { outline: 3px solid var(--white); outline-offset: 2px; }
.dsc-sv--form .dsc-sv__form { width: min(520px, calc(100vw - 32px)); max-height: 92dvh; overflow: auto; box-sizing: border-box;
  padding: 18px; border-radius: var(--radius-lg); background: var(--bg-primary); color: var(--text-primary); display: grid; gap: 10px;
  grid-template-columns: minmax(0, 1fr); }
.dsc-sv__form .dsc-field input { width: 100%; min-width: 0; box-sizing: border-box; }
.dsc-sv__form-title { margin: 0; font-size: 1.15rem; }
.dsc-sv__mode { border: 0; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 16px; }
.dsc-sv__mode legend { font-weight: 600; font-size: .85rem; margin-bottom: 4px; }
.dsc-sv__consent { font-size: .875rem; }
.dsc-sv__hint { margin: 0; font-size: .8rem; color: var(--text-muted); }
.dsc-sv__error { margin: 0; font-size: .85rem; color: var(--danger, var(--text-primary)); }
.dsc-sv__error:empty { display: none; }
.dsc-sv__row { display: flex; gap: 8px; flex-wrap: wrap; }
@media (max-width: 600px) {
  .dsc-sv__row > .dsc-btn {
    flex: 1 1 auto; min-width: 0; padding: 8px 12px;
    font-size: var(--font-size-sm, .875rem); overflow-wrap: anywhere;
  }
}

