/* ============================================================
   Картка маршруту та список маршрутів Атласу — RECRE-367.

   ЧОМУ ОКРЕМИЙ ФАЙЛ, А НЕ main.css: правка main.css заблокована
   паралельним незакоміченим WIP (той самий випадок і та сама причина,
   що вже дали army-banner.css — див. коментар у base.html). При нагоді
   перенести в main.css одним блоком; жодних перевизначень наявних
   селекторів тут немає, тільки нові класи з префіксами rt-, pdm-routes,
   pdm-rrow, тому перенесення буде механічним.
   УВАГА: у CSS-коментарі НЕ можна писати глоб-патерни виду «префікс-* /»
   разом (зірочка+слеш) — така пара обриває коментар достроково, і решта
   тексту стає битим селектором, який мовчки з'їдає НАСТУПНЕ правило
   (саме так тут загинуло .pdm-info__name + .rt-meta, а в
   suggestion-ux.css — гостьовий контур кнопок; у main.css досі лежить
   та сама міна на рядку 60 — токен --event-marker мертвий, файл
   захищений WIP, тому токен відновлено нижче в цьому файлі).

   Токени — з main.css (:root). Власної палітри файл не вводить, окрім
   --rt-mark: це колір ФІЗИЧНОГО маркування на дереві (жовта смуга,
   синій хрест), який приходить з API per-route, а не токен теми.
   ============================================================ */

/* Відновлення токена, з'їденого міною «зірочка+слеш» у коментарі
   main.css:60 (див. шапку): --event-marker (фолбек маркера події,
   RECRE-169/280) випадав з парсингу разом із битим коментарем. main.css
   правити не можна (WIP), тому дублюємо значення тут — при розблокуванні
   main.css цей блок і міна там прибираються разом. */
:root { --event-marker: #8A5A83; }

/* --- Картка маршруту в доку/шторці (.pdm-info) --------------------- */

.pdm-info__name + .rt-meta { margin-top: 8px; }

.rt-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-bottom: 10px;
}

/* Маркування: свотч + ТЕКСТ. Текст обов'язковий — колір не може бути
   єдиним каналом інформації (ТЗ §4.2 п.3, прецедент RECRE-357 §15.1),
   тому в розмітці немає варіанту «тільки кружечок». */
.rt-mark {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 9px 3px 6px;
    border: 1px solid var(--border-2);
    border-radius: 999px;
    background: var(--surface-2);
    font-size: 12.5px;
    color: var(--ink-2);
    white-space: nowrap;
}

.rt-mark__swatch {
    width: 12px;
    height: 12px;
    border-radius: 3px;
    background: var(--rt-mark, var(--muted-2));
    /* Обведення, а не темніший hex: біле й жовте маркування на кремовому
       тлі інакше зникає, а підмінити колір маркування не можна — свотч
       має відповідати тому, що людина побачить у лісі. */
    box-shadow: inset 0 0 0 1px rgb(46 36 25 / 0.28);
}

.rt-ref,
.rt-net {
    display: inline-flex;
    align-items: center;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 12.5px;
    white-space: nowrap;
}

.rt-ref {
    background: var(--chip-amenity-bg);
    color: var(--chip-amenity-fg);
    font-weight: 600;
}

.rt-net {
    border: 1px solid var(--border-2);
    color: var(--muted);
}

/* --- Довжина ------------------------------------------------------- */

.rt-len {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 6px;
    margin: 10px 0;
    font-size: 14px;
    color: var(--ink-2);
}

.rt-len i,
.rt-elev i,
.rt-diff i,
.rt-surface i {
    width: 15px;
    height: 15px;
    flex: 0 0 auto;
    color: var(--muted-2);
    align-self: center;
}

.rt-len strong { font-size: 16px; }

.rt-len__full {
    color: var(--muted);
    font-size: 13px;
}

/* --- Висотний блок ------------------------------------------------- */

.rt-elev {
    margin: 12px 0;
    padding: 10px 12px;
    border: 1px solid var(--border-3);
    border-radius: 12px;
    background: var(--surface);
}

/* Перепад — ОСНОВНЕ число картки (ТЗ §4.2а блок 13): єдина висотна
   величина, повністю інваріантна до напрямку зберігання геометрії.
   Тому воно й найбільше на блоці: 30 % рядків записані «донизу», і
   акцент на наборі показав би їм «0 м» на підйомі в сотні метрів. */
.rt-elev__main {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 8px;
}

.rt-elev__range {
    font-size: 16px;
    font-weight: 700;
    color: var(--ink);
}

.rt-elev__amp {
    font-size: 13px;
    color: var(--muted);
}

/* Набір і спуск — ЗАВЖДИ разом, одним рядком. Верстка навмисно не має
   способу показати одне без іншого (ТЗ §4.2а, ризик 8). */
.rt-elev__pair {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 6px;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

.rt-elev__up { color: var(--terracotta); font-weight: 600; }
.rt-elev__down { color: var(--sage); font-weight: 600; }
.rt-elev__sep { color: var(--dash); }

.rt-elev__time {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px dashed var(--dash);
    font-size: 13.5px;
    color: var(--ink-2);
}

/* «орієнтовно» — не декоративний хвостик: підпис часу ОБОВ'ЯЗКОВО
   подається як оцінка, а не факт (ТЗ §4.2а блок 15). */
.rt-elev__est {
    font-size: 12px;
    color: var(--muted-3);
}

.rt-diff,
.rt-surface {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 8px 0;
    font-size: 13.5px;
    color: var(--ink-2);
}

/* --- Дія «Наблизити до маршруту» (§4.2 п.8) ------------------------ */

.rt-zoom {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: 12px 0 4px;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--green);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}

.rt-zoom:hover { background: var(--bg-2); border-color: var(--sage-light); }
.rt-zoom i { width: 15px; height: 15px; }

.rt-also {
    margin: 10px 0 0;
    font-size: 13px;
    color: var(--muted);
}

.rt-also a { color: var(--green); text-decoration: underline; }

/* --- Підвал джерела (атрибуція ODbL + зріз + рельєф) --------------- */

.rt-src {
    margin-top: 14px;
    padding-top: 10px;
    border-top: 1px solid var(--border-3);
}

.rt-src p {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 4px;
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--muted-3);
}

.rt-src i { width: 13px; height: 13px; flex: 0 0 auto; }
.rt-src__date,
.rt-src__dem { padding-left: 19px; }

/* --- Список-вибір при перекритті ліній (У-3) ----------------------- */

.rt-pick {
    list-style: none;
    margin: 0;
    padding: 0;
}

.rt-pick li + li { border-top: 1px solid var(--border-3); }

.rt-pick button {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 4px 10px;
    width: 100%;
    padding: 10px 4px;
    border: 0;
    background: none;
    text-align: left;
    cursor: pointer;
}

.rt-pick button:hover { background: var(--surface-2); }

.rt-pick__swatch {
    width: 12px;
    height: 12px;
    border-radius: 3px;
    background: var(--rt-mark, var(--muted-2));
    box-shadow: inset 0 0 0 1px rgb(46 36 25 / 0.28);
    grid-row: span 2;
}

.rt-pick__swatch--none,
.pdm-rrow__swatch.is-none {
    background: repeating-linear-gradient(
        45deg, var(--dash) 0 3px, transparent 3px 6px
    );
}

.rt-pick__name {
    font-size: 14px;
    font-weight: 600;
    color: var(--ink);
}

.rt-pick__meta {
    grid-column: 2;
    font-size: 12px;
    color: var(--muted);
}

/* --- Список маршрутів парку в легенді (У-9/У-10) ------------------- */

.pdm-routes__head {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 6px;
    border: 0;
    background: none;
    color: var(--ink-2);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}

.pdm-routes__head i { width: 15px; height: 15px; color: var(--muted-2); }
.pdm-routes__head > span:nth-child(2) { flex: 1; text-align: left; }

/* Скролабельний (У-10): 43 маршрути КНПП не мають виштовхувати
   легенду за екран. */
.pdm-routes__list {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 240px;
    overflow-y: auto;
}

.pdm-rrow {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 2px 8px;
    width: 100%;
    padding: 7px 6px;
    border: 0;
    border-radius: 8px;
    background: none;
    text-align: left;
    cursor: pointer;
}

.pdm-rrow:hover { background: var(--surface-2); }

/* Клавіатурний фокус видимий явно: список — ЄДИНИЙ клавіатурний шлях
   до картки маршруту (лінія на <canvas> не фокусується), тож ховати
   тут outline не можна (критерій 7). */
.pdm-rrow:focus-visible {
    outline: 2px solid var(--sage);
    outline-offset: 1px;
}

.pdm-rrow.is-active { background: var(--bg-2); }

.pdm-rrow__swatch {
    width: 10px;
    height: 10px;
    border-radius: 2px;
    background: var(--sw, var(--muted-2));
    box-shadow: inset 0 0 0 1px rgb(46 36 25 / 0.28);
    grid-row: span 2;
}

.pdm-rrow__name {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ink-2);
    line-height: 1.3;
}

.pdm-rrow__meta {
    grid-column: 2;
    font-size: 11px;
    color: var(--muted-3);
}

/* --- Мобільна поверхня (У-11) -------------------------------------- */
/* Паритет блоків із десктопом за конструкцією: та сама розмітка в тій
   самій .pdm-info, яка на ≤900px рендериться шторкою. Свотч маркування
   й довжина мусять лишатись видимими БЕЗ розгортання (критерій 8), тому
   нижче лише щільніші відступи — жодного display:none на цих блоках. */
@media (max-width: 900px) {
    .rt-elev { padding: 9px 10px; }
    .rt-elev__range { font-size: 15px; }
    .rt-zoom { width: 100%; justify-content: center; }
    .pdm-routes__list { max-height: 180px; }
}

/* ============================================================
   RECRE-418 — блок «Маршрути парку» + стан «маршрут обрано»
   (TOR-recre418-route-card-block, мокапи design_mockups/
   route-card-block/). Продовження того самого файлу: правка
   main.css і далі заблокована паралельним незакоміченим WIP.

   ПЕРЕВИКОРИСТАНО БЕЗ ЗМІН (жодного нового правила):
     .pcat-head / .pcat-head__count / .pcat-nav / .pcat-nav__btn
        — шапка секції спільна з «Каталогом точок інтересу»: два
          блоки мусять читатись як брати, а не як два віджети;
     .rt-mark / .rt-mark__swatch / .rt-net / .rt-ref — пілюлі з
          RECRE-367 вище: та сама пілюля в картці треку і в доці.

   ВІДХИЛЕННЯ ВІД ТЗ §7 (свідоме, з причиною): трек оголошений
   ОКРЕМИМ селектором .rtc-track, а не спільним
   `.pcat-track, .rtc-track { … }`. Правило .pcat-track живе в
   main.css, який у цьому тікеті чіпати заборонено. При
   перенесенні route-card.css у main.css два блоки треба злити в
   один селектор — це механічна правка, і вона тут описана саме
   для того, щоб її не забули.

   Нових hex немає; --rt-mark (колір фізичного маркування) уже
   введено RECRE-367 вище.
   ============================================================ */

/* --- 1. Секція «Маршрути парку» ------------------------------------ */

/* Дзеркало .pcat: явна верхня межа + відступ — секція читається
   окремим структурним блоком під сценою Атласу. */
.rtc {
    scroll-margin-top: calc(var(--header-h) + 12px);
    border-top: 1px solid var(--border-2);
    padding-top: 14px;
    margin-top: 22px;
}

/* Одне речення, яке знімає головне непорозуміння тікета («на карті
   можна натиснути на маршрут, а це неінтуїтивно») — тепер вхід у
   маршрут видимий текстом. */
.rtc__lead {
    margin: -2px 0 12px;
    font-size: 13px;
    color: var(--muted);
    max-width: 78ch;
}

/* Механіка треку — та сама, що .pcat-track (overflow-x + snap).
   RECRE-514: крайова маска (RECRE-236) знята ТУТ І ТАМ одночасно —
   дві каруселі одного продукту не можуть говорити різними мовами про
   те саме «є ще праворуч». Розгорнуте обґрунтування — в коментарі
   .pcat-track (main.css); коротко: фейд гасив край картки, за яким
   нічого не було, а тепер його роботу виконує візирна картка
   (--rm-carousel-peek). Класи is-at-start/is-at-end лишаються —
   вони дизейблять стрілки .pcat-nav у шапці секції. */
.rtc-track {
    display: flex;
    overflow-x: auto;
    padding: 2px 2px 12px;
    scroll-snap-type: x proximity;
    scroll-padding-left: 2px;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}
.rtc-track:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(126, 148, 102, 0.45); }
.rtc-track::-webkit-scrollbar { height: 8px; }
.rtc-track::-webkit-scrollbar-thumb { background: var(--border); border-radius: 8px; }
.rtc-track::-webkit-scrollbar-track { background: transparent; }

/* RECRE-514: слот маршруту = слот POI, СПІЛЬНИМ токеном.
   Було `clamp(262px, 30%, 316px)` — «вужчий за POI-шний, бо в картці
   маршруту немає фото, отже немає й 16/10-пропорції». Аргумент виявився
   хибним на практиці: ширину картки маршруту диктує не фото, а РЯД
   ПЛИТОК ФАКТІВ («у парку» · «перепад» · «час»), і на 316px він
   ламався у два стовпчики (скріншот ПВ, «Лопушне – Синевир»). Тому
   ширина тепер одна на обидві каруселі — --rm-carousel-slot (main.css,
   :root): на сцені 1060px це 331px замість 316px (а картка POI —
   331px замість 344px: різницю з'їла смуга визирної картки, якою
   RECRE-514 замінив крайовий фейд). Три плитки фактів стають в один
   ряд. Токен, а не число: дві копії тієї самої константи вже одного
   разу розійшлись, і саме це й породило тікет. */
.rtc-slot {
    flex: 0 0 var(--rm-carousel-slot);
    min-width: 0;
    margin-right: var(--rm-carousel-gap);
    display: flex;
    align-items: stretch;
    scroll-snap-align: start;
}
.rtc-slot:last-child { margin-right: 0; }

/* --- 2. Картка маршруту в треку ------------------------------------ */

.rtc-card {
    position: relative;
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 13px 15px 12px 18px;
    background: var(--surface);
    border: 1px solid var(--border-2);
    border-radius: 18px;
    box-shadow: 0 14px 30px -26px rgba(47, 74, 55, 0.55);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    transition: translate .18s ease, box-shadow .18s ease,
                border-color .18s ease, background .18s ease;
}

/* Колірна рейка маркування — та сама інформація, що свотч у пілюлі,
   але скановна вертикально: 43 маршрути КНПП користувач перебирає
   очима по кольору. Дубль кольору НЕ порушує правило «колір не єдиний
   канал»: підпис «жовте маркування» лишається в пілюлі нижче. */
.rtc-card::before {
    content: "";
    position: absolute;
    left: 0; top: 14px; bottom: 14px;
    width: 4px;
    border-radius: 0 4px 4px 0;
    background: var(--rt-mark, var(--muted-2));
}
/* Маршрут без маркування — штрихування, а не вигаданий колір. */
.rtc-card.is-unmarked::before {
    background: repeating-linear-gradient(45deg,
        var(--dash) 0 3px, transparent 3px 6px);
}

@media (min-width: 901px) {
    .rtc-card:hover {
        translate: 0 -3px;
        box-shadow: 0 18px 34px -24px rgba(47, 74, 55, 0.6);
        border-color: var(--border);
    }
}
.rtc-card:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(126, 148, 102, 0.45);
}

/* Обрана картка. Свідомо НЕ повторює linked-FLIP POI-каталогу («слот
   стуляється, картка відлітає в док»): у маршруту немає фото-hero,
   заради якого FLIP існує, а зникла з ряду картка ламає ГОЛОВНИЙ
   сценарій — перебір маршрутів порівнянням (43 у КНПП). */
.rtc-card.is-active {
    border-color: var(--sage);
    background: var(--surface-2);
    box-shadow: 0 0 0 2px rgba(126, 148, 102, 0.32),
                0 16px 30px -24px rgba(47, 74, 55, 0.6);
}

.rtc-card__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: 1.3px;
    text-transform: uppercase;
    color: var(--terracotta);
}
.rtc-card__eyebrow i, .rtc-card__eyebrow svg { width: 13px; height: 13px; flex: none; }
/* Номер маршруту праворуч в eyebrow-ряду — коли він справді номер */
.rtc-card__eyebrow .rt-ref { margin-left: auto; }

.rtc-card__name {
    margin: 0;
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 20px;
    font-weight: 700;
    line-height: 1.1;
    color: var(--green);
    /* Назви маршрутів довгі («№5048 «Стежками легендарної Тустані»»);
       у треку — прев'ю на 2 рядки, повна назва — в aria-label і в
       картці дока */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}

.rtc-card__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 1px;
}

/* Факти: до трьох чисел у ряд. Порожній факт → КОМІРКИ НЕМАЄ
   (правило «без заглушок»), ряд просто коротший. */
.rtc-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 3px 0 0;
}
/* RECRE-472: `min-width: fit-content` замість жорстких `76px`.
   ЧОМУ: `flex: 1 1 76px` ділить ряд між трьома комірками порівну (на
   картці 316px це ~90px кожній), а `min-width: 76px` ЗНІМАЄ автоматичний
   мінімум `auto` (= min-content) — і комірка отримує право стати вужчою
   за власне значення. Разом із `white-space: nowrap` у `dd` (нижче) це
   давало мовчазний оверфлоу: «≈ 2 дні (з ночівлею)» — найдовше можливе
   значення `routeTimeLabel` (гілка П-6 «дні», §4.2а блок 15) — займає
   146px і вилазило за межу картки в сусідню (скріншот ПО, «№504
   Трускавець – Славсько», 30,4 км · 604 м · ≈ 2 дні).

   `fit-content` = min(max-content, доступна ширина): комірка ніколи не
   вужча за свій текст, але й ніколи не ширша за ряд. Ряд уже
   `flex-wrap: wrap`, тож довга комірка просто ПЕРЕНОСИТЬСЯ на власний
   рядок і розтягується на всю ширину — жодного обрізання, ellipsis чи
   скорочення значення (число+одиниця мусять читатись цілими; той самий
   принцип, що заборона прочерків вище). 76px лишаються у flex-basis —
   саме вони й далі задають «три в ряд» для коротких чисел.

   NB: `min-width: min(100%, max-content)` тут НЕ працює — інтринсик-
   ключове слово не є `<length-percentage>` і всередині `min()` робить
   декларацію невалідною (перевірено в браузері: правило відкидається). */
.rtc-fact {
    flex: 1 1 76px;
    min-width: fit-content;
    padding: 6px 9px 7px;
    border: 1px solid var(--border-3);
    border-radius: 11px;
    background: var(--bg-2);
}
.rtc-fact dt {
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: var(--muted-2);
    white-space: nowrap;
}
.rtc-fact dd {
    margin: 2px 0 0;
    font-size: 14.5px;
    font-weight: 800;
    line-height: 1.2;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
/* «≈ 3 год» — час завжди подається як ОЦІНКА (RECRE-367 §4.2а
   блок 15), тому знак «≈» частина значення, а не декор. */
.rtc-fact--est dd { color: var(--ink-2); }

/* Примітка про фрагментованість геометрії: чесна межа замість тихо
   заниженого числа. */
.rtc-card__note {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 2px 0 0;
    font-size: 11.5px;
    line-height: 1.35;
    color: var(--muted-3);
}
.rtc-card__note i, .rtc-card__note svg {
    width: 12px; height: 12px; flex: none; margin-top: 1px;
}

/* Афорданс дії. НЕ вкладена кнопка: клікабельна вся картка
   (role="button"), а вкладений інтерактив усередині role="button" —
   пастка доступності. */
.rtc-card__cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: auto;
    padding-top: 9px;
    font-size: 12px;
    font-weight: 800;
    color: var(--green);
}
.rtc-card__cta i, .rtc-card__cta svg { width: 13px; height: 13px; }
.rtc-card__cta .icon-swap { display: inline-flex; }
.rtc-card.is-active .rtc-card__cta { color: var(--sage); }

/* --- 3. Стан «маршрут обрано» на полотні Атласу --------------------- */

/* 3.1 Притлумлення РОІ. Ключова вимога тікета: РОІ НЕ зникають — вони
   «додаткова історія про те, що поруч». Тому opacity, а не
   display:none і не filter: .38 лишає пін упізнаваним за кольором
   категорії й формою краплі, але знімає його з першого плану
   (grayscale заборонений: колір піна — і є категорія). Наведення/
   фокус повертає повну непрозорість — пін лишається робочим об'єктом.
   Маркери кінців під селектор не потрапляють: у них власний .rt-end. */
.pdm-canvas.is-route-focus .rm-poi-divicon,
.pdm-canvas.is-route-focus .rm-event-divicon {
    opacity: .38;
    transition: opacity .2s ease;
}
.pdm-canvas.is-route-focus .rm-poi-divicon:hover,
.pdm-canvas.is-route-focus .rm-poi-divicon:focus-within,
.pdm-canvas.is-route-focus .rm-event-divicon:hover {
    opacity: 1;
}
/* Активний пін (картка РОІ відкрита) під притлумлення не потрапляє —
   але цього стану й не буває: один обраний об'єкт на Атлас (У-4). */
.pdm-canvas.is-route-focus .rm-poi-divicon:has(.rm-poi-marker.is-active) {
    opacity: 1;
}
/* Стан лишається, зникає лише перехід */
@media (prefers-reduced-motion: reduce) {
    .pdm-canvas.is-route-focus .rm-poi-divicon,
    .pdm-canvas.is-route-focus .rm-event-divicon { transition: none; }
}

/* 3.2 Пілюля стану над полотном. Без неї притлумлення РОІ читається
   як баг («чому все зблякло?»): пілюля називає причину, показує колір
   маркування й дає вихід одним тапом.

   RECRE-447: bottom — НЕ 12px. Той самий низ-ліво кут займає контрол
   атрибуції Leaflet (park-mini-map.js додає L.control.attribution у
   position:"bottomleft"; leaflet.css кладе його з тим самим left:0/
   bottom:0, вище за z-index від .rt-focus — тобто рядок атрибуції
   малюється ПОВЕРХ пілюлі, а не поруч). За замовчуванням (короткий
   рядок CyclOSM) це непомітні кілька пікселів нахлесту, але на
   супутниковому шарі (basemap.js, довгий рядок Esri/Maxar/Earthstar,
   що переноситься в 2 рядки на вузькому Атласі) нахлест зʼїдає майже
   половину висоти пілюлі — саме комбінація «маршрут + супутник +
   вузький Атлас» зі скріншота PO. 40px — висота двох рядків атрибуції
   (leaflet.css: font 11px/1.4 ≈ 15.4px/рядок) плюс запас; атрибуцію
   свідомо НЕ чіпаємо (юридично обов'язкова), піднімаємо пілюлю. */
.rt-focus {
    position: absolute;
    left: 12px; bottom: 40px;
    z-index: 10;
    display: inline-flex;
    align-items: center;
    gap: 9px;
    /* RECRE-475: 200px, а не 24px, — це побічний ефект самого RECRE-447.
       Той тікет підняв пілюлю з bottom:12 на bottom:40, щоб вона зійшла
       з рядка атрибуції, — і тим самим поставив її в один рядок із
       пілюлею «Відкрити на карті» (.pdm-fullmap: right 12 / bottom 12,
       ~155px). На широкому полотні вони й далі не сходяться, але на
       вузькому Атласі сторінки парку (заміряно 504px на 1440px екрані)
       нахлест 17×5 px повернувся — просто в іншій парі.
       200 = 12 (відступ .pdm-fullmap) + ~156 (її ширина з підписом) +
       32 (проміжок): на вузькому полотні пілюля маршруту зупиняється,
       не доходячи до неї, а на широкому в силі лишається та сама
       стеля 340px, що й була. */
    max-width: min(340px, calc(100% - 200px));
    padding: 7px 8px 7px 12px;
    background: rgba(251, 245, 233, 0.95);
    border: 1px solid var(--border);
    border-radius: 30px;
    box-shadow: 0 12px 26px -16px rgba(47, 74, 55, 0.55);
    backdrop-filter: blur(4px);
}
.rt-focus__swatch {
    width: 10px; height: 10px; flex: none;
    border-radius: 3px;
    background: var(--rt-mark, var(--muted-2));
    box-shadow: inset 0 0 0 1px rgb(46 36 25 / 0.28);
}
.rt-focus__swatch.is-none {
    background: repeating-linear-gradient(45deg,
        var(--dash) 0 3px, transparent 3px 6px);
}
.rt-focus__name {
    font-size: 12px;
    font-weight: 800;
    color: var(--green);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rt-focus__hint {
    font-size: 11px;
    color: var(--muted-2);
    white-space: nowrap;
}
/* Кнопка скидання: візуально 26px, зона влучання 44×44 через ::after —
   правило touch-таргета не має ламати щільність пілюлі. */
.rt-focus__close {
    position: relative;
    display: grid;
    place-items: center;
    width: 26px; height: 26px;
    flex: none;
    border: 1px solid var(--border-2);
    border-radius: 50%;
    background: var(--surface-2);
    color: var(--muted);
    cursor: pointer;
}
.rt-focus__close::after {
    content: "";
    position: absolute;
    left: 50%; top: 50%;
    width: 44px; height: 44px;
    transform: translate(-50%, -50%);
}
.rt-focus__close:hover { background: var(--bg-2); color: var(--ink-2); }
.rt-focus__close:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(126, 148, 102, 0.45);
}
.rt-focus__close i, .rt-focus__close svg { width: 14px; height: 14px; }

/* ≤900px низ полотна зайнятий шторкою картки — пілюля переїжджає
   вгору, праворуч від кнопок зуму (.pdm-zoom: top 12 / left 12 / 32px)

   RECRE-475: right був 12px — пілюля доїжджала до самого краю полотна
   й лягала ПІД правий стовпчик кнопок (заміряно нахлест 30×30 px із
   .rm-locate «Моє місцеположення» у повноекранному Атласі на 375px).
   Тепер правий край впирається в той самий жолоб --atlas-ctl-r, що й
   .vs-pill (atlas.css): обидва банери над полотном рахують стовпчики
   однаково, а не кожен по-своєму. */
@media (max-width: 900px) {
    .rt-focus {
        left: 54px; right: var(--atlas-ctl-r, 52px); bottom: auto; top: 12px;
        max-width: none;
        padding: 6px 6px 6px 10px;
    }
    .rt-focus__hint { display: none; }
}

/* --- 4. Маркери кінців маршруту (divIcon) --------------------------- */

/* Корінь divIcon — 44×44 прозорий бокс: сам знак 22px, але палець
   отримує повний touch-таргет (iconSize [44,44], iconAnchor [22,22]). */
.rt-end {
    display: grid;
    place-items: center;
    width: 44px; height: 44px;
    background: none;
    border: 0;
}
.rt-end__body {
    display: grid;
    place-items: center;
    width: 22px; height: 22px;
    border-radius: 50%;
    background: var(--surface-2);
    border: 2px solid var(--rt-mark, var(--green));
    box-shadow: 0 6px 14px -8px rgba(46, 36, 25, 0.85);
    font-size: 10px;
    font-weight: 800;
    line-height: 1;
    color: var(--green);
}
.rt-end__body i, .rt-end__body svg { width: 11px; height: 11px; }

/* ДВА ЗНАКИ ПАРИ, А НЕ «СТАРТ І ФІНІШ». Напрямок зберігання геометрії
   довільний (виміряно RECRE-372: 30 % рядків записані «донизу»), тож
   жоден із кінців не має права називатись початком. У 1.1.0 обидва —
   рівноправні А/Б, різниться лише ЗАЛИВКА (щоб пара розрізнялась без
   кольору) і ПІДПИС тултипа. Знаки play/flag усередині .rt-end__body —
   РЕЗЕРВ під напрямлений Trail (RECRE-286), тут не вмикаються. */
.rt-end--finish .rt-end__body {
    background: var(--green);
    border-color: var(--surface-2);
    color: var(--surface-2);
    box-shadow: 0 0 0 1px rgba(46, 36, 25, 0.25),
                0 6px 14px -8px rgba(46, 36, 25, 0.85);
}

/* Поява разом із вибором маршруту */
.rt-end__body { animation: rtEndIn .22s cubic-bezier(.2,.8,.25,1) both; }
@keyframes rtEndIn {
    from { transform: scale(.4); opacity: 0; }
    to   { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .rt-end__body { animation: none; }
}

/* Підпис-тултип кінця (Leaflet tooltip, permanent: false) */
.rt-end-tip.leaflet-tooltip {
    background: rgba(251, 245, 233, 0.97);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 10px 22px -16px rgba(47, 74, 55, 0.6);
    color: var(--ink-2);
    font-size: 11.5px;
    font-weight: 700;
    padding: 4px 8px;
}
.rt-end-tip.leaflet-tooltip::before { display: none; }

/* --- 5. Кінці маршруту текстом у картці дока ------------------------ */
/* Знак на карті без пояснення в картці — це знак, який нікуди не веде */

.rt-ends { margin: 12px 0 4px; display: flex; flex-direction: column; gap: 6px; }
.rt-ends__row {
    display: flex; align-items: center; gap: 8px;
    font-size: 13px; color: var(--ink-2);
}
.rt-ends__badge {
    display: grid; place-items: center;
    width: 18px; height: 18px; flex: none;
    border-radius: 50%;
    border: 2px solid var(--rt-mark, var(--green));
    background: var(--surface-2);
    color: var(--green);
    font-size: 9.5px; font-weight: 800;
}
.rt-ends__badge--b {
    background: var(--green);
    color: var(--surface-2);
    border-color: var(--surface-2);
    box-shadow: 0 0 0 1px rgba(46, 36, 25, 0.25);
}

/* --- 6. Мобільна поверхня блоку карток ------------------------------ */
/* RECRE-514: власних ширин слота тут БІЛЬШЕ НЕМАЄ (було 252px на ≤900
   і 236px на ≤680) — і те, і те приходить спільним --rm-carousel-slot
   з медіа-блоків main.css, точно як у каталогу POI. Лишились самі лише
   типографіка й щільність картки. */
@media (max-width: 900px) {
    .rtc-card { padding: 12px 13px 11px 16px; }
    .rtc-card__name { font-size: 18px; }
    .rtc-fact dd { font-size: 14px; }
}
@media (max-width: 680px) {
    /* Стрілки треку ховаються (свайп) — те саме правило, що для
       .pcat-nav у main.css */
    .rtc .pcat-nav { display: none; }
    /* RECRE-514: «домінантна картка + визирна» вимагає mandatory —
       з proximity слот шириною майже на весь трек лишався б у стані
       спокою напівпрокрученим. Дзеркало .pcat-track на цій же ширині. */
    .rtc-track { scroll-snap-type: x mandatory; }
}

/* ============================================================
   RECRE-439 — доопрацювання картки маршруту: щільність, ритм,
   доступність (TOR-recre439-route-card-polish, мокапи
   design_mockups/route-card-polish/). Продовження того самого файлу:
   правка main.css і далі заблокована паралельним незакоміченим WIP.

   Секція лягає В КІНЦІ файлу навмисно: усе нижче — ПЕРЕОЗНАЧЕННЯ
   селекторів, оголошених вище (.rt-elev, .rt-zoom, .rt-src, .rt-mark__swatch
   тощо) плюс кілька нових класів каркаса ритму (.rt-card, .rt-nums,
   .rt-stats, .rt-stat, .rt-ends__pair, .rt-sr). Каскад вирішує все сам —
   останнє правило в файлі виграє за рівної специфічності, тому нічого не
   видаляється й не редагується по місцю вище.

   НОВИХ HEX НЕМАЄ. --rt-up = значення наявного --poi-restaurant
   (#B0552F), --rt-down = наявний --chip-amenity-fg. Обидва введені
   локально на .rt-elev, бо :root живе в main.css, який і далі
   заблокований паралельним WIP (та сама причина, що в шапці файлу).

   Коли route-card.css переноситимуть у main.css — підняти цю пару в
   :root іменованими токенами й злити .rt-stat з .rtc-fact в один
   селектор (так само, як уже записано про .pcat-track/.rtc-track вище).
   ============================================================ */

/* ------------------------------------------------------------------
   1. РИТМ. Один флекс-контейнер замість семи ad-hoc margin-ів.

   Чому обгортка, а не правка margin-ів по місцю:
   а) margin-и сусідніх блоків СХЛОПУВАЛИСЬ (10 + 12 давало 12), тож
      «відступ» у CSS і відступ на екрані були різними числами;
   б) .rt-zoom — inline-flex, і його margin-и НЕ схлопуються, зате
      навколо кнопки з'являлось міжрядкове поле анонімного line-box
      (~6px згори й знизу, залежно від line-height дока) — саме через
      це кнопка на скріншоті замовника «притиснута» згори й «відірвана»
      знизу нерівно;
   в) flex-gap не схлопується ніколи і не залежить від порядку блоків,
      тож будь-яка комбінація наявних/відсутніх полів картки дає той
      самий ритм.
   ------------------------------------------------------------------ */
.rt-card {
    display: flex;
    flex-direction: column;
    gap: 16px;                    /* МІЖ смисловими групами */
}
/* margin-и всередині картки більше не керують ритмом узагалі */
.rt-card > * { margin: 0; }

/* Шапка: назва + пілюлі — одна група, всередині 8px */
.rt-card__head { display: flex; flex-direction: column; gap: 8px; }
.rt-card__head .pdm-info__name { margin: 0; }
.rt-meta { margin: 0; }

/* Числова група: плитки довжини + висотний блок, всередині 10px */
.rt-nums { display: flex; flex-direction: column; gap: 10px; }

/* ------------------------------------------------------------------
   2. ДОВЖИНА — дві плитки dl замість речення на два рядки.

   Формула плитки — та сама, що .rtc-fact у картці треку (RECRE-418),
   тільки в док-масштабі: два «однакові» блоки мають виглядати
   однаково. Чесність підпису з RECRE-367 §4.2 п.4 збережена дослівно:
   не «Довжина», а «у межах парку» / «повна довжина» — просто тепер це
   <dt>, а не хвіст речення, тож пара «підпис → число» стає групою і
   для ока, і для скрінрідера.
   ------------------------------------------------------------------ */
.rt-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0;
}
.rt-stat {
    flex: 1 1 118px;
    min-width: 118px;
    padding: 7px 10px 8px;
    border: 1px solid var(--border-3);
    border-radius: 12px;
    background: var(--surface-2);
}
.rt-stat dt {
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: var(--muted);          /* 5,9:1 — було --muted-2 (3,3:1) */
    white-space: nowrap;
}
.rt-stat dd {
    margin: 2px 0 0;
    font-size: 16px;
    font-weight: 800;
    line-height: 1.2;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
/* Другорядна плитка (повна довжина) — те саме число, менший акцент */
.rt-stat--sub dd { font-size: 14.5px; color: var(--ink-2); }

/* ------------------------------------------------------------------
   3. ВИСОТНИЙ БЛОК. Було 4 рядки, стало 3:
     * «перепад 657 м у межах парку» -> «перепад 657 м». Хвіст «у межах
       парку» ЛИШАЄТЬСЯ в даних і виводиться, тільки коли плитки
       довжини відсутні (§3.2 ТЗ) — інакше та сама фраза стояла в
       картці тричі (довжина, перепад, кінці);
     * пунктирна лінія над часом прибрана: усередині рамки блоку це
       другий роздільник на 12px простору. Роль «це оцінка» несуть
       знак «≈» і слово «орієнтовно» — обидва лишаються.
   ------------------------------------------------------------------ */
.rt-elev {
    margin: 0;
    padding: 11px 12px 12px;
    display: flex;
    flex-direction: column;
    gap: 7px;
    border: 1px solid var(--border-3);
    border-radius: 12px;
    /* було var(--surface) — тобто рівно фон дока: рамка 1px --border-3
       на тому самому фоні дає 1,06:1 і блок читався як «нічий» текст.
       --surface-2 — house-патерн вкладеної картки (.pdc-teaser,
       .pdc-poi-group, .pdc-route--panel) */
    background: var(--surface-2);
    --rt-up: #B0552F;                      /* = значення --poi-restaurant */
    --rt-down: var(--chip-amenity-fg);     /* #5E6B48 */
}
.rt-elev > * { margin: 0; }
.rt-elev__main { gap: 3px 8px; }
.rt-elev__amp { color: var(--muted); }
/* Набір/спуск: --terracotta (#C16D45) на кремовому дає 3,7:1 і на
   14px це провал AA; --sage (#7E9466) — 3,2:1. Беремо глибші тони з
   тієї самої палітри: 4,9:1 і 5,6:1. Пара лишається НЕРОЗРИВНОЮ. */
.rt-elev__up { color: var(--rt-up); }
.rt-elev__down { color: var(--rt-down); }
.rt-elev__sep { color: var(--muted-3); }
.rt-elev__time {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
    color: var(--ink-2);
}
.rt-elev__est { font-size: 12px; color: var(--muted); }  /* було --muted-3, 3,1:1 */
/* RECRE-451: примітка «оцінка враховує довжину й підйом/спуск» — той
   самий приглушений тон і розмір, що .rtc-card__note компактної картки
   (house-патерн для «чесних» приміток під числом-оцінкою). --muted,
   НЕ --muted-3: на 11,5px --muted-3 провалює AA (3,1:1, §6 ТЗ,
   див. .rtc-card__note нижче), --muted лишає 5,9:1. */
.rt-elev__note {
    font-size: 11.5px;
    line-height: 1.35;
    color: var(--muted);
}

/* ------------------------------------------------------------------
   4. КІНЦІ А/Б — ОДИН рядок замість двох однакових.

   routeEndLabel() за конструкцією повертає ОДНАКОВИЙ підпис для обох
   кінців (він залежить від маршруту, не від кінця). Отже другий рядок
   не ніс жодного біта інформації — тільки 25px висоти й другий прохід
   скрінрідера тим самим текстом.
   ------------------------------------------------------------------ */
.rt-ends {
    display: flex;
    flex-direction: row;
    align-items: flex-start;   /* довгий підпис переноситься, знаки лишаються вгорі */
    gap: 8px;
    margin: 0;
    font-size: 13px;
    line-height: 1.45;
    color: var(--ink-2);
}
.rt-ends__pair { display: inline-flex; gap: 4px; flex: none; margin-top: 1px; }
.rt-ends__badge {
    width: 20px; height: 20px;
    font-size: 10px;
    /* Зовнішнє кільце: обвід знака А — це колір МАРКУВАННЯ (жовтий,
       білий), і на кремовому він давав 1,2:1, тобто знак А фактично
       зникав. 55 % темного дає 3,5:1 незалежно від кольору маркування
       і не підмінює сам колір. Те саме правило — на .rt-end__body
       (знак на полотні) нижче. */
    box-shadow: 0 0 0 1px rgb(46 36 25 / .55);
}
.rt-ends__badge--b {
    box-shadow: 0 0 0 1px rgb(46 36 25 / .55);
}
.rt-end__body { box-shadow: 0 0 0 1px rgb(46 36 25 / .55), 0 6px 14px -8px rgba(46, 36, 25, 0.85); }

/* ------------------------------------------------------------------
   5. ДІЯ. Головна (і єдина) дія картки.
     * висота 44px — touch-таргет був ~37px і на мобільному теж;
     * на всю ширину — прецедент .pdp-aside .pdc-btn--primary;
     * фон --bg-2 + рамка --sage: пара «--surface-2 + --border» давала
       межу 1,35:1, тобто кнопка не читалась як кнопка; тепер межа
       3,1:1 (AA для нетекстового), текст --green на --bg-2 — 7,8:1;
     * :focus-visible з'явився взагалі вперше (у продакшні його немає).
   ------------------------------------------------------------------ */
.rt-zoom {
    margin: 0;
    width: 100%;
    justify-content: center;
    min-height: 44px;
    padding: 11px 18px;
    background: var(--bg-2);
    border-color: var(--sage);
    font-size: 14px;
}
.rt-zoom:hover { background: var(--border); border-color: var(--green); }
.rt-zoom:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(126, 148, 102, 0.45);
}
.rt-zoom i, .rt-zoom svg { width: 16px; height: 16px; }

.rt-also { margin: 0; font-size: 13px; color: var(--muted); }

/* ------------------------------------------------------------------
   6. ПІДВАЛ ДЖЕРЕЛА. Три рядки 11,5px кольором --muted-3 (3,1:1 —
   провал AA) -> два рядки кольором --muted (5,9:1). Дата зрізу й
   джерело рельєфу — одним рядком через «·»: це один факт «звідки
   дані», а не два.
   ------------------------------------------------------------------ */
.rt-src {
    margin: 0;
    padding-top: 12px;
    border-top: 1px solid var(--border-3);
}
.rt-src p { color: var(--muted); margin: 0 0 3px; }
.rt-src p:last-child { margin-bottom: 0; }
.rt-src__meta { padding-left: 19px; }

/* ==================================================================
   RECRE-550 — «Парки на шляху» і застереження прикордонних ділянок.

   Обидва блоки живуть у ТІЙ САМІЙ картці .rt-card, що й усе вище, і
   тому не вводять ні власного ритму, ні власних токенів: вертикальні
   відступи задає `gap` контейнера (§2 ТЗ RECRE-439), кольори — :root
   з main.css.
   ------------------------------------------------------------------ */

/* Застереження про прикордонні ділянки. Терракота тут доречна саме
   тому, що в .pdc-rules вона вже означає «заборони й обмеження» — блок
   читається як обмеження, а не як довідка. Рамка ліворуч 3px + радіус
   0 10px 10px 0 — той самий рецепт контейнера, що .pdc-mountain. */
.rt-border {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin: 0;
    padding: 10px 12px 10px 11px;
    background: rgba(193, 109, 69, 0.08);
    border-left: 3px solid var(--terracotta);
    border-radius: 0 10px 10px 0;
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--ink);
}
.rt-border i, .rt-border svg {
    width: 15px; height: 15px; flex: none;
    margin-top: 1px;
    color: var(--terracotta);
}

/* «Парки на шляху». Список, а не речення через кому (на відміну від
   .rt-also): у кожного рядка є ДРУГЕ поле — довжина ділянки, і
   загорнути пару «назва + число» в суцільний текст означало б
   змусити око розбирати, де закінчується одне й починається інше. */
.rt-parks { margin: 0; }
.rt-parks__title {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 6px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--muted);
}
.rt-parks__title i, .rt-parks__title svg {
    width: 14px; height: 14px; flex: none; color: var(--green);
}
.rt-parks__list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.rt-parks__list li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 5px 0;
    font-size: 13px;
    border-bottom: 1px solid var(--border-3);
}
.rt-parks__list li:last-child { border-bottom: 0; }
.rt-parks__list a {
    color: var(--green);
    text-decoration: underline;
    padding: 2px 0;
}
.rt-parks__list a:hover { text-decoration: none; }
.rt-parks__km {
    flex: none;
    font-variant-numeric: tabular-nums;
    font-size: 12.5px;
    color: var(--muted);
}

/* ------------------------------------------------------------------
   7. Контрастні правки, спільні з карткою треку й пілюлею фокусу
   (виміри — §6 ТЗ).
   ------------------------------------------------------------------ */
/* Обвід свотча маркування. Рахувати треба по НАЙГІРШОМУ кольору
   довідника ROUTE_COLOUR_HEX, а це не жовтий, а БІЛИЙ (#F5F1E6):
   при 28 % обвід дає 1,92:1 (жовтий #E8B33A — 3,05:1, тобто на самій
   межі). 45 % білому все ще мало (2,89:1), тому 55 %: білий 3,79:1,
   жовтий 5,36:1. Сам колір маркування НЕ підмінюється — темнішає
   лише обвід у 1px. */
.rt-mark__swatch,
.rt-focus__swatch { box-shadow: inset 0 0 0 1px rgb(46 36 25 / .55); }
.rt-focus__hint { color: var(--muted); }
.rtc-card__note { color: var(--muted); }
.rtc-fact dt { color: var(--muted); font-size: 10px; }
/* Eyebrow КАРТКИ ТРЕКУ: --terracotta (#C16D45) на кремовому = 3,50:1.
   Eyebrow ДОКА не чіпаємо: він фарбується з LAYER_META.trail.color
   (#B4552D = 4,52:1) через --poi-type-color і вже проходить AA. */
.rtc-card__eyebrow { color: #B0552F; }   /* 3,50:1 -> 4,62:1 */

/* Візуально прихований текст для скрінрідера. У бою краще підняти в
   main.css як загальну .rm-sr (прецедент .rm-seo-ssr у seo-ssr.css) —
   тут локально, бо main.css заблокований. */
.rt-sr {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ------------------------------------------------------------------
   8. МОБІЛЬНА ПОВЕРХНЯ (шторка .poi-sheet, ≤900px).
   Ритм на крок щільніший (14px), але все ще більший за нинішні 10–12.
   ------------------------------------------------------------------ */
@media (max-width: 900px) {
    .rt-card { gap: 14px; }
    .rt-card__head { gap: 7px; }
    .rt-nums { gap: 9px; }
    .rt-elev { padding: 10px 11px 11px; }
    .rt-stat { flex: 1 1 108px; min-width: 108px; }
    .rt-stat dd { font-size: 15.5px; }
    .rt-zoom { min-height: 46px; }   /* палець на ходу, не за столом */
}

/* ============================================================
   RECRE-449 — «peek»-висота мобільної шторки маршруту (≤900px).

   ЩО БУЛО НЕ ТАК (скріншот замовника, 375–390px): .poi-sheet
   відкривається на max-height: min(72dvh, 640px), і на 812px-екрані
   від карти лишалась смуга ~90px. Тобто картка маршруту фізично не
   могла стояти поруч із самим маршрутом, хоча весь її сенс —
   зіставити числа з лінією.

   ЩО ЗМІНЕНО: ЛИШЕ ВИСОТА/ПОДАЧА контейнера. Вміст картки —
   дослівно той, що зробив RECRE-439 (ритм .rt-card, плитки .rt-stat,
   висотний блок): жодного правила звідти нижче не перевизначено,
   жодного display:none на блоках картки немає — межа «peek» лишається
   ЧИСТО геометричною, тому будь-який набір наявних/відсутніх полів
   маршруту дає коректну шторку без «дірок».

   ЛІНІЯ ЗРІЗУ (свідома, не побічна):
     ВИДНО БЕЗ РОЗГОРТАННЯ — назва, пілюлі (№, маркування, рівень
       мережі), плитки довжини, висотний блок (перепад / набір-спуск /
       ≈ час). Це рівно ті числа, заради яких маршрут і відкривають,
       і рівно той порядок, у якому їх кладе routeCardHtml — тому
       зріз працює висотою, без окремої «короткої версії» картки.
     ПОТРЕБУЄ РОЗГОРТАННЯ — опис, складність/покриття, кінці А/Б,
       «проходить також через», кнопка «Наблизити до маршруту»,
       підвал джерела (атрибуція ODbL + зріз + DEM).
   Атрибуція ODbL нікуди не зникає (юридична вимога, RECRE-439 §11
   П-3): вона в тій самій картці, за одним тапом, як і решта хвоста.

   ЧОМУ 42dvh: нижче ~196px не влазить група «назва + пілюлі +
   плитки» і зріз почав би різати саме те, заради чого шторку
   лишили відкритою; вище ~344px карта знову перестає читатись на
   зростом 812px. clamp тримає обидві межі на будь-якій діагоналі.
   ============================================================ */
@media (max-width: 900px) {
    /* height, а не max-height: .poi-sheet — флекс-колонка, і саме
       фіксована висота дає .poi-sheet__body передбачувану смугу
       зрізу (max-height лишився б без ефекту на короткій картці). */
    .poi-sheet.is-peek {
        height: clamp(196px, 42dvh, 344px);
    }
    /* Скрол у стуленому стані вимкнено НАВМИСНО: інакше вміст їздив
       би під нерухомий зріз і «показати все» перетворилось би на
       гру в прокрутку 200px вікном. Розгортання — єдиний шлях далі. */
    .poi-sheet.is-peek .poi-sheet__body {
        overflow: hidden;
        /* Уся площа стуленої картки — афорданс (@click -> розгорнути) */
        cursor: pointer;
        /* Згасання нижнього краю: зріз має читатись як «є ще», а не
           як кінець картки.
           NB (RECRE-514): горизонтальна маска країв .rtc-track/
           .pcat-track знята, але ЦЯ лишається — випадок інший.
           Там фейд гасив край СУСІДНЬОЇ картки, яку видно цілком і
           до якої можна доскролити; тут — обрив ОДНОГО тексту
           всередині картки, у якого немає ні сусіда, ні скролу
           (.poi-sheet__body { overflow: hidden } вище), тож єдиний
           канал сказати «текст триває» — саме згасання. */
        -webkit-mask-image: linear-gradient(to bottom,
            #000 calc(100% - 42px), transparent 100%);
        mask-image: linear-gradient(to bottom,
            #000 calc(100% - 42px), transparent 100%);
    }
    /* Плавна зміна висоти в тому ж темпі, що поява шторки */
    .poi-sheet { transition: transform .28s cubic-bezier(.33, 1, .4, 1),
                             height .28s cubic-bezier(.33, 1, .4, 1); }

    /* Кнопка «Показати все / Згорнути» в шапці шторки — ГЕОМЕТРИЧНА
       ПАРА до .pdm-info__close (26px коло, та сама рамка й фон): дві
       дії шапки мусять читатись як пара, а не як пілюля плюс кнопка.
       .pdm-info__close має margin-left: auto — auto забирає ця кнопка,
       а «×» його складає, інакше вільний простір поділився б між
       двома auto-полями й пара роз'їхалась би. */
    .poi-sheet__more {
        margin-left: auto;
        position: relative;
        display: grid;
        place-items: center;
        width: 26px; height: 26px; flex: none;
        border: 1px solid var(--border);
        border-radius: 50%;
        background: var(--surface-2);
        color: var(--green);
        cursor: pointer;
    }
    .poi-sheet__more + .pdm-info__close { margin-left: 0; }
    /* Шеврон — псевдоелемент, а не lucide-іконка (див. коментар у
       includes/poi_sheet.html: refreshIcons підміняє <i> на <svg>,
       і реактивний :data-lucide на підміненому вузлі не працює). */
    .poi-sheet__more::before {
        content: "";
        width: 7px; height: 7px;
        border-left: 2px solid currentColor;
        border-top: 2px solid currentColor;
        rotate: 45deg;                     /* вгору = «буде більше» */
        translate: 0 1px;
        transition: rotate .18s ease;
    }
    .poi-sheet__more[aria-expanded="true"]::before {
        rotate: -135deg;                   /* вниз = «згорнути» */
        translate: 0 -2px;
    }
    /* Візуально 26px, зона влучання 44×44 — той самий прийом ::after,
       що в .rt-focus__close і button.poi-sheet__grip. */
    .poi-sheet__more::after {
        content: "";
        position: absolute;
        left: 50%; top: 50%;
        width: 44px; height: 44px;
        transform: translate(-50%, -50%);
    }
    .poi-sheet__more:hover { background: var(--bg-2); }
    .poi-sheet__more:focus-visible {
        outline: none;
        box-shadow: 0 0 0 3px rgba(126, 148, 102, 0.45);
    }
}
@media (prefers-reduced-motion: reduce) {
    .poi-sheet { transition: none; }
    .poi-sheet__more::before { transition: none; }
}

/* ============================================================
   RECRE-474 — жест по грипу шторки (свайп) і його геометрія.

   Скарга продакт-оунера окремим рядком до самого тікета: грип
   виглядає як ручка, за яку тягнуть шторку, але тягнути його не
   можна було взагалі (RECRE-449 свідомо лишив лише тап). Афорданс
   без поведінки читається як зламаний елемент.

   Стан веде JS (sheetDragStart, atlasRouteCatalog у alpine-data.js),
   сюди він приходить двома значеннями:
     --sheet-drag — зсув під пальцем у px (0 = шторка на місці);
     .is-dragging — жест триває.
   ============================================================ */
@media (max-width: 900px) {
    /* Зсув кладеться ПОВЕРХ transform відкритого стану. Тому саме
       translate, а не transform: у .poi-sheet.is-open уже стоїть
       transform: translateY(0), і другий transform його переписав би
       (а разом із ним і закритий стан translateY(105%) — шторка
       стрибала б у кадр із-за краю екрана). Окрема властивість
       translate компонується з transform, не сперечаючись із ним. */
    .poi-sheet.is-open { translate: 0 var(--sheet-drag, 0px); }
    /* Довжину/темп бере зі скороченого запису §RECRE-449 вище (список
       значень повторюється циклічно), тому тут лише ДОДАЄМО translate
       до вже наявних transform/height — щоб повернення шторки на місце
       після незавершеного жесту анімувалось так само, як решта її
       станів, а не стрибало. */
    .poi-sheet { transition-property: transform, height, translate; }
    /* На час жесту перехід вимкнено: інакше шторка йшла б за пальцем
       із запізненням .28s і жест читався б як «залипає». Після
       pointerup клас знімається, --sheet-drag стає 0 — і повернення
       на місце вже анімується тим самим переходом, що й решта
       станів шторки. */
    .poi-sheet.is-dragging { transition: none; }
    /* Текст під пальцем не має виділятись на дразі */
    .poi-sheet.is-dragging, .poi-sheet.is-dragging * { user-select: none; }
}

/* ============================================================
   RECRE-549 — плаваюча картка НАСКРІЗНОГО маршруту на /map/.

   ВМІСТ картки не має власних стилів ЗОВСІМ: усередині
   .trail-card__body лежить рівно та сама розмітка
   .rt-card/.rt-meta/.rt-stats/.rt-src, що й у доці Атласу (одна
   функція routeCardHtml на два джерела, В-3), тож усі правила вище
   застосовуються без жодного дубля. Тут — лише КОНТЕЙНЕР: де панель
   стоїть над полотном і як згортається.

   Кут — правий верхній: лівий верх зайнятий зумом, лівий низ —
   панеллю фільтрів (і атрибуцією тайлів Leaflet). На вузьких екранах
   панель переїжджає в нижню шторку на всю ширину: у картці маршруту
   головне — довгий опис і числа, а не позиція в кутку.
   ============================================================ */
.trail-card {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 12;
    width: min(380px, calc(100% - 24px));
    max-height: calc(100% - 24px);
    display: flex;
    flex-direction: column;
    background: var(--paper, #FBF7EF);
    border: 1px solid rgba(138, 122, 92, 0.28);
    border-radius: 14px;
    box-shadow: 0 10px 30px rgba(46, 42, 38, 0.18);
    overflow: hidden;
}
.trail-card__bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 8px 10px 14px;
    border-bottom: 1px solid rgba(138, 122, 92, 0.18);
    background: rgba(138, 122, 92, 0.06);
}
.trail-card__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 1;
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted-2, #8A7A5C);
}
.trail-card__eyebrow svg { width: 14px; height: 14px; }
.trail-card__close {
    flex: none;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 10px;
    background: transparent;
    color: var(--muted-2, #8A7A5C);
    cursor: pointer;
}
.trail-card__close:hover { background: rgba(138, 122, 92, 0.12); }
.trail-card__close:focus-visible {
    outline: 2px solid var(--ochre, #D79A3F);
    outline-offset: 1px;
}
.trail-card__close svg { width: 18px; height: 18px; }
/* Опис Camino Podolico — кілька речень; панель гортається сама, а не
   виштовхує карту */
.trail-card__body {
    padding: 14px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Бага (ПВ, 2026-09-16): обидва — прямі сусіди під тим самим полотном
   карти (templates/map.html), і обидва претендують на правий верхній
   кут: .env-widget (main.css, position:absolute, top/right:16px) на
   ≥681px малюється ПОВЕРХ .trail-card (z-index 20 проти 12 тут).
   Усі чотири кути зайняті на цій сторінці (зум — низ-право, атрибуція
   Leaflet і панель фільтрів — низ-ліво), тож «посунути вбік» із
   застереження ПВ означає «вниз, під віджет» — єдиний вільний напрямок.
   Висота .env-widget — контент, не константа (текст погоди/AQI, стан
   завантаження), тому й ДВІ сходинки, а не одна: звичайний стан
   виміряно 299.6px (16 top + 300 + 16 запас = 332px), а
   .env-widget--intro (пояснення при першому показі, RECRE-414) — 408.6px
   (16 + 409 + 16 = 441px). :has() дивиться на сусіда за DOM-порядком
   (.env-widget рендериться нижче в розмітці), тому напрямок відносно
   .trail-card саме такий, не навпаки. */
@media (min-width: 681px) {
    /* Строго десктоп: .env-widget лишається в DOM (без .is-hidden) і
       на мобільному — там його ховає ІНШИЙ медіазапит (display:none,
       нижче в main.css), а не клас, тож без цього обмеження правило
       перебило б mobile-версію .trail-card (top:auto) специфічністю
       :has(), не порядком джерела.

       RECRE-564: кожній сходинці top — ВЛАСНА стеля max-height.
       Базовий calc(100% - 24px) рахує від top:12px, і зсунута вниз
       картка вилазила за низ полотна на весь зсув (виміряно на
       вьюпорті 768: top 441px + висота 645px = низ на 1185px — 417px
       за екраном, атрибуція і хвіст опису недосяжні НАВІТЬ скролом,
       бо гортається __body, а не сама картка). Стеля = висота полотна
       мінус top мінус той самий нижній відступ 12px, що в базовому
       стані: тіло картки (overflow-y:auto) далі гортається всередині,
       низ картки більше не пірнає під край в'юпорта. */
    .trail-card:has(~ .env-widget:not(.is-hidden)) {
        top: 332px;
        max-height: calc(100% - 344px);
    }
    .trail-card:has(~ .env-widget.env-widget--intro:not(.is-hidden)) {
        top: 441px;
        max-height: calc(100% - 453px);
    }
}

@media (max-width: 680px) {
    /* Шторка знизу: правий верх на телефоні перекриває і зум, і шапку */
    .trail-card {
        top: auto;
        right: 0;
        left: 0;
        bottom: 0;
        width: 100%;
        max-height: 62%;
        border-radius: 16px 16px 0 0;
        border-bottom: 0;
    }
    /* Бага (ПВ, 2026-09-16): .map-fab «Фільтри» — fixed, bottom:20px,
       z-index:15 (main.css) — тобто позиціюється відносно viewport,
       а не цієї шторки, і лежить ПОВЕРХ (z-index у неї 12) останніх
       рядків тексту, навіть прогорнутих до кінця. Прийом той самий,
       що вже рятує .survey-popup--map від того самого FAB (main.css,
       коментар «попап не перекриває FAB, ТЗ 2.6»): резервуємо простір
       ЗСЕРЕДИНИ прокручуваного __body, а не зсуваємо саму шторку —
       вона й далі впирається в самий низ екрана (задум «шторка знизу»
       незайманий), просто останній рядок тепер прогортується вище
       кнопки, а не ховається під нею назавжди.

       RECRE-564: 78px (як у survey-popup) виявилось замало САМЕ тут.
       Виміряно на 375x812: FAB із бейджем «N зони» займає 750..792px,
       а прогорнутий до упору низ футера картки (атрибуція OSM +
       «Зріз…») закінчувався на 734px — запас 16px, тонший за один
       рядок мети. Досить бейджу перенестись, шрифту стати на крок
       більшим (система/доступність) чи FAB піднятись над safe-area —
       і під кнопкою тоне саме рядок «Зріз…», який ПВ і побачив.
       Резерв тепер = 20px (bottom FAB) + 42px (висота FAB, виміряна З
       бейджем) + 36px запасу на його ріст — останній рядок футера
       гарантовано вище кнопки навіть у грубших умовах рендерингу. */
    .trail-card__body { padding-bottom: 98px; }
}
