/* Дополнительные стили поверх Tailwind.

   Основная дизайн-система — в base.html (CSS-переменные --bg, --ink,
   --accent, --tone-* и компоненты .btn-*, .club-card, .category-tile,
   .chip, .hero-cta, .radio-card). Здесь — только узкие правки и
   стилизация Яндекс.Карт. */

/* ── Global :focus-visible (a11y) ───────────────────────────────────────
   Раньше отсутствовало — клавиатурные пользователи не видели фокуса.
   .kw-input/hero-search input имеют свой box-shadow focus (в base.html);
   эти правила его не перебивают (он работает на :focus, не :focus-visible).
   :focus без :focus-visible (т.е. mouse-click) — outline убираем, чтобы не
   плодить лишнюю обводку при кликах. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--r-sm);
}
button:focus:not(:focus-visible),
a:focus:not(:focus-visible),
[role="button"]:focus:not(:focus-visible),
summary:focus:not(:focus-visible) {
    outline: none;
}
/* Inputs/textarea: focus подсвечиваем box-shadow в .kw-input, а
   focus-visible — стандартным outline. У hero-search input убран outline
   на :focus, чтобы рамка-обёртка отвечала за визуал; добавляем
   focus-visible-обводку поверх обёртки. */
.hero-search:focus-within,
.kw-distance-hero__form:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

/* Ссылки в теле статьи (страницы /about, /for-owners) */
.prose a {
    color: var(--accent);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.prose a:hover {
    color: var(--accent-hover);
}
.prose p {
    margin-bottom: 1em;
    line-height: 1.6;
}

/* Яндекс.Карты v3: маркер и popup. Через CSS-переменные, чтобы менять цвет
   маркера сразу для всей карты при смене темы. */
.ymap-marker {
    position: relative;
    cursor: pointer;
    width: 0;
    height: 0;
    outline: none;
}
.ymap-marker:focus-visible .ymap-marker__pin {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}
.ymap-marker__pin {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    /* По умолчанию accent (mixed). Tone-модификаторы ниже переопределяют
       background через --pin-bg, ставя её в соответствующий tone-deep
       (см. base.html). */
    background: var(--pin-bg, var(--accent));
    border: 3px solid var(--surface);
    box-shadow: 0 2px 6px rgba(21,22,28,0.25);
    transform: translate(-50%, -100%);
    transition: transform 120ms ease;
}
.ymap-marker:hover .ymap-marker__pin,
.ymap-marker:focus-visible .ymap-marker__pin {
    transform: translate(-50%, -100%) scale(1.12);
}

/* Раскраска маркеров по interest-тону клуба (Vasya order #40, 2026-05-15).
   Цвета — те же CSS-vars что у карточек кружков (base.html), чтобы
   карта и список визуально читались как одно целое. mixed = accent
   (фолбэк, если у клуба нет распознаваемого interest-тега). */
.ymap-marker__pin--sport  { --pin-bg: var(--tone-sport-deep); }
.ymap-marker__pin--art    { --pin-bg: var(--tone-art-deep); }
.ymap-marker__pin--sci    { --pin-bg: var(--tone-sci-deep); }
.ymap-marker__pin--music  { --pin-bg: var(--tone-music-deep); }
.ymap-marker__pin--dance  { --pin-bg: var(--tone-dance-deep); }
.ymap-marker__pin--lang   { --pin-bg: var(--tone-lang-deep); }
.ymap-marker__pin--school { --pin-bg: var(--tone-school-deep); }
.ymap-marker__pin--warm   { --pin-bg: var(--tone-warm-deep); }
.ymap-marker__pin--tiny   { --pin-bg: var(--tone-tiny-deep); }
.ymap-marker__pin--mixed  { --pin-bg: var(--accent); }

/* Кластер маркеров (Yandex Maps Clusterer). */
.ymap-cluster {
    min-width: 40px;
    height: 40px;
    padding: 0 10px;
    border-radius: 999px;
    background: var(--accent);
    color: #fff;
    font-weight: 700;
    font-size: 13px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 3px solid var(--surface);
    box-shadow: 0 2px 8px rgba(21,22,28,0.30);
    cursor: pointer;
    transform: translate(-50%, -50%);
}

/* Кастомный popup над маркером. */
.ymap-popup {
    position: relative;
    min-width: 220px;
    max-width: 280px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-lg);
    padding: 12px 32px 12px 14px;
    font-size: 14px;
    line-height: 1.5;
    transform: translate(-50%, calc(-100% - 36px));
}
.ymap-popup__title {
    font-weight: 700;
    color: var(--ink);
    margin-bottom: 4px;
}
.ymap-popup__meta {
    color: var(--ink-muted);
    margin-bottom: 8px;
    font-size: 13px;
}
.ymap-popup__link {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}
.ymap-popup__link:hover {
    text-decoration: underline;
}
.ymap-popup__close {
    position: absolute;
    top: 4px;
    right: 8px;
    background: transparent;
    border: 0;
    font-size: 18px;
    line-height: 1;
    color: var(--ink-soft);
    cursor: pointer;
    padding: 4px 6px;
}
.ymap-popup__close:hover {
    color: var(--ink);
}

/* Заглушка при отсутствии API-ключа карт. */
.ymap-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--surface-muted);
    color: var(--ink-muted);
    text-align: center;
    padding: 20px;
    font-size: 14px;
    border-radius: var(--r-lg);
}

/* Лента chip-ов горизонтально-скроллящаяся. На мобилке — без полосы скролла. */
.chips-row {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    padding: 4px 4px 8px;
    scroll-behavior: smooth;
    scrollbar-width: none;
}
.chips-row::-webkit-scrollbar { display: none; }

/* Кастомные чекбоксы (фильтры, ассистент). Минимально, без внешних либ. */
input[type="checkbox"].kw-check {
    appearance: none;
    -webkit-appearance: none;
    width: 18px; height: 18px;
    border: 2px solid var(--line-deep);
    border-radius: 4px;
    background: var(--surface);
    cursor: pointer;
    position: relative;
    flex-shrink: 0;
    transition: background 100ms ease, border-color 100ms ease;
}
input[type="checkbox"].kw-check:checked {
    background: var(--accent);
    border-color: var(--accent);
}
input[type="checkbox"].kw-check:checked::after {
    content: "";
    position: absolute;
    top: 1px; left: 5px;
    width: 4px; height: 8px;
    border: solid var(--accent-ink);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
input[type="checkbox"].kw-check:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Collapsible-секция фильтров */
.filter-group {
    border-bottom: 1px solid var(--line);
    padding: 14px 0;
}
.filter-group:last-child { border-bottom: 0; }
.filter-group summary {
    list-style: none;
    cursor: pointer;
    font-weight: 700;
    font-size: 14px;
    color: var(--ink);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 4px 0;
}
.filter-group summary::-webkit-details-marker { display: none; }
.filter-group summary::after {
    content: "+";
    font-weight: 600;
    color: var(--ink-soft);
    transition: transform 150ms ease;
}
.filter-group[open] summary::after {
    content: "–";
}
.filter-group__body {
    margin-top: 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* ── Distance hero-banner (home + search) ─────────────────────────────── */
.kw-distance-hero {
    position: relative;
    display: grid;
    grid-template-columns: 1fr;
    gap: 24px;
    background: linear-gradient(135deg,
        var(--tone-art-bg) 0%,
        var(--tone-sci-bg) 100%);
    border: 1px solid var(--line);
    border-radius: 16px;
    padding: clamp(20px, 3vw, 32px);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}
@media (min-width: 768px) {
    .kw-distance-hero {
        grid-template-columns: 1fr auto;
        align-items: center;
        padding: 32px 36px;
    }
    .kw-distance-hero--compact {
        grid-template-columns: 1fr;
        padding: 24px 28px;
    }
}
.kw-distance-hero__title {
    font-weight: 800;
    font-size: clamp(22px, 2.6vw, 32px);
    line-height: 1.15;
    color: var(--ink);
    margin: 0;
}
.kw-distance-hero__sub {
    margin-top: 10px;
    font-size: 15px;
    line-height: 1.5;
    color: var(--ink-muted);
    max-width: 560px;
}
.kw-distance-hero__form {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 18px;
    background: var(--surface);
    border-radius: var(--r-lg);
    padding: 8px;
    box-shadow: var(--shadow-sm);
    border: 1px solid var(--line);
    max-width: 640px;
}
.kw-distance-hero__form input[type="text"] {
    flex: 1 1 240px;
    min-width: 0;
    border: 0;
    background: transparent;
    padding: 12px 14px;
    font: inherit;
    font-size: 15px;
    color: var(--ink);
    min-height: 52px;
}
.kw-distance-hero__form input[type="text"]:focus { outline: none; }
.kw-distance-hero__form input[type="text"]::placeholder { color: var(--ink-soft); }
.kw-distance-hero__hint {
    margin-top: 10px;
    font-size: 12px;
    color: var(--ink-muted);
}
.kw-distance-hero__deco {
    position: relative;
    width: 160px;
    height: 160px;
    display: none;
}
@media (min-width: 768px) {
    .kw-distance-hero__deco { display: block; }
}
.kw-distance-hero__pin {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-size: 64px;
    z-index: 2;
    filter: drop-shadow(0 4px 8px rgba(21,22,28,0.18));
}
.kw-distance-hero__rings {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
}
.kw-distance-hero__rings span {
    position: absolute;
    border: 2px solid var(--accent);
    border-radius: 50%;
    opacity: 0.35;
    animation: kw-distance-ring 2.8s ease-out infinite;
}
.kw-distance-hero__rings span:nth-child(1) { width: 80px;  height: 80px;  animation-delay: 0s; }
.kw-distance-hero__rings span:nth-child(2) { width: 80px;  height: 80px;  animation-delay: 0.9s; }
.kw-distance-hero__rings span:nth-child(3) { width: 80px;  height: 80px;  animation-delay: 1.8s; }
@keyframes kw-distance-ring {
    0%   { transform: scale(0.5); opacity: 0.6; }
    100% { transform: scale(2.2); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .kw-distance-hero__rings span { animation: none; }
}

.kw-distance-hero__sliders {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
    max-width: 640px;
}
@media (min-width: 640px) {
    .kw-distance-hero__sliders {
        grid-template-columns: repeat(3, 1fr);
        gap: 14px;
    }
}
.kw-distance-hero__slider {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 10px 12px;
    font-size: 12.5px;
    color: var(--ink);
    display: block;
}
.kw-distance-hero__slider span { display: block; margin-bottom: 6px; }
.kw-distance-hero__slider strong { font-weight: 700; }
.kw-distance-hero__slider em { font-style: normal; font-weight: 700; color: var(--accent-700); }
.kw-distance-hero__slider input[type="range"] {
    width: 100%;
    accent-color: var(--accent);
}
.kw-distance-hero__slider input[type="range"][disabled] { opacity: 0.5; cursor: not-allowed; }
.kw-distance-hero__sliders + .kw-distance-hero__hint { grid-column: 1 / -1; }

/* ── «Адрес сохранён» banner ─────────────────────────────────────────── */
.kw-addr-pill {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 8px 14px 8px 12px;
    background: var(--accent-50);
    color: var(--accent-700);
    border: 1px solid var(--accent);
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    max-width: 100%;
}
.kw-addr-pill__icon { font-size: 14px; }
.kw-addr-pill__text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 360px;
}
.kw-addr-pill__action {
    background: transparent;
    border: 0;
    color: var(--accent-700);
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
    padding: 0 2px;
}

/* ── Onboarding tooltip ─────────────────────────────────────────────── */
.kw-onboarding {
    position: relative;
    margin-top: 12px;
    background: var(--ink);
    color: var(--surface);
    border-radius: 12px;
    padding: 14px 16px;
    font-size: 13.5px;
    line-height: 1.4;
    max-width: 520px;
    box-shadow: var(--shadow-md);
    display: flex;
    align-items: flex-start;
    gap: 12px;
}
.kw-onboarding::before {
    content: "";
    position: absolute;
    top: -8px;
    left: 32px;
    width: 14px;
    height: 14px;
    background: var(--ink);
    transform: rotate(45deg);
}
.kw-onboarding__text { flex: 1; min-width: 0; }
.kw-onboarding__title { font-weight: 700; margin-bottom: 2px; }
.kw-onboarding__dismiss {
    background: var(--surface);
    color: var(--ink);
    border: 0;
    border-radius: 8px;
    padding: 6px 12px;
    font-weight: 600;
    font-size: 12.5px;
    cursor: pointer;
    flex-shrink: 0;
}
.kw-onboarding__dismiss:hover { background: var(--surface-muted); }

/* ── Club detail bits (recruiting / quality / promo) ─────────────────────
   Раньше эти классы существовали только в inline-style на club_detail.html.
   Вынесены в CSS для консистентности (а inline-style оставлен как fallback
   для старых кэшированных HTML). */
.kw-recruiting-pin {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px;
    border-radius: var(--r-full);
    font-size: 13px;
    font-weight: 600;
    background: var(--accent);
    color: var(--accent-ink, #fff);
}
.kw-quality-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px;
    border-radius: var(--r-full);
    font-size: 13px;
    font-weight: 600;
    background: var(--tone-bg, var(--accent-soft));
    color: var(--tone-ink, var(--accent-700));
}
.kw-promo-code {
    font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace;
    font-size: 18px;
    letter-spacing: 0.05em;
    color: var(--ink);
    background: var(--tone-music-bg);
    padding: 2px 8px;
    border-radius: 6px;
}

/* Старый алиас на случай, если где-то остались ссылки на .category-card */
.category-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: 16px;
    min-height: 84px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    transition: transform 150ms ease, box-shadow 150ms ease;
}
.category-card:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-1px);
}

/* ---------------------------------------------------------------------------
   Trust-as-content (sprint 2-C, P0 creative-deputy 2026-05-14).
   Блок «Почему мы уверены» в верху aside на /club/<id>. Тон headline
   акцентируется по band: gold (тёплый), silver (нейтральный), bronze
   (приглушённый). Pastel-cool — переиспользуем существующие tone-vars.
--------------------------------------------------------------------------- */
.trust-block {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 14px 14px 12px;
    margin-bottom: 16px;
    border-radius: var(--r-md);
    background: var(--surface);
    border: 1px solid var(--line);
    border-left-width: 4px;
}

.trust-block__head {
    display: flex;
    align-items: center;
    gap: 8px;
}

.trust-block__band-pin {
    display: inline-block;
    padding: 2px 8px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border-radius: var(--r-full, 999px);
    background: var(--accent-soft);
    color: var(--ink);
}

.trust-block__title {
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.trust-block__headline {
    margin: 2px 0 0;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--ink);
}

.trust-block__subtitle {
    margin: 0;
    font-size: 13px;
    line-height: 1.35;
    color: var(--ink-muted);
}

.trust-block__evidence {
    list-style: none;
    margin: 6px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.trust-block__evidence-item {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 13px;
    line-height: 1.35;
    color: var(--ink);
}

.trust-block__evidence-icon {
    flex: 0 0 16px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--accent);
    margin-top: 1px;
}

.trust-block__evidence-text {
    flex: 1 1 auto;
}

/* Тоны по band. Через band-* алиасы (объявлены в base.html), сами
   алиасы пока указывают на tone-music/tone-sci/tone-school — но через
   слой алиасов, чтобы при будущем рестайлинге band-семантики не
   приходилось менять каждый стилизатор и не съезжали тоны категорий. */
.trust-block.trust-band-gold {
    background: var(--band-gold-bg);
    border-left-color: var(--band-gold-ink);
}
.trust-block.trust-band-gold .trust-block__band-pin {
    background: var(--band-gold-deep);
    color: var(--band-gold-ink);
}
.trust-block.trust-band-gold .trust-block__evidence-icon {
    color: var(--band-gold-ink);
}

.trust-block.trust-band-silver {
    background: var(--band-silver-bg);
    border-left-color: var(--band-silver-ink);
}
.trust-block.trust-band-silver .trust-block__band-pin {
    background: var(--band-silver-deep);
    color: var(--band-silver-ink);
}
.trust-block.trust-band-silver .trust-block__evidence-icon {
    color: var(--band-silver-ink);
}

.trust-block.trust-band-bronze {
    background: var(--band-bronze-bg);
    border-left-color: var(--band-bronze-ink);
}
.trust-block.trust-band-bronze .trust-block__band-pin {
    background: var(--band-bronze-deep);
    color: var(--band-bronze-ink);
}
.trust-block.trust-band-bronze .trust-block__evidence-icon {
    color: var(--band-bronze-ink);
}

/* ──────────────────────────────────────────────────────────────────────────
   Conversational hero (Sprint 2). Главная: один textarea + чипы + карта.

   .kw-hero-conv        — внешняя обёртка секции; задаёт max-width и spacing.
   .kw-freetext         — большая form-обёртка вокруг textarea и кнопки.
   .kw-freetext-examples — горизонтальная полоска чипов-примеров.
   .kw-hero-conv__map   — карточка-обёртка под Яндекс.Карту (480-560px).
   .kw-trust-strip      — узкая trust-полоска под картой (3 элемента).
────────────────────────────────────────────────────────────────────────── */

.kw-hero-conv {
    max-width: 880px;
    margin: 0 auto;
}
.kw-hero-conv__head {
    max-width: 720px;
}

/* Textarea-обёртка. Грид: textarea на всю ширину, кнопка справа на десктопе,
   снизу на мобильнике. */
.kw-freetext {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto auto;
    gap: 12px 14px;
    align-items: stretch;
    padding: 14px;
    background: var(--surface);
    border: 1.5px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    transition: border-color 150ms ease, box-shadow 150ms ease;
}
.kw-freetext:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.kw-freetext textarea {
    grid-column: 1 / 2;
    grid-row: 1 / 2;
    min-height: 64px;
    width: 100%;
    padding: 10px 12px;
    border: 0;
    border-radius: var(--r-md);
    background: transparent;
    color: var(--ink);
    font-family: inherit;
    font-size: 18px;
    line-height: 1.5;
    resize: vertical;
}
.kw-freetext textarea:focus { outline: none; }
.kw-freetext textarea::placeholder { color: var(--ink-soft); }

.kw-freetext__btn {
    grid-column: 2 / 3;
    grid-row: 1 / 2;
    min-height: 56px;
    height: auto;
    padding: 0 22px;
    align-self: stretch;
}

.kw-freetext__hint {
    grid-column: 1 / -1;
    grid-row: 2 / 3;
    font-size: 12px;
    color: var(--ink-soft);
    padding: 0 2px;
}

.kw-freetext__error {
    grid-column: 1 / -1;
    grid-row: 3 / 4;
    font-size: 13px;
    color: var(--danger, #c0392b);
    background: var(--danger-soft, #fdecea);
    padding: 8px 10px;
    border-radius: var(--r-sm);
}

@media (max-width: 640px) {
    .kw-freetext {
        grid-template-columns: 1fr;
    }
    .kw-freetext textarea { grid-column: 1 / -1; }
    .kw-freetext__btn { grid-column: 1 / -1; grid-row: 2 / 3; width: 100%; }
    .kw-freetext__hint { grid-row: 3 / 4; }
    .kw-freetext__error { grid-row: 4 / 5; }
}

/* Полоска чипов. Горизонтальный flex, переносится на новую строку. */
.kw-freetext-examples {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 16px;
}
.kw-freetext-examples .chip {
    cursor: pointer;
    border: 1px solid var(--line);
    background: var(--surface-muted);
    color: var(--ink);
    font-size: 13px;
    padding: 6px 12px;
    border-radius: 999px;
    font: inherit;
    line-height: 1.3;
    transition: background-color 120ms ease, border-color 120ms ease,
                color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}
.kw-freetext-examples .chip:hover {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
    /* Fix #1 (microux 2026-05-15): hover-lift в стиле Banki.ru / Циан.
       Чип приподнимается на 1px + получает мягкую тень — родитель
       чувствует «это интерактивно, не просто статичный текст». */
    transform: translateY(-1px);
    box-shadow: var(--shadow-sm);
}
.kw-freetext-examples .chip:active {
    transform: translateY(0);
    box-shadow: none;
}

/* Карта района — большая, 480-560px на десктопе. */
.kw-hero-conv__map {
    margin-top: 28px;
}
.kw-hero-conv__map-canvas {
    width: 100%;
    min-height: 480px;
    height: clamp(480px, 55vh, 560px);
}
.kw-hero-conv__map-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--tone-tiny-bg);
    text-align: center;
    padding: 24px;
}
.kw-hero-conv__map-fallback-inner {
    max-width: 320px;
}
.kw-hero-conv__map-pin {
    font-size: 48px;
    line-height: 1;
    margin-bottom: 14px;
}

/* Trust-полоска под картой — узкая, 3 элемента + разделители-точки. */
.kw-trust-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 6px 10px;
    font-size: 13px;
    color: var(--ink-soft);
}
.kw-trust-strip__item {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
}
.kw-trust-strip__num {
    font-family: var(--ff-display);
    font-weight: 700;
    color: var(--ink);
    font-size: 15px;
}
.kw-trust-strip__lbl {
    color: var(--ink-soft);
}
.kw-trust-strip__sep {
    color: var(--ink-soft);
    opacity: 0.5;
}

/* sr-only — для accessibility label'ов. Раньше класс был в Tailwind-only,
   но мы его явно используем в hero — дублируем здесь, чтобы не зависеть
   от того, осталась ли утилита в JIT-сборке. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Sprint 3-D seasonal cards / Sprint 6-A seasonal-hub удалены 2026-05-14
   при radical-cut главной (вариант B). Если когда-то вернём
   /season — стили будут жить там же, не на главной. */

/* ----------------------------------------------------------------------
   Sprint 5-B (messenger deeplink, JTBD-3): кнопки «Записаться в WhatsApp/
   Telegram/Позвонить» на карточке кружка.

   Брендовые цвета: WhatsApp #25D366 (зелёный), Telegram #0088CC (синий).
   На мобильных — полная ширина и высота 56px (комфортная зона касания
   по Material Design + iOS HIG ≥ 44pt).
---------------------------------------------------------------------- */
.messenger-buttons {
    /* контейнер для группы deeplink-кнопок в aside-блоке карточки. */
}
.btn-whatsapp,
a.btn-whatsapp {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    background: #25D366;
    color: #fff;
    border: 1px solid #25D366;
    font-weight: 600;
    transition: background-color 150ms ease, transform 100ms ease;
}
.btn-whatsapp:hover,
a.btn-whatsapp:hover {
    background: #1ebe5d;
    border-color: #1ebe5d;
    color: #fff;
}
.btn-whatsapp:active,
a.btn-whatsapp:active {
    transform: translateY(1px);
}
.btn-telegram,
a.btn-telegram {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    background: #0088CC;
    color: #fff;
    border: 1px solid #0088CC;
    font-weight: 600;
    transition: background-color 150ms ease, transform 100ms ease;
}
.btn-telegram:hover,
a.btn-telegram:hover {
    background: #0077b3;
    border-color: #0077b3;
    color: #fff;
}
.btn-telegram:active,
a.btn-telegram:active {
    transform: translateY(1px);
}
.btn-whatsapp svg,
.btn-telegram svg {
    flex-shrink: 0;
}
/* Mobile (≤ 640px): полная ширина и комфортная высота 56px. */
@media (max-width: 640px) {
    .messenger-buttons .btn-whatsapp,
    .messenger-buttons .btn-telegram,
    .messenger-buttons a.btn-whatsapp,
    .messenger-buttons a.btn-telegram,
    .messenger-buttons a.btn-secondary {
        width: 100%;
        min-height: 56px;
        font-size: 16px;
    }
}
.messenger-hint {
    line-height: 1.4;
    font-size: 12px;
    color: var(--ink-muted);
    margin-top: -4px;
}

/* ── Chat-assistant (Sprint 5-A) ────────────────────────────────────────
   Диалоговый подбор кружков. Pastel-cool палитра, в стиле iMessage:
   bot слева с аватаркой K, user справа без аватарки. */

.kw-chat-wrap {
    /* На мобильных хочется, чтобы input-форма «висела» внизу видимой области.
       На десктопе — обычный поток. Делаем через flex + min-height. */
}

.chat-container {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-height: 280px;
    padding: 8px 4px;
    /* Контейнер прокручивается, чтобы новые сообщения уезжали вверх. */
    max-height: 60vh;
    overflow-y: auto;
    scroll-behavior: smooth;
}

.chat-bubble {
    display: flex;
    gap: 10px;
    align-items: flex-end;
    max-width: 100%;
    animation: kw-chat-bubble-in 220ms ease-out;
}

@keyframes kw-chat-bubble-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

.chat-bubble__avatar {
    flex: 0 0 28px;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--accent-soft, #e6efff);
    color: var(--accent, #2f6fed);
    font-weight: 600;
    font-size: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

.chat-bubble__body {
    padding: 10px 14px;
    border-radius: 16px;
    max-width: min(560px, 80%);
    word-wrap: break-word;
    line-height: 1.4;
    font-size: 15px;
}

.chat-bubble__text {
    margin: 0;
}

.chat-bubble__hint {
    margin: 6px 0 0;
    font-size: 12px;
    opacity: 0.7;
}

.chat-bubble-bot .chat-bubble__body {
    background: var(--tone-cool-soft, #eef3fb);
    color: var(--ink, #1a1f2e);
    border-bottom-left-radius: 4px;
}

.chat-bubble-user {
    justify-content: flex-end;
}

.chat-bubble-user .chat-bubble__body {
    background: var(--accent, #2f6fed);
    color: #fff;
    border-bottom-right-radius: 4px;
    margin-left: auto;
}

/* Чипы — горизонтальный flex, обёртка после bot-bubble. */
.chat-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 4px 0 4px 38px; /* выровнено по правому краю аватарки */
}

.chat-chip {
    /* Наследует .chip из base.html — фон, бордер, hover. Тут только
       уплотняем под чат. */
    padding: 6px 12px;
    font-size: 13px;
}

/* Typing-indicator: три точки, пульсирующие по очереди. */
.chat-typing-wrap .chat-bubble__body {
    padding: 12px 14px;
}

.chat-typing-indicator {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 14px;
}
.chat-typing-indicator > span {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ink-muted, #6b7280);
    animation: kw-chat-typing 1.2s infinite ease-in-out both;
}
.chat-typing-indicator > span:nth-child(2) { animation-delay: 0.15s; }
.chat-typing-indicator > span:nth-child(3) { animation-delay: 0.3s; }

@keyframes kw-chat-typing {
    0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
    40%           { transform: scale(1.0); opacity: 1.0; }
}

/* Input-форма внизу. На мобильных растягиваем на всю ширину. */
.chat-input-form {
    display: flex;
    gap: 8px;
    align-items: stretch;
}

.chat-input {
    flex: 1 1 auto;
    min-height: 44px;
    padding: 10px 14px;
    border-radius: 12px;
    border: 1px solid var(--border, #e1e5ee);
    background: #fff;
    font-size: 15px;
}

.chat-input__btn {
    flex: 0 0 auto;
    min-height: 44px;
    min-width: 44px;
    border-radius: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

@media (max-width: 640px) {
    .chat-container { max-height: 50vh; }
    .chat-bubble__body { font-size: 14px; }
    .chat-chips { margin-left: 32px; }
}

/* 2026-05-14 hot-fix: «Записаться» absolute bottom-left z-index:2 наезжала
   на теги в _club_card.html (Vasya screenshot). Desktop: padding-left=140px
   делает «дыру» под absolute-кнопку. Mobile: padding-bottom=48px — кнопка
   уходит на свою строку под теги, теги во всю ширину. */
.club-card__tags {
    padding-left: 140px;
    min-height: 32px;
}
@media (max-width: 640px) {
    .club-card__tags {
        padding-left: 0;
        padding-bottom: 48px;
    }
}

/* Sprint 7-C: pastel-fallback cover для карточек без owner-photo и без
   cover_photo_real_url. Цвет фона приходит из inline-style (var(--tone-*-bg)),
   эмодзи 64px центрируется. 0/20 карточек у user-tester'а имели реальное фото —
   без cover карточка выглядит «голой», эмодзи на pastel-цвете категории
   читается как «это спорт/арт/наука» с одного взгляда.
   Размер 240x140 для desktop sidebar-grid, на mobile растягивается на ширину. */
.club-card__cover-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 140px;
    min-height: 140px;
    overflow: hidden;
}
.club-card__cover-fallback-emoji {
    font-size: 64px;
    line-height: 1;
    /* Edge-rendering: emoji-glyph не размывается при разном DPR. */
    -webkit-font-smoothing: antialiased;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
    pointer-events: none;
    user-select: none;
}
@media (max-width: 640px) {
    .club-card__cover-fallback {
        height: 120px;
        min-height: 120px;
    }
    .club-card__cover-fallback-emoji {
        font-size: 56px;
    }
}

/* ----------------------------------------------------------------------
   Sprint 7-D (FIX-3): «Записаться на пробное» — главное CTA на карточке.

   user-tester репортил «выглядит как текст-ссылка, не CTA». Корень: в
   base.html .btn-primary имеет min-height 44px и padding 0 18px — на
   широком aside-блоке без явного font-size кнопка визуально сливается с
   остальными «второстепенными» (Поделиться / Маршрут / Сравнить).

   Решение: kw-cta-trial — pinpoint-override. Увеличиваем font-size (17px),
   padding-y (14px), вес шрифта (700), добавляем мягкую accent-тень.
   Скорость взгляда родителя: 0.3s → 0.1s до распознавания «это кнопка».
---------------------------------------------------------------------- */
.kw-cta-trial,
button.kw-cta-trial {
    font-size: 17px;
    font-weight: 700;
    padding: 14px 18px;
    min-height: 52px;
    letter-spacing: 0.01em;
    box-shadow: 0 2px 8px var(--accent-soft, rgba(255, 122, 158, 0.35));
}
.kw-cta-trial:hover,
button.kw-cta-trial:hover {
    box-shadow: 0 4px 12px var(--accent-soft, rgba(255, 122, 158, 0.5));
}
@media (max-width: 640px) {
    .kw-cta-trial,
    button.kw-cta-trial {
        min-height: 56px;
        font-size: 17px;
    }
}

/* ----------------------------------------------------------------------
   Sprint-8 unified signals row (2026-05-14).

   Designer audit (docs/visual_audit_2026-05-14.md) обнаружил pin-стек:
   3 absolute-positioned спан'а в правом верхнем углу шапки (🔔 Идёт набор,
   🟢 Открыто сейчас, 🆓 Пробное бесплатно) конфликтуют с ☆ compare-toggle
   и ★ favorite-toggle (тоже верхний-правый угол). Pин'ы съезжают на
   ★ кнопку, обрезаются, наезжают друг на друга.

   Решение: объединить в одну строку «🔔 Идёт набор · 🟢 Открыто · 🆓 …»
   ПОД заголовком карточки (внутри club-card__head-text, между title и meta).
   Inline-flex с wrap, цвет каждого сигнала — отдельный (recruiting=accent,
   open-now=green, free-trial=violet) чтобы родитель глазом распознавал тип.

   CSS-debt: старых селекторов .club-card__recruiting / __pin-open /
   __pin-free-trial в app.css не было (стили inline в шаблоне — теперь
   удалены). Удалять нечего, но фиксируем: эти 3 класса больше не
   используются в проекте.
---------------------------------------------------------------------- */
.club-card__signals {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--ink);
}
.club-card__signal {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
}
.club-card__signal--recruiting { color: var(--accent, #FF7A9E); }
.club-card__signal--open-now { color: #16a34a; }
.club-card__signal--free-trial { color: #7c3aed; }
.club-card__signal-sep {
    color: var(--ink-muted);
    opacity: 0.6;
}

/* ----------------------------------------------------------------------
   Migration 2026-05-14: inline-style → classes (Trek Designer).
   Concept-audit нашёл 3 335 атрибутов style="..." на главной + 919
   литералов border-radius: 999px. _club_card.html — самый «жирный»
   (333 × inline-string).

   Стратегия: tone передаётся ОДИН раз через --tone-bg / --tone-ink /
   --tone-deep на .club-card-wrap; все дочерние стили consume через
   var(...). Не-tone-зависимые литералы (999px, clamp, padding) — в CSS.

   Совместимость: старые селекторы .club-card__head/.club-card__icon/etc.
   определены в base.html ниже; модификаторы --toned ТОЛЬКО переопределяют
   цвет (background/color), не меняют geometry. Если --tone-bg не задана
   (родитель без --toned wrapper) — отрабатывает fallback в существующих
   правилах base.html (var(--surface-muted) / var(--line)).
---------------------------------------------------------------------- */

/* Cover: тонированный фон fallback'а + базовый цвет под img loading state. */
.club-card__cover--toned {
    background: var(--tone-bg, var(--surface-muted));
    color: var(--tone-ink, var(--ink));
}

/* Head: цветная шапка карточки. position:relative для абсолют-pin'ов
   (если когда-нибудь вернутся). */
.club-card__head--toned {
    background: var(--tone-bg, var(--surface-muted));
    color: var(--tone-ink, var(--ink));
    position: relative;
}

/* Icon: тёмный кружок с emoji слева от заголовка. */
.club-card__icon--toned {
    background: var(--tone-deep, var(--line));
}

/* Title + meta: цвет наследуется из tone-ink. meta — приглушённая. */
.club-card__title--toned {
    color: var(--tone-ink, var(--ink));
}
.club-card__meta--toned {
    color: var(--tone-ink, var(--ink-muted));
    opacity: 0.75;
}

/* Short-desc: clamp на 2 строки. До migration сидело inline на каждой
   из 333 карточек × ~85 символов string = ~28KB DOM-веса только на этом
   шаблоне. */
.club-card__short-desc {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Badges: row карточек-категорий под short-desc. max-height=28px чтобы
   не растягивать карточку при множестве бейджей. */
.club-card__badges {
    overflow: hidden;
    max-height: 28px;
}
.club-card__badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--r-full);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    background: var(--badge-bg, var(--surface-muted));
    color: var(--badge-ink, var(--ink));
}

/* Enroll CTA: главная кнопка карточки, absolute в bottom-left.
   z-index:2 поверх .club-card__tags (которые с padding-left: 140px
   как раз под эту кнопку — см. правило выше). */
.club-card__enroll-cta {
    position: absolute;
    bottom: 12px;
    left: 12px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border-radius: var(--r-full);
    background: var(--accent, #FF7A9E);
    color: var(--accent-ink, #fff);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
    z-index: 2;
}
.club-card__enroll-cta:hover {
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
    transform: translateY(-1px);
}

/* ----------------------------------------------------------------------
   Migration 2026-05-15: inline-style → classes (Trek Designer, batch-2).
   club_detail.html / geo_landing.html / catalog.html. 999px → var(--r-full).
---------------------------------------------------------------------- */
:root {
    --alert-warn-bg: #FFF8E1; --alert-warn-line: #FFE082; --alert-warn-ink: #7C4A00;
    --alert-ok-bg: #E6F4EA;   --alert-ok-line: #B7E1C5;   --alert-ok-ink: #1E5631;
    --alert-err-bg: #FFE9E5;  --alert-err-line: #FFCFC8;  --alert-err-ink: #8B1A0F;
    --callout-warn-bg: #FFF8EC; --callout-warn-accent: #E5B85F;
}
.kw-alert { border-radius: var(--r-md); }
.kw-alert--warn { background: var(--alert-warn-bg); border: 1px solid var(--alert-warn-line); color: var(--alert-warn-ink); }
.kw-alert--ok   { background: var(--alert-ok-bg);   border: 1px solid var(--alert-ok-line);   color: var(--alert-ok-ink); }
.kw-alert--err  { background: var(--alert-err-bg);  border: 1px solid var(--alert-err-line);  color: var(--alert-err-ink); }
.kw-surface-card { background: var(--surface); border: 1px solid var(--line); }
.kw-surface-card--dashed { background: var(--surface); border: 1px dashed var(--line); }
.kw-promo-banner { background: var(--accent-soft); border: 1px solid var(--accent); }
.kw-promo-icon { font-size: 22px; line-height: 1; }
.kw-promo-eyebrow { color: var(--accent); }
.kw-promo-note { color: var(--ink-muted); }
.kw-field-report { margin: 24px 0; padding: 24px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); }
.kw-field-report__img { width: 100%; max-height: 320px; object-fit: cover; border-radius: var(--r-md); margin-bottom: 16px; }
.kw-field-report__quote { font-size: 18px; font-style: italic; padding-left: 16px; border-left: 4px solid var(--accent); margin-bottom: 8px; }
.kw-field-report__cite { display: block; margin-top: 8px; font-size: 14px; color: var(--ink-muted); font-style: normal; }
.kw-field-report__fact { font-weight: 600; font-size: 16px; color: var(--ink); margin: 12px 0; }
.kw-anti-portrait { margin: 24px 0; padding: 16px 20px; background: var(--callout-warn-bg); border-left: 4px solid var(--callout-warn-accent); border-radius: 8px; }
.kw-anti-portrait__body { margin-top: 8px; color: var(--ink); }
.kw-dt-muted { color: var(--ink-muted); }
.kw-link-accent { color: var(--accent); }
.kw-text-ink { color: var(--ink); }
.kw-text-muted { color: var(--ink-muted); }
.kw-tone-card { background: var(--tone-bg, var(--surface-muted)); color: var(--tone-ink, var(--ink)); }
.kw-tone--sci    { --tone-bg: var(--tone-sci-bg);    --tone-ink: var(--tone-sci-ink); }
.kw-tone--art    { --tone-bg: var(--tone-art-bg);    --tone-ink: var(--tone-art-ink); }
.kw-tone--sport  { --tone-bg: var(--tone-sport-bg);  --tone-ink: var(--tone-sport-ink); }
.kw-tone--school { --tone-bg: var(--tone-school-bg, #FFF1D6); --tone-ink: var(--tone-school-ink, #6B4A12); }
.kw-tile-accent { background: var(--accent-soft); color: var(--ink); }
.kw-required { color: #B71C1C; }
.kw-prewrap { white-space: pre-wrap; }
.kw-enroll-submit { padding: 12px 24px; font-size: 16px; }
.kw-club-map { height: 320px; border: 1px solid var(--line); }
.kw-club-map-iframe { height: 300px; border: 1px solid var(--line); }
.kw-landing-section { padding-top: clamp(24px, 4vw, 48px); padding-bottom: 8px; }
.kw-landing-h1 { font-size: clamp(28px, 4vw, 48px); }
.kw-landing-subtitle { max-width: 720px; }
.kw-landing-faq-wrap { max-width: 760px; }
.kw-landing-map { width: 100%; height: 480px; border-radius: var(--r-lg); background: var(--surface-muted); margin: 24px 0; }
.kw-landing-card-wrap { position: relative; }
.kw-landing-distance-pin { position: absolute; top: 8px; right: 8px; background: var(--surface); color: var(--ink); font-size: 12px; padding: 4px 8px; border-radius: var(--r-full); border: 1px solid var(--line); }
.kw-catalog-section { padding-top: clamp(24px, 4vw, 48px); padding-bottom: 8px; }
.kw-catalog-section--bottom { padding-bottom: clamp(28px, 3vw, 48px); }
.kw-catalog-h1 { font-size: clamp(28px, 3.6vw, 46px); }
.kw-catalog-h2 { font-size: clamp(24px, 2.6vw, 34px); }
.kw-catalog-subtitle { max-width: 620px; }
.kw-eyebrow-rule { display: inline-block; width: 22px; height: 1px; background: var(--ink); }
.kw-catalog-tile { transition: transform 150ms ease, border-color 150ms ease; }
.kw-tile-thumb { width: 64px; height: 64px; }
.kw-tile-cta { color: var(--accent-700); }
.kw-district-map { height: 560px; background: var(--tone-tiny-bg); }
.kw-district-map-fallback { --ph-bg: var(--tone-tiny-bg); height: 380px; }
.kw-filters-close { background: var(--surface-muted); color: var(--ink); }

/* ----------------------------------------------------------------------
   Sticky filter sidebar (Banki.ru / Циан / Самолет паттерн).
   Vasya order 2026-05-15: при скролле /all и /search фильтр-sidebar
   остаётся видимым (sticky). На узких viewport-ах (641–900px) и mobile
   (≤640px) уходит в drawer.

   Header высота ~64px + 16px зазор → top: 80px.
   max-height: calc(100vh - 100px) — фильтр сам скроллится, если выше
   viewport.

   ВАЖНО: правило для ≥901px. На ≤900px (drawer) sticky убирается и
   sidebar скрывается, .kw-filters-trigger форсится во flex.
   ---------------------------------------------------------------------- */
@media (min-width: 901px) {
    .kw-filters-sidebar {
        position: sticky;
        top: 80px;
        max-height: calc(100vh - 100px);
        overflow-y: auto;
        scrollbar-width: thin;
    }
    .kw-filters-sidebar::-webkit-scrollbar { width: 6px; }
    .kw-filters-sidebar::-webkit-scrollbar-thumb {
        background: var(--line);
        border-radius: 3px;
    }
}

/* Узкий desktop / tablet (641–900px): sidebar в drawer как mobile.
   Перекрываем Tailwind `md:block` (>=768px) принудительным display:none. */
@media (max-width: 900px) {
    .kw-filters-sidebar {
        display: none !important;
    }
}
@media (min-width: 641px) and (max-width: 900px) {
    /* Trigger «Фильтры» (Tailwind `md:hidden` его прячет >=768px) —
       форсим обратно во flex для diapason 641-900px. */
    .kw-filters-trigger {
        display: flex !important;
    }
    /* На этом diapason кольпсим grid в одну колонку (base.html правило
       для ≤880px). 880 vs 900 — 20px gap; явный override страхует. */
    .kw-catalog {
        grid-template-columns: 1fr !important;
    }
}

/* ----------------------------------------------------------------------
   Mobile audit 2026-05-15 (iPhone 375×812 viewport).
   Sources: docs/screenshots/2026-05-15-after-radical-cut/*_mobile.png.

   Все правила — additive, только @media (max-width: 640px). НЕ ломают
   desktop. НЕ меняют структуру HTML.

   Найденные проблемы:
   - P0 PWA-баннер «Установить Kidswall» накрывает контент и CTA-чипы
     на главной. Кнопка «Поставить» 36px — ниже WCAG-touch 44px.
   - P0 Карта /all и /search 560px → дoминирует на mobile-viewport 812px.
     North Star: «карта не должна доминировать».
   - P1 Body 15px → iOS zooming при focus на textarea. Apple HIG ≥16px.
   - P1 Club-card __enroll-cta absolute-positioned слишком близко к
     краю на узком viewport — иногда наезжает на длинные теги.
   - P2 btn-link 13.5px на mobile — мелкий тач-таргет «На карте /
     Развернуть →».
---------------------------------------------------------------------- */
@media (max-width: 640px) {
    /* P0-1: PWA install banner — touch-target и meньше визуальный вес. */
    #kw-pwa-install #kw-pwa-install-btn {
        min-height: 44px !important;
        padding: 0 14px !important;
        font-size: 14px !important;
    }
    #kw-pwa-install #kw-pwa-install-close {
        min-width: 44px;
        min-height: 44px;
    }
    /* Mobile: баннер растягивается по ширине внизу экрана, не накрывает
       hero-карту Москвы и CTA-чипы (на mobile карта 320px, баннер ниже неё). */
    #kw-pwa-install {
        left: 8px !important;
        right: 8px !important;
        bottom: 8px !important;
        max-width: none !important;
    }

    /* P0-2: Карта района — не выше 320px на mobile (North Star: не
       доминирует). 560px-десктоп оставляем без изменений. */
    .kw-district-map {
        height: 320px;
    }
    .kw-district-map-fallback {
        height: 240px;
    }

    /* P1-1: Body 15px → 16px на mobile, чтобы iOS не zoom'ил textarea.
       Apple HIG: 16px минимум для form-inputs, иначе viewport zoom-on-focus. */
    body {
        font-size: 16px;
    }
    /* Textarea на /assistant и hero-freetext — гарантия 16px. */
    .kw-input,
    .kw-freetext textarea,
    input[type="text"],
    input[type="search"],
    input[type="email"],
    input[type="tel"],
    textarea {
        font-size: 16px;
    }

    /* P1-2: Club-card enroll CTA — увеличиваем touch-target на mobile,
       при этом не растягиваем карточку (только padding-y +2px). */
    .club-card__enroll-cta {
        min-height: 36px;
        padding: 9px 14px;
        font-size: 13.5px;
    }

    /* P2-1: btn-link («На карте», «Развернуть») — увеличиваем
       тач-target до 44px и font-size до 14.5px для читаемости. */
    .btn-link {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        font-size: 14.5px;
        padding: 4px 0;
    }

    /* P2-2: Tag-badges в club-card — slightly larger для мобильного
       тача (если родитель захочет filter-by-tag в будущем). */
    .tag-badge {
        font-size: 12.5px;
        padding: 5px 11px;
    }

    /* P2-3: Уменьшаем большой aspect-ratio cover для club-card
       fallback на mobile — 4/3 → 16/9, чтобы карточка не «съедала»
       вертикальный ритм каталога. */
    .club-card__cover {
        aspect-ratio: 16 / 9;
    }
}

/* ─────────────────────────────────────────────────────────────────────────
   Filter-count toast (Vasya order #38, 2026-05-15).
   При смене фильтра HTMX подгружает HTML «N кружков найдено» в
   #filter-count-toast → CSS-анимация показывает его на 3 секунды и плавно
   скрывает. Position fixed top-center, не мешает скроллу.

   Состояния:
   - default (без .is-visible): opacity=0, pointer-events:none → не мешает.
   - HTMX вешает .is-visible через afterSwap → fade-in 200ms.
   - JS убирает .is-visible через 3000ms → fade-out 250ms.
   ───────────────────────────────────────────────────────────────────────── */
.kw-filter-toast {
    position: fixed;
    top: max(16px, env(safe-area-inset-top));
    left: 50%;
    transform: translate(-50%, -14px);
    z-index: 60;
    pointer-events: none;
    opacity: 0;
    transition: opacity 200ms ease, transform 200ms ease;
}
.kw-filter-toast.is-visible {
    opacity: 1;
    transform: translate(-50%, 0);
}
.kw-filter-toast__inner {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    padding: 10px 18px;
    border-radius: var(--r-full);
    background: var(--ink);
    color: var(--surface);
    box-shadow: var(--shadow-lg);
    font-size: 14px;
    line-height: 1.2;
    font-weight: 600;
    letter-spacing: -0.01em;
    /* На мобильном — переносы не нужны, текст короткий. */
    white-space: nowrap;
}
.kw-filter-toast__num {
    font-size: 16px;
    font-weight: 700;
    color: var(--accent-50);
}
.kw-filter-toast__word {
    color: var(--surface);
    opacity: 0.92;
}

/* На мобильном делаем toast чуть меньше — экран узкий. */
@media (max-width: 640px) {
    .kw-filter-toast__inner {
        padding: 8px 14px;
        font-size: 13px;
    }
    .kw-filter-toast__num {
        font-size: 15px;
    }
}

/* ──────────────────────────────────────────────────────────────────────
   Distance promo banner — Vasya order #41 (2026-05-15).
   Inline-CTA под H1+lede на главной → переход на /search с focus
   на distance-block. Не дублирует input на главной (radical-cut).
   ────────────────────────────────────────────────────────────────────── */
.kw-distance-promo {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    max-width: 620px;
    padding: 12px 16px;
    border-radius: var(--r-md, 12px);
    background: var(--accent-soft, #eef0ff);
    color: var(--ink);
    text-decoration: none;
    border: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
    transition: background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
}
.kw-distance-promo:hover,
.kw-distance-promo:focus-visible {
    background: color-mix(in srgb, var(--accent) 14%, white);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 25%, transparent);
}
.kw-distance-promo:active {
    transform: translateY(1px);
}
.kw-distance-promo__icon {
    font-size: 22px;
    flex-shrink: 0;
    line-height: 1;
}
.kw-distance-promo__text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    line-height: 1.3;
    flex: 1;
}
.kw-distance-promo__title {
    font-weight: 600;
    font-size: 14px;
}
.kw-distance-promo__sub {
    font-size: 12.5px;
    color: var(--ink-muted, #6b7280);
}
.kw-distance-promo__arrow {
    font-size: 16px;
    color: var(--accent);
    flex-shrink: 0;
    font-weight: 600;
}

@media (max-width: 640px) {
    .kw-distance-promo {
        max-width: 100%;
        width: 100%;
    }
    .kw-distance-promo__sub {
        font-size: 12px;
    }
}

/* «Истории родителей» killer-feature #42 — CSS-блок .kw-stories* удалён
   2026-05-15 (Vasya order #45, концепция забракована). Шаблон + роут
   тоже зачищены. */

/* ─────────────────────────────────────────────────────────────────────────
   Micro-UX batch 2026-05-15 (creative-deputy, Vasya order #43).
   Полировка hover / focus / loading / scroll-anchor — все правила
   additive и не ломают существующие компоненты.
   Источник: docs/microux_audit_2026-05-15.md, топ-10 fixes.
   ───────────────────────────────────────────────────────────────────────── */

/* Fix #5: scroll-margin-top на якорях.
   Sticky-header высотой ~64px перекрывает anchor-target при переходе
   по якорю (например, /catalog#district из мобильного «На карте»).
   Все h1/h2/h3/section[id] получают отступ-снизу для скролла. */
h1[id],
h2[id],
h3[id],
section[id],
[id]:target,
.kw-section[id] {
    scroll-margin-top: 80px;
}

/* Fix #10: btn-link underline-on-hover.
   В base.html .btn-link меняет цвет на hover, но без underline. Web-стандарт
   для текстовых линков — подчёркивание при hover; без него родитель не уверен,
   что это ссылка (особенно при отключённом hover-effect на тач-устройствах). */
.btn-link:hover,
a.btn-link:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1.5px;
}

/* Fix #4: ★ favorite pulse animation при клике.
   Когда родитель кликает на ☆ — звёздочка делает короткий «пульс» (scale up→down),
   подтверждая что действие принято. Optimistic UI уже flip'ает иконку, pulse —
   эмоциональная подсветка действия. Длится 320ms, prefers-reduced-motion отключает. */
@keyframes kw-fav-pulse {
    0%   { transform: scale(1); }
    35%  { transform: scale(1.35); }
    70%  { transform: scale(0.95); }
    100% { transform: scale(1); }
}
.club-card__fav.is-pulsing .kw-fav-toggle__star {
    display: inline-block;
    animation: kw-fav-pulse 320ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
    .club-card__fav.is-pulsing .kw-fav-toggle__star { animation: none; }
}

/* Fix #6: Loading-state кнопки «Подобрать».
   При submit hero-формы — заменяем содержимое кнопки на spinner + текст.
   Класс .is-loading управляется JS-ом в home.html. */
.kw-freetext__btn.is-loading {
    opacity: 0.85;
    cursor: wait;
    pointer-events: none;
}
.kw-freetext__btn.is-loading .kw-freetext__btn-label::before {
    content: "";
    display: inline-block;
    width: 14px;
    height: 14px;
    margin-right: 8px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    vertical-align: -2px;
    animation: kw-spin 700ms linear infinite;
}
@keyframes kw-spin {
    to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
    .kw-freetext__btn.is-loading .kw-freetext__btn-label::before { animation: none; }
}

/* Bonus: Empty-state CTA-chips на /search (fix from audit). */
.kw-empty-state {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: 32px 24px;
    text-align: center;
}
.kw-empty-state__icon {
    font-size: 40px;
    line-height: 1;
    margin-bottom: 12px;
    opacity: 0.7;
}
.kw-empty-state__title {
    font-weight: 700;
    font-size: 17px;
    color: var(--ink);
    margin: 0 0 6px;
}
.kw-empty-state__sub {
    color: var(--ink-muted);
    font-size: 14px;
    margin: 0 0 16px;
}
.kw-empty-state__chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin-top: 8px;
}

/* ── Mobile bottom-nav (Vasya order 2026-05-15) ──────────────────────────
   Banki.ru-стиль bottom-nav: 5 элементов, fixed bottom, видна только на
   viewport ≤640px. На десктопе display:none (десктопная nav в _header).
   z-index 40 (как .site-header) — ниже drawer-overlay (50) и toast (1000),
   чтобы открытый mobile drawer перекрывал bottom-nav.
   safe-area-inset-bottom — для iPhone с home-indicator.
*/
.kw-bottom-nav {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: var(--surface);
    border-top: 1px solid var(--line);
    padding: 6px 4px;
    padding-bottom: max(6px, env(safe-area-inset-bottom));
    z-index: 40;
    box-shadow: 0 -2px 12px rgba(21, 22, 28, 0.06);
}
@media (max-width: 640px) {
    .kw-bottom-nav {
        display: flex;
        justify-content: space-around;
        align-items: stretch;
    }
    /* Контент не должен прятаться за nav'ом. 64px = ~min-height + padding. */
    body {
        padding-bottom: calc(64px + env(safe-area-inset-bottom));
    }
}
.kw-bottom-nav__link {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    flex: 1;
    padding: 4px 6px;
    color: var(--ink-muted);
    text-decoration: none;
    min-height: 48px;
    min-width: 56px;
    font-size: 11px;
    line-height: 1.1;
    border-radius: var(--r-sm);
    transition: color 120ms ease, background 120ms ease;
}
.kw-bottom-nav__link:hover {
    color: var(--ink);
}
.kw-bottom-nav__link.is-active,
.kw-bottom-nav__link[aria-current="page"] {
    color: var(--accent);
    font-weight: 600;
}
.kw-bottom-nav__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}
.kw-bottom-nav__label {
    white-space: nowrap;
    letter-spacing: -0.005em;
}
/* На очень узких экранах (≤340px) и пользователях с reduce-motion
   убираем label — оставляем только иконки. */
@media (max-width: 340px) {
    .kw-bottom-nav__label {
        display: none;
    }
    .kw-bottom-nav__link {
        min-height: 44px;
    }
}
/* Когда открыт mobile drawer/regions/filters — bottom-nav не должна торчать
   поверх overlay. Overlay имеет z-index 50, наш nav — 40, но на iOS Safari
   fixed-position иногда «лезет» поверх. Дополнительно прячем через CSS,
   когда overlay открыт. */
body:has(.drawer-overlay.open) .kw-bottom-nav,
body:has(.filters-overlay.open) .kw-bottom-nav {
    visibility: hidden;
}
/* Graphite theme: чуть более контрастный border-top, фон уже var(--surface). */
body[data-theme="graphite"] .kw-bottom-nav {
    box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.5);
}

/* ── Hover-sync card<->marker (Vasya 2026-05-15) ─────────────────────────
   Циан-pattern: hover на карточке → подсветка маркера, и наоборот.
   sync.js ставит .is-highlighted на парный узел по data-club-id. */
.ymap-marker.is-highlighted { z-index: 5; }
.ymap-marker.is-highlighted .ymap-marker__pin {
    transform: translate(-50%, -100%) scale(1.35);
    outline: 3px solid var(--accent);
    outline-offset: 2px;
    box-shadow: 0 6px 14px rgba(21,22,28,0.35);
}
.club-card-wrap { transition: transform 140ms ease, box-shadow 140ms ease; }
.club-card-wrap.is-highlighted {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--r-lg, 12px);
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(21,22,28,0.12);
    position: relative;
    z-index: 2;
}

/* ─────────────────────────────────────────────────────────────────────────
   Card quick-preview tooltip (Vasya P1 / Дима 2026-05-15).
   Hover на карточке /all ≥1s → tooltip справа с фото, headline,
   ближайшими занятиями, anti-portrait. JS: app/static/js/card_preview.js.
   На mobile (≤640px) скрываем — hover недоступен на тач-экранах.
   ───────────────────────────────────────────────────────────────────────── */
.card-preview-tooltip {
    position: absolute;
    z-index: 60;
    background: var(--surface);
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-lg);
    padding: 12px;
    font-size: 13px;
    line-height: 1.4;
    opacity: 0;
    pointer-events: none;
    transition: opacity 150ms ease;
    max-width: 320px;
    left: -9999px;
    top: -9999px;
}
.card-preview-tooltip.is-visible {
    opacity: 1;
}
.card-preview-photos {
    display: flex;
    gap: 4px;
    margin-bottom: 10px;
    overflow: hidden;
}
.card-preview-photo {
    width: 72px;
    height: 72px;
    object-fit: cover;
    border-radius: var(--r-sm);
    flex-shrink: 0;
    background: var(--surface-muted);
}
.card-preview-headline {
    font-weight: 600;
    font-size: 13.5px;
    color: var(--ink);
    margin-bottom: 8px;
    line-height: 1.35;
}
.card-preview-events-wrap {
    margin-bottom: 8px;
}
.card-preview-events-title {
    font-size: 11px;
    color: var(--ink-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
    margin-bottom: 4px;
}
.card-preview-events {
    list-style: none;
    padding: 0;
    margin: 0;
}
.card-preview-event {
    font-size: 12.5px;
    color: var(--ink);
    padding: 2px 0;
}
.card-preview-anti {
    font-size: 12px;
    color: var(--ink-muted);
    line-height: 1.4;
    padding-top: 6px;
    border-top: 1px dashed var(--line);
    margin-top: 4px;
}
.card-preview-anti-label {
    color: var(--ink);
    font-weight: 600;
}
@media (max-width: 640px) {
    .card-preview-tooltip {
        display: none !important;
    }
}
@media (hover: none) {
    .card-preview-tooltip {
        display: none !important;
    }
}

/* ==========================================================================
   DEEP MOBILE-FIRST PASS 2026-05-15 (iPhone 375x812, Vasya order #51).
   Источник: docs/screenshots/2026-05-15-mobile-before/*_mobile.png.
   Все правила additive, не ломают desktop. HTML не трогаем.
   Цели: touch >=44px, font >=16px у inputs, no horizontal overflow,
   safe-area-inset, аккуратная иерархия / читаемость.
   15 фиксов. P0 первыми.
   ========================================================================== */

/* Fix #1 (P0). Horizontal-overflow guard. */
@media (max-width: 640px) {
    html, body { max-width: 100vw; overflow-x: hidden; }
    img, video, iframe, svg { max-width: 100%; height: auto; }
    .kw-container, main, article, section { word-wrap: break-word; overflow-wrap: break-word; }
}

/* Fix #2 (P0). Hero-карта Москвы — 280px (было 480-560px). */
@media (max-width: 640px) {
    .kw-hero-conv__map-canvas { min-height: 280px; height: 280px; }
}

/* Fix #3 (P0). Карта на /club/<id>: 300px → 260px. */
@media (max-width: 640px) {
    .kw-club-map { height: 260px !important; }
}

/* Fix #4 (P0). H1 на geo-landing — hyphens для длинных названий. */
@media (max-width: 640px) {
    h1.h-hero, .h-hero {
        font-size: clamp(22px, 6.4vw, 28px);
        line-height: 1.18;
        word-break: break-word;
        hyphens: auto;
        -webkit-hyphens: auto;
    }
}

/* Fix #5 (P0). Header logo — экономим место. */
@media (max-width: 640px) {
    .site-header .logo-mark { width: 34px; height: 34px; font-size: 16px; }
    .site-header .logo-text { font-size: 16px; }
    .site-header .logo-sub { font-size: 11px; max-width: 180px; }
}

/* Fix #6 (P1). Pin-signals — wrap чище, разделитель прячем. */
@media (max-width: 640px) {
    .club-card__signals {
        gap: 4px 8px;
        font-size: 11.5px;
        line-height: 1.4;
        margin-top: 6px;
        margin-bottom: 6px;
    }
    .club-card__signal { flex: 0 0 auto; max-width: 100%; }
    .club-card__signal-sep { display: none; }
}

/* Fix #7 (P1). Enroll CTA → 44px по HIG. */
@media (max-width: 640px) {
    .club-card__enroll-cta {
        min-height: 44px;
        padding: 11px 16px;
        font-size: 14px;
        border-radius: var(--r-full);
    }
    .club-card__tags { padding-bottom: 56px; }
}

/* Fix #8 (P1). Distance promo — стек icon / title+sub / arrow. */
@media (max-width: 640px) {
    .kw-distance-promo {
        flex-wrap: wrap;
        gap: 8px 12px;
        padding: 14px 16px;
        align-items: flex-start;
    }
    .kw-distance-promo__icon { font-size: 24px; flex: 0 0 auto; }
    .kw-distance-promo__text { flex: 1 1 calc(100% - 56px); min-width: 0; }
    .kw-distance-promo__title { font-size: 15px; }
    .kw-distance-promo__arrow { flex: 0 0 auto; margin-left: auto; align-self: center; }
}

/* Fix #9 (P1). Drawer-panel — 100vw + safe-area-inset. */
.drawer-panel, .filters-overlay-panel {
    padding-top: max(20px, env(safe-area-inset-top));
    padding-bottom: max(20px, env(safe-area-inset-bottom));
}
@media (max-width: 640px) {
    .drawer-panel, .filters-overlay-panel { width: 100vw; }
}

/* Fix #10 (P1). Filter-count toast — снизу (над bottom-nav). */
@media (max-width: 640px) {
    .kw-filter-toast {
        top: auto;
        bottom: calc(72px + env(safe-area-inset-bottom));
        transform: translate(-50%, 14px);
    }
    .kw-filter-toast.is-visible { transform: translate(-50%, 0); }
}

/* Fix #11 (P1). Trust-strip — разделители прячем. */
@media (max-width: 640px) {
    .kw-trust-strip { gap: 6px 14px; font-size: 12.5px; }
    .kw-trust-strip__sep { display: none; }
    .kw-trust-strip__num { font-size: 14px; }
}

/* Fix #12 (P2). Compare-таблица — sticky первая колонка. */
@media (max-width: 640px) {
    .kw-compare th, .kw-compare td { padding: 10px 12px; font-size: 13px; }
    .kw-compare__row-label {
        font-size: 10.5px;
        min-width: 96px;
        position: sticky;
        left: 0;
        z-index: 1;
        background: var(--surface-muted);
    }
    .kw-compare__club-head { min-width: 180px; font-size: 14px; }
    .kw-compare__cover { width: 100px; }
}

/* Fix #13 (P2). Club-card cover — 5/3, fallback 100px. */
@media (max-width: 640px) {
    .club-card__cover { aspect-ratio: 5 / 3; }
    .club-card__cover-fallback { height: 100px; min-height: 100px; }
    .club-card__cover-fallback-emoji { font-size: 48px; }
}

/* Fix #14 (P2). Inputs / textarea / select / button — 16px + 44px. */
@media (max-width: 640px) {
    input[type="text"], input[type="search"], input[type="email"],
    input[type="tel"], input[type="number"], input[type="url"],
    input[type="date"], select, textarea,
    .kw-input, .chat-input,
    .kw-distance-hero__form input[type="text"],
    .kw-freetext textarea {
        font-size: 16px !important;
        min-height: 44px;
    }
    select { padding: 10px 12px; }
    button:not(.kw-bottom-nav__link):not(.club-card__compare):not(.club-card__fav):not(.ymap-popup__close):not(.kw-fav-toggle),
    a.btn-primary, a.btn-secondary {
        min-height: 44px;
    }
}

/* Fix #15 (P2). Safe-area-inset для PWA-баннера. */
@media (max-width: 640px) {
    #kw-pwa-install {
        bottom: max(8px, env(safe-area-inset-bottom)) !important;
    }
}

/* Skeleton card (Vasya 2026-05-15, /search payload reduction).
   Off-screen карточки рендерятся как skeleton (cover+title+address), JS
   card_lazy.js дёргает /api/clubs/card/<id>/hydrate когда карточка
   приближается к viewport — заменяет innerHTML на полный HTML. */
.club-card-wrap--skeleton {
    min-height: 300px;
    position: relative;
    contain: layout style;
}
@media (max-width: 640px) {
    .club-card-wrap--skeleton {
        min-height: 240px;
    }
}
.club-card-wrap--skeleton.is-hydrating::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: linear-gradient(90deg, transparent, var(--accent, #FF7A9E), transparent);
    animation: kw-skel-shimmer 1.2s linear infinite;
    pointer-events: none;
}
@keyframes kw-skel-shimmer {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) {
    .club-card-wrap--skeleton.is-hydrating::after { animation: none; }
}
