/* Тёмная тема — не украшение: приложением пользуются в лесу на рассвете
   и в сумерках, когда светлый экран слепит. */
:root {
  --bg: #fcfcfb; --card: #ffffff; --line: #e3e2dd;
  --ink: #0b0b0b; --ink2: #52514e; --muted: #86857f;
  --accent: #256abf; --accent-ink: #184f95;
  --yes: #1baf7a; --no: #b8483a;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #17181a; --card: #1f2124; --line: #313337;
    --ink: #f2f2f0; --ink2: #c3c2b7; --muted: #8d8c85;
    --accent: #3987e5; --accent-ink: #86b6ef;
    --yes: #199e70; --no: #d1584a;
  }
}
* { box-sizing: border-box; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 16px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  padding-bottom: env(safe-area-inset-bottom);
}
h1 { font-size: 1.1rem; margin: 0; }
h2 { font-size: 1.05rem; margin: 0 0 .5rem; }
.muted { color: var(--muted); }
.small { font-size: .85rem; }

/* Без потолка ширины страница на широком экране растягивалась во всю ширину
   окна, и с ней — график: 88 точек на 1000+ px читались как редкие вешки
   вместо линии. Один столбец на весь сайт, по центру, на любой ширине окна. */
:root { --content-w: 640px; }

header { position: sticky; top: 0; z-index: 500; background: var(--bg);
         border-bottom: 1px solid var(--line); padding: .6rem .8rem 0; }
.head-row { display: flex; align-items: baseline; gap: .6rem; margin: 0 auto .5rem;
            max-width: var(--content-w); }
#region-select { font-size: .8rem; color: var(--ink2); padding: .25rem .4rem;
                 border-radius: 6px; margin-left: auto; }
.tabs { display: flex; gap: .25rem; margin: 0 auto; max-width: var(--content-w); }
.tabs button {
  flex: 1; padding: .55rem .3rem; font: inherit; font-size: .9rem;
  background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--ink2); cursor: pointer;
}
.tabs button.active { color: var(--accent-ink); border-bottom-color: var(--accent); font-weight: 600; }

main { padding: .8rem; max-width: var(--content-w); margin: 0 auto; }
.tab[hidden] { display: none; }

/* карточки вердикта */
.card {
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  padding: .7rem .8rem; margin-bottom: .6rem;
}
.card-top { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem; }
.card-name { font-weight: 600; }
.verdict { font-size: .9rem; padding: .1rem .45rem; border-radius: 999px;
           border: 1px solid var(--line); color: var(--ink2); white-space: nowrap; }
.verdict.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.bar { height: 6px; border-radius: 3px; background: var(--line); margin: .5rem 0 .35rem; overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--accent); }
.conf { font-size: .8rem; color: var(--muted); }

/* график динамики (спарклайн на карточке вида) */
.spark { position: relative; margin: .3rem 0 .1rem; }
.spark-svg { display: block; width: 100%; height: 72px; overflow: visible; }
.spark-area { fill: var(--accent); fill-opacity: .1; stroke: none; }
.spark-line { fill: none; stroke: var(--accent-ink); stroke-width: 2;
              stroke-linecap: round; stroke-linejoin: round; }
/* Пунктир = чистая проекция без новых дождей, не измерение и не прогноз API. */
.spark-line-projected { stroke-dasharray: 4 3; opacity: .5; }
.spark-dot { fill: var(--accent-ink); stroke: var(--card); stroke-width: 1.5; }
.spark-cross { stroke: var(--muted); stroke-width: 1; }
.spark-hit { fill: transparent; cursor: crosshair; }
/* Низкая уверенность в дате — та же пунктирная логика, что и в графике:
   визуально одно и то же понятие «это ещё не факт», а не два разных языка. */
.conf-tag {
  display: inline-block; padding: 0 .4rem; border: 1px dashed var(--muted);
  border-radius: 999px; color: var(--ink2);
}
.spark-tip {
  position: absolute; top: -.15rem; transform: translate(-50%, -100%);
  background: var(--card); color: var(--ink); border: 1px solid var(--line);
  font-size: .72rem; line-height: 1.4; padding: .15rem .45rem; border-radius: 5px;
  white-space: nowrap; pointer-events: none; z-index: 5;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .15);
}

/* график погоды (факт + прогноз) на первой вкладке */
#weather-block { margin-bottom: 1rem; }
.wx-title { font-size: .95rem; margin: 0 0 .3rem; }
#wx-chart { position: relative; }
.wx-svg { display: block; width: 100%; height: 150px; overflow: visible; }
.wx-bar { fill: var(--accent); fill-opacity: .55; }
/* Прогнозная часть бледнее факта: осадки дальше горизонта переписываются
   целиком, и рисовать их наравне с измеренными значило бы выдавать
   уверенность, которой нет — та же логика, что у пунктира в спарклайне. */
.wx-bar-fc { fill-opacity: .25; }
.wx-line { fill: none; stroke: #c2410c; stroke-width: 2;
           stroke-linecap: round; stroke-linejoin: round; }
.wx-line-fc { stroke-dasharray: 4 3; opacity: .55; }
.wx-today { stroke: var(--ink2); stroke-width: 1; stroke-dasharray: 2 2; opacity: .6; }

/* карта */
.controls { display: flex; gap: .6rem; align-items: center; margin-bottom: .5rem; flex-wrap: wrap; }
#wx-layer { font-size: .85rem; }
select, input, button { font: inherit; }
select, input { padding: .45rem .5rem; border: 1px solid var(--line);
                border-radius: 8px; background: var(--card); color: var(--ink); }
#map { height: 58vh; min-height: 320px; border-radius: 10px; border: 1px solid var(--line); }
/* Подложку приглушаем: насыщенный цвет на экране должен быть только у данных,
   иначе синий слой пригодности спорит с синей водой OSM. Но saturate(.2) душил
   лес и жильё до почти одинакового серого — проверено математически (матрица
   CSS-фильтра, применённая к пикселям реального тайла: лес RGB(173,209,158)
   и жильё RGB(223,223,222) при .2 расходились на 47/255, а лес выглядел
   пустым — по факту разница держалась на одном канале). saturate(.45)
   возвращает лесу «наполненность», подтверждено на реальных тайлах Смоленска
   в двух масштабах (z9, z13), не только на изолированных пикселях. */
.leaflet-tile-pane { filter: saturate(.45) contrast(.92) brightness(1.02); }
@media (prefers-color-scheme: dark) {
  .leaflet-tile-pane { filter: saturate(.35) brightness(.55) invert(.92) hue-rotate(180deg); }
}
.legend { display: flex; gap: .4rem; flex-wrap: wrap; margin: .5rem 0; font-size: .78rem; }
.legend i { display: inline-block; width: 14px; height: 10px; border-radius: 2px;
            margin-right: .25rem; vertical-align: middle; }

/* точки */
.pt { border-top: 1px solid var(--line); padding: .55rem 0; }
.pt-head { display: flex; justify-content: space-between; gap: .5rem; }
.pt a { color: var(--accent-ink); }
.why { color: var(--muted); font-size: .82rem; }

/* форма */
form label { display: block; margin-bottom: .7rem; font-size: .9rem; color: var(--ink2); }
form input, form select { width: 100%; margin-top: .25rem; }
.row { display: flex; gap: .5rem; }
.row input { flex: 1; }
.row.big button { flex: 1; padding: .8rem; border-radius: 10px; border: 1px solid var(--line);
                  background: var(--card); color: var(--ink); font-weight: 600; }
.row.big button.sel[data-found="1"] { background: var(--yes); border-color: var(--yes); color: #fff; }
.row.big button.sel[data-found="0"] { background: var(--no); border-color: var(--no); color: #fff; }
button.primary { width: 100%; padding: .75rem; border: 0; border-radius: 10px;
                 background: var(--accent); color: #fff; font-weight: 600; cursor: pointer; }
#locate { padding: .45rem .7rem; border: 1px solid var(--line); border-radius: 8px;
          background: var(--card); color: var(--ink); }
.chk { font-size: .85rem; color: var(--ink2); }
.chk input { width: auto; margin-right: .3rem; }

/* модалка */
.modal { position: fixed; inset: 0; background: rgba(0,0,0,.55); z-index: 1000;
         display: flex; align-items: center; justify-content: center; padding: 1rem; }
.modal[hidden] { display: none; }
.modal-box { background: var(--card); border-radius: 12px; padding: 1rem; max-width: 34rem; }
.modal-box ul { padding-left: 1.1rem; font-size: .9rem; color: var(--ink2); }
.pending { color: var(--muted); font-size: .8rem; }

/* Теоретический слой — цвет и рамка отделяют его от проверенной карты:
   это гипотеза для полевой проверки, а не улучшенная версия прогноза. */
.theory-note { border-left: 3px solid #ea580c; padding-left: .5rem; }
.habitat-note { border-left: 3px solid #14b8a6; padding-left: .5rem; }
/* Подпись кольца — «сколько ехать от города», а не элемент данных:
   поэтому приглушена и не перехватывает клики по точкам. */
.ring-label { font-size: .68rem; color: var(--ink2); text-align: center;
              text-shadow: 0 0 3px var(--bg), 0 0 3px var(--bg); pointer-events: none; }
.areas-note { border-left: 3px solid #a855f7; padding-left: .5rem; }
/* Запрет, а не подсказка: единственная красная рамка среди слоёв. */
.oopt-note { border-left: 3px solid var(--no); padding-left: .5rem; }

/* Обратная связь. Ловушка для ботов прячется через position, а не display:none
   и не hidden: часть автозаполнялок пропускает скрытые поля, и ловушка
   перестала бы срабатывать ровно на тех, ради кого поставлена. */
.fb-form { margin-top: 1.4rem; border-top: 1px solid var(--line); padding-top: .9rem; }
.fb-form textarea { width: 100%; margin-top: .25rem; font: inherit; padding: .5rem;
                    border: 1px solid var(--line); border-radius: 8px;
                    background: var(--card); color: var(--ink); resize: vertical; }
.fb-trap { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.page-foot { max-width: var(--content-w); margin: 0 auto; padding: .4rem .8rem 1.6rem;
             font-size: .85rem; }
.page-foot a { color: var(--accent-ink); }

/* --- форма отметки ------------------------------------------------------- */
/* Карта вместо ввода координат. Цифры широты и долготы человек в лесу не
   знает и с телефона не наберёт — он знает место. Поле координат остаётся
   рядом: оно показывает, куда именно поставлена метка, и принимает вставку
   из чужой карты. */
#mark-map { height: 40vh; min-height: 240px; border-radius: 10px;
            border: 1px solid var(--line); margin: .25rem 0 .5rem; }

.fset { border: 1px solid var(--line); border-radius: 10px;
        padding: .6rem .7rem .2rem; margin: 0 0 .8rem; }
.fset legend { font-size: .9rem; color: var(--ink2); padding: 0 .3rem; }
.fset label { margin-bottom: .6rem; }

/* Вид + оценка. Оценка появляется только у отмеченного вида: пустая шкала
   у каждого из пяти видов превращает форму в стену кнопок, а вопрос
   «сколько нашли того, чего не искали» бессмыслен. */
.sp-row { border-top: 1px solid var(--line); padding: .5rem 0 .3rem; }
.sp-row:first-child { border-top: 0; }
.sp-head { display: flex; align-items: center; gap: .45rem; font-size: .95rem; }
.sp-head input { width: auto; margin: 0; }
.sp-head .sp-name { font-weight: 600; color: var(--ink); }
.sp-body[hidden] { display: none; }
.sp-body { padding: .45rem 0 .1rem 1.5rem; }

/* Шкала оценки. Пять делений в столбик, а не пять кнопок в строку: на
   телефоне подписи «на жарёху» и «единично» в строку не влезают, а без
   подписей шкала превращается в звёздочки, по которым потом не понять,
   что человек имел в виду. */
.grade { display: grid; gap: .25rem; }
.grade button {
  display: flex; align-items: baseline; gap: .5rem; text-align: left;
  padding: .4rem .55rem; border: 1px solid var(--line); border-radius: 8px;
  background: var(--card); color: var(--ink2); cursor: pointer; font-size: .88rem;
}
.grade button .g-name { font-weight: 600; color: var(--ink); min-width: 5.6rem; }
.grade button .g-hint { color: var(--muted); font-size: .8rem; }
.grade button.sel { border-color: var(--accent); background: var(--accent); color: #fff; }
.grade button.sel .g-name, .grade button.sel .g-hint { color: #fff; }
/* Ноль — не провал, а данные: красим его не «плохим» красным, а нейтрально,
   иначе люди перестанут его ставить, и проверять модель станет нечем. */
.grade button[data-g="0"].sel { border-color: var(--ink2); background: var(--ink2); }
.sp-count { display: flex; align-items: center; gap: .4rem; margin-top: .4rem;
            font-size: .82rem; color: var(--muted); }
.sp-count input { width: 5.5rem; margin: 0; }

/* Булавка выбранного места. Кольцо, а не капля: капля указывает остриём
   ниже себя, и на телефоне непонятно, отмечена точка под пальцем или
   на сантиметр ниже. Кольцо centred на iconAnchor и не врёт. */
.mark-pin i {
  display: block; width: 22px; height: 22px; border-radius: 50%;
  border: 3px solid var(--accent); background: rgba(37, 106, 191, .3);
  box-shadow: 0 0 0 2px var(--card), 0 1px 4px rgba(0, 0, 0, .4);
  cursor: grab;
}

/* Свои отметки — единственный слой с настоящими данными, а не с гипотезой
   модели, поэтому единственный в цвете самого приложения. */
.mine-note { border-left: 3px solid var(--accent); padding-left: .5rem; }

/* Отметки выезда: квадрат против кругов модели. Форма несёт смысл «это
   измерено», цвет занят оценкой, поэтому различать нечем, кроме формы. */
.my-mark i { display: block; border: 2px solid #fff; border-radius: 2px;
             box-shadow: 0 1px 4px rgba(0, 0, 0, .45); }

/* --- «Ещё мои проекты» ---------------------------------------------------
 * Блок должен быть заметен, но не спорить с прогнозом: он стоит на главном
 * экране, а не в подвале, потому что до подвала (третья вкладка) люди по
 * логам не доходят. Поэтому рамка сверху вместо карточки — визуально это
 * конец содержимого, а не ещё один равноправный блок данных.
 */
.more { margin-top: 1.6rem; border-top: 1px solid var(--line); padding-top: .8rem; }
.more-title { font-size: .95rem; color: var(--ink2); margin: 0 0 .5rem; }
.more-item {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--line); border-radius: 10px;
  padding: .55rem .7rem; margin-bottom: .45rem; background: var(--card);
}
.more-item b { color: var(--accent-ink); }
.more-item span { display: block; font-size: .85rem; color: var(--ink2); margin-top: .1rem; }
.more-item:hover { border-color: var(--accent); }
.more-ask { font-size: .88rem; color: var(--ink2); margin: .6rem 0 0; }
.more-ask a { color: var(--accent-ink); }
