/* ============================================================
   RECRE-293 — оглядовий режим карти (LOD-драбина країна → регіон →
   місто, TOR-map-layer-hierarchy-architecture §3/§7).

   Мета-мітка вузла ієрархії (.rm-node): коло з ЧИСЛОМ рекреаційних зон
   (завжди присутнє, ТЗ §7 питання 7) + підпис-пілюля «Назва · N зон»
   під ним (одиниця виміру — в підписі, не в колі; ТЗ §7 питання 11).
   Контур вузла (boundary_geom) — опційна векторна підложка, стилі
   NODE_BOUNDARY_* живуть у map.js.

   ОКРЕМИЙ файл, а не main.css: підключається лише на /map/
   (templates/map.html), іншим сторінкам ці стилі не потрібні.

   Палітра — токени Boho з main.css (:root доступний глобально).
   TODO(RECRE-339): візуальний концепт регіонів доопрацьовує Дизайнер —
   стилі стартові, під заміну його рішенням.
   ============================================================ */

/* Обгортка divIcon — без дефолтного фону/рамки Leaflet */
.rm-node-divicon {
    background: none;
    border: none;
}

.rm-node {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
}

/* Коло-лічильник: глибокий брендовий зелений, вершкове число й обвід —
   читається і на растровій підложці, і поверх шавлієвого контуру.
   RECRE-357 §15.4: 48→40px (густота кадру); клік-ціль лишається ≥44px —
   рядок .rm-node цілком клікабельний (кнопка з підписом-пілюлею під
   колом, фактична висота > 44px) */
.rm-node__count {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--green, #2F4A37);
    color: var(--surface, #FBF5E9);
    font-size: 13.5px;
    font-weight: 700;
    border: 2.5px solid rgba(251, 245, 233, 0.9);
    box-shadow: 0 6px 18px rgba(46, 36, 25, 0.28);
    transition: transform 0.15s ease, background 0.15s ease;
}

.rm-node:hover .rm-node__count,
.rm-node:focus-visible .rm-node__count {
    background: var(--green-hover, #26402E);
    transform: scale(1.06);
}

.rm-node:focus-visible {
    outline: none;
}

.rm-node:focus-visible .rm-node__count {
    box-shadow: 0 0 0 3px rgba(193, 109, 69, 0.55),
                0 6px 18px rgba(46, 36, 25, 0.28);
}

/* Підпис-пілюля під колом: «Карпати · 12 зон» */
.rm-node__label {
    max-width: 156px;
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(251, 245, 233, 0.92);
    border: 1px solid var(--border, #E3D4B3);
    color: var(--ink, #2E2419);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    box-shadow: 0 2px 8px rgba(46, 36, 25, 0.12);
}

/* ============================================================
   RECRE-339 §13.1 / RECRE-357 §15.3 — підписи вузлів на контурах.
   Регіон показується ПОЛІГОНОМ контуру (regionBoundaryStyle, map.js),
   мітка — лише текстовий підпис-кнопка на центроїді. Свідомо НЕ коло:
   коло-лічильник (.rm-node вище) означає вузол-агрегатор, а тут сенс
   несе сама площа контуру. Підпис без суфікса міста — рішення 15 (§9).

   §15.3: колишня ОДНА теракотова пігулка на регіон і місто зливала
   шари — тепер два різні трактування:
     .rm-region-label — «картографічний напис» (класика атласів:
        назва області — розріджений uppercase-текст із кремовим гало,
        НЕ кнопка-коробка);
     .rm-city-pill — суцільна зелена пігулка-вузол (мова системи:
        суцільний зелений = «можна увійти», як кола-лічильники).
   RECRE-448 — ТЮНІНГ ЧИТАБЕЛЬНОСТІ (типографіка, не нова концепція).
   Продакт-власник: назви областей на огляді країни погано читаються.
   Заміряно на живій карті (бохо-стиль Mapbox, 24 написи, z5-6):

   1. КОЛІР не проходив AA навіть у найкращому випадку. #A3572F на
      чистій землі #F4EBDA = 4.48:1 — нижче порогу 4.5:1 ще ДО будь-якої
      деталізації тайла. На водосховищі під «Черкаською» — 1.45:1.
   2. ГАЛО було не підложкою, а лише тінню. Заміряна середня
      непрозорість крему в кільці 2px навколо штрихів — 0.327: фактичне
      тло під літерою = ⅓ крему + ⅔ тайла. Найгірша точка з гало:
      1.45 → 1.50:1, тобто гало не рятувало взагалі.
   3. ПРИЧИНА слабкого гало — маса самих літер. Cormorant Garamond 700
      на 15px: 52 повністю непрозорих пікселі проти 445 згладжених —
      89.5% напису це антиаліасинг, медіанний горизонтальний штрих 2px
      (10-й перцентиль — 1px). Cormorant — ДИСПЛЕЙНА антиква (оптичний
      розмір 20px+), її волосяні лінії на 15px лягають у субпіксель.
      Розмита тінь від майже прозорого гліфа сама виходить прозорою —
      звідси й 0.327.
   4. ТРЕКІНГ 2.5px на 15px = 0.167em по великих літерах. Разом зі
      штрихом 1-2px рядок розсипається на окремі знаки: кирилична
      капітель і без того позбавлена виносних елементів, які тримають
      силует слова.

   ЩО ЗМІНЕНО і чому саме так, а не «пігулка як у міст». Сусідній
   .rm-city-pill вирішує ту саму задачу суцільною плашкою (крем на
   зеленому = 8.97:1, тло взагалі не впливає). Свідомо НЕ повторюємо:
     • суцільна заливка в мові системи означає «сюди можна увійти»
       (§15.3 вище) — плашка на регіоні знову злила б два шари, які
       RECRE-357 щойно розвів;
     • на z5 в кадрі до 24 областей: два десятки плашок замостили б
       країну хромом і вбили «акварельний атлас».
   Тому прийом лишається «напис із гало», але гало зроблено робочим:
     • колір #6E3A1F — той самий відтінок, що #A3572F (H≈20.6°,
       S≈56%), лише темніший (L 41% → 27%). Не новий колір палітри, а
       затемнений теракотовий тон САМЕ для тексту поверх сирих тайлів;
     • гало = 8 жорстких зсувів по 1px (класичний картографічний
       «faux stroke») + дві м'які тіні для атласної розмитості.
       Заміряна непрозорість кільця: 0.327 → 0.741;
     • 15px → 16px і трекінг 2.5px → 1.6px: частка непрозорого чорнила
       0.105 → 0.175, при цьому напис став ВУЖЧИМ (109px → 106px на
       «ЧЕРКАСЬКА»), тож anti-collision (RECRE-360 §16) вміщує не
       менше написів, ніж раніше.
   Результат на тих самих 10 видимих написах: найгірший контраст
   1.50:1 → 5.68:1, типовий 3.2:1 → 7.2:1 (AAA).

   ------------------------------------------------------------
   RECRE-476 — МАСШТАБ І ТОН. Скарга ПВ (скрін до тікета, z6 над
   центром України): «підписи областей накладаються на базову карту та
   в цілому є позамасштабними… візуально сильно вирізняються і не
   вписуються в загальний дизайн».

   ЩО САМЕ ВИРІЗНЯЛОСЬ — два незалежні прорахунки RECRE-448, обидва
   заміряні на тому самому скріні:

   1. КЕГЛЬ БУВ СТАЛИЙ. 16px трималось на ВСІХ зумах оглядового рівня,
      тобто напис «ДНІПРОПЕТРОВСЬКА» на z5 (уся країна в кадрі, 24
      області) мав рівно ту саму висоту, що на z6 над однією областю.
      У картографії кегль топоніма — функція масштабу: назва області на
      огляді країни мусить бути ДРІБНІШОЮ за назву країни на базовій
      підложці, а не більшою. На скріні навпаки: наш «КИЇВСЬКА» має
      x-height ~1.45× від «Україна» самої підложки — око читає нашу
      область як об'єкт вищого рангу, ніж держава під нею. Звідси й
      «позамасштабними», і «накладаються»: 16px × довга кирилична
      капітель = 190px на «ДНІПРОПЕТРОВСЬКА», що ширше за саму
      область на z5.

   2. ГАЛО БУЛО ХМАРОЮ, А НЕ КОНТУРОМ. Дві м'які тіні RECRE-448 —
      6px і 10px — це кремовий ореол радіусом до 10px навколо КОЖНОЇ
      літери; на рядку в 190px він зливається в суцільну пляму, що
      світлішає тайл під усім написом. Саме її й видно на скріні як
      «вирізняється з дизайну»: базова підложка (бохо-Mapbox) своїх
      написів так не підсвічує.

   ЩО ЗМІНЕНО — і чого СВІДОМО НЕ чіпаємо, щоб не відкотити RECRE-448:

   А. КЕГЛЬ ТЕПЕР ЗАЛЕЖИТЬ ВІД ЗУМУ — `--rm-region-label-size`, яку
      ставить `syncRegionLabelScale()` (map.js) на контейнер карти:
      13px на z≤5 → 16px на z≥8, лінійно між ними. Верхня межа —
      РІВНО значення RECRE-448: там, де напис лишився один (підпис
      активної області на LOD «регіон», .rm-region-label--caption),
      типографіка не змінилась ані на піксель. Змінився лише той
      випадок, на який скаржиться тікет, — натовп написів на огляді
      країни.
      Трекінг переведено з 1.6px на 0.1em: це ТЕ САМЕ значення на 16px
      (1.6/16 = 0.1), але воно тепер їде за кеглем, а не лишається
      непропорційно широким на 13px.

   Б. ЧОРНИЛО НА ДРІБНОМУ КЕГЛІ КОМПЕНСОВАНО ШТРИХОМ, а не
      відмовою від зменшення. Ключове заперечення проти «просто
      зменшити» — п.3 RECRE-448 вище: Cormorant Garamond — дисплейна
      антиква, її волосяні лінії на 15px уже субпіксельні, і саме
      браком непрозорого чорнила там пояснили провал гало. Тому кегль
      знижується РАЗОМ із `-webkit-text-stroke: 0.32px currentColor`
      (той самий колір, що заливка — потовщення штриха, а не обведення):
      медіанний горизонтальний штрих 2px×13/16 = 1.63px → 2.27px,
      тобто ГУСТІШЕ, ніж було на 16px без штриха. Частка непрозорого
      чорнила 0.175 → 0.19. Гало відкидається саме з цього чорнила,
      тож заміряні 0.741 у кільці не просідають.
      Колір #6E3A1F НЕ чіпається — це головний важіль контрасту
      RECRE-448 (7.75:1 на чистій землі), і тікет про масштаб, не про
      тон тексту.

   В. ГАЛО СТИСНУТО, А НЕ ПОСЛАБЛЕНО. Вісім ЖОРСТКИХ зсувів по 1px
      (той самий faux-stroke, та сама альфа 0.92) лишаються без змін —
      це вони дають 0.741 у робочому кільці 2px, тобто саме вони
      тримають читабельність. Прибрано лише широку хмару: 6px/0.90 +
      10px/0.75 → одна тінь 3px/0.70. Ореол падає з ~10px до ~3px,
      напис перестає світити крізь підложку — і при цьому кільце, яке
      RECRE-448 міряв, лишається кремовим.

   Разом: на z5 напис має 13px + компенсаційний штрих замість 16px із
   хмарою, тобто в кадрі стає ~19% вужчим (190px → 154px на
   «ДНІПРОПЕТРОВСЬКА») — це ще й прямий виграш для anti-collision
   RECRE-360 §16: більше областей отримують видиму назву.
   ------------------------------------------------------------
   ============================================================ */

.rm-region-divicon {
    background: none;
    border: none;
}

.rm-region-label {
    position: absolute;
    transform: translate(-50%, -50%);
    padding: 4px 8px;
    background: none;
    border: none;
    /* RECRE-448: затемнений теракотовий (той самий відтінок H≈20.6°,
       що й колишній #A3572F — лише світлота 41% → 27%). #A3572F давав
       4.48:1 на чистій землі, тобто не проходив AA навіть без деталей
       тайла; #6E3A1F дає 7.75:1 на тій самій землі. */
    color: #6E3A1F;
    font-family: 'Cormorant Garamond', Georgia, serif;
    /* RECRE-448: 15px → 16px. Cormorant — дисплейна антиква, її
       волосяні лінії на 15px субпіксельні (89.5% напису — самий лише
       антиаліасинг). Зайвий піксель кегля піднімає частку непрозорого
       чорнила з 0.105 до 0.175 — і саме з цього чорнила відкидається
       гало нижче. */
    /* RECRE-476: кегль — функція ЗУМУ (`syncRegionLabelScale`, map.js
       ставить змінну на контейнер карти). Фолбек 16px = значення
       RECRE-448: якщо JS не встиг/вимкнено, поведінка тотожна
       попередній, ані на піксель не гірша. */
    font-size: var(--rm-region-label-size, 16px);
    font-weight: 700;
    line-height: 1.2;
    /* RECRE-476: компенсація тонкості на ДРІБНОМУ кеглі. Той самий
       колір, що заливка, тобто це потовщення штриха, а не обведення:
       воно повертає Cormorant'у на 13px ту саму густину чорнила, з якої
       RECRE-448 відкидає гало (розбір — у шапці секції, п. Б). */
    -webkit-text-stroke: 0.32px currentColor;
    /* RECRE-448: 2.5px → 1.6px. Розрідження лишається «атласним», але
       рядок знову читається словом, а не низкою окремих знаків.
       RECRE-476: те саме значення записано ВІДНОСНО (1.6/16 = 0.1em),
       щоб трекінг їхав за кеглем — інакше на 13px він лишався б
       непропорційно широким і рядок знову розсипався б на знаки. */
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
    cursor: pointer;
    /* Кремове гало замість фону-плашки: контраст поверх тайлів —
       той самий прийом, що колишній фон 0.92 (§15.4).
       RECRE-448: дві розмиті тіні давали в кільці навколо штриха лише
       0.327 непрозорості (крем «просвічував» тайл наскрізь). Тепер
       спершу 8 ЖОРСТКИХ зсувів по 1px — картографічний «faux stroke»,
       що дає суцільний кремовий контур навколо кожного штриха
       (0.741 у тому ж кільці), і лише потім дві м'які тіні, які
       лишають атласну розмитість краю. Розмиття рахується тільки для
       двох останніх — вісім жорстких копій майже безкоштовні.
       RECRE-476: вісім ЖОРСТКИХ зсувів і їхня альфа 0.92 — БЕЗ ЗМІН
       (це вони дають заміряні 0.741 у кільці 2px, тобто саме вони й
       тримають читабельність). Стиснуто лише широку хмару: 6px/0.90 +
       10px/0.75 → одна тінь 3px/0.70. Ореол з ~10px до ~3px: напис
       перестає підсвічувати тайл під усім рядком і повертається в
       мову бохо-підложки, що своїх написів так не світить. */
    text-shadow:
         1px    0   0 rgba(251, 245, 233, 0.92),
        -1px    0   0 rgba(251, 245, 233, 0.92),
          0    1px  0 rgba(251, 245, 233, 0.92),
          0   -1px  0 rgba(251, 245, 233, 0.92),
         1px   1px  0 rgba(251, 245, 233, 0.92),
        -1px  -1px  0 rgba(251, 245, 233, 0.92),
         1px  -1px  0 rgba(251, 245, 233, 0.92),
        -1px   1px  0 rgba(251, 245, 233, 0.92),
          0    0   3px rgba(251, 245, 233, 0.70);
    border-radius: 8px;   /* лише для фокус-кільця */
    /* opacity 0.2s — fade появи напису, що виграв місце після зуму-in
       (RECRE-360 §16.2 п.4); transform — чинний hover-scale */
    transition: transform 0.15s ease, opacity 0.2s ease;
}

.rm-region-label:hover,
.rm-region-label:focus-visible {
    transform: translate(-50%, -50%) scale(1.06);
}

.rm-region-label:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(193, 109, 69, 0.55);
}

/* Hit-area ≥44px по вертикалі — прозорий ::after (чек-лист §8) */
.rm-region-label::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    height: 46px;
}

/* RECRE-422: напис АКТИВНОГО регіону на рівні «регіон» — підпис-
   ПІДТВЕРДЖЕННЯ того, що називає ліва панель («Парки · Черкащина»), а не
   кнопка навігації: <span>, не <button> (makeRegionLabel opts.caption).
   Типографіка успадковується від .rm-region-label вище — змінюється лише
   інтерактивність: без курсора-руки, без hover-scale, без перехоплення
   вказівника (під написом лишаються клікабельними контури міст і великих
   парків рівня). */
.rm-region-label--caption {
    cursor: default;
    pointer-events: none;
}

/* ============================================================
   RECRE-360 §16 — anti-collision написів регіонів на огляді країни.
   Напис, що програв greedy-перевірку перетину (declutterRegionLabels,
   map.js), ховається ЛИШЕ класом — маркер з карти не знімається, тож
   поява при зумі-in дешева. visibility затримується до кінця fade-out
   (0.2s), а при появі знімається одразу — opacity базового правила
   вище дає симетричний fade 200мс в обидва боки. Типографіка/колір
   §15.3 не чіпаються — фікс лише про видимість.
   Клас застосовується і до фолбек-кола .rm-node регіону без контуру
   (§16.2 п.1) — селектор свідомо самодостатній.
   ============================================================ */
.rm-region-label--collided {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.2s ease, visibility 0s linear 0.2s;
}

/* §16.3: desktop-«peek» — ховер по контуру регіону тимчасово показує
   його прихований напис (z-порядок піднімає setZIndexOffset у
   peekRegionLabel, map.js; кремове гало §15.3 відпрацьовує підложку).
   pointer-events лишаються none: наведення на сам peek-напис не має
   збивати mouseout контуру (мерехтіння); aria-hidden лишається true —
   це курсорна підказка, не новий tab-stop. */
.rm-region-label--collided.rm-region-label--peek {
    opacity: 1;
    visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
    .rm-region-label { transition: none; }
    .rm-region-label:hover { transform: translate(-50%, -50%); }
    /* RECRE-360 §16.2 п.4: поява/зникнення прихованих написів — миттєво */
    .rm-region-label--collided { transition: none; }
}

/* Пігулка міста на рівні регіону (§15.3): суцільна зелена заливка,
   вершковий текст, системний шрифт — вузол-вхід, а не напис-тло */
.rm-city-pill {
    position: absolute;
    transform: translate(-50%, -50%);
    padding: 5px 13px;
    border-radius: 999px;
    background: var(--green, #2F4A37);
    border: none;
    color: var(--surface, #FBF5E9);
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    box-shadow: 0 4px 12px rgba(46, 36, 25, 0.24);
    transition: transform 0.15s ease, background 0.15s ease;
}

.rm-city-pill:hover,
.rm-city-pill:focus-visible {
    transform: translate(-50%, -50%) scale(1.06);
    background: var(--green-hover, #26402E);
}

.rm-city-pill:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(193, 109, 69, 0.55),
                0 4px 12px rgba(46, 36, 25, 0.24);
}

/* Hit-area ≥44px по вертикалі — прозорий ::after (чек-лист §8) */
.rm-city-pill::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    height: 46px;
}

@media (prefers-reduced-motion: reduce) {
    .rm-city-pill { transition: none; }
    .rm-city-pill:hover { transform: translate(-50%, -50%); }
}

/* ============================================================
   RECRE-471 — БУЛЬБАШКА КЛАСТЕРА МІСТ (.rm-city-cluster).

   Скарга ПВ (скрін, z8 над Києвом): «міста хоч і є акуратними та
   точковими, проте необхідно їх зводити в кластер, інакше карта не є
   читабельною». До цього тікета єдиною відповіддю на скупчення була
   крапка .rm-city-pill--collided — 11 супутників Києва (RECRE-458)
   лишались 11 окремими крапками, і жодна з них не казала, що поруч є
   ще десять.

   ЧОМУ ПІГУЛКА, А НЕ КОЛО — у системі вже три кола з числом:
     .rm-cluster      (парки)  — кремове коло, темна цифра;
     .gpark-cluster            — кремове коло, sage-обід, Cormorant;
     .rm-node__count           — ЗЕЛЕНЕ коло, кремова цифра, і воно вже
                                 означає «ОДИН вузол на N зон»
                                 (легенда RECRE-455).
   Ще одне зелене коло з числом читалось би саме як четверте значення в
   тому самому знаку. Пігулка лишає бульбашку у ФОРМІ родини міст
   (.rm-city-pill — «сюди можна увійти»), а трійка крапок + число
   всередині відрізняє «кілька вузлів» від «один вузол». Слово
   («3 міста») у бульбашці свідомо НЕ пишеться: воно є в aria-label
   разом з переліком назв, а на карті зайва ширина плашки поверталася б
   до тієї самої нечитабельності, від якої тікет.
   ============================================================ */
.rm-city-cluster-divicon {
    background: none;
    border: none;
}

.rm-city-cluster {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border-radius: 999px;
    background: var(--green, #2F4A37);
    /* Кремовий обідець — той самий прийом, що в .rm-node__count і в
       крапці .rm-city-pill--collided: бульбашка не зливається з темними
       тайлами лісу й води */
    border: 2px solid rgba(251, 245, 233, 0.9);
    color: var(--surface, #FBF5E9);
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    box-shadow: 0 6px 18px rgba(46, 36, 25, 0.28);
    transition: transform 0.15s ease, background 0.15s ease;
}

/* Трійка крапок = «кілька вузлів». Градієнти, а не три <span>: розмітка
   бульбашки лишається однорядковою, і знак не залежить від шрифта. */
.rm-city-cluster__dots {
    width: 14px;
    height: 4px;
    flex: none;
    background:
        radial-gradient(circle at 2px 2px, currentColor 1.8px, transparent 1.9px),
        radial-gradient(circle at 7px 2px, currentColor 1.8px, transparent 1.9px),
        radial-gradient(circle at 12px 2px, currentColor 1.8px, transparent 1.9px);
    opacity: 0.85;
}

.rm-city-cluster__count { letter-spacing: 0.2px; }

.rm-city-cluster:hover,
.rm-city-cluster:focus-visible {
    transform: translate(-50%, -50%) scale(1.06);
    background: var(--green-hover, #26402E);
}

.rm-city-cluster:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(193, 109, 69, 0.55),
                0 6px 18px rgba(46, 36, 25, 0.28);
}

/* Хіт-ціль ≥44px (чек-лист §8) — плашка має висоту ~28px */
.rm-city-cluster::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    height: 46px;
}

/* Місто, згорнуте в кластер: мітка гасне ПОВНІСТЮ й виходить із
   tab-порядку — на відміну від --collided (RECRE-431), де крапка
   лишалась видимим клікабельним якорем. Тут якорем стає бульбашка:
   лишати під нею ще й невидимий tab-stop кожного члена означало б
   12 «мертвих» зупинок табуляції на одну бульбашку.
   aria-hidden/tabindex ставить JS (syncCityClusters не чіпає атрибути —
   клас достатній, бо pointer-events знімає й клік). */
.rm-city--clustered {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.18s ease, visibility 0s linear 0.18s;
}

@media (prefers-reduced-motion: reduce) {
    .rm-city-cluster { transition: none; }
    .rm-city-cluster:hover { transform: translate(-50%, -50%); }
    .rm-city--clustered { transition: none; }
}

/* ============================================================
   RECRE-357 — мітки великих парків: варіант C «Акварель» (вибір
   продакт-власника, §14.7 дизайн-ТЗ TOR-1.0.9-regions-ui; значення —
   1:1 з мокапа Designer/mockups/regions-1.0.9-gpark-variants/
   gpark-variants.html, секція C: .c-badge / .c-cluster / .c-pill).

   Система міток: вузол навігації = коло з числом; великий парк —
   кінцевий об'єкт, клік відкриває картку, а не рівень нижче. Точка —
   кремовий круглий бейдж із sage-ободом і м'яким ореолом того самого
   кольору (--gpc; RECRE-357 §15.1: колірне кодування типу ПЗФ
   СКАСОВАНО — всі типи --sage #7E9466, тип кодують іконка + рядок
   typeShort + фільтр «Тип території»); підписи — Cormorant italic.
   Жодного пунктиру, жодної жорсткої лінії. Розміри — §15.4 (34px
   бейдж / 40px кластер, клік-цілі ≥44px прозорими ::after).
   Попередній стиль сквіркла/«ДНК зони» (RECRE-339) — замінено.
   ============================================================ */

/* Обгортка divIcon: без дефолтного фону/рамки Leaflet; iconSize [0,0] —
   кліки приймає лише сама кнопка .gpark (pointer-events нижче) */
.gpark-divicon {
    background: none;
    border: none;
}
.leaflet-marker-icon.gpark-divicon { pointer-events: none; }

.gpark {
    --gpc: var(--sage, #7E9466);
    position: absolute;
    transform: translate(-50%, -50%);
    z-index: 3;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    font-family: inherit;
    pointer-events: auto;
}

/* Hit-area ≥44×44 прозорим ::after (патерн прототипу, чек-лист §8) */
.gpark::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 0;
    transform: translateX(-50%);
    width: 46px;
    height: 46px;
}

/* Бейдж точки (= .badge-new мокапа color-hierarchy): кремове коло 34px
   (§15.4: було 42), обід 2.5px --sage, ореол 4px color-mix, іконка
   Lucide 16px — колір скрізь єдиний sage (§15.1) */
.gpark__badge {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--surface, #FBF5E9);
    border: 2.5px solid var(--gpc);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--gpc) 18%, transparent),
                0 6px 12px rgba(36, 52, 38, 0.18);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gpc);
    transition: transform 0.18s ease;
}
.gpark__badge svg {
    width: 16px;
    height: 16px;
}
.gpark:hover .gpark__badge { transform: scale(1.1); }
.gpark:focus-visible { outline: none; }
.gpark:focus-visible .gpark__badge {
    transform: scale(1.12);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--gpc) 28%, transparent),
                0 0 0 6px rgba(47, 74, 55, 0.35);
}

/* Пігулка-назва (= .name-new мокапа): Cormorant italic, без рамок;
   §15.4: 14→12.5px, max-width 240→200px */
.gpark__name {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-style: italic;
    font-size: 12.5px;
    font-weight: 700;
    color: #4E6B41;
    background: rgba(251, 245, 233, 0.92);
    border-radius: 20px;
    padding: 2px 9px;
    white-space: nowrap;
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    box-shadow: 0 2px 5px rgba(36, 52, 38, 0.10);
}

.gpark__type {
    font-size: 8.5px;
    font-weight: 800;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--muted-2, #8A7A5C);
    background: rgba(251, 245, 233, 0.85);
    border-radius: 20px;
    padding: 1px 8px;
    white-space: nowrap;
}

/* Полігонний режим (від gparkPolyMinZoom, §14.2): бейджа немає — лише
   пігулка-підпис контуру; фокус-стан — на пігулці. Свотч і пунктирна
   межа старої мови видалені (§14.7-C: без пунктиру) */
.gpark--poly .gpark__name {
    transition: transform 0.18s ease;
}
.gpark--poly:hover .gpark__name { transform: scale(1.04); }
.gpark--poly:focus-visible .gpark__name {
    box-shadow: 0 0 0 3px rgba(193, 109, 69, 0.45);
}

/* Кластер великих парків (§14.1, = .cluster-new мокапа): коло 40px
   (§15.4: було 48; 40 < 44, тож клік-ціль добирає прозорий ::after) —
   «можна наблизитись» (семантика системи §2); від міського .rm-cluster
   відрізняється тонованим кремовим тлом, sage-ободом і Cormorant-цифрою */
.gpark-cluster-divicon {
    background: none;
    border: none;
}
.gpark-cluster {
    --gpc: var(--sage, #7E9466);
    position: relative;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--gpc) 14%, #FBF5E9);
    border: 2.5px solid var(--gpc);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--gpc) 16%, transparent),
                0 6px 12px rgba(36, 52, 38, 0.18);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 17px;
    font-weight: 700;
    color: var(--green, #2F4A37);
    cursor: pointer;
}
/* Hit-area 44px поверх кола 40px (чек-лист §8) */
.gpark-cluster::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 44px;
    height: 44px;
    border-radius: 50%;
}

/* «Розмитий» край акварельного полігона (§14.7-C): CSS-фільтр на
   SVG-path Leaflet — еквівалент feGaussianBlur stdDeviation=5 мокапа
   без кастомного рендерера. pointer-events: none — підложка
   неінтерактивна і на рівні DOM (страховка до interactive:false) */
.gpark-wc-edge {
    filter: blur(5px);
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    .gpark__badge, .gpark--poly .gpark__name { transition: none; }
    .gpark:hover .gpark__badge, .gpark--poly:hover .gpark__name { transform: none; }
}

/* ============================================================
   RECRE-357 §14.4/§14.5 — «Шари та легенда»: динамічні рядки легенди
   (функція рівня LOD) + перемикачі шарів. Символи (.lgs--*) — суто
   CSS-мініатюри реальних елементів карти (без Lucide: рядки
   перерендерюються Alpine при зміні рівня, іконкам був би потрібен
   повторний refreshIcons).
   ============================================================ */

.layer-row {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;               /* клік-ціль ≥44px (чек-лист §8) */
    padding: 2px 0;
    cursor: pointer;
    font-size: 12.5px;
    color: var(--ink-2, #3A3127);
}
.layer-row__label { flex: 1 1 auto; }

/* Візуально прихований, але фокусований чекбокс (a11y §14.5) */
.tgl__input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    clip: rect(0 0 0 0);
    overflow: hidden;
    white-space: nowrap;
}

/* Повзунок 30×18: увімкнено — --sage, вимкнено — --dash */
.tgl {
    flex: none;
    position: relative;
    width: 30px;
    height: 18px;
    border-radius: 999px;
    background: var(--dash, #D8C69F);
    transition: background 0.18s ease;
}
.tgl::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--surface-2, #FFFDF8);
    box-shadow: 0 1px 3px rgba(46, 36, 25, 0.3);
    transition: transform 0.18s ease;
}
.tgl__input:checked ~ .tgl { background: var(--sage, #7E9466); }
.tgl__input:checked ~ .tgl::after { transform: translateX(12px); }
.tgl__input:focus-visible ~ .tgl {
    box-shadow: 0 0 0 3px rgba(193, 109, 69, 0.45);
}
@media (prefers-reduced-motion: reduce) {
    .tgl, .tgl::after { transition: none; }
}

/* Символи легенди */
.lgs {
    flex: none;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    line-height: 1;
}
/* Бейдж великого парку (мініатюра .gpark__badge, sage як зразок групи) */
.lgs--gpark {
    width: 18px;
    height: 18px;
    margin: 0 3px;
    border-radius: 50%;
    background: var(--surface, #FBF5E9);
    border: 2px solid var(--sage, #7E9466);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--sage, #7E9466) 18%, transparent);
}
/* Кластер великих парків (мініатюра .gpark-cluster) */
.lgs--gpark-cluster {
    width: 20px;
    height: 20px;
    margin: 0 2px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--sage, #7E9466) 14%, #FBF5E9);
    border: 2px solid var(--sage, #7E9466);
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 11px;
    font-weight: 700;
    color: var(--green, #2F4A37);
}
/* Акварельна пляма полігона (розмитий край + ядро) */
.lgs--wc {
    width: 20px;
    height: 16px;
    margin: 0 2px;
    border-radius: 45% 55% 50% 50%;
    background: radial-gradient(closest-side,
        rgba(157, 179, 126, 0.75) 55%, rgba(126, 148, 102, 0.28) 78%,
        transparent 100%);
}
/* Міський кластер (мініатюра .rm-cluster) */
.lgs--cluster {
    width: 20px;
    height: 20px;
    margin: 0 2px;
    border-radius: 50%;
    background: var(--green, #2F4A37);
    color: var(--surface, #FBF5E9);
    font-weight: 700;
}
/* Полігон міського парку (PARK_BASE_STYLE) */
.lgs--park-poly {
    width: 20px;
    height: 14px;
    margin: 0 2px;
    border-radius: 5px;
    background: rgba(157, 179, 126, 0.42);
    border: 1.5px solid #3F5A3C;
}
/* RECRE-505: полігон із НЕПОВНИМ контуром — той самий свотч, що
   .lgs--park-poly, але лінія пунктирна й у тоні провенансу #8A7A5C
   (як .lgs--line-cov нижче). Свотч мусить відповідати реальному
   рендеру (TOR-legend-swatch-map-fidelity, прецедент RECRE-172): на
   карті це заливка парку + обведення PARTIAL_CONTOUR_OUTLINE */
.lgs--park-poly-partial {
    width: 20px;
    height: 14px;
    margin: 0 2px;
    border-radius: 5px;
    background: rgba(157, 179, 126, 0.42);
    border: 1.5px dashed #8A7A5C;
}
/* Пляжний бейдж */
.lgs--beach {
    width: 18px;
    height: 18px;
    margin: 0 3px;
    border-radius: 50%;
    background: #F0DBA8;
    border: 1.5px solid var(--ochre, #D79A3F);
    color: #8A6420;
    font-size: 9px;
}
/* Лінії контурів: admin (суцільна) / приглушена межа регіону /
   покриття агломерації (пунктир 8 6 — конвенція провенансу §3).
   RECRE-357 §15.3: перефарбовано в --muted-2 #8A7A5C — теракоти на
   лініях оглядових шарів більше немає */
.lgs--line-admin::before,
.lgs--line-dim::before,
.lgs--line-cov::before {
    content: "";
    width: 22px;
    border-top: 2px solid #8A7A5C;
}
.lgs--line-dim::before { opacity: 0.45; }
.lgs--line-cov::before { border-top-style: dashed; opacity: 0.8; }
/* RECRE-549: свотч шару наскрізних маршрутів. Відповідає реальному
   рендеру (TOR-legend-swatch-map-fidelity): біла підложка-ореол
   (TRAIL_HALO_*) і кольорова нитка поверх неї. Колір ЗАФІКСОВАНИЙ на
   синьому — це маркування Camino Podolico, першого й поки єдиного
   маршруту шару; коли їх стане кілька з різними кольорами, свотч має
   стати нейтральним, а кольори переїхати в підсписок під рядком (той
   самий шлях, що .krai-list під рядком етнорегіонів) */
.lgs--trail::before {
    content: "";
    width: 22px;
    height: 7px;
    border-radius: 4px;
    background: #FFFFFF;
    box-shadow: 0 0 0 1px rgba(138, 122, 92, 0.35);
}
.lgs--trail::after {
    content: "";
    position: absolute;
    width: 22px;
    border-top: 2.5px solid #3A6EA8;
    border-radius: 2px;
}
.lgs--trail { position: relative; }
/* Мініатюра картографічного НАПИСУ регіону (§15.3: замінила колишню
   .lgs--region-pill) — три letterspaced-літери, тон і гало як у
   .rm-region-label */
.lgs--region-name {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 8px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    /* RECRE-448: тон синхронізовано з .rm-region-label — легенда має
       називати той колір, який реально лежить на карті. Гало лишається
       одинарним: мініатюра сидить на кремовій панелі, а не на тайлах,
       тож несе лише ЗНАК «напис із гало», а не контрастну роботу —
       вісім жорстких зсувів на кеглі 8px злиплися б у пляму. */
    color: #6E3A1F;
    text-shadow: 0 0 3px rgba(251, 245, 233, 0.95);
}
/* Мініатюра пігулки міста (§15.3) — зелена капсула */
.lgs--city-pill {
    width: 22px;
    height: 12px;
    margin: 1px;
    border-radius: 999px;
    background: var(--green, #2F4A37);
}
/* RECRE-455: коло-лічильник (.rm-node__count) — фолбек для міста БЕЗ
   контуру меж */
/* Правка ПВ 2026-09-23: коло несе ЧИСЛО, як і на карті (symText у
   рядку легенди) — саме число відрізняє цей знак від крапки
   .lgs--city-dot нижче, і без нього рядки читались як дубль.
   Розкладка числа — той самий рецепт, що .rm-node__count. */
.lgs--city-counter {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    margin: 0 2px;
    border-radius: 50%;
    background: var(--green, #2F4A37);
    border: 2px solid rgba(251, 245, 233, 0.9);
    box-shadow: 0 2px 6px rgba(46, 36, 25, 0.28);
    color: var(--bg, #FBF5E9);
    font-size: 10px;
    font-weight: 800;
    line-height: 1;
}
/* RECRE-455: крапка (.rm-city-pill--collided) — пігулка програла
   колізійний прохід, лишається клікабельною */
.lgs--city-dot {
    width: 12px;
    height: 12px;
    margin: 4px;
    border-radius: 50%;
    background: var(--green, #2F4A37);
    box-shadow: 0 0 0 2.5px rgba(251, 245, 233, 0.92),
                0 2px 6px rgba(46, 36, 25, 0.30);
}
/* RECRE-471: бульбашка кластера МІСТ — зменшена копія .rm-city-cluster
   (зелена пігулка: трійка крапок + число). Мініатюра несе рівно той
   знак, що лежить на карті, і тим самим відрізняє рядок від
   .lgs--gpark-cluster (кремове коло) нижче. */
.lgs--city-cluster {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
    width: auto;
    min-width: 26px;
    height: 14px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--green, #2F4A37);
    color: var(--surface, #FBF5E9);
    font-size: 8px;
    font-weight: 700;
    box-shadow: 0 2px 6px rgba(46, 36, 25, 0.24);
}
.lgs--city-cluster::before {
    content: "";
    width: 8px;
    height: 3px;
    background:
        radial-gradient(circle at 1.5px 1.5px, currentColor 1.3px, transparent 1.4px),
        radial-gradient(circle at 4px 1.5px, currentColor 1.3px, transparent 1.4px),
        radial-gradient(circle at 6.5px 1.5px, currentColor 1.3px, transparent 1.4px);
}

/* RECRE-357 §15.2: група чипів «Тип території», коли шар-майстер
   «Великі парки та заповідники» (§14.5) вимкнено — видима, але
   неактивна (кнопки мають і власний :disabled) */
.rm-fchip-group--disabled {
    opacity: 0.45;
    pointer-events: none;
}

/* ============================================================
   RECRE-404 → RECRE-423 v2 — декоративний шар ЕТНОГРАФІЧНИХ КРАЇВ
   (дизайн-ТЗ Designer/TOR/TOR-recre423-425-ethno-regions-v2.md, що
   заміщує візуальну частину TOR-recre404-ethno-regions-layer.md;
   вимоги E-1…E-8 з Analyst/TOR/TOR-recre375-oblasts-and-ethno-layer.md).

   ГОЛОВНЕ РІШЕННЯ v1 (§1 TOR-404) лишається: область і край
   розводяться не кольором лінії, а ГРАФІЧНИМ КАНАЛОМ. Навігація —
   ЛІНІЙНИЙ шар (суцільна межа #8A7A5C + напис .rm-region-label вище),
   край — ПЛОЩИННИЙ (штриховане поле).

   ЩО ЗМІНИЛА v2 (RECRE-423). Крапковий край ареалу з v1 лежав піксель
   у піксель на адмінмежі — дві різні лінії на одному місці, і жодна
   після цього не читалась. Тому: контуру в шарі НЕМАЄ ВЗАГАЛІ, край
   згасає маскою (map.js, rmEthnoFeather); чіп-капсула замінена
   розрідженим картографічним написом .krai-label; гало напису
   ОБЛАСТІ при увімкненому шарі підсилюється (ієрархія через
   передній план, а не через гасіння навігації).

   МІСЦЕ ФАЙЛУ. Дизайн-ТЗ §8 пропонував токен --ethno і .rm-ethno-popup*
   класти в main.css. Тут вони живуть у map-overview.css: шар існує
   ВИКЛЮЧНО на /map/, а цей файл підключений лише туди — інші сторінки
   не мають платити за стилі, яких ніколи не використають (та сама
   мотивація, що в шапці файлу). Значення й селектори — 1:1 з макета.
   ============================================================ */

:root {
    /* ============ RECRE-478 §4: ВЛАСНА ПАЛІТРА ЕТНОШАРУ ============
       Скарга ПВ (ask 4): «Наразі кольорова палітра така сама як для
       областей». І це буквально так: RECRE-441 ч.2 звела шар до однієї
       рампи теплої умбри #A88A6E…#472F1E, тобто до ТІЄЇ САМОЇ земляної
       осі, на якій живе вся адміністративна графіка (лінія області
       #8A7A5C, напис області #6E3A1F). Два шари ділили не лише
       родину — вони ділили ВІДТІНОК, і жоден «графічний канал» цього
       не рятував.

       ЧОМУ САМЕ 4 РІЗНІ ТОНИ, А НЕ ОДНА НОВА РАМПА. Рампа однієї барви
       (лаванда RECRE-423, умбра RECRE-441) розрізняє сусідів лише
       СВІТЛОТОЮ — на альфі 0.10-0.13 різниця сусідніх сходинок падає
       нижче помітності, і карта читається як одна пляма з випадковими
       згущеннями. ETHNO_TEXTURE (map.js) розфарбовує граф сусідства в
       4 класи саме для того, щоб сусіди були РІЗНИМИ; дати цим класам
       4 різні ВІДТІНКИ — єдиний спосіб, яким розфарбування взагалі
       починає працювати. Тому це якісна (qualitative) палітра, а не
       послідовна: 4 добре рознесені тони (H≈218° / 5° / 75° / 181°).

       ЧОМУ САМЕ ЦІ ТОНИ. Родина — приглушені РОСЛИННІ БАРВНИКИ
       народного текстилю (індиго-крутик, марена, резеда, мідянка):
       культурна конотація збігається зі змістом шару, насиченість
       низька (S≈20-28%), світлота середня — вони лягають на кремову
       підложку як вицвіла тканина, а не як «інтерфейсні» кольори.
       Заборона RECRE-441 («лаванда вирізняється й не підходить під
       стилістику») не порушується: там була ОДНА холодна барва високої
       світлоти на 100% в'юпорта, тут — приглушений набір під тонкою
       межею (§1 тікета) і 13% заливкою.

       ЧОГО СВІДОМО НЕМАЄ В НАБОРІ: --sage #7E9466 і --terracotta
       #C16D45 (мова рекреації: контур парку, ховер) та вся вісь
       --muted-2 #8A7A5C (мова адміністративна). Резеда навмисно
       жовтіша за sage (H 75° проти 95°), марена — темніша й сіріша за
       теракоту. */
    --ethno-a: #64789B;   /* індиго (крутик) — 5 країв, найбільша площа */
    --ethno-b: #A06B66;   /* марена — 5 країв */
    --ethno-c: #7C8A5E;   /* резеда — 3 краї */
    --ethno-d: #4E7F80;   /* мідянка — 1 край (Поділля) */
    --ethno: var(--ethno-a);        /* представник родини: попап, чипи */
    /* Текст чіпа/попапа/напису краю. Темний нейтрально-індиговий:
       8.8:1 на кремі #FBF5E9 (AAA) і ≥8:1 на найтемнішому полі шару */
    --ethno-ink: #3D4557;
    /* Заливка (фон під межею). 0.10 → 0.13: після того, як межа стала
       ТОНКОЮ (§1 тікета), саме заливка лишилась єдиним носієм «це
       інший край» — на 0.10 чотири нові тони ще не розрізняються */
    --ethno-fill-alpha: 0.13;
    --ethno-fill-alpha-active: 0.26;
    /* ============ RECRE-478 §1: МЕЖА — ЛІНІЯ, А НЕ СМУГА ============
       Скарга ПВ (ask 1): «Межі етнорегіонів є товстими і негарними».
       Причина — геометрія, а не колір: 20px штрих по контуру, зовнішню
       половину якого зрізає маска rmEthnoFeather (stdDeviation 3), дає
       ~10px кольору плюс ~6px розмиття всередину. На стику двох країв
       дві такі смуги стоять впритул — на скріні тікета це суцільна
       темна стрічка ~20px завширшки, що читається як ЩЕ ОДНА сутність
       карти, а не як межа ареалу.
       Тепер: 5px штрих + маска зі stdDeviation 1.2 (map.js) = видима
       лінія ~2.5px з ледь м'яким краєм. Порівняння в кадрі: адмінлінія
       області — 1.5px суцільна #8A7A5C 0.75; межа краю — трохи товща,
       кольорова, м'якша. Ієрархія лишається на боці адмінмежі, а шар
       перестає бути «стрічками». */
    --ethno-band-alpha: 0.55;
    --ethno-band-alpha-active: 0.92;
    --ethno-band-width: 5px;
    /* Ховер (§2 тікета) підсвічує межу не лише альфою, а й товщиною —
       інакше на 2.5px підйом альфи майже непомітний */
    --ethno-band-width-active: 8px;
    /* Свотч легенди лежить на кремовій панелі #FBF5E9, не на тайлі:
       альфа ободка вища за --ethno-band-alpha, бо на панелі під ним
       немає тайла (§5 дизайн-ТЗ RECRE-432 — фіделіті це збіг КІНЦЕВОГО
       кольору на екрані, а не числа альфи) */
    --ethno-wash-legend: rgba(100, 120, 155, 0.62);
}

/* ============================================================
   RECRE-510 — декоративна маска рф (map.js, initRfMask)
   ============================================================ */

/* Обидві панелі маски (rfMaskPane 250 / rfMaskLabelPane 255) — наскрізні
   для вказівника. Це ДРУГИЙ рівень захисту: шар і так монтується з
   `interactive: false`, тобто Leaflet не вішає на path клас
   .leaflet-interactive. Але divIcon напису — звичайний
   .leaflet-marker-icon, і йому Leaflet ставить `pointer-events: auto`
   інлайново на рівні панелі маркерів; правило нижче гасить це для
   НАШОЇ панелі. Маска не має ані ловити кліки, ані заважати ховеру
   контурів областей під нею. */
.rm-rf-mask-pane,
.rm-rf-mask-pane * {
    pointer-events: none;
}

/* Напис маски рф («щоб вам не мозолило очі»). Свідомо НЕ .rm-region-label: та родина (Cormorant
   700, теракота, гало) — це НАШІ дані, назви наших регіонів. Тут —
   імітація тихого топоніма базової карти: той самий гротеск, що в
   інтерфейсі, рядкові літери, розріджений трекінг, приглушений
   --muted-2 (#8A7A5C на заливці #F4EBDA ≈ 3.1:1 — достатньо для
   великого декоративного напису, який до того ж aria-hidden). Гала
   немає навмисно: під написом рівна однотонна заливка маски, гало
   лише зробило б його «наклейкою» замість напису на карті. */
/* Далекі зуми (z<=5, клас вішає map.js): менший кегль — інакше
   градусний слід напису майже подвоюється і рядки звисають з маски
   на сусідні території. Ширина 112px тримає той самий розрив
   «щоб вам не / мозолило очі» при 11px/1.5px трекінгу */
.rm-rf-label-far .rm-rf-mask-label {
    font-size: 11px;
    letter-spacing: 1.5px;
    width: 112px;
}
.rm-rf-mask-label {
    position: absolute;
    /* Центрування в точці маркера — як .rm-region-label/.krai-label:
       divIcon оголошений з iconSize [0,0] */
    transform: translate(-50%, -50%);
    /* Дворядковий блок замість nowrap: подовжений текст ПВ одним рядком
       не вміщується між Білоруссю і віджетом довкілля на 1024-1290px —
       розгорнута геометрія в коментарі біля RF_MASK_LABEL_AT (map.js).
       width підібрано під розрив «щоб вам не / мозолило очі» */
    width: 150px;
    text-align: center;
    font-family: 'Mulish', system-ui, sans-serif;
    font-size: 15px;
    font-weight: 500;
    letter-spacing: 2.4px;
    line-height: 1.2;
    color: var(--muted-2);
    /* Напис живе всередині .leaflet-marker-icon, якому Leaflet інлайном
       ставить розміри з iconSize; user-select знімає випадкове
       виділення тексту при пані карти */
    user-select: none;
    -webkit-user-select: none;
}

/* Панелі шару (ethnoPane 350 / ethnoLabelPane 590, §4) — спільний
   fade появи й зникнення .22s (§7 п.7). Клас-перемикач висить на
   контейнері карти: обидві панелі згасають синхронно, а шари
   знімаються з карти вже ПІСЛЯ згасання (hideEthnoLayer, map.js) */
.rm-ethno-pane {
    opacity: 0;
    transition: opacity 0.22s ease;
}
.leaflet-container.is-ethno-on .rm-ethno-pane {
    opacity: 1;
}
/* §5.2 ТЗ v2: на час зум-анімації шар невидимий. Знімає перерахунок
   маски згасання на кожному кадрі І прибирає «клацання» патерна
   наприкінці анімації (ризик R-1 §8 TOR-404). Селектор навмисно
   специфічніший за правило is-ethno-on вище — порядок правил не має
   бути частиною контракту.

   RECRE-468 (симптом 2 тікета): `transition: opacity 0.22s` вище діяв
   і НА ЦЕЙ стан — шар згасав ~220 мс, тобто майже всю зум-анімацію
   Leaflet (~250 мс) лишався частково видимим, і весь цей час його
   CSS-масштабувало разом із блюром і масками: та сама «розмазана
   діагональна смуга-привид», яку бачив ПВ. Тому перехід тут вимкнено:
   ХОВАЄТЬСЯ шар МИТТЄВО (transition: none у стані is-ethno-zooming),
   а З'ЯВЛЯЄТЬСЯ плавно — знімається клас, повертається базове правило
   з 0.22s. Асиметрія навмисна: «зникло вмить, повернулось м'яко»
   читається як частина зуму, а не як блимання шару. */
.leaflet-container.is-ethno-on.is-ethno-zooming .rm-ethno-pane {
    opacity: 0;
    transition: none;
}

/* ---- RECRE-492 п.1: написи областей на час шару — ЗНОВУ ПРИХОВАНІ
   (повернення поведінки RECRE-432 §4.1; RECRE-478 §3 ставив
   --ethno-muted) ----

   ІСТОРІЯ СТАНУ, щоб наступна правка не крутила маятник наосліп:
     • RECRE-432 §4.1 — напис області ховався повністю (opacity:0 +
       visibility:hidden): дві родини написів у кадрі не читались;
     • RECRE-478 §3 — за скаргою ПВ («підписи областей мають бути
       гармонійними і ВИДИМИМИ») напис лишили на екрані другим планом
       (кегль ×0.84, альфа 0.62);
     • RECRE-492 п.1 — рішення ПВ від 2026-09-04: коли етношар
       увімкнено, підписи областей ВИМИКАЮТЬСЯ повністю. Приглушений
       напис усе одно конкурував з написом краю за той самий піксель,
       а сам етношар — це окремий режим читання карти, а не «карта
       областей із додатковим забарвленням».

   МЕЖІ ОБЛАСТЕЙ ЛИШАЮТЬСЯ. Ховається рівно родина .rm-region-label —
   контур області (.rm-region-outline, правило нижче) не чіпаємо: він
   і є єдиний орієнтир «де я», коли назв у кадрі немає.

   ДРУГИЙ ЕФЕКТ, load-bearing для п.2 тікета. Бокси написів областей
   рахуються зайнятими в розкладці написів країв (ethnoOccupiedBoxes,
   map.js) — але лише ВИДИМІ: селектор там виключає і --collided, і
   цей клас. Тобто приховання звільняє краям реальні пікселі, і саме
   на це місце спирається fit-тест підписів країв (RECRE-492 п.2).
   Якщо колись повернете видимий стан — поверніть і клас у селектор
   ethnoOccupiedBoxes, інакше написи країв ляжуть на написи областей.

   Стан — ОКРЕМИЙ клас (ставить/знімає syncRegionLabelEthnoState,
   map.js), НЕ загальний селектор .is-ethno-on .rm-region-label:
   механізм колізій --collided незалежно керує aria-hidden/tabindex
   тих самих кнопок, і два стани мусять складатися, а не перетирати
   один одного.
   Селектор самодостатній — клас отримує і фолбек-коло .rm-node
   регіону без контуру (як у --collided, коментар вище у файлі).

   Пастка П-3 дизайн-ТЗ лишається чинною: --collided.--peek (0,2,0)
   переб'є однокласовий стан (0,1,0), тож peek міг би «повернути»
   свідомо прихований напис. Тому ДВА селектори, і блок стоїть у файлі
   НИЖЧЕ peek-правила (порядок load-bearing). */
.rm-region-label--ethno-hidden,
.rm-region-label--ethno-hidden.rm-region-label--peek {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    /* Fade 220мс = ETHNO_FADE_MS появи полів: «шар накрив карту, назви
       відступили» — одна подія, а не дві. Зворотний напрям
       асиметричний навмисно: visibility повертається миттєво, opacity
       догасає базовим transition .rm-region-label, клікабельність
       повертається синхронно в hideEthnoLayer. */
    transition: opacity 0.22s ease, visibility 0s linear 0.22s;
}

/* ---- RECRE-432 §4.2: контур області на час шару ----
   Лінія межі лишається (єдиний орієнтир «де я», коли написів немає),
   але: cursor default — клік по ній зараз нічого не робить (гейт
   ethnoLayerVisible у map.js), підказка «можна клікнути» брехала б.

   RECRE-441 ч.2 (П-4 дизайн-ТЗ): милиця RECRE-432 (stroke-opacity
   0.75 → 0.85, бо плоска заливка 30% збивала контраст #8A7A5C до
   фону з ≈4.0:1 до ≈2.9:1) прибрана. K2 звів заливку до фонового
   відмиву 0.10 — власний перерахунок композиту (метод RECRE-432 §2.3,
   тайл #F2EFE9) дає контраст лінії до фону 3.07…3.34 залежно від
   класу (замість 2.09…3.00 при лаванді 0.30), тобто підйом є на
   КОЖНОМУ класі, а не лише в середньому. Підсилення тепер зайве й
   шкідливе (RECRE-432 §4.2 сам позначив цей відкат як допустимий) —
   неклікабельна лінія не повинна ставати наполегливішою. Клас
   rm-region-outline ставить regionBoundaryStyle (map.js). */
.rm-region-outline {
    transition: stroke-opacity 0.22s ease, stroke-width 0.18s ease,
                fill-opacity 0.18s ease;
}
/* RECRE-478 §2: поки шар увімкнено, контур області ще й pointer-
   transparent. Дві причини, і обидві — про той самий курсор:
     • контур лежить в overlayPane (400), поля країв — в ethnoPane
       (350), тобто ВИЩЕ; без цього правила саме контур ковтав би
       кожен mouseover, і ховер по краю не працював би ніде, крім
       вузьких щілин між областями;
     • клікати по ньому все одно нічого не дає з RECRE-432 (гейт
       ethnoLayerVisible), тож нічого й не втрачається.
   Правило знімається разом із класом is-ethno-on — ховер областей
   (нижче) повертається сам, без жодного JS-стану. */
.leaflet-container.is-ethno-on path.rm-region-outline,
.leaflet-container.is-ethno-on path.rm-region-outline.leaflet-interactive {
    cursor: default;
    pointer-events: none;
}

/* ---- RECRE-478 §2: ховер-підсвітка ОБЛАСТІ (шар вимкнено) ----
   Скарга ПВ (ask 2): «забезпечити можливість підсвітки чи виділення
   регіону АБО ОБЛАСТІ при наведенні мишкою». До тікета ховер по
   контуру області робив рівно одне — тимчасово показував ЇЇ ПРИХОВАНИЙ
   колізією напис (peek, RECRE-360 §16.3); сама область при цьому не
   реагувала ніяк, тобто наведення на видиму область не давало
   зворотного зв'язку взагалі.
   Тепер клас ставить JS (regionOutlineHover, map.js) на ті самі
   події mouseover/mouseout, що вже несуть peek — нової підписки
   немає.

   ЧОМУ ТЕРАКОТА, А НЕ ПРОСТО «ТЕМНІШЕ Й ТОВЩЕ». Перша ітерація
   підіймала ті самі канали в тому самому тоні (#8A7A5C 0.75→0.95,
   1.5→2.2px, заливка 0.045→0.10) — і серед двох десятків таких самих
   ліній на z5 ця різниця не читалась узагалі (перевірено в браузері).
   Підсвітка мусить відрізнятись КАНАЛОМ, а не градусом. Мова ховера
   інтерактивного полігона в системі вже є — теракота #C16D45
   (PARK_HOVER_STYLE, map.js), і область на цьому рівні саме
   інтерактивна: клік по ній відкриває регіон. Тому наведена область
   позичає рівно той самий тон, нового кольору в системі не
   з'являється. Заливка лишається слабкою (0.07): підсвічується МЕЖА,
   площа тільки натякає — інакше пляма на пів екрана перекриє власні
   написи області. */
.rm-region-outline--hover {
    stroke: #C16D45;
    stroke-opacity: 0.9;
    stroke-width: 2.4px;
    fill: #C16D45;
    fill-opacity: 0.07;
}

/* ---- Поле етнорегіону: інтер'єрний відмив (RECRE-441 ч.2, K2 §4.1) ----
   Було: плоский напівпрозорий колір на всю площу (RECRE-432 §2).
   Тепер поле — це лише ФОН під ободком (нижче): альфа впала до 0.10,
   тобто ~85% фігури повертається до майже чистого тайла. Контраст
   класів більше НЕ тримається на цьому шарі — його забезпечує
   .ethno-band. 4 класи — той самий результат розфарбування графа
   сусідства (ETHNO_TEXTURE, map.js, RECRE-425 ч.2), змінилось лише
   ЧИМ малюється клас. CSS перекриває presentation-атрибути Leaflet
   (fillOpacity=1 у buildEthnoLayer лишився як був). */
.ethno-field {
    stroke: none;
    /* RECRE-478 §2: поле САМЕ приймає вказівник — воно і є ціллю
       ховера/кліку краю (interactive:true, buildEthnoLayer). До цього
       тікета єдиною ціллю шару був напис розміром у кілька десятків
       пікселів, і ПВ просив «підсвітку при наведенні мишкою на нього»,
       тобто на сам РЕГІОН. Правило A-9 («клік має пролітати до контуру
       області») втратило предмет ще в RECRE-432: поки шар увімкнено,
       клік по області нічого не робить (гейт ethnoLayerVisible), тож
       перехоплювати нема чого — а сам контур на час шару стає
       pointer-transparent (правило .is-ethno-on нижче). */
    pointer-events: auto;
    cursor: pointer;
    fill-opacity: var(--ethno-fill-alpha);
    transition: fill-opacity 0.18s ease, opacity 0.18s ease;
}
.ethno-field--a { fill: var(--ethno-a); }
.ethno-field--b { fill: var(--ethno-b); }
.ethno-field--c { fill: var(--ethno-c); }
/* §5.4 ТЗ v2: четвертий клас — ареалів 14, граф сусідства щільніший,
   трьох класів не вистачало гарантовано. Носій один (Поділля) —
   найтемніший кінець рампи на найменшій площі (§2.4 дизайн-ТЗ) */
.ethno-field--d { fill: var(--ethno-d); }

/* ---- Ободок ареалу (RECRE-441 ч.2, K2 §4.1 → RECRE-466 топологія) ----
   RECRE-441 ч.2: другий L.geoJSON тієї самої геометрії, fill:none,
   лише stroke — м'яка смуга вздовж контуру ЗСЕРЕДИНИ. Носій контрасту
   («більш контрасні» зі скарги ПВ): локальний перепад «ободок ↔
   середина того самого ареалу» = 13,1 L* проти 4,5 L* на стику класів
   у старій плоскій заливці.

   RECRE-466 → RECRE-468 (відкат рендеру, бо зникла причина). RECRE-466
   зауважив, що SVG-штрих ЦЕНТРОВАНИЙ на лінії контуру — ліз на
   ±stroke-width/2 по обидва боки від межі, і на міжкрайових межах
   (ареали ПЕРЕКРИВАЛИСЬ перехідними смугами) дві незалежні лінії
   сусідів на z5-z6 проходили за лічені екранні пікселі одна від одної:
   два штрихи покривали те саме місце подвійною альфа-сумішшю — темні
   «лінзи»/дуги на скріншотах ПВ. Обхід був у даних: окрема геометрія
   `band_ring` (кільце всередині власного контуру), залита як fill.
   RECRE-468 прибрав саму причину: краї стали ЗЛИТНИМ топологічним
   поділом (build_ethno_krai.py, _resolve_overlaps) — у сусідів ОДНА
   спільна межа, а не дві близькі, тож центрований штрих подвоїтись не
   може, і ободок повертається до простого stroke по власному контуру
   (K2/RECRE-441), без зайвої сутності в даних.

   П-1 дизайн-ТЗ (load-bearing): rmEthnoFeather мусить накривати ОБИДВА
   <path> того самого краю — і .ethno-field, і .ethno-band — як ОДИН
   замаскований вузол. Саме маска зрізає ЗОВНІШНЮ половину штриха, яка
   виходить за контур; без неї ободок вилазив би на сусіда. Реалізація —
   генерований <style> масок (mountEthnoMask/applyEthnoMaskStyle,
   map.js): правило маски адресує `.ethno-f--{slug}, .ethno-b--{slug}`
   ОДНИМ селектором. */
.ethno-band {
    fill: none;
    /* Ободок лишається суто декоративним: ховер/клік краю ловить поле
       під ним (.ethno-field вище), а не ця лінія — інакше на 2.5px
       смузі курсор «провалювався» б між лінією і полем */
    pointer-events: none;   /* страховка до interactive:false (§4) */
    stroke-width: var(--ethno-band-width);
    stroke-opacity: var(--ethno-band-alpha);
    stroke-linejoin: round;
    transition: stroke-opacity 0.18s ease, stroke-width 0.18s ease,
                opacity 0.18s ease;
}
.ethno-band--a { stroke: var(--ethno-a); }
.ethno-band--b { stroke: var(--ethno-b); }
.ethno-band--c { stroke: var(--ethno-c); }
.ethno-band--d { stroke: var(--ethno-d); }

/* §5.1: біле path-джерело маски згасання. Живе всередині <mask> у
   <defs> рендерера, тобто НЕ рендериться саме по собі; клас потрібен
   лише щоб перебити fill, який ставить Leaflet presentation-атрибутом.
   Розмиття вішає фільтр rmEthnoFeather (атрибут ставить map.js) —
   тому размивається САМЕ АЛЬФА, а не штрих: напрям штриха є єдиним
   каналом розрізнення сусідів, незалежним від колірного зору. */
.ethno-mask-src {
    fill: #fff;
    stroke: none;
    pointer-events: none;
}

/* Ховер/фокус напису краю підсвічує СВОЄ поле (§8.2). Досяжно без
   подій на самому полігоні — slug відомий із напису, а поле подій не
   приймає. Інші поля падають до .45: питання «а де це» отримує
   відповідь без жодного кліку. RECRE-441 ч.2: ободок — окремий
   елемент DOM (не дитина поля), тож те саме дімування дублюється
   на .ethno-band, інакше підсвічений край лишав би сусідні ободки
   на повній яскравості поруч із притлумленими полями. */
.rm-ethno-pane.has-active .ethno-field,
.rm-ethno-pane.has-active .ethno-band {
    opacity: 0.45;
}
.rm-ethno-pane.has-active .ethno-field.is-active,
.rm-ethno-pane.has-active .ethno-band.is-active {
    opacity: 1;
}
/* RECRE-432 пастка П-1 (найдорожча помилка ТЗ): зі штрихом альфа жила
   ВСЕРЕДИНІ патерна, тож fill-opacity:1 тут був нешкідливий — тепер,
   коли колір плоский, те саме правило перетворило б підсвічений край
   на ПОВНІСТЮ НЕПРОЗОРУ пляму поверх тайлів. Замінено на
   --ethno-fill-alpha-active (0.16, RECRE-441 ч.2 §3.1). */
.ethno-field.is-active {
    fill-opacity: var(--ethno-fill-alpha-active);
}
/* RECRE-441 ч.2, пастка П-3 (той самий клас пастки, що П-1 у
   RECRE-432): альфа ободка — ІНШИЙ канал за fill-opacity поля (різні
   елементи DOM, до того ж ободок малюється штрихом). Правило
   .ethno-field.is-active вище підняло б лише заливку поля —
   підсвічений край не підняв би ободок узагалі. Два токени, два
   рядки. */
.ethno-band.is-active {
    stroke-opacity: var(--ethno-band-alpha-active);
    /* RECRE-478 §2: після §1 межа — лінія 2.5px, і саме лише підняття
       альфи на ній читається слабко. Ховер додає ТОВЩИНУ (5→8px, тобто
       видимих 2.5→4px): підсвічений край обводиться помітно, лишаючись
       у мові «лінія», а не повертаючись до старої смуги */
    stroke-width: var(--ethno-band-width-active);
}

/* ---- §4.3/§8.2 ТЗ v2: НАПИС КРАЮ (.krai-label) ----
   ЄДИНА клікабельна ціль шару. Замінив чіп-капсулу v1 (та лежала за
   22px від пігулки області й читалась як її підзаголовок — саме на це
   скаржився RECRE-423).

   Два підписи розведені РЕГІСТРОМ, а не відстанню:
     .rm-region-label — uppercase, Cormorant 700, трекінг 1.6px,
        #6E3A1F, кремове гало (RECRE-448), markerPane 600;
     .krai-label      — рядкові, Cormorant 500 КУРСИВ, трекінг 5.5px,
        #372844/.94, кремове гало (RECRE-441, слабше за
        .rm-region-label), БЕЗ коробки-пігулки, нахил ±25° з даних,
        ethnoLabelPane 590 (нижче навігації).
   Це різні картографічні регістри: «назва на мапі» проти «розрідженого
   напису поверх ареалу» — класика етнографічних атласів. Гало в обох —
   спільна МОВА читаності поверх тайлів/заливки; коробка-пігулка
   (фон+radius) лишається лише за .rm-region-label — саме вона й
   відрізняє «навігаційний вузол» від «розрідженого напису ареалу». */
.krai-label-wrap {
    background: none;
    border: none;
}
/* iconSize [0,0]: кліки приймає лише сама кнопка (той самий прийом,
   що .gpark-divicon) */
.leaflet-marker-icon.krai-label-wrap { pointer-events: none; }

.krai-label {
    position: absolute;
    /* --krai-angle — нахил за головною віссю ареалу (Г-6, |a| ≤ 25°);
       ставить map.js з даних, розкладка рахує AABB повернутого боксу */
    transform: translate(-50%, -50%) rotate(var(--krai-angle, 0deg));
    padding: 2px 6px;
    border: none;
    background: none;
    /* RECRE-441 ч.1: --ethno-ink (#5E4E6B) при opacity .78 і БЕЗ гала
       було підібрано під штрих RECRE-423 — там під написом лежала лише
       ~6-12% вибілена штрихом підкладка, майже крем. RECRE-432 замінив
       штрих плоскою заливкою --ethno-a…d (альфа 0.30) — контраст
       впав нижче межі читання. Колір затемнено, opacity піднято з .78
       до .94.

       RECRE-441 ч.2 (K2, П-6): #372844 — темна слива під лавандову
       родину, під нову умбру вона б брехала. Замінено на #3B2A1E.
       Обчислений контраст на найгіршому фоні (ободок класу D) —
       5.18:1 (метод RECRE-432 §2.3).

       RECRE-466: та сама розбіжність «формула проти пікселя», що
       RECRE-448 знайшов на .rm-region-label. Скарга ПВ: «підписи
       хуйня і не видно взагалі» — при нібито 5.18:1. Виміряно (canvas,
       той самий метод, що RECRE-448 — glyph rasterize + двофонове
       відновлення альфи): Cormorant Garamond italic 500 15px «донеччина»
       має 0% суцільно непрозорих пікселів (region-label 700 16px мав
       хоч 8.8%) — 100% напису це антиаліасинг, курсив+трекінг 5.5px
       ще й розбиває силует на окремі тонкі штрихи. Старе гало (2 м'які
       тіні, рядок нижче був закоментований забороною RECRE-441 ч.2
       §5 п.1 — ця заборона писалась ДО скарги, яку зараз саме
       усуває RECRE-466, тому переглядається) давало в кільці 2px
       навколо штриха лише 0.167 непрозорості кремового тону — гірше,
       ніж 0.327 у .rm-region-label до RECRE-448. Тому: перейти на
       ДВА концентричні кільця жорстких зсувів (1px і 2px — на 15px
       курсиві з тонкими штрихами саме 2px «підлив» дав перелом, 1px
       сам вирівнював лише до ~0.50) + ті самі 2 м'які тіні для
       атласної розмитості країв. Результат кільця 2px: 0.167 → 0.843
       (вище за 0.741 .rm-region-label — компенсує ще тонший штрих).

       RECRE-478 §3 (ask 3 тікета: «підписи… гармонійними і видимими»).
       Скріншот ПВ показує рівно те, що описано вище як ЗАЛИШКОВИЙ
       ризик RECRE-466: на 15px курсиві 500 з трекінгом 5.5px кремове
       гало з ДВОХ кілець (1px і 2px) за площею перекриває сам гліф —
       напис читається світлим, майже білим, і «зникає» на кремі,
       тобто лікування виявилось важчим за хворобу.

       Замість того, щоб і далі нарощувати гало, беремо ГОТОВИЙ
       рецепт RECRE-476 (той самий, яким щойно полагодили написи
       областей — звідси й «гармонійність»: дві родини написів тепер
       побудовані ОДНАКОВО, різняться лише регістром і кеглем):
         • кегль — драбина від зуму (--rm-krai-label-size,
           syncRegionLabelScale у map.js), на +1.5px вище за напис
           області: край має лишатись домінантою СВОГО шару;
         • трекінг — у em (0.36em = ті самі 5.5px на 15px), щоб їхав
           за кеглем, а не розсипав рядок на дрібному;
         • густина чорнила — -webkit-text-stroke тим самим кольором
           (не обведення, а потовщення штриха), 0.34px: курсив 600
           тонший за прямий 700, тож трохи більше за 0.32px областей;
         • гало — ОДНЕ кільце жорстких зсувів 1px + одна м'яка тінь
           3px, тобто рівно граматика .rm-region-label. Друге кільце
           2px (RECRE-466) прибрано: саме воно й вибілювало напис;
         • колір — --ethno-ink (палітра шару, §4 тікета) замість
           теплого #3B2A1E: 8.8:1 на кремі, ≥8:1 на найтемнішому полі.
       opacity 0.94 → 1: приглушення тут більше нічому не служить,
       ієрархію тримає притлумлений напис ОБЛАСТІ (§3 вище). */
    color: var(--ethno-ink);
    opacity: 1;
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-style: italic;
    font-size: var(--rm-krai-label-size, 16px);
    font-weight: 600;
    -webkit-text-stroke: 0.34px currentColor;
    letter-spacing: 0.36em;
    line-height: 1.15;
    /* Рядкові — правило регістру §4.3; text-transform, а не текст у
       даних: назва краю в попапі, списку легенди й aria-label
       лишається нормальною («Полтавщина», не «полтавщина») */
    text-transform: lowercase;
    white-space: nowrap;
    cursor: pointer;
    pointer-events: auto;
    /* Тла (боксу) немає й далі — напис краю не позичає кремову
       ПІГУЛКУ .rm-region-label.
       RECRE-478 §3: гало = рівно граматика .rm-region-label (RECRE-476)
       — 8 ЖОРСТКИХ зсувів по 1px @0.92 + ОДНА м'яка тінь 3px @0.70.
       Друге кільце 2px і другу м'яку тінь RECRE-466 прибрано: разом
       вони давали ореол ~3px навколо кожного тонкого штриха курсиву,
       і на 15px гліф тонув усередині власного гала (саме це видно на
       скріні тікета — «підписи не видно»). Чорнило, з якого гало
       відкидається, компенсоване інакше: вага 500 → 600 і
       -webkit-text-stroke 0.34px вище. */
    text-shadow:
         1px    0   0 rgba(251, 245, 233, 0.92),
        -1px    0   0 rgba(251, 245, 233, 0.92),
          0    1px  0 rgba(251, 245, 233, 0.92),
          0   -1px  0 rgba(251, 245, 233, 0.92),
         1px   1px  0 rgba(251, 245, 233, 0.92),
        -1px  -1px  0 rgba(251, 245, 233, 0.92),
         1px  -1px  0 rgba(251, 245, 233, 0.92),
        -1px   1px  0 rgba(251, 245, 233, 0.92),
          0    0   3px rgba(251, 245, 233, 0.70);
    transition: opacity 0.18s ease, letter-spacing 0.18s ease;
}
/* Ховер/фокус: трекінг +0.06em (те саме «дихання» напису, що було
   5.5→6.5px, лише відносно кегля) */
.krai-label:hover,
.krai-label:focus-visible {
    opacity: 1;
    letter-spacing: 0.42em;
}
.krai-label:focus-visible {
    outline: none;
    border-radius: 8px;   /* лише для фокус-кільця */
    /* наявний фокусний тон системи (--terra 0.5) */
    box-shadow: 0 0 0 3px rgba(193, 109, 69, 0.5);
}
/* Розкритий край (є попап): вага вже 600 у базі, тож стан позначає
   себе густішим штрихом — той самий канал, що й у базовому правилі */
.krai-label[aria-expanded="true"] {
    opacity: 1;
    font-weight: 700;
    -webkit-text-stroke: 0.4px currentColor;
}

/* Hit-area ≥44px по вертикалі — прозорий ::after (той самий прийом,
   що .rm-region-label::after вище). ВИДИМИЙ кегль на touch свідомо НЕ
   роздувається: на масштабі країни це зіпсувало б карту */
.krai-label::after {
    content: "";
    position: absolute;
    left: -4px;
    right: -4px;
    top: 50%;
    transform: translateY(-50%);
    height: 44px;
}

/* §4.4 п.4: жоден якір не підійшов — напис ховається класом, маркер з
   карти НЕ знімається (на наступному цілому зумі з'явиться сам), а
   ПОЛЕ лишається видимим. Випадає з tab-порядку — aria-hidden/
   tabindex ставить JS; край лишається досяжним зі списку легенди */
.krai-label--collided {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.22s ease, visibility 0s linear 0.22s;
}

/* RECRE-509: desktop-«peek» країв — рівно та сама механіка, що в
   областей (§16.3 RECRE-360 → RECRE-431 §4.4, правило
   .rm-region-label--collided.rm-region-label--peek вище у файлі):
   ховер по ПОЛЮ ареалу тимчасово показує напис, який сховав fit-тест
   RECRE-492. Скарга ПВ: «якщо не висвічується підпис етнорегіону, то я
   не можу на нього навести і обрати» — підсвітка поля без назви не
   каже, ЩО саме обираєш.

   Клас ставить/знімає peekKraiLabel (map.js); z-порядок піднімає
   setZIndexOffset, щоб peek не пірнув під видимий напис сусіда.
   pointer-events лишаються none (успадковані від --collided): peek —
   це відповідь на ховер ПОЛЯ, і власна hit-область напису тут збивала
   б mouseout поля мерехтінням.
   aria-hidden лишається true (його ставить setKraiLabelHidden) — peek
   є курсорною підказкою, а не новим tab-stop; клавіатурний шлях до
   краю з прихованим написом — рядок списку легенди (§8.3).
   Переходи — базові .krai-label / --collided, тож reduced-motion-блок
   нижче накриває і peek без окремого селектора. */
/* RECRE-590: peek більше не показує напис «як є» — він показує
   ПІДІГНАНИЙ під власний ареал варіант. Кегль і трекінг приїжджають
   змінними від kraiPeekPlacement (map.js): та сама драбина
   --rm-krai-label-size, помножена на 0.7-1, і трекінг, стиснутий з
   0.36em до 0.18em на довгих назвах. Дефолти в var() — базові
   значення, тож напис, якому підгонка не знадобилась, виглядає рівно
   як раніше.

   Специфічність (0,2,0) і позиція нижче .krai-label:hover — навмисні,
   як і в сусідньому правилі --peek-yield: інакше базове правило
   .krai-label (0,1,0) все одно програло б, а от :hover (0,2,0) вище у
   файлі перебив би трекінг. Практично :hover тут і не виникає
   (pointer-events:none успадковані від --collided), але покладатись на
   це в каскаді не варто. */
.krai-label--collided.krai-label--peek {
    opacity: 1;
    visibility: visible;
    font-size: calc(
        var(--rm-krai-label-size, 16px) * var(--krai-peek-scale, 1)
    );
    letter-spacing: var(--krai-peek-track, 0.36em);
}

/* RECRE-513: ВИДИМИЙ сусід поступається місцем peek-напису.

   Скарга ПВ (2026-09-05, скрін): peek «середня наддніпрянщина» лягає
   навхрест на видиме «поділля». z-порядок (setZIndexOffset(1000),
   RECRE-509) вирішує, ХТО зверху, але не рятує читабельність: обидва
   написи прозорі, розріджені трекінгом і без плашки — верхній читається
   крізь нижній не краще, ніж навпаки. Тому той, хто ЗАВАЖАЄ, на час
   peek гасне (applyKraiPeekYield ставить клас лише написам, чиї бокси
   реально перетинаються з боксом peek).

   Канал — opacity, а не visibility: поступка триває долі секунди й
   мусить згасати/повертатись плавно базовим переходом .krai-label
   (0.18s), тоді як --collided навмисно перемикає ще й visibility з
   відкладеним переходом. pointer-events:none — щоб невидимий напис не
   ловив ховер і не смикав mouseout поля, з якого росте сам peek.

   Специфічність (0,2,0) і позиція ПІСЛЯ .krai-label:hover — навмисні:
   інакше ховер по тому ж місцю повернув би opacity:1 і поступка нічого
   б не дала.

   aria/tabindex тут НЕ чіпаються (JS теж їх не торкається): стан живе
   рівно доти, доки курсор стоїть на чужому полі, а ховера без миші не
   буває — читачеві екрана цей напис не зникає.

   Переходи — базові .krai-label, тож reduced-motion-блок нижче накриває
   і поступку без окремого селектора. */
.krai-label.krai-label--peek-yield {
    opacity: 0;
    pointer-events: none;
}

/* Вузький екран: кегль лишається функцією зуму (драбина працює й тут),
   але масштабується коефіцієнтом — 375px-кадр вміщає ~втричі менше
   написів, ніж десктопний. Трекінг у em їде за кеглем сам, тож окремих
   px-значень більше немає (RECRE-478 §3) */
@media (max-width: 680px) {
    .krai-label {
        font-size: calc(var(--rm-krai-label-size, 16px) * 0.84);
        letter-spacing: 0.26em;
    }
    .krai-label:hover,
    .krai-label:focus-visible { letter-spacing: 0.32em; }
}

@media (prefers-reduced-motion: reduce) {
    .rm-ethno-pane,
    .ethno-field,
    .ethno-band,
    .krai-label,
    .krai-label--collided,
    /* RECRE-432 → RECRE-478 → RECRE-492: обидва переходи (написи
       областей, контур) — миттєво, без блимання (§9.6 чек-лист
       дизайн-ТЗ) */
    .rm-region-label--ethno-hidden,
    .rm-region-outline { transition: none; }
}

/* ---- Попап етнорегіону (§5.5) ----
   Патерн .mpp-popup / .rm-poi-popup (main.css): обгортка Leaflet
   прозора, хвостик — власний ::after. У попапі СВІДОМО немає жодної
   навігаційної дії, лічильників парків і площі — це закриває E-6/A-8
   структурно, а не домовленістю. */
.leaflet-popup.rm-ethno-popup-wrap .leaflet-popup-content-wrapper {
    background: transparent;
    box-shadow: none;
    padding: 0;
    border-radius: 0;
}
.leaflet-popup.rm-ethno-popup-wrap .leaflet-popup-content {
    margin: 0;
    line-height: inherit;
    width: auto !important;
}
.leaflet-popup.rm-ethno-popup-wrap .leaflet-popup-tip-container {
    display: none;                  /* хвостик — наш ::after */
}

.ethno-popup {
    position: relative;
    width: 272px;
    max-width: calc(100vw - 32px);
    box-sizing: border-box;
    padding: 13px 14px 12px;
    background: var(--surface, #FBF5E9);
    border: 1px solid var(--border-2, #EADFC6);
    border-radius: 16px;
    box-shadow: 0 26px 60px -28px rgba(47, 74, 55, 0.72);
    font-family: 'Mulish', system-ui, sans-serif;
    font-size: 13px;
    color: var(--ink-2, #3A3127);
}
.ethno-popup::after {               /* хвостик до чіпа */
    content: "";
    position: absolute;
    left: 50%;
    bottom: -7px;
    width: 13px;
    height: 13px;
    transform: translateX(-50%) rotate(45deg);
    background: var(--surface, #FBF5E9);
    border-right: 1px solid var(--border-2, #EADFC6);
    border-bottom: 1px solid var(--border-2, #EADFC6);
}
.ethno-popup__head {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 7px;
    padding-right: 22px;            /* місце під × */
}
.ethno-popup__icon {
    flex: none;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(100, 120, 155, 0.16);
    color: var(--ethno-ink);
}
.ethno-popup__icon i,
.ethno-popup__icon svg { width: 16px; height: 16px; }
/* Eyebrow обов'язковий: без нього попап читається як картка вузла
   навігації, а не як анотація декоративного шару */
.ethno-popup__eyebrow {
    margin-bottom: 1px;
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: 1.3px;
    text-transform: uppercase;
    color: var(--ethno-ink);
    opacity: 0.8;
}
.ethno-popup__name {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 20px;
    font-weight: 700;
    line-height: 1.05;
    color: var(--green, #2F4A37);   /* 9.1:1 на кремі */
}
.ethno-popup__char {
    margin: 0 0 9px;
    font-size: 13px;
    line-height: 1.5;
    color: var(--muted, #6B5D49);   /* 4.5:1 */
}
.ethno-popup__kw {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-bottom: 10px;
}
.ethno-kw {
    padding: 3px 9px;
    border-radius: 999px;
    background: rgba(100, 120, 155, 0.15);
    color: var(--ethno-ink);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.2px;
}

/* §8.4 п.5 ТЗ v2: «Охоплює повністю або частково» — плашка з переліком.
   Пряма відповідь на «що є що»: користувач бачить зв'язок із
   навігаційним шаром І слова «повністю або частково», тобто що це не
   межа.
   RECRE-489: НАЗВИ областей у переліку стали кнопками переходу на
   відповідний вузол навігації (вимога ПВ). Орієнтири («північ»,
   «південний схід») і розділові знаки лишаються текстом — саме
   контраст «сіре пояснення / темна назва» і показує, що клікабельна
   рівно назва. */
.ethno-popup__oblasts {
    margin-bottom: 10px;
    padding: 7px 9px;
    border-radius: 10px;
    background: var(--bg-2, #F3E9D6);
    font-size: 12px;
    line-height: 1.5;
    color: var(--muted, #6B5D49);
}
.ethno-popup__oblasts-t {
    display: block;
    margin-bottom: 1px;
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: 1.1px;
    text-transform: uppercase;
    color: var(--ethno-ink);
    opacity: 0.85;
}
/* RECRE-506 (вимога ПВ, одразу після приймання RECRE-489): перелік —
   це ПЕРЕЛІК РЯДКІВ, а не назви-посилання в суцільній фразі. Було:
   мішень розміром зі слово (~70×14px) серед такого ж тексту; на
   телефоні в неї треба цілитись, а сусідні назви стоять упритул.
   Стало: один рядок = одна область, клікає ВЕСЬ рядок на всю ширину
   плашки (~226px) — те саме, що робить .rm-city-item у меню міст.

   ЧОМУ НЕ ПІЛЮЛІ (як .ethno-kw). Картка вузька (272px), а орієнтир —
   частина рядка («південний схід Житомирської»): пілюлі з такими
   підписами йшли б по одній у ряд, тобто були б тим самим переліком,
   але з гіршим вирівнюванням лівого краю й дірками між рядами.

   ВИСОТА. 30px на миші (компактно — карток на 5 рядків достатньо, щоб
   картка не переросла екран) і 44px на дотику, де курсора-точки
   немає. Псевдоелемент, що розтягує зону (прийом .panel-close), тут
   НЕ годиться: у вертикальному переліку розтягнуті зони сусідів
   наклались би одна на одну, і верхній рядок ловив би кліки нижнього. */
.ethno-popup__oblast-list {
    list-style: none;
    margin: 3px -5px 0;
    padding: 0;
}
.ethno-popup__oblast-row { margin: 0; }
.ethno-popup__oblast,
.ethno-popup__oblast-plain {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    box-sizing: border-box;
    width: 100%;
    min-height: 30px;
    margin: 0;
    padding: 5px 7px;
    border: 0;
    border-radius: 8px;
    background: none;
    font: inherit;
    font-size: 12px;
    line-height: 1.35;
    text-align: left;
}
/* Клікабельний рядок: колір --ethno-ink палітри шару (RECRE-478) і
   вага 700 — той самий словник «це дія», що був у RECRE-489, лише
   пунктирне підкреслення замінене підсвіткою рядка (у переліку воно
   читалося б як помилка правопису) */
.ethno-popup__oblast {
    color: var(--ethno-ink);
    font-weight: 700;
    cursor: pointer;
    transition: background .12s ease, color .12s ease;
}
.ethno-popup__oblast:hover {
    background: rgba(100, 120, 155, 0.16);
    color: var(--ink, #2E2419);
}
.ethno-popup__oblast:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(193, 109, 69, 0.5);
}
.ethno-popup__oblast-t { min-width: 0; }
/* Шеврон — той самий натяк «рядок веде далі», що в списках проєкту.
   Клас лишається на <svg> після lucide, але селектор по тегу надійніший */
.ethno-popup__oblast-go,
.ethno-popup__oblast > svg {
    flex: none;
    width: 13px;
    height: 13px;
    opacity: 0.5;
}
.ethno-popup__oblast:hover > svg { opacity: 0.9; }
/* Область без вузла в сцені (RECRE-489-фолбек) — рівно той самий
   рядок, лише неклікабельний і приглушений: перелік лишається
   переліком, ніщо з нього не зникає */
.ethno-popup__oblast-plain {
    color: var(--muted, #6B5D49);
    font-weight: 600;
}
/* ДОТИК: рядок доростає до 44px — і саме тому картка отримує СТЕЛЮ.
   Виміряно на 375×812: 6 рядків Волині дають картку 473px, а на карті
   (630px) autoPan лишає під попап 630−72−90 = 468px (FIT_PADDING_MOBILE
   TL/BR, map.js) — тобто найдовший перелік уже не влазив би, а на
   екрані 667px не влазив би з великим запасом. Стеля стоїть на КАРТЦІ,
   а прокручується лише перелік: шапка з назвою краю, характер і
   ключові слова мусять лишатись видимими — без них картка перестає
   відповідати на «що це за місцевість», заради чого й існує.
   344px = висота шапки сторінки над картою (182) + вертикальні поля
   autoPan (162). */
@media (hover: none) {
    .ethno-popup__oblast,
    .ethno-popup__oblast-plain { min-height: 44px; }
    .ethno-popup {
        display: flex;
        flex-direction: column;
        max-height: calc(100vh - 344px);
        max-height: calc(100dvh - 344px);
    }
    .ethno-popup > * { flex: none; }
    .ethno-popup__oblasts {
        display: flex;
        flex-direction: column;
        flex: 0 1 auto;
        min-height: 0;
    }
    .ethno-popup__oblast-list {
        min-height: 44px;               /* хоч один рядок, а не 0 */
        overflow-y: auto;
        overscroll-behavior: contain;   /* прокрутка не тягне карту */
        scrollbar-width: thin;
    }
}
.ethno-popup__close {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--bg-2, #F3E9D6);
    color: var(--muted, #6B5D49);
    font-size: 15px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.ethno-popup__close:hover {
    background: var(--border, #E3D4B3);
    color: var(--ink, #2E2419);
}
.ethno-popup__close:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(193, 109, 69, 0.5);
}

/* Символ легенди (§8.1 ТЗ v2 → RECRE-441 ч.2 §4.4, П-5): мініатюра
   ПЛОЩИННОГО шару. Свотч має відповідати реальному рендеру (прецедент
   RECRE-172, TOR-legend-swatch-map-fidelity) — і головне на карті
   тепер ОБОДОК, а не заливка, тож капсула легенди отримала ту саму
   структуру: inset box-shadow малює кільце ободка по контуру капсули,
   background-color — ледь помітний внутрішній відмив. Радіальна
   маска-згасання лишається без змін (той самий принцип «край свотча
   згасає, як край ареалу»).
   Колір ободка: --ethno-wash-legend 0.40 поверх кремової панелі
   #FBF5E9 (а не 0.38 --ethno-band-alpha поверх тайла) — фіделіті тут
   це збіг КІНЦЕВОГО кольору на екрані, різні підложки вимагають різної
   альфи для того самого візуального результату (§5 дизайн-ТЗ
   RECRE-432, той самий метод). Внутрішній відмив — окрема, значно
   слабша rgba (0.11), бо це вже НЕ ободок, а фонова заливка 0.10. */
/* RECRE-478 §4: шар більше не одноколірний — свотч теж. Чотири смуги
   = чотири тони розфарбування графа сусідства (ETHNO_TEXTURE), тобто
   легенда чесно каже «сусідні краї різного кольору», а не показує
   один випадковий тон із чотирьох. Ободок став тонким (1.5px замість
   3px) слідом за §1: свотч і далі відповідає реальному рендеру
   (прецедент RECRE-172, TOR-legend-swatch-map-fidelity).
   rgba-літерали дублюють --ethno-a…d навмисно: альфу до змінної тут
   не застосувати без color-mix, а фолбек на нього коштував би дорожче
   за чотири коментовані рядки. */
.lgs--ethno {
    width: 22px;
    height: 15px;
    margin: 0 1px;
    border: none;
    border-radius: 4px;
    background-color: transparent;
    box-shadow: inset 0 0 0 1.5px var(--ethno-wash-legend);
    background-image: linear-gradient(102deg,
        rgba(100, 120, 155, 0.45) 0 25%,     /* --ethno-a індиго */
        rgba(160, 107, 102, 0.45) 25% 50%,   /* --ethno-b марена */
        rgba(124, 138, 94, 0.45) 50% 75%,    /* --ethno-c резеда */
        rgba(78, 127, 128, 0.45) 75% 100%);  /* --ethno-d мідянка */
    -webkit-mask-image: radial-gradient(ellipse at center,
        #000 42%, transparent 78%);
    mask-image: radial-gradient(ellipse at center,
        #000 42%, transparent 78%);
}

/* ---- §8.3 ТЗ v2: список країв під рядком-перемикачем легенди ----
   Закриває три речі одразу: клавіатурний доступ до країв, чий напис
   сховала розкладка; відповідь «скільки їх і як звуться»; зв'язок
   «назва ↔ місце» без кліку (ховер підсвічує поле на карті). */
.krai-list {
    display: flex;
    flex-direction: column;
    gap: 1px;
    margin: 4px 0 2px 6px;
    padding-left: 8px;
    border-left: 1px solid var(--border-2, #EADFC6);
}
.krai-item {
    display: flex;
    align-items: center;
    gap: 7px;
    width: 100%;
    min-height: 30px;
    padding: 3px 7px;
    border: 0;
    border-radius: 8px;
    background: none;
    color: var(--ethno-ink);
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-style: italic;
    font-size: 14px;
    line-height: 1.2;
    text-align: left;
    cursor: pointer;
    transition: background 0.15s ease;
}
.krai-item:hover,
.krai-item:focus-visible {
    background: rgba(100, 120, 155, 0.14);
}

/* Правка ПВ 2026-09-25: той самий вигляд, коли курсор стоїть на
   АРЕАЛІ карти (ethnoActiveSlug). Після рішення «напис, що не влазить,
   не показуємо» список лишився єдиним місцем, де під курсором видно
   назву краю, тож зв'язок зроблено двобічним. Окремим правилом, а не
   третім селектором у групі вище: коментар усередині списку селекторів
   формально дозволений, але одну реалізацію він уже збив з пантелику
   (фон не застосувався), а ціна окремого правила — нуль. */
.krai-item.is-active {
    background: rgba(100, 120, 155, 0.14);
    font-weight: 600;
}
.krai-item:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px rgba(193, 109, 69, 0.5);
}
.krai-item i,
.krai-item svg {
    width: 13px;
    height: 13px;
    flex: none;
    opacity: 0.8;
}
/* Край, чий напис сховала розкладка: рядок лишається клікабельним —
   у цьому й сенс списку (§8.3) */
.krai-item__hidden {
    margin-left: auto;
    font-family: 'Mulish', system-ui, sans-serif;
    font-style: normal;
    font-size: 9.5px;
    letter-spacing: 0.3px;
    color: var(--muted-3, #9A8A6E);
}

/* RECRE-466: дисклеймер шару — переїхав із футера КОЖНОГО попапа краю
   (був .ethno-popup__foot, видалено разом із переносом) сюди, під
   .krai-list, ОДИН раз на всю легенду. Скарга ПВ: той самий текст
   повторювався щоразу, коли користувач відкривав попап іншого краю,
   і відволікав від унікального вмісту попапа (назва/характер/ключові
   слова). Типографіка успадкована 1:1 від колишнього
   .ethno-popup__foot (--muted #6B5D49, а НЕ --muted-3 — останній дає
   3.1:1 і завалює дрібний текст; кегль 11.5px), лише розділювач
   зверху інший (суцільна лінія панелі, а не пунктир картки попапа —
   .krai-list вище вже має власний border-left, візуально це
   продовження того самого блоку легенди, не окрема картка). */
.krai-disclaimer {
    margin: 6px 0 2px 6px;
    padding: 8px 0 2px 9px;
    border-top: 1px dashed var(--dash, #D8C69F);
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--muted, #6B5D49);
}
.krai-disclaimer b { color: var(--ink-2, #3A3127); font-weight: 700; }

/* ---- §4.6 ТЗ v2: одноразова стрічка-орієнтир ----
   Показується рівно при ПЕРШОМУ вмиканні шару в сесії й закривається
   × або сама за 6с. Найдешевша відповідь на скаргу «незрозуміло, що є
   що»: інтерфейс називає дві системи вголос у момент, коли користувач
   уперше бачить їх разом. z-index — над панами карти (Leaflet
   максимум 800 у popupPane) і нижче попапа шару. */
.rm-ethno-hint {
    position: absolute;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 850;
    display: flex;
    align-items: flex-start;
    gap: 8px;
    max-width: min(520px, calc(100% - 24px));
    padding: 9px 10px 9px 12px;
    border: 1px solid rgba(100, 120, 155, 0.5);
    border-radius: 14px;
    background: rgba(251, 245, 233, 0.95);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    box-shadow: 0 18px 40px -24px rgba(47, 74, 55, 0.7);
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--ink-2, #3A3127);
}
.rm-ethno-hint i,
.rm-ethno-hint svg {
    width: 16px;
    height: 16px;
    flex: none;
    margin-top: 1px;
    color: var(--ethno-ink);
}
.rm-ethno-hint p { margin: 0; }
.rm-ethno-hint b { font-weight: 800; }
.rm-ethno-hint__close {
    position: relative;
    flex: none;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--muted, #6B5D49);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
}
/* Hit-area 44px без роздування видимої кнопки (той самий прийом, що
   .krai-label::after) */
.rm-ethno-hint__close::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
}
.rm-ethno-hint__close:hover { color: var(--ink, #2E2419); }
.rm-ethno-hint__close:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(193, 109, 69, 0.5);
}

@media (prefers-reduced-motion: reduce) {
    .krai-item,
    .rm-ethno-hint { transition: none; }
}

/* ============================================================
   RECRE-431 — розрідження написів оглядової карти на z7-9.
   Дельта з design_mockups/recre431-map-declutter/declutter.css,
   перенесена як є (жодне з наявних правил вище НЕ РЕДАГУВАЛОСЬ).

   Принцип, спільний для всіх трьох родин міток (declutterLabelEntries,
   map.js): «ховаємо ТЕКСТ, а не об'єкт — кожен програний напис лишає
   по собі ЯКІР, який тримає позицію, клік і фокус».
     • місто (.rm-city-pill)        → пігулка згортається в крапку 12px;
     • місто без контуру (.rm-node) → лишається коло-лічильник,
       ховається лише підпис;
     • великий парк (.gpark)        → лишається кремовий бейдж 34px,
       ховаються пігулки назви/типу;
     • великий парк, полігонний режим (.gpark--poly) → пігулка
       ховається повністю: якорем працює сам акварельний контур.

   Наявний патерн .rm-region-label--collided (вище, §182-206) НЕ
   ЧІПАЄТЬСЯ — рівень «країна» лишається біт-у-біт як є (регресійний
   критерій §16.4 RECRE-360 / §10-4 Designer ТЗ RECRE-431).
   ============================================================ */

/* ------------------------------------------------------------
   1. МІСТО-ВХІД: .rm-city-pill

   Мікрозміна розмітки в makeRegionLabel (map.js): видимий текст
   пігулки загорнутий у <span class="rm-city-pill__text">. Без
   обгортки згорнути пігулку в крапку неможливо без overflow:hidden на
   самій кнопці, а overflow обрізав би прозорий ::after (хіт-ціль
   44px) — тобто зламав би чек-лист §8.
   ------------------------------------------------------------ */
.rm-city-pill__text {
    display: inline-block;
    /* 180мс — у межах 150-300мс; збігається з чинним transform 0.15s */
    transition: opacity 0.18s ease;
}

/* Пігулка, що програла колізійний прохід → ЯКІР-КРАПКА.
   Геометрія перемикається миттєво (стан змінюється лише на zoomend,
   де вся сцена й так перебудовується — «морф» ширини читався б як
   лаг), текст згасає 180мс. */
.rm-city-pill--collided {
    width: 12px;
    height: 12px;
    min-width: 0;
    padding: 0;
    border-radius: 50%;
    /* Кремовий обідець — крапка не зливається з темними тайлами
       лісу/води; та сама роль, що гало написів областей (§15.3) */
    box-shadow: 0 0 0 2.5px rgba(251, 245, 233, 0.92),
                0 2px 6px rgba(46, 36, 25, 0.30);
}

.rm-city-pill--collided .rm-city-pill__text {
    opacity: 0;
    width: 0;
    display: block;
    overflow: hidden;
}

/* Хіт-ціль 44×44 навколо крапки (базове правило дає смугу на всю
   ширину пігулки — для крапки 12px це було б 12×46) */
.rm-city-pill--collided::after {
    left: 50%;
    right: auto;
    top: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
}

/* PEEK міста — три канали, усі дають ОДИН і той самий вигляд:
     а) ховер по самій крапці (CSS, без JS: riseOnHover маркера вже
        піднімає z-порядок — пігулка не пірне під сусіда);
     б) клавіатурний фокус — крапка лишається tab-stop, бо лишається
        видимою і клікабельною (на відміну від написів областей, які
        зникають зовсім і виводяться з tab-порядку);
     в) --peek з JS (peekLabel) — ховер по КОНТУРУ міста, як у
        RECRE-360 §16.3 для областей. */
.rm-city-pill--collided:hover,
.rm-city-pill--collided:focus-visible,
.rm-city-pill--collided.rm-city-pill--peek {
    width: auto;
    height: auto;
    padding: 5px 13px;
    border-radius: 999px;
    box-shadow: 0 4px 12px rgba(46, 36, 25, 0.24);
}

.rm-city-pill--collided:hover .rm-city-pill__text,
.rm-city-pill--collided:focus-visible .rm-city-pill__text,
.rm-city-pill--collided.rm-city-pill--peek .rm-city-pill__text {
    opacity: 1;
    width: auto;
    display: inline-block;
}

/* Розгорнута крапка повертає і фокус-кільце базового правила */
.rm-city-pill--collided:focus-visible {
    box-shadow: 0 0 0 3px rgba(193, 109, 69, 0.55),
                0 4px 12px rgba(46, 36, 25, 0.24);
}

/* ------------------------------------------------------------
   2. МІСТО БЕЗ КОНТУРУ: фолбек-коло .rm-node
   Ховається ЛИШЕ підпис — коло з числом зон лишається (воно і є
   змістом мітки). visibility, а не display: коло не має «стрибати»
   вгору на висоту знятого підпису.
   ------------------------------------------------------------ */
.rm-node--collided .rm-node__label {
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.18s ease, visibility 0s linear 0.18s;
}

.rm-node--collided:hover .rm-node__label,
.rm-node--collided:focus-visible .rm-node__label,
.rm-node--collided.rm-node--peek .rm-node__label {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.18s ease;
}

/* ------------------------------------------------------------
   3. ВЕЛИКИЙ ПАРК: .gpark
   Один клас на обидва режими мітки — розгалуження в селекторах нижче.

   ТОЧКОВИЙ режим (бейдж 34px + назва + тип): ховаються обидві
   текстові пігулки, бейдж лишається. visibility (НЕ display) —
   критично: .gpark центрується transform: translate(-50%,-50%) на
   всю колонку, тож display:none зрушив би бейдж із геоточки вниз.
   ------------------------------------------------------------ */
.gpark--collided .gpark__name,
.gpark--collided .gpark__type {
    opacity: 0;
    visibility: hidden;
    /* 200мс — те саме значення, що в .rm-region-label--collided */
    transition: opacity 0.2s ease, visibility 0s linear 0.2s;
}

/* Peek точкового режиму — ховер/фокус по самому бейджу (тултіпа в
   makeGparkMarker немає, тож канал відновлення назви лише цей) */
.gpark--collided:hover .gpark__name,
.gpark--collided:hover .gpark__type,
.gpark--collided:focus-visible .gpark__name,
.gpark--collided:focus-visible .gpark__type,
.gpark--collided.gpark--peek .gpark__name,
.gpark--collided.gpark--peek .gpark__type {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.2s ease;
}

/* ПОЛІГОННИЙ режим: кнопка і Є текст — ховається цілком і перестає
   ловити вказівник. Якір/клік/назву перебирає на себе сам контур:
   клік по акварелі → selectPark (map.js:4513), ховер → sticky-тултіп
   .rm-tip з ПОВНОЮ назвою (map.js:4502). Саме тому окремого JS-peek
   для цієї родини не додаємо — він дублював би тултіп. */
.gpark--poly.gpark--collided {
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    .rm-city-pill__text,
    .rm-node--collided .rm-node__label,
    .gpark--collided .gpark__name,
    .gpark--collided .gpark__type {
        transition: none;
    }
}

/* =====================================================================
   RECRE-500 — індикатор завантаження даних НАД ПОЛОТНОМ карти
   =====================================================================
   Скарга ПО: «завантаження може тривати декілька секунд, поки в цей час
   користувач спостерігає — нічого». Афорданси в проєкті були, але всі —
   у ЛІВІЙ ПАНЕЛІ (.rm-loadbar/.panel-count--loading/:aria-busy), а вона
   на ≤680px за замовчуванням закрита; сама карта не показувала нічого.

   Нової візуальної мови не заводимо: смужка — це той самий .rm-loadbar
   з main.css (ті ж rmShimmer/rmFade, той самий блок prefers-reduced-
   motion), лише перенесений на верхню кромку полотна. Додано рівно один
   новий елемент — пілюля з текстом: 3-піксельна смужка каже «щось іде»,
   але не каже ЩО, а тікет просить саме «сповіщення».

   z-index 39 — свідомо НИЖЧЕ .park-overlay (40): «Відкриваємо парк…»
   мусить сховатись під overlay, що саме відкрився, а не висіти над ним
   решту мінімального часу показу. Вище за .map-scrim(25)/.left-panel
   (20, ≤680px — 30)/.map-fab(15). Пани Leaflet тут не конкурують: #map
   ізольований власним z-index:0 (main.css:2729), тож будь-який
   позитивний z-index сусіда вже над ними. Зі стрічкою країв (850)
   розводить не z-index, а .rm-ethno-hint--below нижче. */
.map-loading {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 39;
    /* Індикатор ніколи не перехоплює клік/драг карти — він повідомляє,
       а не є контролом (та сама причина, що в .rm-loadbar панелі) */
    pointer-events: none;
}

/* .rm-loadbar уже абсолютний із top/left/right:0 — усередині цього
   нуль-висотного контейнера він лягає рівно по кромці полотна */

.map-loading__pill {
    position: absolute;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    margin: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: min(320px, calc(100% - 24px));
    padding: 7px 14px 7px 11px;
    border: 1px solid var(--border, #E3D4B3);
    border-radius: 30px;
    background: rgba(251, 245, 233, 0.95);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    box-shadow: 0 18px 40px -24px rgba(47, 74, 55, 0.7);
    font-size: 12.5px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--ink-2, #3A3127);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    /* Та сама затримка появи, що в .rm-loadbar (.15s): показ уже
       відкладений станом на 300 мс, fade лише згладжує вхід */
    animation: rmFade .2s ease .05s both;
}

/* Пульс замість спінера: у боho-системі немає жодного обертового
   елемента, а rmChipPulse уже носить сенс «дані ще не готові»
   (.panel-count--loading лівої панелі) */
.map-loading__dot {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--sage, #7E9466);
    animation: rmChipPulse 1.2s ease-in-out infinite;
}

/* ≤680px: центр верхньої кромки зайнятий — там стоїть пілюля «Довкілля»
   (.env-pill, top-right, ~110px). Центрована пілюля індикатора з нею
   перетиналась, тож на вузьких екранах вона притискається ЛІВОРУЧ:
   верхній лівий кут полотна вільний (контроли зуму — знизу праворуч),
   а max-width лишає «Довкіллю» його місце. */
@media (max-width: 680px) {
    .map-loading__pill {
        top: 10px;
        left: 10px;
        transform: none;
        max-width: calc(100% - 140px);
        font-size: 12px;
        padding: 6px 12px 6px 10px;
    }
}

/* RECRE-500: підказка країв ділить слот із пілюлею — на час індикатора
   опускається під нього (обидва з'являються разом при вмиканні шару) */
.rm-ethno-hint--below { top: 52px; }
@media (max-width: 680px) {
    .rm-ethno-hint--below { top: 48px; }
}

@media (prefers-reduced-motion: reduce) {
    .map-loading__pill { animation: none; }
    .map-loading__dot { animation: none; opacity: .75; }
}

/* ============================================================
   RECRE-507 — ПІЛЮЛЯ АВТОЗМІНИ НАПРЯМКУ (.map-region-toast).

   Скарга ПВ: «коли я переміщую карту і в мене зверху змінюється
   область, то потрібно користувача якось про це попередити». Механіка
   RECRE-421/422 перемикає напрямок тихо (moveend → updateRegionPanel),
   і користувач бачить уже іншу вибірку, не помітивши моменту.

   Нової візуальної мови НЕ заводимо: це буквально .map-loading__pill
   RECRE-500 — та сама форма, кегль, тінь, blur і та сама поведінка на
   ≤680px (притискання ліворуч, бо верх-праворуч зайнятий .env-pill).
   Відрізняє її лише іконка-шпилька: пілюля повідомляє МІСЦЕ, а не
   процес, тож пульсуючої крапки тут немає.

   Слот у обох один — верх полотна. Розводяться так само, як індикатор
   і стрічка країв: на час індикатора пілюля напрямку опускається
   (--below), а не накладається. Пріоритет саме такий, бо індикатор
   тримається рівно доти, доки триває завантаження (він швидкоплинніший
   і прив'язаний до кромки полотна зі смужкою), а напрямок читається
   спокійно 3 секунди нижче.

   z-index 39 — той самий, що в .map-loading: НИЖЧЕ .park-overlay (40),
   щоб пілюля ховалась під overlay парку, який саме відкрився. */
.map-region-toast {
    position: absolute;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 39;
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    max-width: min(340px, calc(100% - 24px));
    padding: 7px 14px 7px 11px;
    border: 1px solid var(--border, #E3D4B3);
    border-radius: 30px;
    background: rgba(251, 245, 233, 0.95);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    box-shadow: 0 18px 40px -24px rgba(47, 74, 55, 0.7);
    font-size: 12.5px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--ink-2, #3A3127);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    /* Повідомляє, а не є контролом: клік/драг карти проходить крізь */
    pointer-events: none;
    animation: rmFade .2s ease both;
}

.map-region-toast i,
.map-region-toast svg {
    flex: none;
    width: 15px;
    height: 15px;
    color: var(--sage, #7E9466);
}

/* На час індикатора завантаження — під ним (спільний слот) */
.map-region-toast--below { top: 52px; }

/* ≤680px: та сама причина, що в .map-loading__pill — центр верхньої
   кромки з'їдає .env-pill (top-right), тож пілюля йде ліворуч */
@media (max-width: 680px) {
    .map-region-toast {
        top: 10px;
        left: 10px;
        transform: none;
        max-width: calc(100% - 140px);
        font-size: 12px;
        padding: 6px 12px 6px 10px;
    }
    .map-region-toast--below { top: 48px; }
}

@media (prefers-reduced-motion: reduce) {
    .map-region-toast { animation: none; }
}

/* ============================================================
   RECRE-501 — СПИСОК-ВИБІР МІСТ КЛАСТЕРА (.rm-city-pick).

   Скарга ПВ: «при натисканні на кластер з трьох об'єктів він не
   зумиться та не розпадається». Причина — геометрична (розбір у
   cityClusterSplitZoom, map.js): група, вужча за
   CITY_CLUSTER_RADIUS_PX навіть на стелі рівня «регіон», не
   розпадеться на жодному дозволеному зумі, і клік не мав куди вести.
   Відповідь тут — та сама, що в списку-виборі POI (RECRE-433): коли
   геометрія відповіді не дає, її дає СПИСОК.

   Форма — картка попапа тієї ж родини, що .ethno-popup вище (кремове
   тло, --border-2, радіус 16, м'яка тінь): це не новий тип UI, а
   наявний тип із новим вмістом. Обгортка Leaflet прозора, як усюди в
   проєкті; хвостик лишаємо СТАНДАРТНИЙ (на відміну від .ethno-popup з
   власним ::after) — картка вужча, і власний хвостик тут не давав би
   нічого, крім ще одного місця для розсинхрону.
   ============================================================ */
.leaflet-popup.rm-city-pick-popup .leaflet-popup-content-wrapper {
    background: var(--surface, #FBF5E9);
    border: 1px solid var(--border-2, #E8D9BB);
    border-radius: 16px;
    box-shadow: 0 26px 60px -28px rgba(47, 74, 55, 0.72);
    padding: 0;
}
.leaflet-popup.rm-city-pick-popup .leaflet-popup-content {
    margin: 0;
    line-height: inherit;
    width: auto !important;
}
.leaflet-popup.rm-city-pick-popup .leaflet-popup-tip {
    background: var(--surface, #FBF5E9);
}

.rm-city-pick {
    width: 230px;
    max-width: calc(100vw - 48px);
    box-sizing: border-box;
    padding: 12px 8px 8px;
    font-family: 'Mulish', system-ui, sans-serif;
}

.rm-city-pick__title {
    margin: 0 8px 8px;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted-2, #8A7A5C);
}

.rm-city-pick__list {
    list-style: none;
    margin: 0;
    padding: 0;
    /* 6 рядків видно без прокрутки; довший кластер (11 супутників
       Києва, RECRE-458) прокручується всередині картки, а не розтягує
       попап на пів-екрана */
    max-height: 240px;
    overflow-y: auto;
}

.rm-city-pick__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    /* ≥44px хіт-ціль без прозорих псевдоелементів — рядок і є ціллю */
    min-height: 44px;
    padding: 8px 10px;
    border: none;
    border-radius: 10px;
    background: none;
    font: inherit;
    text-align: left;
    color: var(--ink, #2E2419);
    cursor: pointer;
}

.rm-city-pick__row:hover,
.rm-city-pick__row:focus-visible {
    background: var(--bg-2, #EFE3CD);
}

.rm-city-pick__row:focus-visible {
    outline: 2px solid var(--terracotta, #C16D45);
    outline-offset: -2px;
}

.rm-city-pick__name {
    font-weight: 700;
    font-size: 14px;
}

.rm-city-pick__meta {
    flex: none;
    font-size: 12px;
    color: var(--muted-2, #8A7A5C);
    white-space: nowrap;
}

/* ============================================================
   RECRE-589 — ХІТ-ЗОНА ПІДПИСІВ = ЇХНЄ ВИДИМЕ ЧОРНИЛО.

   Скарга ПВ (живе тестування 2026-09-22, скрін обласного зуму):
   «інформація про парк з'являється коли курсор потрапляє в блок
   лейбла, навіть не торкаючись самого контуру символу. Це створює
   складності взаємодії з картою, бо підпис виникає рандомно для
   користувача, а не коли він наводить на контур символу».

   ПРИЧИНА. Мітка великого парку .gpark — flex-КОЛОНКА: бейдж 34px,
   під ним пігулка-назва (до 200px), під нею рядок типу. Ширину кнопки
   задає найширша дитина, висоту — сума трьох рядів, і вся ця площа
   ловила вказівник (pointer-events: auto на самій кнопці). Заміряно
   в браузері на «НПП Гомільшанські ліси» (1440x900, рівень регіону):
   бокс кнопки 146.8x75.6px, 2812 проб по сітці 2px — УСІ повертають
   саму кнопку, з них 1735 (61.7%) лежать поза будь-якою видимою
   дитиною, тобто на чистому прозорому полі. Курсор за 53px ЛІВОРУЧ
   від кружка вже давав .gpark:hover і збільшення бейджа до 1.1.
   Те саме структурно в .rm-node (divIcon 160x74: коло 40px + пілюля),
   і те саме, слабше, у ПРОЗОРИХ ::after-смугах 44-46px, якими
   написи областей/міст/країв добирають тач-ціль поверх чорнила
   заввишки 21-25px.

   ПРАВКА. На вказівнику ТОЧНОМУ (миша, трекпад) хіт-зона
   звужується рівно до видимих частин: сам бейдж, пігулка-назва,
   рядок типу, коло-лічильник, текст напису. На вказівнику ГРУБОМУ
   (тач) НІЧОГО не змінюється — клік-цілі ≥44px чек-листа §8
   лишаються недоторканими, бо на тачі немає ані ховера, ані скарги.

   ЧОМУ ЦЕ НЕ ЛАМАЄ НАЯВНОЇ МЕХАНІКИ:
     • :hover самої кнопки живий — наведення на дитину дає :hover і
       всім її предкам, тож .gpark:hover .gpark__badge, peek
       .gpark--collided:hover .gpark__name і .rm-node:hover
       .rm-node__count працюють як раніше;
     • клік теж — подія з дитини спливає до <button>, далі до вузла
       divIcon, де її підхоплює штатна делегація Leaflet (той самий
       прийом, що вже діє для .gpark-divicon і .krai-label-wrap);
     • розкладка (declutterLabelEntries) міряє getBoundingClientRect
       САМОЇ кнопки, а абсолютний ::after у її бокс не входить —
       жодне число деклаттера не змінюється;
     • приховані стани (--collided, --clustered, --ethno-hidden)
       вимикають чорнило через visibility: hidden, а невидимий
       елемент мішенню вказівника не буває — крім полігонної пігулки
       .gpark--poly.gpark--collided, де приховання трималося саме на
       pointer-events кнопки: їй повернуто явну заборону нижче.
   ============================================================ */

@media (hover: hover) and (pointer: fine) {
    /* Великий парк: вказівник приймають лише бейдж і два написи */
    .gpark {
        pointer-events: none;
    }
    .gpark__badge,
    .gpark__name,
    .gpark__type {
        pointer-events: auto;
    }
    /* Прозорий квадрат 46px довкола бейджа — тач-ціль; на миші він
       зайвий (бейдж і так ловить вказівник) і саме він розширював
       реакцію на 6px за контур символу */
    .gpark::after {
        pointer-events: none;
    }
    /* Повністю прихована пігулка полігонного режиму: приховання
       трималося на pointer-events кнопки (.gpark--poly.gpark--collided
       вище у файлі), тож заборону дублюємо на дітях — інакше правило
       .gpark__name вище зняло б її й невидимий напис знову крав би
       ховер у власного контуру-акварелі */
    .gpark--poly.gpark--collided .gpark__name,
    .gpark--poly.gpark--collided .gpark__type {
        pointer-events: none;
    }

    /* Вузол-лічильник: divIcon оголошений 160x74, видимого чорнила —
       коло 40px і пілюля під ним */
    .leaflet-marker-icon.rm-node-divicon {
        pointer-events: none;
    }
    .rm-node {
        pointer-events: none;
    }
    .rm-node__count,
    .rm-node__label {
        pointer-events: auto;
    }

    /* Написи областей, пігулки міст, бульбашки кластерів і написи
       етнокраїв: власний бокс кнопки вже дорівнює чорнилу (падінг
       2-8px), зайвою лишалась тільки прозора смуга ::after заввишки
       44-46px. 24px — нижня межа WCAG 2.5.8 для точного вказівника,
       і вона вже НЕ виступає за кнопку (її бокс 24-28px).
       Для написів країв це ще й прямий виграш шару: смуга лежала в
       ethnoLabelPane (590) НАД полем ареалу і з'їдала його ховер */
    .rm-region-label::after,
    .rm-city-pill::after,
    .rm-city-cluster::after,
    .krai-label::after {
        height: 24px;
    }
}
