/* Сказочная карта: та же тёмно-золотая палитра, что и в игре.
   Карта и игра — одно место, и выглядеть они должны как одно место. */

:root {
  --bg: #12100c;
  --glass: rgba(28, 23, 17, 0.9);
  --glass-2: rgba(58, 48, 34, 0.72);
  --edge: rgba(226, 197, 128, 0.35);
  --edge-hot: #f0d68a;
  --gold: #ffe6a6;
  --text: #f3ecd9;
  --dim: #c9bda0;
  --font: "Trebuchet MS", "Segoe UI", sans-serif;
  --mono: "Consolas", "DejaVu Sans Mono", monospace;

  /* Высота шапки, измеренная на живой странице (`map.js`), и отступ панелей под
     неё. Раньше во всех панелях стояло `top: 74px` — число под шапку в один ряд.
     На узком экране она встаёт в три ряда и вырастает до 126px, и панели
     залезали ей под низ: в альбомной ориентации телефона книжка накрывала
     полосу кнопок целиком, и нажать их было нельзя, пока не закроешь сказку.
     Значение здесь запасное — на случай, если разметку ещё не измерили. */
  --шапка: 62px;
  --подШапкой: calc(var(--шапка) + 12px);
  /* Высота полосы вкладок. Считает её js/map/shtorka.js по живому замеру: она
     зависит от того, влезли ли подписи в одну строку, а подписи — русские
     слова, а не значки. От неё поднимается всё, что стоит у нижнего края:
     панели-листы на телефоне, легенда, кнопки зума, кружок «ⓘ». */
  --рейкаВысота: 0px;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  background: var(--bg); color: var(--text);
  font-family: var(--font); font-size: 14px;
  overflow: hidden;
}

/* Фон под подложкой — светлый, того же цвета, что и незастроенная земля на
   самой карте.
   Он виден в двух местах: там, куда плитки ещё не доехали, и за краем мира.
   Сперва он был почти чёрным — это читалось как дыра. Потом стал тёмной
   охрой — заметно лучше, но пустота всё равно бросалась в глаза тёмным
   пятном. Теперь он одного семейства с приглушённой землёй подложки
   (rgb 136, 130, 121), только на десяток единиц тише: пропуск виден, если
   присматриваться, и не виден, если просто смотришь на карту. Это ровно то,
   чего от него и надо.
   Два оттенка, а не один: дочиста плоская заливка во весь экран выглядит не
   бумагой, а сбоем отрисовки. Мягкий перелив по диагонали читается как лист,
   на котором ещё не всё нарисовано, — и не спорит с картой, потому что
   разница между его краями всего десять единиц из 255. */
#map {
  position: absolute; inset: 0;
  background: linear-gradient(155deg, #8a857d 0%, #7e7a72 100%);
}

/* Подложка приглушена: карта здесь — фон для точек, а не самоцель. Живые цвета
   OSM перетягивали внимание на автозаправки.
   Приглушение делается НЕ здесь, а в самой плитке, когда она пришла:
   `js/map/map.js` рисует картинку на холст с тем же фильтром, и в разметке
   лежит уже приглушённый холст. Причина — цена: CSS-фильтр заставляет браузер
   собрать слой карты в отдельную поверхность и пройти по каждой её точке; слой
   размером во всю прокрученную карту, а под нехваткой видеопамяти Chromium
   этого прохода не доводит, оставляя куски ненарисованными — те самые чёрные
   квадраты, на которые владелец жаловался трижды.
   Правило ниже — запасное, для браузеров, которые не умеют фильтровать холст
   (Safari до 17-й): там класс на `<html>` ставит map.js, и всё возвращается к
   прежнему, дорогому, но верному по цвету способу. */
html.фильтр-стилями .leaflet-tile {
  filter: grayscale(0.55) brightness(0.52) contrast(1.05) sepia(0.25);
}
/* Цвет фона здесь не повторяем: `.leaflet-container` — это тот же самый `#map`
   (класс Leaflet вешает при заводе карты), и два места для одного цвета
   однажды разойдутся. Всё про фон — выше, в правиле `#map`. */
.leaflet-container { font-family: var(--font); }
/* Штатной полосы с подписью нет (см. `map.js`), но если Leaflet заведёт её сам
   — например, у слоя со своей `attribution`, — она не должна вылезти поперёк
   карты. Подпись живёт под кнопкой «ⓘ». */
.leaflet-control-attribution { display: none !important; }

/* `position: relative` — ради раскрытой подписи ниже: с 04.09 под «ⓘ» в том же
   углу стоят кнопки зума, и растущий в потоке блок толкал бы их вниз прямо
   под пальцем. */
.о-карте { margin: 0 8px 8px 0 !important; text-align: right; position: relative; }
.о-карте button {
  width: 26px; height: 26px; line-height: 1; padding: 0;
  background: var(--glass); border: 1px solid var(--edge); border-radius: 50%;
  color: var(--dim); cursor: pointer; font-size: 14px;
}
.о-карте button:hover { color: var(--gold); border-color: var(--edge-hot); }
.о-карте .строки {
  /* Всплывает, а не раздвигает угол: иначе она толкала бы вниз кнопки зума,
     стоящие в том же углу под нею.
     Стоит НАД кнопкой «ⓘ»: отступ снизу — мерка живой кнопки из «map.js»
     («--оНиз»), а не край окна. Прижатая к нижнему краю окна, подсказка
     накрывала саму кнопку, и закрыть её было нечем (04.09). Высота при этом
     не задирается вверх без спроса — потолок считается от того, что осталось
     между шапкой и самой кнопкой. Запасное значение — на случай, если мерка
     ещё не прошла: столбик из трёх кнопок в углу как раз около 104 точек.
     Шире прежних 260 точек: с 04.09 здесь же лежит легенда, и девять округов
     в такой ширине рассыпались бы на пять строк. */
  position: fixed; right: 12px; z-index: 1000;
  bottom: var(--оНиз, calc(var(--рейкаВысота, 0px) + 104px));
  width: max-content; max-width: min(420px, calc(100vw - 32px));
  max-height: calc(100vh - var(--шапка) - var(--оНиз, calc(var(--рейкаВысота, 0px) + 104px)) - 12px);
  overflow-y: auto;
  padding: 10px 12px;
  background: rgba(20, 17, 12, .97); border: 1px solid var(--edge); border-radius: 9px;
  color: var(--dim); font-size: 11px; line-height: 1.5; text-align: left;
}
/* Легенда — вторым разделом подсказки, отчёркнутая от двух строк о карте:
   выше — чья подложка, ниже — что значит цвет точки. Разговор один. */
.оЛегенда {
  display: flex; flex-direction: column; gap: 3px;
  margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--edge);
}
/* Подписи разделов и хвостовая строка. `white-space: normal` — потому что
   `.имяполя` в панелях однострочная и обрезается многоточием, а здесь она
   рядом с узкой подсказкой на телефоне. `z-index` у подсказки выше нуля
   нарочно: кнопки зума — соседний контрол Leaflet и стоят в разметке позже,
   без него они рисовались прямо поверх раскрытой легенды. */
.оЛегенда .имяполя { margin: 4px 0 0; white-space: normal; overflow: visible; }
.оЛегенда .имяполя:first-child { margin-top: 0; }
.оЛегенда .мелко { margin-top: 8px; }
.о-карте .строки a { color: var(--gold); }
/* Пока подсказка раскрыта, соседи по углу — зум и «Где я» — уходят с глаз.
   Бороться с ними z-index'ом бесполезно: это отдельные контролы Leaflet, они
   стоят в разметке позже и рисуются поверх; проверено снимком — кнопки
   ложились прямо на список округов. `visibility`, а не `display`: угол не
   должен схлопнуться и утащить за собой саму кнопку «ⓘ». Под подсказкой они
   всё равно не видны, а закрыть её — одно нажатие по тому же «ⓘ». */
.leaflet-bottom.leaflet-right:has(.о-карте .строки:not([hidden])) .leaflet-control-zoom,
.leaflet-bottom.leaflet-right:has(.о-карте .строки:not([hidden])) .гдеЯКнопка {
  visibility: hidden;
}
.leaflet-bar a {
  background: var(--glass); color: var(--gold); border-color: var(--edge);
}
.leaflet-bar a:hover { background: var(--glass-2); color: var(--edge-hot); }
/* Кнопки зума живут внизу слева, над легендой. Наверху им места нет: там
   шапка, а под шапкой — панель викторины, и «плюс» садился то на название
   карты, то на первый вопрос.
   С 04.09 кнопки зума и «Где я» стоят у ПРАВОГО края, а не над легендой:
   телефон держат правой рукой, и большой палец достаёт до правого нижнего
   угла, не перехватывая аппарат. Прежняя мерка высоты легенды вместе с
   переменной `--нижЛевВысота` убрана — над легендой теперь пусто.
   Поднять правый угол надо только над полосой вкладок: она стоит по центру и
   на узком экране дотягивается до него. */
.leaflet-bottom.leaflet-right {
  margin-bottom: var(--рейкаВысота, 0px);
  /* Порядок в углу задаём сами. Leaflet кладёт кнопки нижних углов в обратном
     порядке добавления, и «ⓘ» оказывалась ниже зума — то есть на самом удобном
     для пальца месте доставалась самой редкой кнопке. Снизу вверх: зум, «Где
     я», «ⓘ». Чем чаще нажимают, тем ближе к углу. */
  display: flex; flex-direction: column; align-items: flex-end;
}
.leaflet-bottom.leaflet-right .о-карте { order: 1; }
.leaflet-bottom.leaflet-right .гдеЯКнопка { order: 2; }
.leaflet-bottom.leaflet-right .leaflet-control-zoom { order: 3; }

/* Значок сказки-квеста поверх обычной точки: книжка вместо кружка — видно
   издалека, где на карте можно начать читать, а не только по клику узнавать,
   что тут есть сказка. */
.сказка-иконка {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%;
  background: rgba(20, 16, 10, .92); border: 2px solid var(--gold);
  box-shadow: 0 0 10px rgba(240, 214, 138, .55);
  font-size: 14px; line-height: 1; cursor: pointer;
  transition: transform .1s ease-out, box-shadow .1s ease-out;
}
.сказка-иконка:hover { transform: scale(1.12); box-shadow: 0 0 16px rgba(240, 214, 138, .85); }

/* Значок жанра (былина/легенда/хождение) поверх точки — меньше книжки
   сказки-квеста и с приглушённой рамкой, чтобы не спорить с ней визуально
   там, где обе метки могли бы оказаться рядом. */
.жанр-иконка {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: rgba(20, 16, 10, .88); border: 2px solid var(--dim);
  font-size: 12px; line-height: 1; cursor: pointer;
  transition: transform .1s ease-out;
}
.жанр-иконка:hover { transform: scale(1.12); }

/* ─── Полосы прокрутки ───────────────────────────────────────────────────── */
/* Системная полоса — белая и широкая: в тёмных панелях она светила ярче
   содержимого. Тонкая, полупрозрачным золотом интерфейса. Chrome и Firefox
   понимают стандартную пару свойств; дубль ::-webkit-scrollbar — для старых
   WebKit, новые его игнорируют при заданном scrollbar-width. */
* { scrollbar-width: thin; scrollbar-color: rgba(226,197,128,.38) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: rgba(226,197,128,.32); border-radius: 4px; }
*::-webkit-scrollbar-thumb:hover { background: rgba(226,197,128,.55); }
*::-webkit-scrollbar-corner { background: transparent; }

/* ─── Шапка ──────────────────────────────────────────────────────────────── */

#шапка {
  position: absolute; z-index: 500; inset: 0 0 auto 0;
  display: flex; align-items: center; gap: 14px;
  padding: 10px 14px;
  /* Размытия за шапкой больше нет: `backdrop-filter` заставляет браузер
     снять всё, что под элементом, в отдельную поверхность — а под шапкой лежит
     вся карта. Под нехваткой видеопамяти это ровно та работа, которую Chromium
     бросает недоделанной, оставляя чёрные прямоугольники (см. плёнку
     приглушения в js/map/map.js). Заливка градиентом стала чуть плотнее —
     этого хватает, чтобы кнопки читались над любой картой. */
  background: linear-gradient(180deg, rgba(18,16,12,.97) 0%, rgba(18,16,12,.82) 70%, rgba(18,16,12,0) 100%);
  pointer-events: none;
}
#шапка > * { pointer-events: auto; }

/* Название — кнопка: за ним рассказ о проекте. Выглядит текстом нарочно, а
   подчёркивается только под курсором: шапка не место для третьей яркой кнопки. */
.титул {
  display: flex; flex-direction: column; align-items: flex-start;
  line-height: 1.25; white-space: nowrap; cursor: pointer;
  background: transparent; border: 0; padding: 0; text-align: left;
  font-family: var(--font);
}
.титул b { color: var(--gold); letter-spacing: 2px; font-size: 15px; }
.титул:hover b { text-decoration: underline; }
.титул span { color: var(--dim); font-size: 11px; font-family: var(--mono); }

#оПроектеОкно {
  position: absolute; z-index: 560; top: var(--подШапкой); left: 12px;
  width: 380px; max-width: calc(100vw - 24px);
  max-height: calc(100vh - 100px); overflow-y: auto;
  padding: 16px 18px 18px;
  background: var(--glass); border: 1px solid var(--edge-hot); border-radius: 10px;
}
#оПроектеОкно[hidden] { display: none; }
#оПроектеОкно h2 { margin: 4px 0 10px; font-size: 19px; color: var(--gold); line-height: 1.2; }
#закрытьОПроекте {
  position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; line-height: 1;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); border-radius: 6px; cursor: pointer;
}
#оСписок { margin: 6px 0 0; padding-left: 18px; color: var(--text); font-size: 13px; line-height: 1.7; }
#оВИгру { text-decoration: none; display: inline-block; }

/* min-width: кнопок в шапке прибавилось («Продолжить…», имя странника), и
   flexbox сжимал поиск до автоминимума поля ввода — от него оставался
   квадратик. Теперь ужимается полоса кнопок (она листается), а не поиск. */
.поиск { position: relative; flex: 1; max-width: 560px; min-width: 200px; }
#поиск {
  width: 100%; padding: 9px 12px;
  background: var(--glass); color: var(--text);
  border: 1px solid var(--edge); border-radius: 7px;
  font-family: var(--font); font-size: 14px; outline: none;
}
#поиск:focus { border-color: var(--edge-hot); }
#поиск::placeholder { color: #8a7f68; }

#подсказки {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0;
  max-height: 58vh; overflow-y: auto;
  background: var(--glass); border: 1px solid var(--edge); border-radius: 7px;
}
#подсказки .строка {
  padding: 8px 11px; cursor: pointer; border-bottom: 1px solid rgba(226,197,128,.12);
}
#подсказки .строка:last-child { border-bottom: 0; }
#подсказки .строка:hover, #подсказки .строка.на { background: var(--glass-2); }
#подсказки .имя { color: var(--gold); }
#подсказки .где { color: var(--dim); font-size: 11px; font-family: var(--mono); }
#подсказки .пусто { padding: 10px 11px; color: var(--dim); }
/* Заголовок группы («Сказки-квесты», «Маршруты», «Места на карте») — три
   разных списка на одной ленте подсказок, и без подписи непонятно, куда
   ведёт клик: в книжку, в панель маршрута или на точку карты. */
#подсказки .группаЗаголовок {
  padding: 7px 11px 4px; color: #9c8f74; font-size: 10px; letter-spacing: .04em;
  text-transform: uppercase; font-family: var(--mono);
}
#подсказки .группаЗаголовок:not(:first-child) {
  border-top: 1px solid rgba(226,197,128,.12); margin-top: 4px;
}
/* Когда нашли не по написанному, а по догадке — строка сверху говорит, что
   именно поняли. Тише самих находок: это пояснение, а не результат. */
#подсказки .намёк {
  padding: 7px 11px; color: #9c8f74; font-size: 11px; font-family: var(--mono);
  border-bottom: 1px solid rgba(226,197,128,.12); background: rgba(58,48,34,.35);
}

/* Полоса кнопок листается и на столе, как на телефоне: кнопок стало больше,
   чем влезает рядом с поиском, а перенос растил бы шапку вниз и закрывал
   карту. Колесо мыши крутит её вбок (map.js), о скрытых кнопках говорит
   растворённый край (.естьДальше). */
.кнопки {
  display: flex; align-items: center; gap: 10px;
  min-width: 0; overflow-x: auto; scrollbar-width: none;
}
.кнопки::-webkit-scrollbar { display: none; }
.кнопки > * { flex: 0 0 auto; }
/* «Продолжить…» несёт название сказки и главы и может вырасти шире экрана —
   обрезается многоточием: полный список закладок и так есть в профиле. */
#продолжитьЧтение { max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Двойники «Скрыть панели», «Во весь экран» и «Правка карты» в профиле — тоже
   только для телефона (t138): на столе те же действия и так стоят в шапке, и
   дублировать их внутри профиля незачем. Показ — в том же media-блоке. */
.рядКнопок.профильЭкран, #профильПравка, #профильПоддержать { display: none; }

/* Убрать панели с карты. Кнопка живёт в шапке рядом со «Войти», но при
   скрытых панелях остаётся видна одна она — иначе открыть панели обратно
   было бы нечем. */
#панелиКнопка, #экранКнопка, #профильПанели, #профильВоВесь {
  padding: 8px 12px; border-radius: 7px; cursor: pointer;
  background: var(--glass); border: 1px solid var(--edge);
  color: var(--dim); font-family: var(--font); font-size: 12px;
}
/* Значок вместо слова: подписи «Во весь экран» не нужно — она есть в title, а
   полоса кнопок на телефоне и так уезжает вбок. Ширину задаём, чтобы значок
   не прыгал при смене на «выйти из полного экрана». */
#экранКнопка { min-width: 38px; font-size: 14px; line-height: 1; text-align: center; }
#панелиКнопка:hover, #экранКнопка:hover, #профильПанели:hover, #профильВоВесь:hover { color: var(--gold); border-color: var(--edge-hot); }
#панелиКнопка.горит, #экранКнопка.горит, #профильПанели.горит, #профильВоВесь.горит {
  background: #6d4b12; color: #fff3cf; border-color: var(--edge-hot);
}
#экранКнопка[hidden], #профильВоВесь[hidden] { display: none; }

/* Скрыто — значит не видно; ничего при этом не закрывается и не забывается.
   Открытая карточка останется открытой, когда панели вернут. */
body.панели-скрыты #карточка,
body.панели-скрыты #профиль,
body.панели-скрыты #вход,
body.панели-скрыты #поддержка,
body.панели-скрыты #рядом,
body.панели-скрыты #мршСписок,
body.панели-скрыты #дорога,
body.панели-скрыты #правка,
body.панели-скрыты #викторина,
body.панели-скрыты #оПроектеОкно,
body.панели-скрыты #сказка,
body.панели-скрыты #скзСписок,
body.панели-скрыты #знание,
body.панели-скрыты #шторкаОкно,
body.панели-скрыты #нижЛев { display: none !important; }
/* Рейку убираем только там, где есть чем её вернуть. На столе и планшете это
   кнопка «Скрыть панели» в шапке, она нарочно остаётся видимой. На телефоне
   кнопок в шапке нет вовсе — та же кнопка лежит в профиле, а профиль сам из
   числа убранных: спрятав рейку, мы заперли бы человека на голой карте.
   Поэтому там рейка остаётся, и нажатие на любую вкладку возвращает панели
   (см. `поВкладке` в js/map/shtorka.js). */
@media (min-width: 721px) {
  body.панели-скрыты #шторкаРейка { display: none !important; }
}
/* Шапка — тоже панель, но кнопку, которая их возвращает, спрятать нельзя. */
/* Вместе с «Скрыть панели» остаётся и «во весь экран»: панели убирают именно
   затем, чтобы смотреть карту, и развернуть её хочется тут же. */
body.панели-скрыты #шапка > *:not(.кнопки),
body.панели-скрыты .кнопки > *:not(#панелиКнопка):not(#экранКнопка) { visibility: hidden; }

#играть, #кнопкаВикторины {
  padding: 9px 16px; border-radius: 7px; white-space: nowrap;
  background: var(--glass-2); border: 1px solid var(--edge-hot);
  color: var(--gold); text-decoration: none; letter-spacing: 1px;
  font-family: var(--font); font-size: 14px; cursor: pointer;
}
#играть:hover, #кнопкаВикторины:hover { background: #4a3d26; color: #fff3cf; }
/* Викторина тише «Войти в игру»: она развлечение, а не главный путь. */
#кнопкаВикторины { border-color: var(--edge); }

/* ─── Викторина ──────────────────────────────────────────────────────────── */

#викторина {
  position: absolute; z-index: 520; left: 12px; top: var(--подШапкой);
  width: 400px; max-width: calc(100vw - 24px);
  max-height: calc(100vh - 100px); overflow-y: auto;
  padding: 16px 18px 18px;
  background: var(--glass); border: 1px solid var(--edge-hot); border-radius: 10px;
}
#викторина[hidden] { display: none; }
#закрытьВикторину {
  position: absolute; top: 8px; right: 8px; width: 28px; height: 28px;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); border-radius: 6px; cursor: pointer; line-height: 1;
}
#закрытьВикторину:hover { color: var(--gold); border-color: var(--edge-hot); }
.ярлык { padding: 2px 7px; border-radius: 20px; background: var(--edge-hot); color: #12100c; font-weight: bold; }
#ходВикторины { color: var(--dim); font-family: var(--mono); font-size: 11px; }
#темаВопроса {
  margin-top: 10px; font-family: var(--mono); font-size: 10px;
  letter-spacing: 2px; text-transform: uppercase; color: #9c8f74;
}
#викторина h2 { margin: 4px 0 12px; font-size: 17px; line-height: 1.35; color: var(--gold); }

#варианты { display: flex; flex-direction: column; gap: 7px; }
.вариант {
  text-align: left; padding: 10px 12px; line-height: 1.4;
  background: rgba(58,48,34,.5); border: 1px solid var(--edge);
  color: var(--text); border-radius: 7px; cursor: pointer;
  font-family: var(--font); font-size: 14px;
}
.вариант:hover:not(:disabled) { background: var(--glass-2); border-color: var(--edge-hot); }
.вариант:disabled { cursor: default; }
.вариант.верно { border-color: #a8e86a; background: rgba(168,232,106,.16); color: #dcffbc; }
.вариант.мимо { border-color: #ff7a6a; background: rgba(255,122,106,.13); color: #ffcfc8; }
.вариант.тускло { opacity: .45; }

#разбор { margin-top: 12px; padding: 10px 12px; border-radius: 7px;
  background: rgba(58,48,34,.45); line-height: 1.5; }
#разбор.верно { border-left: 3px solid #a8e86a; }
#разбор.мимо { border-left: 3px solid #ff7a6a; }

.низВикторины { display: flex; gap: 8px; margin-top: 12px; }
.низВикторины button {
  padding: 8px 14px; border-radius: 7px; cursor: pointer;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); font-family: var(--font); font-size: 13px;
}
.низВикторины button:hover { color: var(--gold); border-color: var(--edge-hot); }
#дальше { margin-left: auto; color: var(--gold); border-color: var(--edge-hot); }
#подсказкаТекст {
  margin-top: 10px; color: #cbbf9f; font-size: 13px; line-height: 1.5;
  padding-left: 10px; border-left: 2px solid var(--edge);
}
#итогВикторины { margin-top: 10px; line-height: 1.5; }

/* ─── Карточка сказки ────────────────────────────────────────────────────── */

#карточка {
  position: absolute; z-index: 500; right: 12px; top: var(--подШапкой); bottom: 12px;
  width: 380px; max-width: calc(100vw - 24px);
  overflow-y: auto; padding: 16px 18px 20px;
  background: var(--glass); border: 1px solid var(--edge); border-radius: 10px;
}
#карточка[hidden] { display: none; }
#закрыть {
  position: absolute; top: 8px; right: 8px;
  width: 28px; height: 28px; line-height: 1;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); border-radius: 6px; cursor: pointer;
}
#закрыть:hover { color: var(--gold); border-color: var(--edge-hot); }

.метка { display: flex; gap: 8px; align-items: center; font-family: var(--mono); font-size: 11px; }
#округ { padding: 2px 7px; border-radius: 20px; color: #12100c; font-weight: bold; }
#номер { color: var(--dim); }
#карточка h1 { margin: 8px 0 2px; font-size: 21px; color: var(--gold); line-height: 1.2; }
.место { color: var(--dim); font-size: 12px; margin-bottom: 14px; }

.поле { margin-bottom: 13px; }
.имяполя {
  font-family: var(--mono); font-size: 10px; letter-spacing: 2px;
  text-transform: uppercase; color: #9c8f74; margin-bottom: 3px;
}
.поле > div:last-child { line-height: 1.5; }
#вывод { color: #ffeec2; }
.поле.пусто > div:last-child { color: #8a7f68; font-style: italic; }

/* Зов прочесть сказку стоит сразу под названием места, а не в конце карточки:
   на телефоне карточка ограничена по высоте и прокручивается внутри себя, и
   снизу кнопка уходила за нижний край экрана — до сказки нельзя было добраться
   вовсе. Сверху она видна на любом экране без прокрутки. */
#карточкаСказка {
  display: block; width: 100%; margin: 2px 0 16px; padding: 10px 12px;
  border-radius: 7px; cursor: pointer;
  background: var(--glass-2); border: 1px solid var(--edge-hot);
  color: var(--gold); font-family: var(--font); font-size: 13px;
}
#карточкаСказка:hover { background: #4a3d26; color: #fff3cf; }
#карточкаСказка[hidden] { display: none; }

/* Прежде на столе шириной 1280–1440 карточка при открытой сказке сама
   сворачивалась до строки заголовка: сказка (520px слева) и карточка (380px
   справа) вместе съедали карту почти целиком. Правило снято вместе с
   переездом на шторку — сказка и разбор точки стали двумя её вкладками и
   больше не могут стоять на экране разом, а шторка занимает одну полосу
   вместо двух. Свёрнутое состояние карточки осталось только на телефоне
   (t126), где оно и было придумано. */

/* Реестр героя (js/data/geroi.js) над списком связей: кто он и кнопка сузить
   карту до его точек. Текст «кто» — не кнопка, просто абзац; фильтром служит
   только сама кнопка снизу. */
#реестрГероя[hidden] { display: none; }
.реестрКто {
  margin-bottom: 6px; color: var(--dim); font-size: 12px; line-height: 1.4;
}
.реестрФильтрКнопка {
  display: block; width: 100%; margin-bottom: 10px; padding: 7px 10px;
  border-radius: 7px; cursor: pointer;
  background: rgba(58,48,34,.5); border: 1px solid var(--edge-hot);
  color: var(--gold); font-family: var(--font); font-size: 12px;
}
.реестрФильтрКнопка:hover { background: #4a3d26; color: #fff3cf; }

/* Связи: куда идти дальше от этой точки — сперва герой, потом край.
   Строка целиком кнопка, а не ссылка со стрелочкой: на телефоне промахнуться
   мимо маленькой цели проще, чем попасть, и вся карточка держится на пальце. */
.поле.связи { margin-bottom: 16px; }
.связь {
  display: block; width: 100%; text-align: left; margin-bottom: 6px;
  padding: 7px 10px; border-radius: 7px; cursor: pointer;
  background: rgba(58,48,34,.35); border: 1px solid var(--edge);
  color: var(--gold); font-family: var(--font); font-size: 13px; line-height: 1.35;
}
.связь:hover { background: #4a3d26; border-color: var(--edge-hot); color: #fff3cf; }
.связьИмя { display: block; }
/* Герой и край строкой ниже: по названию сказку узнаёт тот, кто её уже знает,
   а остальным нужно, кто там и где это. */
.связьГде { display: block; color: var(--dim); font-size: 11px; }
.связьПовод {
  display: block; margin-top: 2px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 1px;
  text-transform: uppercase; color: #9c8f74;
}
.связьЕщё {
  display: block; width: 100%; padding: 5px; cursor: pointer;
  background: none; border: 1px dashed var(--edge); border-radius: 7px;
  color: var(--dim); font-family: var(--font); font-size: 12px;
}
.связьЕщё:hover { color: var(--gold); border-color: var(--edge-hot); }

/* Ссылки на книги barius.ru (t207): та же строка, что у связей, но это
   настоящая ссылка на чужой сайт, а не переход по карте — поэтому `<a>`
   с target="_blank", а не кнопка. */
.книга {
  display: block; width: 100%; text-align: left; margin-bottom: 6px;
  padding: 7px 10px; border-radius: 7px;
  background: rgba(58,48,34,.35); border: 1px solid var(--edge);
  color: var(--gold); font-family: var(--font); font-size: 13px; line-height: 1.35;
  text-decoration: none;
}
.книга:hover { background: #4a3d26; border-color: var(--edge-hot); color: #fff3cf; }
.книгаИмя { display: block; }
.книгаКто { display: block; color: var(--dim); font-size: 11px; }

.сноска {
  margin-top: 16px; padding-top: 12px; border-top: 1px solid rgba(226,197,128,.15);
  color: #8a7f68; font-size: 11px; line-height: 1.5;
}

/* ─── Вход, профиль, правка ──────────────────────────────────────────────── */

#войти, #ктоЯ, #правкаКнопка, #продолжитьЧтение {
  padding: 9px 14px; border-radius: 7px; white-space: nowrap; cursor: pointer;
  background: var(--glass); border: 1px solid var(--edge);
  color: var(--gold); font-family: var(--font); font-size: 14px;
}
#войти:hover, #ктоЯ:hover, #правкаКнопка:hover, #продолжитьЧтение:hover { background: var(--glass-2); border-color: var(--edge-hot); }
#продолжитьЧтение { border-color: var(--edge-hot); }
/* Горящая кнопка — единственный признак, что карта сейчас в режиме правки.
   Без него легко забыть и утащить точку, думая, что двигаешь карту.
   Двойник в профиле (`#профильПравка`, t138) горит тем же классом — оба
   переключает один `переключитьПравку` в map.js. */
#правкаКнопка.горит, #профильПравка.горит { background: #6d4b12; color: #fff3cf; border-color: var(--edge-hot); }
#профильПравка[hidden] { display: none; }

#вход, #профиль, #правка {
  position: absolute; z-index: 560; top: var(--подШапкой); right: 12px;
  width: 340px; max-width: calc(100vw - 24px);
  max-height: calc(100vh - 100px); overflow-y: auto;
  padding: 16px 18px 18px;
  background: var(--glass); border: 1px solid var(--edge-hot); border-radius: 10px;
}
#правка { left: 12px; right: auto; width: 360px; }
#вход[hidden], #профиль[hidden], #правка[hidden] { display: none; }
#вход h2, #профиль h2 { margin: 6px 0 12px; font-size: 18px; color: var(--gold); }
#закрытьВход, #закрытьПрофиль, #правкаЗакрыть {
  position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; line-height: 1;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); border-radius: 6px; cursor: pointer;
}
#вход label, .правкаСтрока {
  display: block; margin-bottom: 10px; color: var(--dim); font-size: 12px;
}
#вход input, .правкаСтрока input, .правкаСтрока textarea {
  display: block; width: 100%; margin-top: 4px; padding: 8px 10px;
  background: rgba(18,16,12,.7); color: var(--text);
  border: 1px solid var(--edge); border-radius: 6px;
  font-family: var(--font); font-size: 13px; outline: none; resize: vertical;
}
#вход input:focus, .правкаСтрока input:focus, .правкаСтрока textarea:focus { border-color: var(--edge-hot); }

.правкаИллюстрацияБлок {
  border-top: 1px solid var(--edge); padding-top: 12px; margin-top: 12px;
}
#правкаПросмотрИллюстрации {
  margin-top: 8px; max-width: 100%; border-radius: 6px; overflow: hidden;
}
#правкаПросмотрИллюстрации img {
  width: 100%; height: auto; display: block;
}
.иллюстрКнопка {
  padding: 6px 12px; border-radius: 6px; cursor: pointer;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); font-family: var(--font); font-size: 12px;
  flex: 1;
}
.иллюстрКнопка:hover { color: var(--gold); border-color: var(--edge-hot); }
#правкаПолямиИллюстрации {
  margin-top: 10px; display: flex; flex-direction: column; gap: 8px;
}
#правкаПолямиИллюстрации label {
  display: flex; flex-direction: column; color: var(--dim); font-size: 11px;
}
#правкаПолямиИллюстрации input {
  margin-top: 4px; padding: 6px 8px;
  background: rgba(18,16,12,.7); color: var(--text);
  border: 1px solid var(--edge); border-radius: 5px;
  font-family: var(--font); font-size: 12px; outline: none;
}
#правкаПолямиИллюстрации input:focus { border-color: var(--edge-hot); }

.рядКнопок { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
/* Ссылка в этом ряду — такая же кнопка, как остальные: «Войти в игру» ведёт на
   другую страницу, но для человека это то же самое действие, и выглядеть оно
   должно так же. */
.рядКнопок button, .рядКнопок a {
  padding: 9px 14px; border-radius: 7px; cursor: pointer;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); font-family: var(--font); font-size: 13px;
}
.рядКнопок button:hover, .рядКнопок a:hover { color: var(--gold); border-color: var(--edge-hot); }
.рядКнопок .главная { background: var(--glass-2); color: var(--gold); border-color: var(--edge-hot); }

#входВесть, #правкаВесть { margin-top: 10px; color: #cbbf9f; font-size: 12px; line-height: 1.5; min-height: 16px; }
#входВесть.беда, #правкаВесть.беда { color: #ff9c8c; }
.мелко { margin-top: 10px; color: #8a7f68; font-size: 11px; line-height: 1.5; }
.строчка { color: var(--text); font-size: 13px; line-height: 1.5; margin-bottom: 12px; }
.строчкаКнопка {
  display: inline-block; margin-bottom: 12px; padding: 6px 10px;
  background: transparent; border: 1px solid var(--edge); border-radius: 6px;
  color: var(--dim); cursor: pointer; font-family: var(--font); font-size: 12px;
}
.строчкаКнопка:hover { color: var(--gold); border-color: var(--edge-hot); }
/* `display: inline-block` выше перебивает атрибут `hidden`: кнопка, которую
   код спрятал, оставалась на виду. Ловилось на «Ярлыке на телефон». */
.строчкаКнопка[hidden] { display: none; }
/* Список незаконченных сказок в профиле: строка на всю ширину панели, а не
   в ряд — их может быть несколько, и в ряд они бы слиплись без переносов. */
.закладкаСказки {
  display: block; width: 100%; margin-bottom: 6px;
  text-align: left; border-color: var(--edge-hot);
}
#профильИмяФорма { margin-bottom: 12px; }
#профильИмяФорма label { display: block; margin-bottom: 8px; color: var(--dim); font-size: 12px; }
#профильИмяФорма input {
  display: block; width: 100%; margin-top: 4px; padding: 8px 10px;
  background: rgba(18,16,12,.7); color: var(--text);
  border: 1px solid var(--edge); border-radius: 6px;
  font-family: var(--font); font-size: 13px; outline: none;
}
#профильИмяФорма input:focus { border-color: var(--edge-hot); }
#профильИмяВесть { margin-top: 8px; color: #cbbf9f; font-size: 12px; line-height: 1.5; }
#профильИмяВесть.беда { color: #ff9c8c; }
#профильПочта { color: var(--dim); font-family: var(--mono); font-size: 11px; }
#профильПерсонаж { margin-top: 4px; font-size: 13px; line-height: 1.6; }
#профильПерсонаж .строка { display: flex; justify-content: space-between; color: var(--dim); }
#профильПерсонаж .строка b { color: var(--gold); }
#профильПерсонаж .навыки { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 6px; color: var(--dim); }
#профильПерсонаж .навыки b { color: var(--gold); }
#профильПерсонаж .дела { margin-top: 8px; color: var(--dim); font-size: 12px; }
#профильПерсонаж .пустое { color: #8a7f68; font-style: italic; }
#правкаЗаголовок { color: var(--gold); font-size: 14px; margin-bottom: 4px; }

/* В режиме правки курсор говорит, что точку можно взять: без этого её
   перетаскивание — тайное знание. */
body.режим-правки .leaflet-interactive { cursor: grab; }
body.тащим, body.тащим .leaflet-interactive { cursor: grabbing !important; }

#менюКарты {
  position: fixed; z-index: 700; min-width: 220px; padding: 4px;
  background: var(--glass); border: 1px solid var(--edge-hot); border-radius: 8px;
}
#менюКарты[hidden] { display: none; }
#менюКарты .пункт {
  padding: 8px 10px; border-radius: 5px; cursor: pointer;
  color: var(--text); font-size: 13px;
}
#менюКарты .пункт:hover { background: var(--glass-2); color: var(--gold); }

/* ─── Сказка-квест ───────────────────────────────────────────────────────── */

/* «Маршруты» одеты ровно как «Сказки»: это две двери в одно — прочитать про
   место и съездить в него, — и разный вид развёл бы их по важности. Кнопки
   шапки стилизованы поимённо, общего правила у них нет: новая кнопка без своей
   строки осталась бы белым браузерным прямоугольником среди тёмных. */
#кнопкаСказки, #кнопкаМаршруты {
  padding: 9px 16px; border-radius: 7px; white-space: nowrap; cursor: pointer;
  background: var(--glass-2); border: 1px solid var(--edge);
  color: var(--gold); font-family: var(--font); font-size: 14px; letter-spacing: 1px;
}
#кнопкаСказки:hover, #кнопкаМаршруты:hover { background: #4a3d26; color: #fff3cf; border-color: var(--edge-hot); }

/* Список сказок: показывается, только если их несколько — выбор нужен один раз, */
/* а не на каждое открытие книги. */
#скзСписок {
  position: absolute; z-index: 590; left: 12px; top: var(--подШапкой);
  width: 360px; max-width: calc(100vw - 24px);
  max-height: calc(100vh - 100px); overflow-y: auto;
  padding: 16px 18px 18px;
  background: var(--glass); border: 1px solid var(--edge-hot); border-radius: 10px;
}
#скзСписок[hidden] { display: none; }
#скзСписок h2 { margin: 4px 0 12px; font-size: 17px; color: var(--gold); }
#закрытьСкзСписок {
  position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; line-height: 1;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); border-radius: 6px; cursor: pointer;
}
#скзСписокПоле {
  display: block; width: 100%; margin-bottom: 12px; padding: 9px 12px;
  background: var(--glass); color: var(--text);
  border: 1px solid var(--edge); border-radius: 7px;
  font-family: var(--font); font-size: 14px; outline: none;
}
#скзСписокПоле:focus { border-color: var(--edge-hot); }
#скзСписокПоле::placeholder { color: #8a7f68; }
.скзСписокПусто { padding: 10px 2px; color: var(--dim); }

/* ─── Осведомлённость ────────────────────────────────────────────────────── */
/*
   Список сказок с полоской знания. Полоска, а не одни числа: двадцать одна
   строка «7 из 10» читается как таблица, а глазом нужно одно — где пусто.
*/
#знание {
  position: absolute; z-index: 600; left: 12px; top: var(--подШапкой);
  width: 400px; max-width: calc(100vw - 24px);
  max-height: calc(100vh - 100px); overflow-y: auto;
  padding: 16px 18px 18px;
  background: var(--glass); border: 1px solid var(--edge-hot); border-radius: 10px;
}
#знание[hidden] { display: none; }
#знание h2 { margin: 6px 0 8px; font-size: 17px; color: var(--gold); }
#знаниеСчёт { color: var(--dim); }
#знаниеСвод { margin-bottom: 12px; line-height: 1.5; }
#закрытьЗнание {
  position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; line-height: 1;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); border-radius: 6px; cursor: pointer;
}
#закрытьЗнание:hover { color: var(--gold); border-color: var(--edge-hot); }

.знСтрока {
  display: grid; grid-template-columns: 1fr 84px; gap: 2px 10px; align-items: center;
  width: 100%; margin-bottom: 6px; padding: 8px 10px; text-align: left; cursor: pointer;
  background: rgba(58,48,34,.35); border: 1px solid var(--edge); border-radius: 7px;
  color: var(--gold); font-family: var(--font); font-size: 13px;
}
.знСтрока:hover { background: #4a3d26; border-color: var(--edge-hot); color: #fff3cf; }
/* Сказка без вопросов — видимая, но не нажимаемая: спрятать её значило бы
   ответить молчанием на вопрос «а эту проверяли?». */
.знСтрока.пусто { cursor: default; opacity: .55; }
.знСтрока.пусто:hover { background: rgba(58,48,34,.35); border-color: var(--edge); color: var(--gold); }
.знИмя { grid-column: 1; }
.знИтог { grid-column: 2; text-align: right; color: var(--dim); font-size: 11px; }
.знПолоса {
  grid-column: 1; height: 6px; border-radius: 4px;
  background: rgba(0,0,0,.35); border: 1px solid var(--edge); overflow: hidden;
}
.знПолоса i { display: block; height: 100%; background: var(--gold); }
.знСколько {
  grid-column: 2; text-align: right;
  font-family: var(--mono); font-size: 10px; letter-spacing: 1px; color: #9c8f74;
}
.скзСписокПункт {
  display: flex; flex-direction: column; gap: 3px; width: 100%; text-align: left;
  padding: 10px 12px; margin-bottom: 8px; border-radius: 8px; cursor: pointer;
  background: rgba(58,48,34,.45); border: 1px solid var(--edge);
  font-family: var(--font);
}
.скзСписокПункт:last-child { margin-bottom: 0; }
.скзСписокПункт:hover { background: var(--glass-2); border-color: var(--edge-hot); }
.скзСписокПункт b { color: var(--gold); font-size: 14px; }
.скзСписокПункт span { color: var(--dim); font-size: 12px; }

/* Взрослый слой: разбор с источниками. Отделён рамкой, а не цветом фона —
   он идёт под сказкой, и заливка спорила бы с самим текстом за внимание. */
.скзВзрослый { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--edge); }
.взрЗачем { margin-bottom: 12px; color: var(--dim); font-size: 13px; font-style: italic; }
.взрПункт { margin-bottom: 14px; }
.взрПункт b { display: block; margin-bottom: 4px; color: var(--gold); font-size: 14px; }
.взрПункт > div { font-size: 14px; line-height: 1.55; }
/* Источник мельче текста нарочно: он нужен, чтобы проверить, а не чтобы
   читать подряд. Но он есть всегда — пункт без него не показывается вовсе. */
.взрИсточник { margin-top: 4px; color: var(--dim); font-size: 12px !important; }
#скзСлой.горит { background: #4a3d26; color: #fff3cf; border-color: var(--edge-hot); }
#скзСлой:disabled { opacity: .4; cursor: default; }
/* Задуманная сказка: видно, что она будет, и видно, что открыть её нельзя.
   Гасим целиком, а не только подпись — иначе пункт выглядит рабочим, и по
   нему будут жать до тех пор, пока не решат, что сайт сломан. */
.скзСписокПункт.вРазработке { opacity: .5; cursor: default; }
.скзСписокПункт.вРазработке:hover {
  background: rgba(58,48,34,.45); border-color: var(--edge);
}
.скзМетка {
  align-self: flex-start; margin-top: 2px; padding: 1px 6px;
  border: 1px solid var(--edge); border-radius: 4px;
  font-size: 11px !important; color: var(--dim);
}

#сказка {
  position: absolute; z-index: 580; left: 12px; top: var(--подШапкой); bottom: 12px;
  width: 520px; max-width: calc(100vw - 24px);
  display: flex; flex-direction: column;
  /* Плотнее прочих панелей нарочно: сквозь обычные девяносто процентов
     просвечивала карточка под ней, и строки двух текстов накладывались друг на
     друга. Читать сказку сквозь другой текст невозможно. */
  background: rgba(20, 17, 12, .985);
  border: 1px solid var(--edge-hot); border-radius: 10px;
}
#сказка[hidden] { display: none; }
/* Дорога: сказка сжимается в верхнюю половину экрана, карта с путём героя
   открывается под ней целиком — не нужно закрывать сказку, чтобы её увидеть. */
#сказка.дорога-режим {
  top: var(--подШапкой); left: 12px; right: 12px; bottom: auto;
  height: calc(50vh - var(--подШапкой)); width: auto; max-width: none;
}

.скзШапка {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 14px; border-bottom: 1px solid rgba(226,197,128,.18);
}
/* Имя сказки и «глава · концовок N из M» — одна строка, а не две: раньше
   заголовок панели занимал две строки высоты без нужды, хотя обе надписи
   короткие и рядом читаются так же ясно. Места на строку не всегда хватает —
   тогда длинный текст обрезаем многоточием, а не переносим на вторую строку. */
.скзТитул { display: flex; align-items: baseline; gap: 8px; flex: 1; min-width: 0; }
.скзТитул b {
  color: var(--gold); font-size: 15px; flex: 0 1 auto;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.скзТитул span {
  color: var(--dim); font-size: 11px; font-family: var(--mono); flex: 1 1 auto; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.скзШапка button {
  padding: 6px 10px; border-radius: 6px; cursor: pointer;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); font-family: var(--font); font-size: 12px;
}
.скзШапка button:hover { color: var(--gold); border-color: var(--edge-hot); }
.скзШапка button.горит { background: #6d4b12; color: #fff3cf; border-color: var(--edge-hot); }

/* Колонка чтения не шире 820 точек, как бы ни было широко окно. Панель с
   04.09 занимает экран целиком, и на стольном мониторе строка вытягивалась на
   полторы тысячи точек: глаз, дочитав до конца, не находит начала следующей.
   Поля растут от краёв, а не от текста, поэтому иллюстрации и разборы остаются
   на своих местах. */
.скзПолотно {
  flex: 1; overflow-y: auto;
  padding: 14px max(18px, calc((100% - 820px) / 2)) 18px;
}

.скзГде { display: flex; flex-direction: column; gap: 2px; margin-bottom: 12px; }
#скзМесто { color: var(--gold); font-size: 12px; font-family: var(--mono); }
#скзЧем { color: #8a7f68; font-size: 11px; line-height: 1.5; }
/* Вёрсты и адрес: «долго ли, коротко ли» числом и место, куда можно поехать. */
.скзВёрсты { color: #cbbf9f; font-size: 11px; font-family: var(--mono); margin-top: 2px; }
.скзАдрес { color: #9c8f74; font-size: 11px; line-height: 1.5; }
.скзВёрсты[hidden], .скзАдрес[hidden] { display: none; }

/* Иллюстрация главы: миниатюра в потоке текста, открывается в лайтбоксе. */
.скзКартинка {
  display: block; width: 100%; margin-bottom: 12px; padding: 0; border: none;
  background: none; cursor: zoom-in; text-align: left;
}
.скзКартинка[hidden] { display: none; }
.скзКартинка img {
  display: block; width: 100%; max-height: 280px; object-fit: contain;
  background: rgba(10, 9, 6, .35);
  border-radius: 8px; border: 1px solid var(--edge);
}
.скзКартинка span {
  display: block; margin-top: 4px; color: #8a7f68; font-size: 11px; font-style: italic;
}

/* Ожидание снимка (js/map/kartinka.js). Пока новый лист едет, на его месте
   пустая рамка с кружком, а не снимок предыдущей точки: подписи под ним уже
   новые, и человек не может понять, к этому месту картинка или к прошлому.
   Высота рамки взята с запасом, чтобы приезд снимка не дёргал текст сильнее
   необходимого; совсем без сдвига не выйдет — высоту листа заранее не знает
   никто, а держать под неё постоянное место значило бы отдать треть панели
   пустоте на всех точках, где снимка нет вовсе. */
.скзКартинка.грузится, .скзКартинка.неПришла {
  position: relative; min-height: 150px;
  background: rgba(10, 9, 6, .35);
  border: 1px solid var(--edge); border-radius: 8px;
}
.скзКартинка.грузится img, .скзКартинка.неПришла img { display: none; }
.скзКартинка.грузится::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 26px; height: 26px; margin: -13px 0 0 -13px;
  border: 2px solid rgba(226, 197, 128, .25);
  border-top-color: var(--edge-hot); border-radius: 50%;
  animation: кружокОжидания .9s linear infinite;
}
@keyframes кружокОжидания { to { transform: rotate(360deg); } }
/* Тем, кому движение мешает, кружок остаётся, но еле ползёт: совсем убрать
   его нельзя — он единственное, что говорит «идёт загрузка», а не «пусто». */
@media (prefers-reduced-motion: reduce) {
  .скзКартинка.грузится::after { animation-duration: 4s; }
}
/* Не приехал — говорим словами. Молчащая пустая рамка выглядит поломкой. */
.скзКартинка.неПришла::after {
  content: 'Снимок не пришёл'; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: #8a7f68; font-size: 12px; font-style: italic;
}
/* В «Дороге» картинка свёрнута в узкую строку — рамка ожидания там своя,
   иначе полутораста точек высоты разорвали бы строку пополам. */
#сказка.дорога-режим .скзКартинка.грузится,
#сказка.дорога-режим .скзКартинка.неПришла { min-height: 0; }
/* В обычном виде картинка и так во всю ширину панели — звать некуда. */
.скзКартинкаЗов { display: none; }

/* Режим «Дорога»: панель занимает верхнюю половину экрана, и полноразмерная
   иллюстрация съедала её почти целиком — текст главы уходил под нижний край, а
   саму картинку в оставшейся полоске всё равно было не разглядеть. Сворачиваем
   её в строку-кнопку: миниатюра, зов и подпись. Полный размер — по нажатию, в
   лайтбоксе, как и раньше; смотреть его поверх половины экрана всё равно
   удобнее, чем втискивать в неё. */
/* В «Дороге» панель растянута во всю ширину экрана, и строка текста доходила до
   182 знаков на столе и 140 на планшете — на такой длине глаз теряет начало
   следующей строки. Держим колонку в книжной мерке: читают в 60–75 знаков.
   Карта под панелью при этом остаётся во всю ширину, ради чего режим и заведён.
   На телефоне правило ни на что не влияет — там и так 41 знак. */
#сказка.дорога-режим .скзПолотно > * { max-width: 68ch; }

#сказка.дорога-режим .скзКартинка {
  display: grid; grid-template-columns: 72px 1fr; align-items: center;
  column-gap: 10px; padding: 8px 10px;
  border: 1px solid var(--edge); border-radius: 8px;
  background: rgba(58, 48, 34, .35);
}
#сказка.дорога-режим .скзКартинка img {
  grid-row: 1 / 3; width: 72px; height: 48px; object-fit: cover;
  border-radius: 6px; max-height: none;
}
#сказка.дорога-режим .скзКартинкаЗов {
  display: block; margin: 0; color: var(--gold); font-size: 13px; font-style: normal;
}
#сказка.дорога-режим #скзКартинкаПодпись { margin: 0; }

/* Свёрнутую картинку легко принять за подпись под текстом. Короткий отклик на
   новой главе говорит, что там есть что посмотреть, — дважды и негромко, а не
   мигание без конца: оно бы спорило с самим чтением. */
@keyframes зовётКартинка {
  0%, 100% { box-shadow: 0 0 0 0 rgba(240, 214, 138, 0); }
  35% { box-shadow: 0 0 0 3px rgba(240, 214, 138, .45); }
}
#сказка.дорога-режим .скзКартинка.зовёт { animation: зовётКартинка 1.1s ease-out 2; }
@media (prefers-reduced-motion: reduce) {
  #сказка.дорога-режим .скзКартинка.зовёт { animation: none; }
}
.скзЛайтбокс {
  position: fixed; z-index: 900; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 40px 20px;
  background: rgba(8, 7, 5, .92);
}
.скзЛайтбокс[hidden] { display: none; }
.скзЛайтбокс img {
  max-width: min(90vw, 900px); max-height: 80vh; object-fit: contain;
  border-radius: 6px; border: 1px solid var(--edge-hot);
}
.скзЛайтбоксПодпись { color: #cbbf9f; font-size: 13px; font-style: italic; }
#скзЛайтбоксЗакрыть {
  position: absolute; top: 16px; right: 16px; z-index: 1;
  padding: 8px 12px; border-radius: 6px; cursor: pointer;
  background: var(--glass-2); border: 1px solid var(--edge-hot);
  color: var(--gold); font-family: var(--font); font-size: 14px;
}
#скзЛайтбоксЗакрыть:hover { color: #fff3cf; }

/* Верстовые столбы на карте: номер главы кружком на дороге Ивана. */
.верста span {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: rgba(18,16,12,.9); border: 1px solid var(--edge);
  color: var(--dim); font-family: var(--mono); font-size: 11px;
}
.верста span.тут { background: #6d4b12; border-color: var(--edge-hot); color: #fff3cf; }

/* Привалы: мелкие точки вдоль дороги на длинных перегонах — тут герой мог
   заночевать или перекусить, если идти от главы к главе слишком далеко
   за один день. Мельче и тише верстовых столбов — это не глава, а привал. */
.привал span {
  display: block; width: 8px; height: 8px; border-radius: 50%;
  background: rgba(18,16,12,.85); border: 1px solid var(--edge);
}
.привал:hover span { background: #6d4b12; border-color: var(--edge-hot); }

/* Бегущие искры на дороге (t137): штрихи `dashArray` едут по пути героя —
   не мигание всей линии разом, а бег вдоль неё, как след. Только
   `stroke-dashoffset`: свойство недорогое для одного `<path>` (их на нить
   ровно один, см. `построитьДорогу` в map.js) и не трогает раскладку
   страницы, так что перелёт камеры этим не проседает. Шаг смещения равен
   сумме штриха и разрыва (4 + 12), иначе анимация будет дёргаться на стыке
   витка. */
@keyframes дорогаИскрыБег { to { stroke-dashoffset: -16; } }
.дорогаИскры { animation: дорогаИскрыБег 1s linear infinite; }
@media (prefers-reduced-motion: reduce) {
  .дорогаИскры { animation: none; }
}

/* Сам текст сказки — главное на странице, и набран он как в книге: колонка не
   во всю ширину, строка с воздухом, первая буква не жмётся к краю. */
.скзТекст { color: var(--text); font-size: 15px; line-height: 1.75; }
.скзТекст p { margin: 0 0 12px; }
.скзСобытие {
  margin: 16px 0 12px; padding: 12px 14px; border-radius: 8px;
  background: rgba(58,48,34,.5); border-left: 3px solid var(--edge-hot);
  color: #ffeec2; font-size: 14px; line-height: 1.6;
}
.скзСобытие p { margin: 0 0 8px; }
.скзСобытие p:last-child { margin: 0; }

.скзВыборы { display: flex; flex-direction: column; gap: 8px; }
.скзВыбор {
  display: flex; gap: 10px; align-items: flex-start; text-align: left;
  padding: 11px 13px; border-radius: 8px; cursor: pointer;
  background: rgba(58,48,34,.45); border: 1px solid var(--edge);
  color: var(--text); font-family: var(--font); font-size: 14px; line-height: 1.5;
}
.скзВыбор:hover:not(:disabled) { background: var(--glass-2); border-color: var(--edge-hot); }
.скзВыбор:disabled { cursor: default; }
.скзВыбор .буква {
  flex: 0 0 auto; width: 22px; height: 22px; line-height: 21px; text-align: center;
  border-radius: 50%; background: var(--edge); color: #12100c; font-weight: bold; font-size: 12px;
}
/* Дорога сказки подсвечивается только ПОСЛЕ ответа: подскажи раньше — и выбор
   перестанет быть выбором. */
.скзВыбор.сюжет:disabled { border-color: #a8e86a; background: rgba(168,232,106,.14); }
.скзВыбор.сюжет:disabled .буква { background: #a8e86a; }
.скзВыбор.выбран { border-width: 2px; }
.скзВыбор.тускло { opacity: .45; }

.скзРазбор {
  margin-top: 14px; padding: 12px 14px; border-radius: 8px;
  background: rgba(58,48,34,.45); color: var(--text); font-size: 14px; line-height: 1.65;
}
.скзРазбор.сюжет { border-left: 3px solid #a8e86a; }
.скзРазбор.мимо { border-left: 3px solid #e8a86a; }
.скзРазбор.конец { border-left: 3px solid var(--edge-hot); }
.скзРазбор .концовка { margin-top: 10px; padding-top: 10px;
  border-top: 1px solid rgba(226,197,128,.15); color: var(--gold); font-size: 13px; }

/* Котомка: что при тебе. Полоска, а не список: это память о выборах, а не
   инвентарь — считать в ней нечего. */
.скзКотомка { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.скзКотомка span {
  padding: 3px 8px; border-radius: 20px; font-size: 11px;
  background: rgba(58,48,34,.6); border: 1px solid var(--edge); color: var(--dim);
}
.скзКотомка[hidden] { display: none; }

/* Имя порока над последствием: ребёнок должен увидеть не «неверный ответ», а
   знакомое человеческое свойство — и то, куда оно приводит. */
.скзТекст .порок {
  display: inline-block; margin-bottom: 8px; padding: 2px 9px; border-radius: 20px;
  background: #6d4b12; color: #ffe6a6; font-size: 11px;
  letter-spacing: 1px; text-transform: uppercase;
}
.скзРазбор p { margin: 0 0 10px; }
.скзРазбор .почему, .скзРазбор .урок, .скзРазбор .назад {
  margin-top: 10px; padding-top: 10px; border-top: 1px solid rgba(226,197,128,.15);
  font-size: 13px; color: #e6dcc2;
}
.скзРазбор .почему b, .скзРазбор .урок b { color: var(--gold); }
.скзРазбор .назад { color: #8a7f68; font-style: italic; }

.скзНиз { display: flex; justify-content: flex-end; margin-top: 14px; }
.скзНиз button {
  padding: 10px 18px; border-radius: 7px; cursor: pointer;
  background: var(--glass-2); border: 1px solid var(--edge-hot);
  color: var(--gold); font-family: var(--font); font-size: 14px;
}
.скзНиз button:hover { background: #4a3d26; color: #fff3cf; }

/* В левом нижнем углу у Leaflet больше нет ни одной кнопки: и зум, и «Где я»
   переехали направо. Прежнее правило с `margin-left` снято вместе с самой
   шириной шторки — панель открывается во весь экран, отступать не от чего. */

/* Режим чтения: карта уходит, текст расходится на всю ширину и растёт.
   Панели, кнопки и легенда прячутся — на странице остаётся сказка. */
body.чтение #сказка {
  left: 0; right: 0; top: 0; bottom: 0; width: auto;
  /* Ограничение ширины снимаем нарочно: в обычном виде панель не должна
     закрывать карту целиком, а в режиме чтения — обязана. Без этой строки
     справа оставалась полоска карты, и она мешала ровно тем, что мигала. */
  max-width: none;
  /* На телефоне у панели снизу-листом есть свой max-height (68–76vh) — без
     сброса книжка на весь экран не растягивалась, а сказка обрывалась на
     середине, и снизу была видна карта: читать было нечем. */
  max-height: none;
  border: 0; border-radius: 0; background: #14110c;
}
/* Шторку в режиме чтения прячем целиком: сама книжка на это время выезжает из
   неё в документ (js/map/shtorka.js), а полоса вкладок на пустой странице с
   текстом — лишний повод отвлечься. */
body.чтение #шапка, body.чтение #нижЛев, body.чтение #карточка,
body.чтение #викторина, body.чтение #знание, body.чтение #шторка,
body.чтение .leaflet-control-container { display: none; }
body.чтение .скзПолотно { padding: 24px max(24px, calc((100vw - 760px) / 2)); }
body.чтение .скзТекст { font-size: 19px; line-height: 1.85; }
body.чтение .скзСобытие, body.чтение .скзВыбор, body.чтение .скзРазбор { font-size: 16px; }
/* `body.чтение #map { filter: blur(0) }` убрано: размытия у карты нигде нет,
   и отменять этой строке было нечего — а собственный фильтр, пусть и нулевой,
   заставляет браузер держать всю карту отдельным растровым слоем. Ровно этим
   и объяснялись чёрные прямоугольники по границам плиток (см. `.leaflet-tile`
   в начале файла). */

@media (max-width: 720px) {
  #сказка { left: 8px; right: 8px; width: auto; top: 8px; bottom: 8px; }
  .скзТекст { font-size: 16px; }
  body.чтение .скзПолотно { padding: 18px; }
  body.чтение .скзТекст { font-size: 18px; }

  /* Заголовок сказки и пять кнопок в одну строку на телефоне не помещались:
     flexbox сжимал `.скзТитул` до нескольких пикселей, и длинное название
     переносилось по буквам. Переносим заголовок на свою строку сверху — там
     уже есть место, — а кнопки уходят под него единой строкой поуже. */
  .скзШапка { flex-wrap: wrap; padding: 8px 10px; gap: 4px 6px; }
  .скзТитул { flex: 1 1 100%; gap: 6px; }
  .скзТитул b { font-size: 14px; line-height: 1.25; }
  .скзТитул span { font-size: 10px; }
  .скзШапка button { padding: 5px 8px; font-size: 11px; }
}

/* ─── Легенда и фильтр жанра ──────────────────────────────────────────────
   Живут в подсказке кнопки «ⓘ» (04.09), а в углу карты остался один чип
   фильтра по герою. Обёртка `#нижЛев` держит его над полосой вкладок в левом
   нижнем углу. */

#нижЛев {
  position: absolute; z-index: 400; bottom: calc(12px + var(--рейкаВысота, 0px));
  left: 12px;
  display: flex; flex-direction: column; gap: 6px; max-width: 340px;
  align-items: flex-start;
}
/* Своего ящика и кнопки у легенды больше нет: она лежит вторым разделом
   подсказки «ⓘ» (`.оЛегенда` выше), и раскрывает её сама подсказка. */
/* Чип фильтра по герою стоит прямо на карте — ему рамка нужна. */
#геройФильтр {
  display: flex; flex-wrap: wrap; gap: 4px 12px;
  padding: 9px 12px; border-radius: 9px;
  background: var(--glass); border: 1px solid var(--edge);
  font-size: 11px; color: var(--dim);
}
/* Легенда и жанр лежат внутри подсказки «ⓘ» — своей рамки им там не нужно,
   рамка у подсказки уже есть, а вторая читалась бы окном в окне. */
#легенда, #жанрФильтр {
  display: flex; flex-wrap: wrap; gap: 4px 12px;
  font-size: 11px; color: var(--dim);
}
#жанрФильтр:empty { display: none; }
#легенда span, #жанрФильтр span { display: flex; align-items: center; gap: 5px; cursor: pointer; }
#легенда i { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
#легенда span.выкл { opacity: .35; }
/* Жанр — «показать только этот», а не «снять один из многих», поэтому
   подсветка не тусклая (как у выключенного округа), а яркая: выбранное
   видно, а не то, что убрано. */
#жанрФильтр span.выбран { color: var(--gold); font-weight: 600; }

/* Фильтр по герою реестра: не переключатель, как жанр, а разовое сужение —
   поэтому вместо строки в общем списке свой чип с явной кнопкой сброса. */
#геройФильтр[hidden] { display: none; }
#геройФильтр { align-items: center; color: var(--gold); }
#геройФильтр span { font-weight: 600; }
#геройФильтр button {
  padding: 3px 8px; border-radius: 6px; cursor: pointer;
  background: none; border: 1px dashed var(--edge); color: var(--dim);
  font-family: var(--font); font-size: 11px;
}
#геройФильтр button:hover { color: var(--gold); border-color: var(--edge-hot); }

/* ─── Планшет и телефон: шапка в несколько рядов ────────────────────────── */

/* Одной строкой, а не тремя. Прежде здесь шапка переносилась: название, поиск
   и полоса кнопок занимали по полной строке каждый, и на планшете шапка съедала
   около 120 точек — восьмую часть портретного экрана и шестую альбомного.
   Сделано так было ради поиска: в одну строку flexbox сжимал его до
   автоминимума поля ввода, и оно выглядело квадратиком, а не полем для текста.
   Лечится это не переносом, а полом: у поиска свой `min-width`, ниже которого
   он не ужимается, а весь недостаток ширины забирает полоса кнопок — она для
   того и листается вбок, и о спрятанном справа говорит растворённым краем
   (`.естьДальше`). Название отдаёт своё: счётчик мест убран, буквы теснее. */
@media (max-width: 1024px) {
  #шапка { flex-wrap: nowrap; gap: 8px; padding: 8px 10px; }
  /* Название ужимается первым и до многоточия: оно ведёт в «Что это такое», а
     не называет действие, и обрезанное остаётся узнаваемым. */
  .титул { flex: 0 1 auto; min-width: 0; overflow: hidden; }
  .титул b {
    font-size: 13px; letter-spacing: 1px;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  }
  /* Счётчик мест — украшение, а не действие; здесь он отнимает ширину у поиска. */
  .титул span { display: none; }
  /* Пол поиска: 170 точек — это ещё поле, в котором виден набранный запрос.
     Потолок снят: пусть забирает всё, что осталось от кнопок. */
  .поиск { flex: 1 1 220px; min-width: 170px; max-width: none; }
  #поиск { padding: 7px 10px; font-size: 13px; }
  /* Подсказки висят над картой, а не над тёмной панелью, и сквозь стекло их
     тяжело читать. Место они берут из `.поиск` — как на столе. */
  #подсказки { background: #14110c; box-shadow: 0 12px 26px rgba(0, 0, 0, .5); }
  .кнопки {
    flex: 0 1 auto; gap: 6px;
    overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .кнопки::-webkit-scrollbar { display: none; }
  .кнопки > * { flex: 0 0 auto; padding: 7px 11px; font-size: 13px; }
  /* Полоса листается, и важно не сколько кнопок влезло, а какие именно: видны
     первые. Вперёд ставим то, зачем сюда приходят; учётка и правка карты
     уезжают вправо — они нужны редко и тем, кто уже знает, что они есть. */
  #кнопкаСказки { order: 1; }
  /* Тот же номер, что у викторины: при равенстве флексбокс держит порядок
     разметки, а там «Маршруты» стоят сразу за «Сказками» — рядом с тем, чему
     они пара. Ничьи здесь уже в ходу (см. `#играть` и `#дорогаКнопка`). */
  #кнопкаМаршруты { order: 2; }
  #кнопкаВикторины { order: 2; }
  #играть { order: 3; }
  #дорогаКнопка { order: 3; }
  #поддержатьКнопка { order: 4; }
  /* Учётка впереди «Скрыть панели» и «Во весь экран». Прежде она стояла
     последней — полоса тогда занимала целую строку, все пять кнопок были на
     виду, и порядок решал только, что читается первым. В одну строку полоса
     короче ширины кнопок, и последняя уезжает за край: там «Войти» стала бы
     невидимой, а на планшете это единственная дверь в профиль — нижней
     навигации с вкладкой «Профиль» здесь нет. Убранные панели и полный экран
     переживут: их зовут те, кто уже освоился. */
  #войти, #ктоЯ { order: 5; }
  #экранКнопка { order: 6; }
  #панелиКнопка { order: 7; }
  #правкаКнопка { order: 8; }
}

/* Низкий экран — это телефон, повёрнутый набок. Ширины там хватает, а высоты
   нет: шапка в три ряда занимала треть экрана (126px из 390). Сжимаем её —
   подзаголовок убираем совсем, отступы и шрифт ужимаем: карте достаётся около
   сорока пикселей, и это заметно, когда всего их 390. */
@media (max-height: 500px) {
  #шапка { padding: 4px 10px; gap: 4px; }
  .титул span { display: none; }
  #поиск { padding: 5px 10px; font-size: 12px; }
  .кнопки > * { padding: 5px 10px; font-size: 12px; }
  /* Книжке здесь нужна доля больше половины: при высоте экрана 390 половина —
     это 195 точек, из которых шапка панели и строка места съедают почти всё. */
  #сказка.дорога-режим { height: calc(70vh - var(--подШапкой)); }
}

/* ─── Телефон ────────────────────────────────────────────────────────────── */

@media (max-width: 720px) {
  /* Кнопок в шапке телефона нет: разделы карты живут в рейке вкладок слева
     (одной на все экраны с 04.09), а «Скрыть панели», «Во весь экран» и
     «Правка карты» переехали в профиль (t138). Шапке остаются заголовок и
     поиск — двух рядов на них довольно. */
  .кнопки { display: none; }

  /* Шапка теснее трёхрядной: заголовок и поиск занимают ровно по одной
     строке каждый, а не три с кнопками вперемешку. Подзаголовок-счётчик
     («…», число сказок и точек) убираем — это украшение, а не действие, и
     как раз он растягивал первую строку на две. */
  /* Два ряда, а не один: заголовок своей строкой, поиск своей. Планшетное
     правило выше ставит шапку в одну строку — там это выигрыш, кнопок пять и
     полоса всё равно листается. Здесь кнопок нет вовсе (они ушли в нижнюю
     навигацию), и делить строку поиску не с чем, кроме названия: в одну
     строку от поля оставалось 190 точек из 390, и набранный запрос переставал
     быть виден целиком. Ряд стоит 28 точек — поле их стоит. */
  #шапка { flex-wrap: wrap; padding: 6px 10px; gap: 4px; }
  .титул { flex: 1 1 100%; }
  .титул b { font-size: 14px; letter-spacing: 2px; }
  .титул span { display: none; }
  .поиск { flex: 1 1 100%; }
  #поиск { padding: 6px 10px; font-size: 13px; }

  /* Двойники в профиле (t138) — видны только здесь, на столе те же действия
     стоят в шапке. `:not([hidden])` у правки — чтобы ширина не отменяла
     собственный запрет на неадминов, который ставит `обновитьШапку()`. */
  .рядКнопок.профильЭкран { display: flex; }
  #профильПравка:not([hidden]) { display: inline-block; }
  #профильПоддержать { display: inline-block; }

  /* Панели снизу листом: боковая панель на телефоне съедает всю карту. */
  #викторина, #вход, #профиль, #правка, #оПроектеОкно, #сказка, #скзСписок,
  #знание, #поддержка, #рядом, #мршСписок, #дорога, #отзыв {
    left: 8px; right: 8px; width: auto;
    /* Снизу — с запасом на полосу жестов телефона: без него кнопки «Дальше» и
       «Назад к развилке» ложились прямо под системную полосу. Запас на нижнюю
       навигацию отсюда снят вместе с ней самой. */
    top: auto; bottom: calc(8px + env(safe-area-inset-bottom, 0px)); max-height: 68vh; max-width: none;
  }
  #сказка { max-height: 76vh; }

  /* Карточка точки была шторкой снизу (t126): открывалась узкой полосой в
     96 точек — имя, герой и «Читать сказку», — чтобы точка, к которой только
     что прилетела карта, осталась видна, а разбор доставали ручкой сверху.
     С 04.09 все панели открываются во весь экран: смотреть на карту из-под
     панели больше не нужно, для этого есть вкладка «Карта». Вместе со
     свёрнутым состоянием ушли ручка, порядок полей (имя и герой поднимались
     наверх ради полосы) и обе высоты. Осталась общая вёрстка листа. */
  #карточка { padding: 14px 16px 20px; }
  #точкаКартинкаМини { max-height: 27.2vh; }
  /* «Дорога» на телефоне отдаёт книжке больше половины. Половина рассчитана на
     стол, где под шапку уходит 56 точек; здесь шапка в три ряда съедает 126, и
     панель, честно вставшая под неё, оставляла на текст пять строк — режим
     превращался в свою вывеску. Карте внизу остаётся около трети экрана: этого
     довольно, чтобы видеть, куда ведёт дорога. */
  #сказка.дорога-режим { height: calc(62vh - var(--подШапкой)); }
  /* Прежде весь угол на телефоне прятали: девять округов легенды не помещались
     рядом с картой. Легенда уехала в профиль, а чип «показан такой-то герой»
     остался — и на телефоне он нужен ровно так же, как на столе: без него
     непонятно, почему на карте вместо пятисот точек десяток. */
  /* Правый нижний угол на телефоне поднимается на те же 8 точек просвета над
     полосой вкладок, что и панели-листы: сама высота полосы уже учтена общим
     правилом выше. */
  .leaflet-bottom.leaflet-right { margin-bottom: calc(var(--рейкаВысота) + 8px); }
  /* Меню правой кнопки на телефоне — по нижнему краю: у пальца нет курсора,
     и всплывающее у точки касания меню наполовину уезжает за экран. */
  #менюКарты {
    left: 8px !important; right: 8px; top: auto !important;
    bottom: calc(var(--рейкаВысота) + 16px);
  }
  /* Пока читают сказку, кнопки карты садятся прямо на текст: панель занимает
     весь низ экрана. Зум пальцем щипком никуда не девается. */
  /* Поддержка и «моя дорога» — не вкладки шторки, а плавающие двери. На
     телефоне они всё равно ложатся листом на весь низ, и кнопки карты под
     ними не нужны. */
  body:has(#поддержка:not([hidden])) .leaflet-control-container,
  body:has(#дорога:not([hidden])) .leaflet-control-container { display: none; }
}

/* Панель вкладки занимает экран целиком, и кнопки карты оказывались прямо
   поверх её текста: у Leaflet своя полоса контролов с большим z-index, чем у
   шторки, и она всплывает над нею. Убираем их на то время, пока панель ВИДНА;
   щипок пальцем и колесо мыши никуда не деваются, а вернуть кнопки — одна
   вкладка «Карта».

   Прежде правило жило только в телефонном блоке: там панель была листом на две
   трети экрана, а на столе шторка стояла узкой колонкой сбоку и кнопкам не
   мешала. С 04.09 колонки нет — панель во весь экран на любом размере.

   `:not(.штСкрыта)` обязателен: «закрыта» и «не видна» — разные вещи. Нажав
   «Викторину» поверх открытых сказок, человек не закрывает сказки, а убирает
   их с глаз, и атрибута `hidden` у них по-прежнему нет. Правило, смотревшее на
   один `hidden`, срабатывало на панель, которой на экране нет, — и кнопки
   пропадали навсегда, стоило походить по трём вкладкам. Поймано снимком
   экрана: измерения говорили, что кнопки на месте, а на карте их не было. */
body:has(#сказка:not([hidden]):not(.штСкрыта)) .leaflet-control-container,
body:has(#карточка:not([hidden]):not(.штСкрыта)) .leaflet-control-container,
body:has(#викторина:not([hidden]):not(.штСкрыта)) .leaflet-control-container,
body:has(#знание:not([hidden]):not(.штСкрыта)) .leaflet-control-container,
body:has(#скзСписок:not([hidden]):not(.штСкрыта)) .leaflet-control-container,
body:has(#маршрут:not([hidden]):not(.штСкрыта)) .leaflet-control-container,
body:has(#мршСписок:not([hidden]):not(.штСкрыта)) .leaflet-control-container,
body:has(#рядом:not([hidden]):not(.штСкрыта)) .leaflet-control-container,
body:has(#профиль:not([hidden]):not(.штСкрыта)) .leaflet-control-container,
body:has(#вход:not([hidden]):not(.штСкрыта)) .leaflet-control-container {
  display: none;
}

/* ─── Палец крупнее курсора ──────────────────────────────────────────────── */
/*
   Крестики закрытия — 26×26 и 28×28: попасть по ним пальцем трудно, а промах
   закрывает не панель, а что-нибудь под ней. Общая мерка для сенсорных
   экранов — 44 точки. Растим их и кнопки зума Leaflet (он рисует их по 26
   точек, под курсор). Кнопки шапки оставляем как есть: они 36 точек в высоту
   при большой ширине, а поднимать их до 44 значит растить саму шапку, которой
   на телефоне и без того отдано 15% экрана.
*/
@media (hover: none), (pointer: coarse) {
  #закрыть, #закрытьВикторину, #закрытьОПроекте, #закрытьСкзСписок,
  #закрытьВход, #закрытьПрофиль, #закрытьПоддержку, #закрытьРядом, #закрытьДорогу, #скзЛайтбоксЗакрыть {
    width: 44px; height: 44px; font-size: 16px;
  }
  .leaflet-touch .leaflet-control-zoom a, .leaflet-control-zoom a, .гдеЯКнопка a {
    width: 44px; height: 44px; line-height: 44px; font-size: 20px;
  }
}

/* ─── Туристический маршрут ──────────────────────────────────────────────── */
/*
   Панель стоит там же, где сказка, и такой же ширины: это продолжение чтения,
   а не отдельный раздел. Открытая поверх сказки, она её и перекрывает — читать
   и собираться в дорогу одновременно всё равно нельзя.
*/
#маршрут {
  position: absolute; z-index: 585; left: 12px; top: var(--подШапкой); bottom: 12px;
  width: 520px; max-width: calc(100vw - 24px);
  display: flex; flex-direction: column;
  background: rgba(20, 17, 12, .985);
  border: 1px solid var(--edge-hot); border-radius: 10px;
}
#маршрут[hidden] { display: none; }
.мршШапка {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 14px; border-bottom: 1px solid rgba(226,197,128,.18);
}
.мршТитул { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.мршТитул b { color: var(--gold); font-size: 15px; }
.мршТитул span { color: var(--dim); font-size: 11px; font-family: var(--mono); }
#мршЗакрыть {
  width: 28px; height: 28px; line-height: 1; flex: 0 0 auto;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); border-radius: 6px; cursor: pointer;
}
#мршЗакрыть:hover { color: var(--gold); border-color: var(--edge-hot); }

.мршПолотно { flex: 1; overflow-y: auto; padding: 14px 18px 18px; }
.мршГде {
  color: var(--gold); font-family: var(--mono); font-size: 12px; margin-bottom: 10px;
}
.мршЗачем { color: var(--text); font-size: 14px; line-height: 1.6; margin-bottom: 14px; }
.мршЗачем[hidden], .мршБлок[hidden] { display: none; }
.мршЗаголовок {
  font-family: var(--mono); font-size: 10px; letter-spacing: 2px;
  text-transform: uppercase; color: #9c8f74; margin: 14px 0 6px;
}
#мршДобраться { margin: 0; padding-left: 18px; color: var(--dim); font-size: 13px; line-height: 1.6; }

/* Остановка — кнопка, а не строка: нажатие уводит карту к ней. */
.мршОстановка {
  display: block; width: 100%; text-align: left;
  margin-bottom: 8px; padding: 10px 12px; border-radius: 8px; cursor: pointer;
  background: rgba(58,48,34,.35); border: 1px solid var(--edge);
  color: var(--text); font-family: var(--font);
}
.мршОстановка:hover { border-color: var(--edge-hot); background: var(--glass-2); }
.мршОстановка.тут { border-color: var(--edge-hot); background: #4a3d26; }
.мршВерх { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.мршВерх b { color: var(--gold); font-size: 14px; }
.мршЗначок { font-size: 15px; }
/* Слово рядом со значком: значок один читает как «музей», другой как
   «смотровая», и без подписи список превращается в ребус. */
.мршВид {
  margin-left: auto; flex: 0 0 auto;
  font-family: var(--mono); font-size: 10px; letter-spacing: 1px; color: #8a7f68;
}
.мршЧто { font-size: 13px; line-height: 1.5; }
/* Сказочная связь — то, ради чего сюда и едут: выделяем её цветом, а не прячем
   в общий текст. */
.мршСказка {
  margin-top: 6px; padding-left: 9px; border-left: 2px solid var(--edge-hot);
  color: #ffeec2; font-size: 13px; line-height: 1.5; font-style: italic;
}
.мршДело { margin-top: 8px; font-size: 12px; line-height: 1.7; color: var(--dim); }
.мршДело b { color: #9c8f74; font-weight: normal; }
.мршДело a { color: var(--gold); }
.мршОсторожно {
  margin-top: 6px; color: #ffcfc8; font-size: 12px; line-height: 1.5;
}
.мршПроверено {
  margin-top: 16px; padding-top: 12px; border-top: 1px solid rgba(226,197,128,.15);
  color: #8a7f68; font-size: 11px; line-height: 1.6;
}
.мршИсточники { display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
.мршИсточники a { color: var(--dim); }
.мршИсточники a:hover { color: var(--gold); }

/* Метка остановки на карте: значок вида в кружке, крупнее точек сказок —
   пока маршрут открыт, он главный на экране. */
.мршМетка { background: none; border: 0; }
.мршМетка span {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: #14110c; border: 2px solid var(--edge-hot);
  font-size: 15px; box-shadow: 0 2px 8px rgba(0,0,0,.5);
}

#карточкаМаршрут {
  display: block; width: 100%; margin: 0 0 16px; padding: 10px 12px;
  border-radius: 7px; cursor: pointer;
  background: rgba(58,48,34,.45); border: 1px solid var(--edge);
  color: var(--gold); font-family: var(--font); font-size: 13px;
}
#карточкаМаршрут:hover { background: #4a3d26; color: #fff3cf; border-color: var(--edge-hot); }
#карточкаМаршрут[hidden], #скзМаршрут[hidden] { display: none; }

/* Хождение — тот же вид кнопки, что у маршрута: обе зовут показать что-то по
   этой точке, а не открывают отдельную большую панель. */
#карточкаХождение {
  display: block; width: 100%; margin: 0 0 16px; padding: 10px 12px;
  border-radius: 7px; cursor: pointer;
  background: rgba(58,48,34,.45); border: 1px solid var(--edge);
  color: var(--gold); font-family: var(--font); font-size: 13px;
}
#карточкаХождение:hover { background: #4a3d26; color: #fff3cf; border-color: var(--edge-hot); }
#карточкаХождение[hidden] { display: none; }

@media (max-width: 720px) {
  #маршрут {
    left: 8px; right: 8px; width: auto;
    top: auto; bottom: calc(8px + env(safe-area-inset-bottom, 0px));
    max-height: 76vh; max-width: none;
  }
}
body.панели-скрыты #маршрут { display: none !important; }

/* ─── Палец вместо мыши ──────────────────────────────────────────────────── */
/*
   На сенсорном экране наведения не бывает, а отвечал на прикосновение здесь
   только `:hover`. Выходило, что нажатие не отзывается ничем: человек не
   знает, промахнулся он или кнопка сломана, — и жмёт ещё раз, уже сердито.
   Поэтому у нажатия есть свой вид, и описан он сразу для всех устройств:
   мышь тоже нажимает, и отклик ей не мешает.
*/
#кнопкаСказки, #кнопкаМаршруты, #кнопкаВикторины, #играть, #войти, #панелиКнопка, #экранКнопка, #правкаКнопка,
#продолжитьЧтение, .строчкаКнопка,
#карточкаСказка, #закрыть, #закрытьСкзСписок, #закрытьВикторину,
#закрытьОПроекте, #закрытьВход, #закрытьПрофиль, .скзШапка button,
.вариант, .скзСписокПункт, #подсказки .строка, #легенда span, #жанрФильтр span, .связь, .связьЕщё,
.знСтрока, #знаниеКнопка, #закрытьЗнание, .реестрФильтрКнопка, #геройФильтр button {
  /* Своя подсветка вместо серого прямоугольника, который телефон рисует сам:
     о наших скруглениях он не знает и мажет углы. */
  -webkit-tap-highlight-color: transparent;
  transition: transform .06s ease-out, filter .06s ease-out, background-color .12s ease-out;
}
#кнопкаСказки:active, #кнопкаМаршруты:active, #кнопкаВикторины:active, #играть:active, #войти:active,
#панелиКнопка:active, #экранКнопка:active, #правкаКнопка:active, #карточкаСказка:active,
#продолжитьЧтение:active, .строчкаКнопка:active,
#закрыть:active, #закрытьСкзСписок:active, #закрытьВикторину:active,
#закрытьОПроекте:active, #закрытьВход:active, #закрытьПрофиль:active,
.скзШапка button:active, .вариант:not(:disabled):active,
.скзСписокПункт:not(.вРазработке):active, .реестрФильтрКнопка:active, #геройФильтр button:active {
  transform: scale(.97);
  filter: brightness(1.35);
}
/* Строки списков не жмутся, а подсвечиваются: сжимать строку во всю ширину
   панели значит дёргать всю панель разом. */
#подсказки .строка:active, #легенда span:active, #жанрФильтр span:active,
.связь:active, .связьЕщё:active, .знСтрока:not(.пусто):active { background: var(--glass-2); }

/* Подпись под снимком места. Вынесена из кнопки, потому что у снимков под
   CC BY-SA она несёт ссылку на автора, а ссылка внутри кнопки — и негодная
   разметка, и ловушка для пальца. Выглядит так же, как подпись у листа
   сказки: та же приглушённая курсивная строка. */
.точкаПодпись {
  display: block; margin: -8px 0 12px; color: #8a7f68; font-size: 11px; font-style: italic;
}
.точкаПодпись[hidden] { display: none; }
.точкаПодпись a { color: #8a7f68; text-decoration: underline dotted; }
.точкаПодпись a:hover { color: #cbbf9f; }

/* ─── Поддержка проекта ──────────────────────────────────────────────────── */
/*
   Панель стоит там же, где вход и профиль: это тоже «про человека», а не про
   карту. Кнопка в шапке — золотой рамкой, как «Продолжить чтение»: она не
   главный призыв страницы (главный — «Сказки» и «Войти в игру»), но и не
   служебная, как «Скрыть панели».
*/
#поддержка {
  position: absolute; z-index: 560; top: var(--подШапкой); right: 12px;
  width: 360px; max-width: calc(100vw - 24px);
  max-height: calc(100vh - 100px); overflow-y: auto;
  padding: 16px 18px 18px;
  background: var(--glass); border: 1px solid var(--edge-hot); border-radius: 10px;
}
#поддержка[hidden] { display: none; }
#поддержка h2 { margin: 6px 0 12px; font-size: 18px; color: var(--gold); }
#поддержка label { display: block; margin: 10px 0 0; color: var(--dim); font-size: 12px; }
#поддержка input {
  display: block; width: 100%; margin-top: 4px; padding: 8px 10px; box-sizing: border-box;
  background: rgba(0, 0, 0, .35); border: 1px solid var(--edge); border-radius: 6px;
  color: var(--text); font-family: var(--font); font-size: 14px;
}
#поддержка input:focus { border-color: var(--edge-hot); outline: none; }
/* Крестик — как у «Моей дороги» и «Рядом»: без правила это была голая кнопка
   браузера, белый квадрат в углу тёмной панели. Телефонный размер (44 точки)
   задан в общем списке крестиков ниже. */
#закрытьПоддержку {
  position: absolute; top: 8px; right: 8px;
  width: 28px; height: 28px; border-radius: 50%; cursor: pointer;
  background: var(--glass-2); border: 1px solid var(--edge); color: var(--dim);
  font-family: var(--font); font-size: 14px; line-height: 1; padding: 0;
}
#закрытьПоддержку:hover { color: var(--gold); border-color: var(--edge-hot); }
#поддержкаСпасибо.спасибо { color: var(--gold); border: 1px solid var(--edge-hot); border-radius: 8px; padding: 10px 12px; }
#поддержатьКнопка {
  padding: 9px 14px; border-radius: 7px; white-space: nowrap; cursor: pointer;
  background: var(--glass); border: 1px solid var(--edge-hot);
  color: var(--gold); font-family: var(--font); font-size: 14px;
}
#поддержатьКнопка:hover { background: var(--glass-2); }
/* Суммы — одной строкой из «монет»; выбранная горит, как кнопки шапки. */
.суммы { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.суммы button {
  padding: 7px 12px; border-radius: 20px; cursor: pointer;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); font-family: var(--font); font-size: 13px;
}
.суммы button:hover { color: var(--gold); border-color: var(--edge-hot); }
.суммы button.горит { background: #6d4b12; color: #fff3cf; border-color: var(--edge-hot); }
#поддержка .суммы input { width: 90px; margin: 0; padding: 6px 10px; border-radius: 20px; font-size: 13px; }
#поддержкаВесть { margin-top: 10px; color: #cbbf9f; font-size: 12px; line-height: 1.5; min-height: 16px; }
#поддержкаВесть.беда { color: #ff9c8c; }
#оПоддержать { margin-left: 4px; }

/* Полоса кнопок в шапке телефона листается вбок, но края об этом не говорили:
   человек видел ровно столько кнопок, сколько влезло, и не знал, что есть ещё.
   Пока справа что-то скрыто (класс ставит map.js по scrollLeft), правый край
   полосы растворяется — это и есть подсказка «потяните». */
.кнопки.естьДальше {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent);
}

/* Панель поддержки описана ниже блока «Телефон», и её стольные `top` и
   `max-height` перебивали телефонные: панель растягивалась от шапки до низа
   с пустотой внутри. Возвращаем телефону его правила. */
@media (max-width: 720px) {
  #поддержка { top: auto; max-height: 68vh; }
}

/* ─── Где я и что рядом ──────────────────────────────────────────────────── */
/*
   Панель стоит слева, где сказка и маршрут: это про дорогу, а не про учётку.
   Уже сказки — список коротких строк, широкая панель тут ни к чему.
*/
/* Список маршрутов живёт по тем же правилам, что «Что рядом»: это две панели
   об одном — куда отсюда поехать, — и разная вёрстка у них означала бы разный
   разговор об одном и том же. */
#рядом, #мршСписок {
  position: absolute; z-index: 570; top: var(--подШапкой); left: 12px;
  width: 380px; max-width: calc(100vw - 24px);
  max-height: calc(100vh - 100px); overflow-y: auto;
  padding: 16px 18px 18px;
  /* Плотный фон, как у ленты и сказки: на телефоне список ближайших мест
     ложится поверх карточки точки, и сквозь стекло они читались вместе. */
  background: rgba(20, 17, 12, .985); border: 1px solid var(--edge-hot); border-radius: 10px;
}
/* Список стоит выше открытой сказки (580), как и сама панель маршрута (585):
   его зовут в том числе из шапки сказки, а под ней он оказывался невидимым —
   человек жал «Маршруты» и не видел ничего. Закрыл список — сказка снова тут,
   на своей главе; ровно так же ведёт себя и панель маршрута. */
#мршСписок { z-index: 585; }
#рядом[hidden], #мршСписок[hidden] { display: none; }
#рядом h2, #мршСписок h2 { margin: 6px 0 10px; font-size: 17px; color: var(--gold); line-height: 1.25; }
#рядом .рядКнопок, #мршСписок .рядКнопок { margin: 0 0 12px; }
#рядомВесть.беда, #мршСпВесть.беда { color: #ff9c8c; }
#закрытьРядом, #мршСпЗакрыть {
  position: absolute; top: 8px; right: 8px;
  width: 28px; height: 28px; border-radius: 50%; cursor: pointer;
  background: var(--glass-2); border: 1px solid var(--edge); color: var(--dim);
}
#закрытьРядом:hover, #мршСпЗакрыть:hover { color: var(--gold); border-color: var(--edge-hot); }
/* Кнопка ⌖ под зумом — той же полосой и тем же размером, что кнопки зума. */
/* Просвет между кнопками угла: они стоят столбиком и без него слипаются в
   одну длинную полосу, в которой не разобрать, где кончается зум. */
.гдеЯКнопка, .leaflet-bottom.leaflet-right .leaflet-control-zoom { margin-top: 6px !important; }
.гдеЯКнопка a { font-size: 20px; line-height: 26px; }
/* Своя точка пульсирует: одна золотая среди пятисот цветных иначе теряется. */
.гдеЯ { animation: гдеЯПульс 1.8s ease-in-out infinite; transform-origin: center; transform-box: fill-box; }
@keyframes гдеЯПульс { 0%, 100% { stroke-opacity: 1; } 50% { stroke-opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .гдеЯ { animation: none; } }
@media (max-width: 720px) {
  #рядом, #мршСписок, #дорога { top: auto; max-height: 68vh; }
}

/* ─── Печати путешественника ─────────────────────────────────────────────── */
#полеЯЗдесь { margin-top: 4px; }
#яЗдесь { margin-bottom: 4px; }
#яЗдесь.есть { color: var(--gold); border-color: var(--edge-hot); background: rgba(58,48,34,.35); }
#яЗдесь:disabled { opacity: .6; cursor: wait; }
#яЗдесьВесть.беда { color: #ff9c8c; }
#профильПечати { margin-bottom: 12px; }
#профильПечати .печать { display: block; width: 100%; text-align: left; margin-bottom: 6px; }
#профильПечати .печать b { color: var(--gold); font-weight: normal; }

/* ─── Моя дорога ─────────────────────────────────────────────────────────── */
/*
   Панель справа, как профиль: это тоже про человека, а не про карту. Шире
   профиля (420 против 340) — в ней лента строк «когда и что», и на 340 точках
   дата переносилась бы на вторую строку у каждой записи.
*/
#дорога {
  position: absolute; z-index: 565; top: var(--подШапкой); right: 12px;
  width: 420px; max-width: calc(100vw - 24px);
  max-height: calc(100vh - 100px); overflow-y: auto;
  padding: 16px 18px 18px;
  /* Плотнее прочих панелей нарочно — по той же причине, что и у сказки: на
     телефоне панели ложатся одна на другую внизу экрана, и сквозь обычные
     девяносто процентов читалась карточка точки под лентой. Два текста
     внахлёст не читаются ни один. */
  background: rgba(20, 17, 12, .985); border: 1px solid var(--edge-hot); border-radius: 10px;
}
#дорога[hidden] { display: none; }
#дорога h2 { margin: 6px 0 12px; font-size: 18px; color: var(--gold); }
#закрытьДорогу {
  position: absolute; top: 8px; right: 8px;
  width: 28px; height: 28px; border-radius: 50%; cursor: pointer;
  background: var(--glass-2); border: 1px solid var(--edge); color: var(--dim);
}
#закрытьДорогу:hover { color: var(--gold); border-color: var(--edge-hot); }
#дорогаСколько { color: var(--dim); font-family: var(--mono); font-size: 11px; }
.дорСтрока { color: var(--text); font-size: 13px; line-height: 1.7; }
.дорСтрока b { color: var(--gold); }
#дорогаПродолжить { margin: 12px 0 4px; }
#дорогаПродолжить .строчкаКнопка { display: block; width: 100%; text-align: left; }
/* Запись ленты: значок, текст, дата. Дата — справа и тише текста: она нужна,
   чтобы отличить сегодняшнее от прошлогоднего, а не чтобы её читали. */
.дорЗапись {
  display: grid; grid-template-columns: 22px 1fr auto; gap: 8px; align-items: baseline;
  padding: 7px 0; border-bottom: 1px solid rgba(226, 197, 128, .1);
  color: var(--text); font-size: 13px; line-height: 1.4;
}
.дорЗапись:last-child { border-bottom: 0; }
.дорЗапись.ведёт { cursor: pointer; }
.дорЗапись.ведёт:hover { color: var(--gold); }
.дорЗначок { font-size: 13px; }
.дорКогда { color: var(--dim); font-family: var(--mono); font-size: 10px; white-space: nowrap; }
#дорогаКнопка {
  padding: 9px 14px; border-radius: 7px; white-space: nowrap; cursor: pointer;
  background: var(--glass); border: 1px solid var(--edge);
  color: var(--gold); font-family: var(--font); font-size: 14px;
}
#дорогаКнопка:hover { background: var(--glass-2); border-color: var(--edge-hot); }

/* ─── Разделы викторины ──────────────────────────────────────────────────── */
/*
   Строки наборов те же, что у осведомлённости (`.знСтрока`): и там и там это
   «набор вопросов, полоска знания, лучший итог». Две разные разметки для
   одного смысла разошлись бы на первой же правке.
*/
#викПродолжить:not(:empty) { margin-bottom: 12px; }
#викПродолжить .строчкаКнопка { display: block; width: 100%; text-align: left; }
#викРазделы { margin-bottom: 10px; }
#викНазад { margin-bottom: 10px; }

/* Телефон: лента ложится листом снизу, как прочие панели. Правило повторено в
   самом конце файла нарочно — базовое `top` у #дорога описано ниже общего
   блока телефона и перебивало его, отчего панель растягивалась от шапки до
   нижнего края с пустотой внутри. */
@media (max-width: 720px) {
  #дорога { top: auto; max-height: 68vh; }
}

/* ─── Шторка с вкладками ─────────────────────────────────────────────────── */
/*
   Один ящик у левого края вместо четырёх плавающих окон: полоса вкладок
   (Сказки, Викторина, Маршруты, Описание) и тело, в котором показывается одна
   панель за раз. Устройство и мотивация — в js/map/shtorka.js.

   Прежние окна с перетаскиванием сняты вместе с этим переездом: окно, которое
   можно унести куда угодно, требует, чтобы человек сперва навёл в нём
   порядок, — а он пришёл смотреть карту. Тянуть у шторки можно одно: ширину.

   Сами панели остаются собственными кусками разметки со своими правилами выше
   по файлу; здесь только то, что нужно, чтобы они встали в общий ящик, — и
   этот блок стоит в файле после них нарочно, чтобы перебивать их `position`,
   `width` и `max-height`, не трогая всего остального.
*/

#шторка {
  /* Снизу оставляем место полосе вкладок: она стоит поверх карты по центру и
     при узком окне заходит на ящик шторки. Пусть ящик кончается над ней —
     полоса нигде не ложится на текст. */
  position: absolute; z-index: 585; left: 0; right: 0; top: var(--шапка);
  bottom: calc(20px + var(--рейкаВысота, 0px));
  display: flex; align-items: stretch;
  /* Сама обёртка мышь не ловит: между рейкой и грани лежит карта, и клик по
     ней должен доходить до карты, а не тонуть в невидимом прямоугольнике. */
  pointer-events: none;
}
#шторка[hidden] { display: none; }
#шторка > * { pointer-events: auto; }

/* Полоса вкладок. Видна всегда и на всех экранах — это и оглавление карты, и
   место, куда возвращаются: по светящейся точке видно, что викторина не
   закрыта, а ждёт на своём вопросе.

   Стоит внизу по центру. Низ — потому что там до неё дотягивается большой
   палец: у телефона полоса и жила внизу, и переносить её вверх значило бы
   менять привычку ради одинаковости со столом. Центр — потому что полоса ни к
   чему не привязана: она не край панели, а ряд кнопок, лежащий поверх карты.

   Плашки под кнопками нет. Прежде это была сплошная тёмная полоса во всю
   ширину, и она читалась дном окна, отрезанным от карты. Теперь фон несут сами
   кнопки: между ними видно карту. Читаемость от этого не страдает — свой фон у
   кнопки есть, той же плотности, что была у полосы.

   Ширина — по кнопкам с подписями, а не по экрану. Если шесть подписей в
   строку не помещаются (узкий телефон), полоса ПЕРЕНОСИТСЯ во второй ряд, а не
   листается вбок. Листание пробовали: на экране в 390 точек за краем оставалась
   «Карта» — единственная дверь обратно к самой карте, — и догадаться потянуть
   полосу было неоткуда. Два ряда честнее: видно всё сразу. */
#шторкаРейка {
  display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center;
  gap: 6px;
  /* Растянут во всю ширину, а кнопки в нём — по центру. Прежде сам блок стоял
     `left: 50%` и сжимался по содержимому — и на этом попались: у элемента,
     прибитого к середине, доступная ширина считается от его левого края до
     правого края экрана, то есть половина. Пока полоса не переносилась, она
     просто вылезала за эту половину и всё выглядело верно; стоило разрешить
     перенос — и шесть вкладок сложились в три ряда по две даже там, где
     помещались в один. Растянутый блок таких сюрпризов не делает.
     Сам он прозрачен и мышь не ловит (`pointer-events`), иначе невидимая
     полоса во всю ширину экрана съедала бы клики по карте под собой. */
  position: fixed; z-index: 585;
  left: 0; right: 0;
  bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  padding: 0 8px; background: none; border: 0;
  pointer-events: none;
}
.штВкладка { pointer-events: auto; }
.штВкладка {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  flex: 0 0 auto;
  padding: 6px 10px; border-radius: 9px; cursor: pointer;
  /* Свой фон вместо общей плашки: кнопка должна читаться и над тёмным лесом, и
     над светлой степью. Плотность та же, что была у плашки. */
  background: rgba(18, 16, 12, .82); border: 1px solid var(--edge);
  color: var(--dim); font-family: var(--font); font-size: 12px;
}
.штВкладка:hover { color: var(--gold); border-color: var(--edge-hot); }
.штВкладка.горит {
  background: var(--glass-2); border-color: var(--edge-hot); color: var(--gold);
}
/* Телефон: шесть подписей в строку помещаются, только если ужать поля и сами
   буквы. Воздуха вокруг подписи не жалко, целой подписи жалко, а перенос во
   второй ряд отнимает у карты вдвое больше высоты.
   Порог в 480 точек, а не в 400: при 400 полоса ужималась на узких телефонах и
   оставалась широкой на обычных — 412 точек у Pixel, 430 у больших iPhone, — и
   ровно там она переносилась в два ряда. Замерено на шести ширинах: в один ряд
   полоса встаёт начиная с 360 точек, уже — переносится, и это честнее
   листания: за краем оставалась бы «Карта». */
@media (max-width: 480px) {
  #шторкаРейка { gap: 4px; }
  .штВкладка { padding: 6px 5px; }
  .штИмя { font-size: 9px; }
}
.штЗначок { font-size: 15px; line-height: 1; }
/* Подпись под значком, а не сбоку: пять подписей в строку рядом со значками не
   помещаются на телефоне, а значки без слов приходится угадывать. Мелко —
   десять точек: это подпись к понятному значку, а не самостоятельный текст. */
.штИмя { font-size: 10px; letter-spacing: .02em; white-space: nowrap; line-height: 1.2; }
/* Точка «здесь открыто»: вкладка со своим содержимым отличается от пустой,
   даже когда шторка свёрнута и на экране одна рейка. */
.штВкладка { position: relative; }
.штВкладка.естьЧто::after {
  /* В углу кнопки, а не отдельной строкой: снизу теперь подпись, и точка
     растила бы всю полосу на пять точек ради самой себя. */
  content: ''; position: absolute; top: 4px; right: 5px;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--edge-hot); box-shadow: 0 0 6px rgba(240,214,138,.8);
}

/* Тело шторки: шапка, которая не прокручивается, и панель под ней. */
/* Сквозь шторку видно карту. Прежние 98% были нужны, когда панели лежали одна
   на другой: сквозь стекло читались два текста разом. В шторке за раз видна
   ровно одна панель, и позади неё только карта — а карта под текстом полезна:
   человек не теряет из виду место, о котором читает.
   Плотность выбрана не на глаз: подложка приглушена до яркости около 130 из
   255, и при 0.82 текст стоит на фоне яркостью ~35 — это больше 11:1 к цвету
   букв, вдвое выше порога читаемости. Размытия за шторкой нарочно нет:
   `backdrop-filter` заставляет браузер держать всю карту отдельной
   поверхностью, а именно из-за этого и чернели плитки (см. плитки в
   js/map/map.js). */
#шторкаОкно {
  /* Во весь экран, а не колонкой у левого края. Прежде ящик занимал около
     четверти ширины, чтобы рядом была видна карта. Оказалось, что смотреть на
     неё из-под панели незачем: у сказки для дороги героя есть свой режим
     «Дорога», а вернуться к самой карте — одна вкладка «Карта». Зато в узкой
     колонке разбор точки, список маршрутов и вопрос викторины жили в четверть
     экрана на экране любого размера.
     Вместе с шириной ушла и грань, за которую её тянули: тянуть больше
     нечего. */
  display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto;
  /* Плотнее прежнего. Полупрозрачность заводилась, когда шторка была узкой
     колонкой: карта под текстом помогала не терять из виду место, о котором
     читаешь. Во весь экран та же прозрачность превращается в рябь из кружков
     точек прямо под строками. Немного карты всё же оставляем — лист поверх
     карты должен читаться листом поверх карты, а не другой страницей. */
  background: rgba(20, 17, 12, .965);
  border-right: 0;
}

/* Шапка стоит над прокруткой, а не в ней: прежде у прокрученной панели уезжал
   наверх и крестик, и закрыть её можно было, только домотав обратно. */
#шторкаШапка {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
  padding: 10px 12px; border-bottom: 1px solid rgba(226,197,128,.18);
}
#шторкаЗаголовок {
  flex: 1; min-width: 0; color: var(--gold); font-size: 14px; letter-spacing: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#шторкаШапка button {
  width: 28px; height: 28px; line-height: 1; flex: 0 0 auto;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); border-radius: 6px; cursor: pointer;
  font-family: var(--font); font-size: 13px;
}
#шторкаШапка button:hover { color: var(--gold); border-color: var(--edge-hot); }
#шторкаШапка button[hidden] { display: none; }

#шторкаТело { position: relative; flex: 1; min-height: 0; display: flex; }

/* Панель, у которой голова не уезжает при прокрутке. Прокручивается только
   `.штПолотно`, а метка и заголовок над ним стоят на месте. Раньше в маршрутах
   и викторине уезжало всё разом: домотав до дальних маршрутов, человек не
   видел ни названия панели, ни того, откуда считаются вёрсты, а в викторине —
   сколько вопросов осталось. Тот же приём давно работает у сказки
   (`.скзПолотно`) и у маршрута (`.мршПолотно`) — здесь он назван общим именем.
   `min-height: 0` обязателен: без него flex не даёт полотну сжаться ниже
   своего содержимого, и прокрутка появляется у всей панели, а не внутри. */
#мршСписок, #викторина {
  display: flex; flex-direction: column; overflow: hidden;
}
.штПолотно { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
/* Убранная вкладка: не закрыта, а спрятана. Атрибут `hidden` панели ставят себе
   сами, и трогать его отсюда нельзя — иначе сказка потеряла бы главу, а
   викторина вопрос.
   Правило общее для всех экранов с 04.09. Прежде оно жило внутри
   `@media (min-width: 721px)`, потому что на телефоне вкладками заведовала
   нижняя полоса, а классы шторки там не ставились вовсе и правило гасило бы
   панели навсегда. Теперь рейка одна на всех экранах и сама снимает класс с
   той панели, которую показывает. */
#шторкаТело > .штСкрыта { display: none !important; }
#шторкаПусто {
  padding: 18px; color: var(--dim); font-size: 13px; line-height: 1.6;
}
#шторкаПусто[hidden] { display: none; }

/* Панель внутри шторки: не окно с собственным местом на экране, а содержимое
   ящика. Всё это — только для стола и планшета: на телефоне те же панели
   остаются листами снизу, и трогать их вёрстку нельзя (см. `display: contents`
   в конце блока). */
@media (min-width: 721px) {
  /* Свёрнутая шторка: остаётся одна рейка. Правило живёт здесь, а не рядом с
     самим окном, нарочно — оно вдвое «сильнее» телефонного `display: contents`
     по весу селектора, и снаружи media-блока гасило бы панели на телефоне,
     где никакой шторки нет вовсе. Проверено прогоном: панели там оказывались
     внутри display:none и не показывались ни по одной кнопке. */
  #шторка:not(.открыта) #шторкаОкно { display: none; }

  /* Снимаем позицию, рамку и потолки высоты — их теперь держит сама шторка.
     `!important` здесь по делу: у каждой панели свои `position` и `width` в её
     собственном блоке выше по файлу, и без него они бы победили. */
  #шторкаТело > aside {
    position: static !important;
    inset: auto !important;
    width: auto !important; max-width: none !important;
    height: auto !important; max-height: none !important;
    flex: 1 1 auto; min-width: 0; min-height: 0;
    margin: 0; border: 0; border-radius: 0; background: transparent;
    overflow-y: auto;
  }
  /* Сказка и маршрут — сами колонки со своей несдвигаемой шапкой и прокруткой
     внутри (`.скзПолотно`, `.мршПолотно`). Им прокрутка снаружи не нужна,
     иначе поедут две сразу. */
  #шторкаТело > #сказка, #шторкаТело > #маршрут,
  #шторкаТело > #мршСписок, #шторкаТело > #викторина {
    display: flex; flex-direction: column; overflow: hidden;
  }
  /* «Дорога» сжимала книжку в верхнюю половину экрана, чтобы под ней была
     видна карта с путём героя. В шторке карта и так видна целиком справа —
     режим остаётся кнопкой, которая ведёт камеру по всей дороге героя, а
     панель под неё больше не жмётся. */
  #шторкаТело > #сказка.дорога-режим { height: auto !important; }
  /* Крестики самих панелей внутри шторки не нужны: закрывает один — в её
     шапке, и он нажимает как раз крестик видимой панели (shtorka.js). */
  #шторкаТело #закрыть, #шторкаТело #закрытьВикторину, #шторкаТело #закрытьЗнание,
  #шторкаТело #закрытьСкзСписок, #шторкаТело #скзЗакрыть, #шторкаТело #мршЗакрыть,
  #шторкаТело #мршСпЗакрыть, #шторкаТело #закрытьРядом,
  #шторкаТело #закрытьПрофиль, #шторкаТело #закрытьВход { display: none; }
  /* Панели с собственным внутренним отступом теряют его вместе с рамкой —
     возвращаем полями прокручиваемой части. */
  #шторкаТело > #карточка, #шторкаТело > #викторина, #шторкаТело > #знание,
  #шторкаТело > #скзСписок, #шторкаТело > #мршСписок, #шторкаТело > #рядом,
  #шторкаТело > #профиль, #шторкаТело > #вход {
    padding: 14px 16px 20px;
  }
  /* Плавающие двери — профиль, вход, поддержка, «моя дорога», о проекте,
     письмо — тоже пропускают карту, но плотнее шторки: они не привязаны к
     краю, под ними может оказаться и сама шторка, и её текст. На телефоне это
     правило не работает: там панели ложатся листами одна на другую, и сквозь
     них читались бы два текста разом. */
  #профиль, #вход, #поддержка, #дорога, #оПроектеОкно, #отзыв {
    background: rgba(20, 17, 12, .9);
  }

  /* Шапка сказки: название и четыре кнопки в одну строку помещались в прежние
     520 точек, а шторку человек волен сузить до трёхсот — и flexbox сжимал
     название до «П.. зо..». Переносим его на свою строку, как это давно
     сделано на телефоне: место там есть, а кнопки уходят под него. Правило
     сидит на самой панели, а не на ширине окна: узка бывает именно шторка. */
  #шторкаТело > #сказка .скзШапка { flex-wrap: wrap; gap: 4px 6px; padding: 10px 12px; }
  #шторкаТело > #сказка .скзТитул { flex: 1 1 100%; gap: 6px; }
  #шторкаТело > #сказка .скзШапка button { padding: 5px 9px; font-size: 12px; }
}

/* Грани, за которую тянули ширину шторки, больше нет: ящик занимает экран
   целиком, и выбирать нечего. Вместе с нею ушли `#шторкаГраница`,
   `--шторкаШирина` и класс `шторкаТянется`. */

/* Телефон: рейка та же, ящика нет. Панели здесь — листы снизу во всю ширину
   (блок «Телефон» выше): ящик в триста точек рядом с картой на экране в триста
   девяносто — это не «карта и текст рядом», а текст и полоска карты.
   `display: contents` убирает обёртку шторки из вёрстки: панели внутри неё
   ведут себя ровно так, как если бы лежали в документе, — и ни одно телефонное
   правило переписывать не пришлось. Полосе вкладок обёртка и не нужна: она
   стоит `position: fixed` у нижнего края и на всех экранах одинаково. */
@media (max-width: 720px) {
  #шторка, #шторкаОкно, #шторкаТело { display: contents; }
  #шторкаШапка, #шторкаПусто { display: none; }
}

/* ─── Обратная связь ─────────────────────────────────────────────────────── */
/* Та же вёрстка, что у входа: это тоже маленький разговор, а не панель
   содержания. z выше карточки: форму открывают из неё. */
#отзыв {
  position: absolute; z-index: 565; top: var(--подШапкой); right: 12px;
  width: 360px; max-width: calc(100vw - 24px);
  max-height: calc(100vh - 100px); overflow-y: auto;
  padding: 16px 18px 18px;
  background: var(--glass); border: 1px solid var(--edge-hot); border-radius: 10px;
}
#отзыв[hidden] { display: none; }
#отзыв h2 { margin: 6px 0 12px; font-size: 18px; color: var(--gold); }
#закрытьОтзыв {
  position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; line-height: 1;
  background: transparent; border: 1px solid var(--edge);
  color: var(--dim); border-radius: 6px; cursor: pointer;
}
#отзыв label { display: block; margin-bottom: 10px; color: var(--dim); font-size: 12px; }
#отзыв input, #отзыв textarea {
  display: block; width: 100%; margin-top: 4px; padding: 8px 10px;
  background: rgba(18,16,12,.7); color: var(--text);
  border: 1px solid var(--edge); border-radius: 6px;
  font-family: var(--font); font-size: 13px; outline: none; resize: vertical;
}
#отзыв input:focus, #отзыв textarea:focus { border-color: var(--edge-hot); }
/* Приманка для ботов: поле честно стоит в форме, но человеку не видно и с
   клавиатуры не достаётся. display:none боты научились уважать, сдвиг — нет. */
#отзыв .отзывСайт { position: absolute; left: -9999px; top: -9999px; }
#отзывПро { color: var(--dim); font-size: 12px; margin: -6px 0 10px; }
#отзывВесть { margin-top: 8px; }
#отзывВесть.беда { color: #ff9c8c; }
#отзывИзКарточки { margin-top: 10px; }

/* ─── Листы снизу и полоса вкладок ───────────────────────────────────────── */
/*
   На телефоне панели — листы во всю ширину у нижнего края, и там же стоит
   полоса вкладок. Без поправки лист ложится прямо на неё, и нажать вкладку
   нельзя: проверено прогоном, клик по «Маршрутам» перехватывал сам список
   маршрутов. Поднимаем листы над полосой — её высоту меряет и кладёт в
   `--рейкаВысота` js/map/shtorka.js.

   Почему `body:not(.чтение)`, а не просто список панелей. Во-первых, по делу:
   в режиме чтения полосы нет вовсе (`body.чтение #шторка` выше), и книжка
   обязана занимать весь экран — запас под спрятанную полосу оставил бы снизу
   необъяснимое поле. Во-вторых, по весу: `#рядом`, `#мршСписок`, `#поддержка`
   и `#маршрут` описаны в этом файле НИЖЕ телефонного блока и ставят свои
   `left`, `top`, `bottom` и `width` после него. У медиазапроса своего веса
   нет, решает порядок, и поправка, сделанная выше, молча проигрывала — ровно
   на этом и попался первый заход. Лишний класс в селекторе поднимает вес, и
   правило выигрывает, где бы ни стояло.

   Заодно чинится давняя мелочь: `#рядом` и `#мршСписок` брали `bottom: 12px`
   из своего блока ниже по файлу и на телефоне сидели под прежней нижней
   навигацией — их нижний край было не нажать.
*/
@media (max-width: 720px) {
  body:not(.чтение) #викторина, body:not(.чтение) #вход,
  body:not(.чтение) #профиль, body:not(.чтение) #правка,
  body:not(.чтение) #оПроектеОкно, body:not(.чтение) #сказка,
  body:not(.чтение) #скзСписок, body:not(.чтение) #знание,
  body:not(.чтение) #поддержка, body:not(.чтение) #рядом,
  body:not(.чтение) #мршСписок, body:not(.чтение) #дорога,
  body:not(.чтение) #отзыв, body:not(.чтение) #карточка,
  body:not(.чтение) #маршрут {
    left: 8px; right: 8px; width: auto; max-width: none;
    /* Во весь экран: от шапки до полосы вкладок. Прежде листы вставали снизу
       на 68% высоты, чтобы над ними была видна карта. Смотреть на неё
       из-под панели незачем — у сказки для дороги героя есть свой режим,
       а к самой карте возвращает вкладка «Карта». Зато список маршрутов и
       вопрос викторины перестали жить в двух третях экрана. */
    top: var(--подШапкой);
    bottom: calc(var(--рейкаВысота) + 8px + env(safe-area-inset-bottom, 0px));
    max-height: none;
  }
}

/* ─── Уровни экрана, зов, аватар (07.09) ────────────────────────────────────
   На экране только то, что нужно в этот момент. Уровень пишет
   js/map/uroven.js в `data-уровень` на <body>: 0 — ничего не выбрано,
   1 — открыта карточка или список, 2 — сказка, маршрут, викторина.
   Зов (плашка внизу) живёт только на нулевом; фокус (чужие точки гаснут)
   ставит карточка классом на #map. Блок стоит в самом конце файла нарочно:
   телефонные правила выше по файлу проигрывают по порядку (см. правило про
   вес селектора в начале телефонного блока), а здесь порядок на нашей
   стороне. */
:root {
  --moss: #5f7a4a;
  --moss-hot: #8fb075;
  --gold-solid: #d9a441;
}

/* Рейка снята (js/map/shtorka.js): у #шторкаРейка стоит display:flex, и одного
   атрибута hidden ему мало. */
#шторкаРейка[hidden] { display: none !important; }

/* Аватар: кружок с кольцом прогресса. Кольцо — SVG-окружность с pathLength=100,
   поэтому доля прочитанного в процентах и есть длина штриха. */
#аватар {
  position: relative; width: 44px; height: 44px; padding: 0; margin: 0;
  display: grid; place-items: center;
  border: 0; border-radius: 50%; background: var(--glass);
  color: var(--gold); font: 700 19px/1 var(--font); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
#аватар .аватарКольцо { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
#аватар .аватарФон { fill: none; stroke: var(--edge); stroke-width: 3; }
#аватар .аватарХод {
  fill: none; stroke: var(--gold-solid); stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: var(--ход, 0) 100;
  transition: stroke-dasharray .6s ease-out;
}
#аватар:hover, #аватар.горит { background: var(--glass-2); }
#аватар.горит .аватарФон { stroke: var(--edge-hot); }
#аватарЗнак { position: relative; }

#аватарМеню {
  position: absolute; z-index: 610; top: var(--подШапкой); right: 12px;
  width: 250px; max-width: calc(100vw - 24px); padding: 6px;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--glass); border: 1px solid var(--edge-hot); border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .45);
}
#аватарМеню[hidden] { display: none; }
#аватарМеню > button, #аватарМеню > a {
  display: block; width: 100%; max-width: none; margin: 0; padding: 11px 12px;
  text-align: left; background: transparent; border: 0; border-radius: 7px;
  color: var(--text); font: 14px/1.25 var(--font); cursor: pointer;
  white-space: normal; text-decoration: none; min-height: 44px;
}
#аватарМеню > button:hover, #аватарМеню > a:hover { background: var(--glass-2); color: var(--gold); border: 0; }
#аватарМеню > button.горит { color: var(--gold); background: rgba(217, 164, 65, .12); }
#аватарМеню > [hidden] { display: none !important; }
#аватарМеню .аватарЧерта { height: 1px; margin: 4px 6px; background: var(--edge); }

/* Зов. Две плашки внизу по центру: золотая — ребёнку, мховая — родителю.
   Fixed, а не absolute, — как стояла рейка: низ дотягивается большим пальцем.
   Сам блок мышь не ловит, ловят кнопки: иначе невидимая полоса съедала бы
   клики по карте между ними. */
#зов {
  position: fixed; z-index: 585; left: 50%;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  display: flex; gap: 10px; width: max-content; max-width: calc(100vw - 24px);
  pointer-events: none;
}
#зов > button { pointer-events: auto; }
body:not([data-уровень="0"]) #зов,
body.панели-скрыты #зов,
body.чтение #зов { display: none; }

#зов > button {
  display: flex; align-items: center; gap: 12px;
  min-height: 56px; padding: 8px 18px 8px 14px;
  border-radius: 16px; cursor: pointer; text-align: left;
  font-family: var(--font);
  box-shadow: 0 10px 28px rgba(0, 0, 0, .45);
  -webkit-tap-highlight-color: transparent;
  transition: transform .08s ease-out, filter .12s ease-out;
}
#зов > button:hover { filter: brightness(1.08); }
#зов > button:active { transform: translateY(1px) scale(.99); }
#зов .зовГлавный {
  background: linear-gradient(180deg, #ecbe63 0%, #c8922e 100%);
  color: #1d1509; border: 1px solid #f6d98c;
}
#зов .зовВторой {
  background: linear-gradient(180deg, #6f8e58 0%, #4c6839 100%);
  color: #f3f0e4; border: 1px solid var(--moss-hot);
}
.зовЗнак { font-size: 24px; line-height: 1; }
.зовТекст { display: flex; flex-direction: column; gap: 2px; line-height: 1.15; }
.зовТекст b { font-size: 16.5px; letter-spacing: .2px; }
.зовТекст small { font-size: 12px; opacity: .85; }

/* Три глагола в карточке точки: читать — ехать — проверить. Один блок, одна
   ширина, разная сила: золото у первого, мох у второго, синий у третьего.
   Правила с #карточка .зовы сильнее прежних #карточкаСказка/#карточкаМаршрут
   (0,1,1 + класс против 0,1,0) и стоят позже — им и решать. */
#карточка .зовы { display: flex; flex-direction: column; gap: 8px; margin: 6px 0 16px; }
#карточка .зовы > button {
  display: block; width: 100%; margin: 0; padding: 13px 14px;
  border-radius: 10px; cursor: pointer; text-align: left;
  font: 600 15px/1.25 var(--font);
  -webkit-tap-highlight-color: transparent;
  transition: transform .06s ease-out, filter .12s ease-out;
}
#карточка .зовы > button:hover { filter: brightness(1.08); }
#карточка .зовы > button:active { transform: translateY(1px); }
#карточка .зовы > button[hidden] { display: none; }
#карточка .зовы > .зовГлавный {
  background: linear-gradient(180deg, #ecbe63 0%, #c8922e 100%);
  color: #1d1509; border: 1px solid #f6d98c;
}
#карточка .зовы > .зовВторой {
  background: rgba(95, 122, 74, .32); color: var(--text); border: 1px solid var(--moss-hot);
}
#карточка .зовы > .зовТретий {
  background: rgba(31, 58, 95, .35); color: var(--text); border: 1px solid #4f78a6;
}
#карточка .зовы > .зовТретий:disabled { opacity: .55; cursor: default; filter: none; transform: none; }
#карточка .зовы > .зовТретий small { display: block; margin-top: 2px; font-weight: 400; font-size: 12px; color: var(--dim); }

/* Фокус: выбрана точка — остальные гаснут, выбранная светится. Класс на
   контейнере карты и один селектор вместо стиля на каждом из пятисот
   маркеров. Нить дороги и метки маршрута (без класса .точка) не гаснут. */
#map.фокус .leaflet-overlay-pane path.точка:not(.выбранная),
#map.фокус .leaflet-marker-pane .сказка-иконка:not(.выбранная),
#map.фокус .leaflet-marker-pane .жанр-иконка:not(.выбранная) {
  opacity: .28;
  transition: opacity .25s ease-out;
}
#map.фокус .leaflet-overlay-pane path.точка.выбранная {
  stroke: #fff3cf; stroke-width: 2.5;
  filter: drop-shadow(0 0 6px rgba(255, 230, 166, .95));
}

@media (max-width: 720px) {
  #зов {
    left: 12px; right: 12px; transform: none;
    width: auto; max-width: none; flex-direction: column; gap: 8px;
    bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  }
  #зов > button { width: 100%; min-height: 52px; }
  #аватарМеню { right: 8px; }
}
@media (prefers-reduced-motion: reduce) {
  #аватар .аватарХод, #зов > button, #карточка .зовы > button,
  #map.фокус .leaflet-overlay-pane path.точка:not(.выбранная) { transition: none; }
}

/* Телефон: аватар стоит в первой строке шапки справа от названия. Прежнее
   правило `.кнопки { display: none }` прятало полосу кнопок целиком — тогда
   в ней были кнопки, ушедшие в рейку; теперь в ней один аватар, и без него
   на телефоне не войти и не открыть свою дорогу. Вес селектора выше, чем у
   голого `.кнопки` в телефонном блоке, и стоит позже: побеждает дважды. */
@media (max-width: 720px) {
  #шапка .кнопки { display: flex; flex: 0 0 auto; order: 1; overflow: visible; }
  #шапка .кнопки > #аватар { width: 38px; height: 38px; padding: 0; font-size: 16px; }
  #шапка .титул { flex: 1 1 auto; order: 0; }
  #шапка .поиск { order: 2; }
}

/* Уровень 1 — колонка, уровень 2 — весь экран. Ящик во весь экран заводился,
   когда единственной дверью обратно к карте была вкладка «Карта». Теперь
   карта — главный экран: карточка точки, список сказок, ближайшие маршруты
   стоят колонкой слева, и человек видит место, о котором читает, и точку,
   которую только что выбрал (она горит фокусом). Сказка, маршрут и викторина
   по-прежнему во весь экран: там читают, а карту зовут своей кнопкой
   «Дорога». Ширина — доля экрана с потолком: разбор точки на 1440 не должен
   растягиваться в строку на всю ширину, а на 800 — терять карту вовсе. */
@media (min-width: 721px) {
  body[data-уровень="1"] #шторка { right: auto; width: clamp(360px, 36vw, 520px); }
  body[data-уровень="1"] #шторкаОкно {
    background: rgba(20, 17, 12, .93);
    border-right: 1px solid var(--edge);
    box-shadow: 12px 0 32px rgba(0, 0, 0, .35);
  }
  /* Аватар — у правого края шапки, а не вплотную к поиску. */
  #шапка .кнопки { margin-left: auto; overflow: visible; }
}

/* Телефон: зум и «где я» поднимаются над зовом, пока он на экране, — иначе
   плюс ложился ровно на «Начать путь». Высота зова там известна: две плашки
   по 52 плюс зазоры. */
@media (max-width: 720px) {
  body[data-уровень="0"]:not(.панели-скрыты) .leaflet-bottom.leaflet-right {
    margin-bottom: calc(var(--рейкаВысота, 0px) + 134px);
  }
}

/* ─── Три языка слоёв (шаг 2, 07.09) ────────────────────────────────────────
   Где живёт герой — круг: точка на холсте, поверх неё медальон сказки.
   Путь героя — золотая нить с бегущим пунктиром (.дорогаИскры, выше).
   Реальный туризм — ромб мхом (.мршМетка). Форма, цвет и движение разные,
   чтобы слои читались без легенды. */

/* Гнездо: несколько точек на зуме страны. Тёмный диск на золотой кайме, число
   моноширинное, как номера точек; книжка в уголке — внутри есть сказка.
   Размер растёт со счётом, но в трёх ступенях, а не плавно: карте нужны
   «мало / много / очень много», а не линейка. Клик — приближение
   (zoomToBoundsOnClick). iconSize не задан — размер даёт вёрстка, а
   центрируем через transform, чтобы Leaflet не сдвигал гнездо к углу. */
.гнездо {
  /* position не трогаем: маркер Leaflet абсолютен, и relative уносил гнёзда
     в поток документа — они разъезжались на сотни точек. */
  display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; margin-left: -18px !important; margin-top: -18px !important;
  border-radius: 50%; cursor: pointer;
  background: radial-gradient(circle at 35% 30%, #3a2f22 0%, #1c1610 70%);
  border: 2px solid var(--gold-solid);
  box-shadow: 0 0 0 4px rgba(217, 164, 65, .18), 0 4px 12px rgba(0, 0, 0, .5);
  color: var(--gold); font-family: var(--mono); font-size: 13px; font-weight: 700;
  transition: transform .1s ease-out, box-shadow .1s ease-out;
}
.гнездо.среднее { width: 44px; height: 44px; margin-left: -22px !important; margin-top: -22px !important; font-size: 14px; }
.гнездо.большое { width: 54px; height: 54px; margin-left: -27px !important; margin-top: -27px !important; font-size: 16px;
  box-shadow: 0 0 0 6px rgba(217, 164, 65, .16), 0 6px 16px rgba(0, 0, 0, .55); }
.гнездо:hover { transform: scale(1.08); box-shadow: 0 0 0 6px rgba(217, 164, 65, .3), 0 6px 16px rgba(0, 0, 0, .55); }
.гнездоКнижка {
  position: absolute; right: -6px; top: -6px;
  width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: #1c1610; border: 1.5px solid var(--gold); font-size: 11px; line-height: 1;
}
/* Гнёзда гаснут в фокусе вместе с точками. */
/* !important: markercluster ставит гнезду opacity инлайном ради своей
   анимации, и без него фокус на гнёзда не действовал (проверено прогоном). */
#map.фокус .гнездо { opacity: .35 !important; }
/* Анимация появления/распада гнёзд из MarkerCluster.css трогает transform у
   всех значков; наши медальоны хвастаются своим transform на hover — не
   спорим, просто короче. */
.leaflet-cluster-anim .leaflet-marker-icon { transition-duration: .2s; }

/* Медальон сказки: круг больше прежней книжки, тёплый диск, золотая кайма.
   Это «где живёт герой» — самая заметная метка на карте после гнезда. Здесь
   же потом встанет портрет героя (общественное достояние, решение владельца). */
.сказка-иконка {
  width: 32px; height: 32px; margin-left: -16px !important; margin-top: -16px !important;
  background: radial-gradient(circle at 35% 30%, #4a3a22 0%, #1c1610 75%);
  border: 2px solid var(--gold-solid);
  box-shadow: 0 0 0 3px rgba(217, 164, 65, .18), 0 3px 10px rgba(0, 0, 0, .5);
  font-size: 16px;
}
.сказка-иконка.выбранная {
  transform: scale(1.25); border-color: #fff3cf;
  box-shadow: 0 0 0 5px rgba(255, 230, 166, .28), 0 0 18px rgba(255, 230, 166, .9);
  z-index: 1000 !important;
}
.жанр-иконка.выбранная { transform: scale(1.2); border-color: var(--gold); }

/* Остановка дня — ромб мхом: другая форма и другой цвет, чем у сказочных
   кругов. Значок внутри не поворачивается: ромб рисует ::before, а span со
   значком лежит поверх. */
.мршМетка { background: none; border: 0; }
.мршМетка::before {
  content: ''; position: absolute; inset: 5px;
  transform: rotate(45deg); border-radius: 5px;
  background: linear-gradient(180deg, #6f8e58 0%, #44603a 100%);
  border: 2px solid var(--moss-hot);
  box-shadow: 0 3px 8px rgba(0, 0, 0, .5);
}
.мршМетка span {
  position: relative; width: 30px; height: 30px;
  background: none; border: 0; box-shadow: none; font-size: 14px;
}
.мршМетка:hover::before { filter: brightness(1.15); }

/* Маршрут — колонка и на втором уровне, только шире: день по Ростову
   читают вместе с картой, где стоят ромбы музеев и еды, а сказка и
   викторина — во весь экран, там карту зовут своей кнопкой. Какая панель
   открыта, пишет js/map/uroven.js в data-панель. Ширина в долю экрана с
   потолком: остановки с часами и ценами шире разбора точки. */
@media (min-width: 721px) {
  body[data-уровень="2"][data-панель="маршрут"] #шторка { right: auto; width: clamp(420px, 46vw, 680px); }
  body[data-уровень="2"][data-панель="маршрут"] #шторкаОкно {
    background: rgba(20, 17, 12, .93);
    border-right: 1px solid var(--edge);
    box-shadow: 12px 0 32px rgba(0, 0, 0, .35);
  }
}

/* ─── Лестница сказок и «после сказки» (шаг 4, 07.09) ───────────────────────
   Список сказок собран по ступеням: от коротких к долгим дорогам. Ступень —
   не «6+», а ёлочки: одна–четыре, ребёнку понятнее шкалы возраста. */
.скзСтупень { margin-bottom: 18px; }
.скзСтупеньШапка {
  display: grid; grid-template-columns: auto 1fr auto; grid-template-areas: "ёлки имя счёт" "ёлки кому счёт";
  align-items: center; column-gap: 10px; row-gap: 2px;
  padding: 8px 4px 10px; border-bottom: 1px solid var(--edge); margin-bottom: 8px;
}
.скзЁлки { grid-area: ёлки; font-size: 15px; letter-spacing: -2px; }
.скзСтупеньШапка b { grid-area: имя; color: var(--gold); font-size: 15px; }
.скзСтупеньКому { grid-area: кому; color: var(--dim); font-size: 12px; }
.скзСтупеньСчёт { grid-area: счёт; color: var(--dim); font-family: var(--mono); font-size: 11px; white-space: nowrap; }
.скзСписокПункт { position: relative; }
.скзСписокПункт.дочитана { border-color: rgba(217, 164, 65, .55); background: rgba(217, 164, 65, .10); }
.скзСписокПункт.дочитана b { color: #f6d98c; }
.скзВозраст { position: absolute; right: 12px; top: 10px; color: var(--dim); font-family: var(--mono); font-size: 11px; }
.скзМетка.начата { background: rgba(95, 122, 74, .35); border-color: var(--moss-hot); color: #e9f0dc; }

/* После концовки: те же зовы, что в карточке, — золотой «Проверить себя»,
   мховый «Дальше по лестнице». Стоят до кнопки «Читать сначала». */
.скзПосле { display: flex; flex-direction: column; gap: 8px; margin: 14px 0 6px; }
.скзПосле[hidden] { display: none; }
.скзПосле > button {
  display: block; width: 100%; padding: 13px 14px; border-radius: 10px;
  cursor: pointer; text-align: left; font: 600 15px/1.25 var(--font);
  -webkit-tap-highlight-color: transparent;
}
.скзПосле > .зовГлавный { background: linear-gradient(180deg, #ecbe63 0%, #c8922e 100%); color: #1d1509; border: 1px solid #f6d98c; }
.скзПосле > .зовВторой { background: rgba(95, 122, 74, .32); color: var(--text); border: 1px solid var(--moss-hot); }
.скзПосле > .зовВторой b { color: #f6d98c; font-weight: 700; }
.скзПосле > .зовВторой small { display: block; margin-top: 2px; font-weight: 400; font-size: 12px; color: var(--dim); }
.скзПосле > button:hover { filter: brightness(1.08); }

/* Дочитанная сказка на карте: галочка на медальоне. Видно с карты, что
   пройдено, — та самая «загоревшаяся» точка из плана (§2). */
.сказка-иконка.дочитана { border-color: #f6d98c; box-shadow: 0 0 0 3px rgba(246, 217, 140, .35), 0 0 14px rgba(255, 230, 166, .7); }
.сказка-иконка.дочитана::after {
  content: '✓'; position: absolute; right: -7px; top: -7px;
  width: 16px; height: 16px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: #c8922e; color: #1d1509; font-size: 11px; font-weight: 700; line-height: 1;
  border: 1.5px solid #f6d98c;
}

/* ─── Лист карточки на телефоне: три положения (шаг 5, 07.09) ───────────────
   js/map/list.js ставит data-лист на #карточка: пик / пол / весь. Высота —
   свойством height, а не max-height: лист должен стоять ровно там, куда его
   положили, а не «до содержимого». Пик 176 точек — та же цифра в list.js.
   Переход анимируется, кроме времени, пока лист тянут пальцем (.листТянется):
   иначе он отстаёт от пальца на длину анимации. Ручка — только здесь. */
#карточкаРучка { display: none; }
@media (max-width: 720px) {
  body:not(.чтение) #карточка[data-лист] {
    top: auto; bottom: 0; left: 0; right: 0; width: auto; max-width: none;
    max-height: none; border-radius: 16px 16px 0 0;
    padding-top: 26px;
    transition: height .22s ease-out;
    overflow-y: auto; overscroll-behavior: contain;
  }
  #карточка.листТянется { transition: none; }
  body:not(.чтение) #карточка[data-лист="пик"] { height: 176px; overflow: hidden; }
  body:not(.чтение) #карточка[data-лист="пол"] { height: 52vh; }
  body:not(.чтение) #карточка[data-лист="весь"] { height: 92vh; }
  #карточкаРучка {
    display: flex; align-items: center; justify-content: center;
    position: absolute; left: 0; right: 0; top: 0; height: 26px;
    background: transparent; border: 0; cursor: grab; touch-action: none;
    -webkit-tap-highlight-color: transparent;
  }
  #карточкаРучка span { width: 44px; height: 5px; border-radius: 3px; background: var(--edge-hot); }
  /* На пике кнопки карты нужны: карта видна и по ней ходят. */
  body:has(#карточка[data-лист="пик"]) #map .leaflet-control-container { display: block; }
  body:has(#карточка[data-лист="пик"]) .leaflet-bottom.leaflet-right { margin-bottom: 184px; }
}
/* На столе колонка не мешает кнопкам карты — возвращаем их (общее правило
   выше прячет контролы при любой видимой панели, оно писалось под ящик во
   весь экран). */
@media (min-width: 721px) {
  body[data-уровень="1"] #map .leaflet-control-container,
  body[data-панель="маршрут"] #map .leaflet-control-container { display: block; }
}

/* ─── Стиль: медальоны с портретами, знаки, палитра (шаг 6, 07.09) ──────────
   Палитра «современный фольклор»: дерево, мох, золото, глубокий синий, лён.
   Переменные — чтобы цвет менялся в одном месте; старые --gold/--edge
   остаются, на них держится вся прежняя вёрстка. */
:root {
  --wood: #2b211a;
  --deep: #1f3a5f;
  --deep-hot: #4f78a6;
  --linen: #f1e8d8;
}

/* Медальон с ликом: иллюстрация сказки в круге, верхняя треть в центре —
   там чаще всего лицо. Книжка-бейдж в уголке говорит «здесь читают»: без
   неё портрет — просто картинка на карте. */
.сказка-иконка.сЛиком { padding: 0; overflow: visible; }
.сказка-иконка.сЛиком img {
  width: 100%; height: 100%; border-radius: 50%; object-fit: cover; object-position: center 30%;
  display: block; background: #1c1610;
}
.сказка-иконка .ликКнижка {
  position: absolute; right: -6px; bottom: -6px;
  width: 17px; height: 17px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: #1c1610; border: 1.5px solid var(--gold-solid); color: var(--gold);
}
.сказка-иконка .ликКнижка svg, .сказка-иконка svg.зн, .гнездоКнижка svg, .зовЗнак { width: 60%; height: 60%; }
.сказка-иконка svg.зн { color: var(--gold); }
.гнездоКнижка { color: var(--gold); }
.гнездоКнижка svg { width: 12px; height: 12px; }
/* Галочка дочитанной сказки на медальоне с ликом — не спорит с книжкой:
   она сверху справа, книжка снизу справа. */
.сказка-иконка.сЛиком.дочитана::after { right: -6px; top: -6px; }
/* Знаки зова — svg вместо эмодзи, того же размера. */
.зовЗнак { width: 26px; height: 26px; flex: 0 0 auto; }
#зов .зовГлавный .зовЗнак { color: #1d1509; }
#зов .зовВторой .зовЗнак { color: #f3f0e4; }
