/* ═══════════════════════════════════════════════════════════
   ЭПОХА · map.css — вид карты (0.66.0)
   Выделен из game.css: у карты появились состояния (достижимая / выбранная /
   вне досягаемости), постоянный маркер игрока с тенью и слой эффектов —
   в двадцати строках общего файла это уже не жило.

   0.99.0 — ГЕКСЫ. Клетка стала шестиугольной (pointy-top, odd-r) и получила
   собственные тайлы: сетка больше не CSS-grid из квадратов, а абсолютно
   позиционированные клетки, координаты которых считает map.js через hex.js.

   Слои сцены (снизу вверх):
     .map-bg      — пергамент (общий фон под всей картой)
     .map-grid    — клетки: тайлы биома/реки/дороги/постройки + туман
     .map-overlay — SVG: только подписи поселений
     .map-fx      — следы, волны, вспышки тумана (pointer-events:none)
     .map-actors  — маркер игрока (pointer-events:none)
   Все слои получают ОДИН transform (пан+зум) из map.js. Плавность камеры —
   класс .is-gliding на сцене (снимается при ручном пане/зуме).
   ═══════════════════════════════════════════════════════════ */

.map-viewport{flex:1; min-height:0; display:flex; align-items:center; justify-content:center; margin-top:2px;}
.map-stage{
  height:100%; aspect-ratio:1/1; max-width:100%; margin:0 auto;
  position:relative; border:1px solid var(--edge-glass); border-radius:var(--r-sm);
  background:#0b0a08; overflow:hidden; box-shadow:var(--shadow); cursor:grab; touch-action:none;
}
.map-stage.is-panning{cursor:grabbing;}

.map-bg{position:absolute; left:0; top:0; background:url('img/map/parchment.jpg') 0 0/620px repeat;
  transform-origin:0 0; pointer-events:none;}
.map-grid{position:absolute; left:0; top:0; transform-origin:0 0;}
.map-overlay{position:absolute; left:0; top:0; pointer-events:none; transform-origin:0 0;
  width:var(--field-w); height:var(--field-h); overflow:visible;}
.map-fx{position:absolute; inset:0; pointer-events:none; transform-origin:0 0;}
.map-actors{position:absolute; inset:0; pointer-events:none; transform-origin:0 0;}

/* Плавный доезд камеры после шага. Клетки и содержимое не участвуют —
   едут только слои целиком, это дёшево (композитор). */
.map-stage.is-gliding .map-bg,
.map-stage.is-gliding .map-grid,
.map-stage.is-gliding .map-overlay,
.map-stage.is-gliding .map-fx,
.map-stage.is-gliding .map-actors{transition:transform .4s cubic-bezier(.25,.8,.35,1);}

/* ── ГЕКСОВАЯ КЛЕТКА (0.99.0) ──────────────────────────────
   Позиция и размер приходят инлайном из map.js: раскладка odd-r не
   выражается средствами CSS — у нечётных строк сдвиг на полклетки, а шаг по
   вертикали равен 3/4 высоты, иначе ряды не входят друг в друга зубцами.

   Слои внутри клетки — отдельные <img>: тайлы НАКЛАДЫВАЮТСЯ (река на сушу,
   дорога поверх, постройка сверху), и менять их надо независимо. */
.map-cell{position:absolute; outline:none; cursor:pointer;
  /* 0.99.0: двойной клик по клетке — игровое действие (шаг). Без запрета
     браузер понимает его как выделение и показывает свою панель «дополнительные
     действия» поверх карты. Раньше клетка была пустым div-ом и выделять в ней
     было нечего; с тайлами внутри появились картинки. */
  user-select:none; -webkit-user-select:none; -webkit-touch-callout:none;}
.map-cell.fog-hidden{cursor:default;}
.map-cell > img{position:absolute; inset:0; width:100%; height:100%;
  display:block; pointer-events:none; user-select:none; -webkit-user-drag:none;}
.map-cell > img[hidden]{display:none;}
.map-cell .c-base{z-index:1}
.map-cell .c-riv{z-index:2}
.map-cell .c-road,.map-cell .c-road2{z-index:3}
.map-cell .c-poi{z-index:4}

/* Туман. Клип гексом — иначе плёнка легла бы квадратом и торчала за клетку.
   НЕОТКРЫТАЯ область раздута на 3%: клипы соседей стыкуются встык, между
   ними остаётся волосяной шов, сквозь который просвечивает пергамент, и на
   тёмном фоне это читается как сетка. Перекрытие плоской заливки не видно. */
/* Туман — фон САМОЙ клетки, а не отдельный элемент внутри: у неразведанной
   клетки потомков теперь нет вовсе (см. ленивое создание слоёв в map.js).
   Неоткрытая раздута на 3%: клипы соседей стыкуются встык, между ними
   остаётся волосяной шов, сквозь который просвечивает пергамент, и на тёмном
   это читается сеткой. Перекрытие плоской заливки не видно. */
.map-cell::before{content:''; position:absolute; inset:0; z-index:5;
  clip-path:polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
  pointer-events:none; display:none;}
.map-cell.fog-seen::before{display:block; background:rgba(38,28,16,.46);}
.map-cell.fog-hidden::before{display:block; background:#20180f; transform:scale(1.03);}

/* Обводка — ТОЛЬКО под курсором и на выбранной, одинаковая (решение автора).
   Заливки нет: цветная пелена поверх рисованной карты глушила бы тушь. */
.map-cell::after{content:""; position:absolute; inset:0; z-index:6; opacity:0;
  clip-path:polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%); pointer-events:none;
  background:
    linear-gradient(#3a2c18,#3a2c18) padding-box;
  -webkit-mask:
    linear-gradient(#000,#000) content-box,
    linear-gradient(#000,#000);
  -webkit-mask-composite:xor; mask-composite:exclude; padding:2px;}
.map-cell:not(.fog-hidden):hover::after,
.map-cell.is-selected::after{opacity:1;}

/* Подписи поселений — тем же шрифтом, что заголовки. Обводка светом, чтобы
   имя читалось поверх штриховки. */
.settle-label{font:600 13px/1 'Alegreya SC',Georgia,serif; fill:#2b2118;
  paint-order:stroke; stroke:#efe6cd; stroke-width:4px; stroke-linejoin:round;}


/* 0.69.0: постоянная подсветка бюджета шагов (сетка золотых квадратов
   вокруг фишки) убрана по просьбе автора — карта чище. Класс is-near
   остаётся ТОЛЬКО ради ховера соседней клетки ниже. */

/* ── Выбор клетки (0.99.0) ─────────────────────────────────
   Уголки-прицел сняты. Они рисовались четырьмя брусками по углам
   ПРЯМОУГОЛЬНИКА клетки и на шестиугольнике повисали в пустоте: два верхних
   угла у гекса вообще не существуют, там скошенные грани. Осталось то, что
   у формы есть, — её собственный контур.

   Обводка одна и та же под курсором и на выбранной (решение автора). Заливки
   нет: цветная пелена поверх рисованной туши глушила бы рисунок. */
.map-cell::after{
  content:''; position:absolute; inset:0; z-index:6; opacity:0;
  pointer-events:none; transition:opacity .12s ease;
  background:
    linear-gradient(transparent, transparent) padding-box,
    var(--sel-ink, #3a2c18) border-box;
  clip-path:polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}
.map-cell:not(.fog-hidden):hover::after,
.map-cell.is-selected::after{opacity:1;}
/* Контур делаем «дыркой»: заливаем гекс краской и вырезаем из него гекс
   поменьше. Обводить clip-path обычным border нельзя — border рисуется до
   обрезки и срезается вместе с углами. */
.map-cell::after{
  -webkit-mask:
    linear-gradient(#000,#000) content-box,
    linear-gradient(#000,#000);
  -webkit-mask-composite:xor;
          mask-composite:exclude;
  padding:2px; box-sizing:border-box;
  background:var(--sel-ink, #3a2c18);
}
.map-cell.is-selected::after{--sel-ink:#8c3b2a;}
@keyframes selIn     {from{opacity:0; transform:scale(.82)} to{opacity:1; transform:scale(1)}}

/* ── Маркер игрока: «фишка» (0.68.0) ────────────────────────
   Вид утверждён автором на мокапах token-mockup-v2..v4, вариант Б:
   ПЛОСКИЙ ВДАВЛЕННЫЙ тёмный диск (рецепт боевой кнопки «Бросок»),
   золотое кольцо с тёмным кантом, иконка ВО ВЕСЬ внутренний круг,
   снизу — сплошной пластиковый торец (толщина фишки).
   ТВЁРДОЕ ТЕЛО: тело фишки не деформируется НИКОГДА (никаких scale в его
   анимациях — «желе» запрещено решением автора); мнётся только тень на
   земле. Постоянный элемент размером в клетку; позиция — translate в
   0.99.0: --mx/--my приходят в ПИКСЕЛЯХ поля (центр гекса), потому что в
   odd-r координата клетки не выражается долей от ширины карты — у нечётных
   строк сдвиг на полклетки. Считает map.js через hex.cellPos. */
.map-marker{
  position:absolute; left:0; top:0;
  /* 0.99.0: размер — доля ГЕКСА, а не сам гекс. При переводе позиций на
     пиксели я заменил размер разом во всех правилах и раздул фишку до
     размера клетки: на карте она стала чёрной кляксой в полклетки. */
  width:calc(var(--hex-w, 92px) * .34); height:calc(var(--hex-w, 92px) * .34);
  left:var(--mx, 0); top:var(--my, 0); transform:translate(-50%, -50%);
  transition:transform .5s cubic-bezier(.4,.1,.4,1); /* = STEP_MS в map.js */
}
.map-marker.no-anim{transition:none;}

/* Тень на земле: единственное, чему можно мяться. В прыжке сжимается и
   бледнеет (контакт потерян), при отскоке чуть поджимается. */
.mk-shadow{
  position:absolute; left:12%; right:12%; top:64%; bottom:0;
  border-radius:50%; background:radial-gradient(ellipse at center, rgba(0,0,0,.6), rgba(0,0,0,0) 70%);
}
.map-marker.is-stepping .mk-shadow{animation:mkShadowHop .5s ease-in-out;}

/* Тело фишки (вариант Б): вдавленный тёмный диск, золотое кольцо в тёмном
   канте, торец-ребро (резкая ступень 0 .1em 0 — толщина пластика), мягкая
   отброшенная тень и слабое тёплое свечение. Дыхание — только свечением. */
.mk-body{
  position:absolute; inset:7%; border-radius:50%;
  background:radial-gradient(circle at 50% 40%, #38322a 0%, #1e1a14 62%, #131009 100%);
  box-shadow:0 0 0 .055em #c99c3e, 0 0 0 .085em var(--rim),
             inset 0 .13em .26em rgba(0,0,0,.8), inset 0 -.1em .18em rgba(226,183,94,.1),
             0 .1em 0 #060607, 0 .18em .3em rgba(0,0,0,.55), 0 0 .35em rgba(255,225,155,.15);
  animation:mkBreath 3.2s ease-in-out infinite;
}
.map-marker.is-stepping .mk-body{animation:mkHop .5s cubic-bezier(.35,.4,.4,1);}

/* Иконка во весь внутренний круг (решение автора). Пока PNG нет — тёмный
   диск; когда появится, достаточно задать здесь background-image (или
   переменную --mk-icon снаружи) — код не трогается. Вдавленность лежит
   тенью ПОВЕРХ картинки; 0.68.0: ослаблена вдвое (0.75 → 0.38) — в полной
   темноте иконка не читалась (правка автора). */
.mk-face{
  position:absolute; inset:6%; border-radius:50%; overflow:hidden;
  background:var(--mk-icon, none) center/cover no-repeat #17140e;
}
.mk-face::after{
  content:''; position:absolute; inset:0; border-radius:50%;
  box-shadow:inset 0 .13em .24em rgba(0,0,0,.38), inset 0 -.06em .12em rgba(255,255,255,.06);
}

/* Прыжок твёрдого тела: подъём → полёт (едет сам .map-marker по transition
   transform) → касание → короткий ЖЁСТКИЙ отскок целиком → покой. */
@keyframes mkHop{
  0%  {transform:translateY(0);}
  42% {transform:translateY(-58%);}
  72% {transform:translateY(0);}
  84% {transform:translateY(-9%);}
  100%{transform:translateY(0);}
}
@keyframes mkShadowHop{
  0%  {transform:scale(1);       opacity:1;}
  42% {transform:scale(.55,.5);  opacity:.4;}
  72% {transform:scale(1);       opacity:1;}
  84% {transform:scale(.88,.82); opacity:.75;}
  100%{transform:scale(1);       opacity:1;}
}
@keyframes mkBreath{
  0%,100%{box-shadow:0 0 0 .055em #c99c3e, 0 0 0 .085em var(--rim),
             inset 0 .13em .26em rgba(0,0,0,.8), inset 0 -.1em .18em rgba(226,183,94,.1),
             0 .1em 0 #060607, 0 .18em .3em rgba(0,0,0,.55), 0 0 .3em rgba(255,225,155,.12);}
  50%    {box-shadow:0 0 0 .055em #c99c3e, 0 0 0 .085em var(--rim),
             inset 0 .13em .26em rgba(0,0,0,.8), inset 0 -.1em .18em rgba(226,183,94,.1),
             0 .1em 0 #060607, 0 .18em .3em rgba(0,0,0,.55), 0 0 .5em rgba(255,225,155,.24);}
}

/* ── Эффекты (спавнятся map-fx.js, сами себя убирают) ───────
   Позиция — та же схема, что у маркера: размер = клетка, translate в
   0.99.0: --fx-x/--fx-y приходят в ПИКСЕЛЯХ поля (центр гекса). В odd-r доля
   от ширины карты не работает — у нечётных строк сдвиг на полклетки. */
.fx-footprint, .fx-ripple, .fx-reveal{
  position:absolute; left:0; top:0;
  width:var(--hex-w,92px); height:calc(var(--hex-w,92px) * 1.142857);
  left:var(--fx-x, 0); top:var(--fx-y, 0); transform:translate(-50%, -50%);
  pointer-events:none;
}
/* След на покинутой клетке: тусклый отпечаток, гаснет. */
.fx-footprint::after{
  content:''; position:absolute; inset:26%;
  border-radius:50%; background:rgba(244,236,220,.28);
  animation:fxFootprint .6s ease-out forwards;
}
@keyframes fxFootprint{
  from{opacity:.8; transform:scale(1);}
  to  {opacity:0;  transform:scale(.6);}
}
/* Волна приземления: расходящееся кольцо. */
.fx-ripple::after{
  content:''; position:absolute; inset:8%;
  border-radius:50%; border:2px solid rgba(226,183,94,.85);
  animation:fxRipple .5s ease-out forwards;
}
@keyframes fxRipple{
  from{opacity:.9; transform:scale(.35);}
  to  {opacity:0;  transform:scale(1.5);}
}
/* Вспышка проявления из тумана: золотистое свечение, затухает. */
.fx-reveal{
  border-radius:20%;
  background:radial-gradient(circle at center, rgba(240,215,150,.55), rgba(240,215,150,0) 72%);
  animation:fxReveal .85s ease-out forwards;
}
@keyframes fxReveal{
  0%  {opacity:0;  left:var(--fx-x,0); top:var(--fx-y,0); transform:translate(-50%,-50%) scale(.6);}
  25% {opacity:1;}
  100%{opacity:0;  left:var(--fx-x,0); top:var(--fx-y,0); transform:translate(-50%,-50%) scale(1.15);}
}

/* ── Подпись под картой ──────────────────────────────────── */
.map-caption{margin-top:12px; height:38px; font-family:var(--f-data); font-size:.83rem; color:var(--muted); text-align:center; display:flex; align-items:center; justify-content:center; gap:10px; flex-wrap:wrap; overflow:hidden;}
.map-caption b{color:var(--ink-soft);}
.map-caption .sw{width:12px; height:12px; border-radius:4px; border:1px solid rgba(0,0,0,.4);}
.map-caption .cap-hint{color:var(--gold);}
.map-err{color:var(--err); font-family:var(--f-data); text-align:center; margin-top:8px;}

/* Пониженная анимация по системной настройке: движение мгновенно, эффекты
   не крутятся. Игровая логика не зависит от анимаций — только вид. */
@media (prefers-reduced-motion: reduce){
  .map-marker, .mk-body, .mk-shadow{transition:none; animation:none;}
  .mk-face::after{box-shadow:none;}
  .map-stage.is-gliding .map-bg,
  .map-stage.is-gliding .map-grid, .map-stage.is-gliding .map-overlay,
  .map-stage.is-gliding .map-fx, .map-stage.is-gliding .map-actors{transition:none;}
  .fx-footprint::after, .fx-ripple::after, .fx-reveal{animation-duration:.01s;}
  .map-cell.is-selected::before, .map-cell.is-selected::after{animation:none;}
}

@media (max-width:900px){
  .map-stage{height:auto; width:min(100%, calc(100vw - 84px));}
}

/* ── Фишки отряда (0.89.0) ─────────────────────────────────
   Сопартийцы видны всегда: маленькая зелёная метка (цвет канала группы),
   позиционируется тем же приёмом --mx/--my (пиксели поля), что своя фишка. Сдвиг товарища
   едет transition'ом — его шаги видно живьём. */
.map-mate{
  /* КУРСОР СКВОЗЬ МЕТКУ (0.97.0). Метка товарища — кружок размером В ЦЕЛУЮ
     КЛЕТКУ, лежащий ПОВЕРХ карты (z-index 2). С pointer-events:auto она
     перехватывала двойной клик: обработчик искал под курсором клетку карты,
     метка клеткой не является — и обработчик молча выходил. Игрок видел, что
     шаг на клетку с товарищем «просто не выполняется», без единой ошибки.
     Подпись (title) работает и без перехвата: браузер показывает её по
     наведению независимо от pointer-events у элемента с текстом. */
  position:absolute; left:0; top:0; pointer-events:none;
  /* 0.99.0: размер — доля ГЕКСА, а не сам гекс. При переводе позиций на
     пиксели я заменил размер разом во всех правилах и раздул фишку до
     размера клетки: на карте она стала чёрной кляксой в полклетки. */
  width:calc(var(--hex-w, 92px) * .34); height:calc(var(--hex-w, 92px) * .34);
  left:var(--mx, 0); top:var(--my, 0); transform:translate(-50%, -50%);
  transition:transform .5s cubic-bezier(.4,.1,.4,1);
  z-index:2;
}
.mate-dot{
  position:absolute; inset:26%;
  border-radius:50%;
  background:radial-gradient(circle at 50% 38%, #5fae62 0%, #2e5c33 68%, #1c3a21 100%);
  box-shadow:0 0 0 .05em #83c07e, 0 .08em .18em rgba(0,0,0,.55), 0 0 .3em rgba(131,192,126,.25);
}
@media (prefers-reduced-motion: reduce){ .map-mate{transition:none;} }
