/* Рама стола и каменные плиты меню.

   Подключается последней: здесь оформление, которое должно побеждать всё
   предыдущее. Заказчик показал два образца — стол как в Genshin TCG (сукно в
   золотой резной раме, с узором и гербом по центру) и меню как в наборе
   каменных вывесок, — и просил такого же ощущения «дорогой настолки».

   Куски рамы (`art/kit/corner.webp`, `edge.webp`, `edge_v.webp`) собирает
   `scripts/boardkit.mjs`. Рама именно из кусков, а не одной картинкой: стол
   на телефоне вытянут вверх, на десктопе вширь, и цельная рамка растянулась
   бы вместе с орнаментом. */

:root {
  /* Сукно. Янтарь — прежний выбор заказчика (зелёное он забраковал), но
     теперь это одна переменная: захочет бирюзу как в образце — меняется
     здесь и нигде больше. */
  --felt-1: #b08238;
  --felt-2: #7d5a22;
  --felt-3: #4a3413;
  --gold-line: rgba(255, 226, 160, 0.55);
}

/* ---------------- стол боя ---------------- */

body.in-battle .table-area {
  position: relative;
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  margin: 2px 2px 4px;
  border-radius: 16px;
  /* Слои сукна: решётка сверху, ткань, свет из центра, цвет. Решётка —
     data-URI, а не картинка: на любом размере она остаётся резкой и не
     стоит ни одного запроса. */
  background:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='44' height='44'><g fill='none' stroke='rgba(255,238,200,0.20)' stroke-width='1.4'><path d='M22 0 L44 22 L22 44 L0 22 Z'/></g></svg>") 0 0 / 44px 44px,
    url('art/kit/felt.webp') center / 300px auto repeat,
    radial-gradient(75% 55% at 50% 50%, rgba(255, 226, 170, 0.22), transparent 70%),
    linear-gradient(180deg, var(--felt-1), var(--felt-2) 55%, var(--felt-3));
  /* Ткань — серое зерно, и работает она смешиванием: цветной текстурой сукно
     превращалось в коричневые подушки. */
  background-blend-mode: normal, soft-light, screen, normal;
  box-shadow:
    inset 0 0 0 2px rgba(0, 0, 0, 0.45),
    inset 0 0 42px rgba(28, 14, 2, 0.75),
    0 10px 26px rgba(0, 0, 0, 0.6);
  overflow: hidden;
}

/* Половины больше не красятся своими подложками: сукно едино, а чья это
   сторона, видно по частицам стихии и по линии фронта. */
body.in-battle .table-area .board {
  background: none;
  box-shadow: none;
}

/* Клеймо по центру сукна. Рисунком, а не иероглифом: шрифта с кандзи на
   устройстве может не быть, и вместо герба посреди стола появлялся квадрат. */
body.in-battle .table-area::before {
  content: '';
  position: absolute; left: 50%; top: 50%;
  width: clamp(120px, 26vh, 240px);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'><g fill='none' stroke='rgba(255,240,205,0.5)' stroke-width='2'><circle cx='100' cy='100' r='86'/><circle cx='100' cy='100' r='62'/><path d='M100 14 L134 100 L100 186 L66 100 Z'/><path d='M14 100 L100 66 L186 100 L100 134 Z'/><circle cx='100' cy='100' r='16'/></g></svg>") center / contain no-repeat;
  opacity: 0.22;
  pointer-events: none;
  z-index: 0;
}

/* Линия фронта поверх сукна: тонкая золотая нить с ромбом посередине. */
body.in-battle .table-area .table-line {
  z-index: 1;
  background:
    linear-gradient(90deg, transparent, var(--gold-line) 18%, rgba(255, 244, 214, 0.85) 50%, var(--gold-line) 82%, transparent) center / 100% 2px no-repeat;
}
body.in-battle .table-area .table-line::after {
  content: '';
  position: absolute; left: 50%; top: 50%;
  width: 12px; height: 12px;
  transform: translate(-50%, -50%) rotate(45deg);
  background: linear-gradient(135deg, #ffeec0, #b3862f);
  box-shadow: 0 0 10px rgba(255, 214, 140, 0.7);
  border-radius: 2px;
}

/* ---------------- рама ---------------- */

.table-frame {
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 3;
}
.table-frame i {
  position: absolute;
  display: block;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.55));
}

/* Кромки тайлятся вдоль сторон, углы садятся поверх их стыков. */
.tf-edge { --w: clamp(16px, 3vh, 26px); }
.tf-top, .tf-bottom {
  left: 0; right: 0; height: var(--w);
  background: url('art/kit/edge.webp') 0 0 / auto 100% repeat-x;
}
.tf-top { top: 0; }
.tf-bottom { bottom: 0; transform: scaleY(-1); }
.tf-left, .tf-right {
  top: 0; bottom: 0; width: var(--w);
  background: url('art/kit/edge_v.webp') 0 0 / 100% auto repeat-y;
}
.tf-left { left: 0; }
.tf-right { right: 0; transform: scaleX(-1); }

.tf-corner {
  width: clamp(34px, 6vh, 62px);
  aspect-ratio: 1;
  background: url('art/kit/corner.webp') center / 100% 100% no-repeat;
}
.tf-tl { top: 0; left: 0; }
.tf-tr { top: 0; right: 0; transform: scaleX(-1); }
.tf-bl { bottom: 0; left: 0; transform: scaleY(-1); }
.tf-br { bottom: 0; right: 0; transform: scale(-1); }

/* На низком экране рама съедает высоту стола — оставляем только углы. */
@media (max-height: 620px) {
  .tf-edge { display: none; }
}

/* ---------------- каменные плиты меню ----------------

   Образец заказчика — вывески из камня с толстой фаской и вырубленными
   уголками. Берём оттуда объём и вырубку, но не цвет: игра тёмная, и
   лиловый мультяшный камень в ней смотрелся бы чужим. */

.menu-tile,
.char-panel,
.panel,
.shop-item,
.profile-card {
  position: relative;
  /* Срезанные углы: ровный прямоугольник и есть та самая «дешёвая» плитка,
     на которую жаловался заказчик. */
  clip-path: polygon(
    14px 0, calc(100% - 14px) 0, 100% 14px,
    100% calc(100% - 14px), calc(100% - 14px) 100%,
    14px 100%, 0 calc(100% - 14px), 0 14px);
}

.menu-tile {
  background:
    linear-gradient(180deg, rgba(255, 236, 200, 0.09), transparent 42%),
    url('art/kit/stone.webp') center / 320px auto repeat,
    linear-gradient(180deg, #26242e, #131218);
  background-blend-mode: normal, soft-light, normal;
  border: 0;
  box-shadow:
    inset 0 2px 0 rgba(255, 240, 210, 0.22),
    inset 0 -3px 0 rgba(0, 0, 0, 0.55),
    inset 0 0 0 1px rgba(0, 0, 0, 0.6),
    0 6px 0 -2px rgba(0, 0, 0, 0.55),
    0 14px 24px rgba(0, 0, 0, 0.5);
}

/* Арт режима убирается внутрь плиты: по краю остаётся полоса камня, и
   картинка выглядит вставленной в вывеску, а не наклеенной на неё. */
.menu-tile .tile-art,
.menu-tile .tile-veil,
.menu-tile .row-sheen {
  inset: 6px;
  border-radius: 6px;
}

/* Золотой кант внутри плиты: он и делает её «вывеской», а не карточкой. */
.menu-tile::after {
  content: '';
  position: absolute; inset: 5px;
  border: 1px solid rgba(226, 186, 110, 0.35);
  border-radius: 4px;
  pointer-events: none;
}

.menu-tile:active {
  transform: translateY(2px);
  box-shadow:
    inset 0 2px 0 rgba(255, 240, 210, 0.16),
    inset 0 -2px 0 rgba(0, 0, 0, 0.55),
    inset 0 0 0 1px rgba(0, 0, 0, 0.6),
    0 3px 0 -2px rgba(0, 0, 0, 0.55),
    0 8px 16px rgba(0, 0, 0, 0.45);
}

/* Заголовок режима — резьба по камню: светлая кромка сверху, тень снизу. */
.menu-tile .row-title {
  color: #f6e6c4;
  text-shadow:
    0 1px 0 rgba(0, 0, 0, 0.85),
    0 -1px 0 rgba(255, 236, 200, 0.16);
  letter-spacing: 0.01em;
}

/* Значок режима — вставка в металлической оправе. */
.menu-tile .icon-tile {
  border-radius: 8px;
  box-shadow:
    inset 0 1px 0 rgba(255, 240, 210, 0.3),
    inset 0 -2px 0 rgba(0, 0, 0, 0.5),
    0 0 0 1px rgba(226, 186, 110, 0.35);
}

/* ---------------- кнопки-плашки ---------------- */

.btn-primary,
.btn-turn,
.menu-tile .row-cta {
  position: relative;
  border: 0;
  /* Скошенные торцы — как на вывеске из образца. */
  clip-path: polygon(
    12px 0, calc(100% - 12px) 0, 100% 50%,
    calc(100% - 12px) 100%, 12px 100%, 0 50%);
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--accent, #ff6a3d) 88%, #fff) 0%,
      var(--accent, #ff6a3d) 46%,
      color-mix(in srgb, var(--accent, #ff6a3d) 72%, #000) 100%);
  color: #fff;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.35),
    inset 0 -3px 0 rgba(0, 0, 0, 0.35),
    0 6px 16px -4px color-mix(in srgb, var(--accent, #ff6a3d) 70%, transparent);
}
.btn-primary:active,
.btn-turn:active { transform: translateY(2px); }

/* ---------------- бережно ---------------- */

@media (prefers-reduced-motion: reduce) {
  .menu-tile:active, .btn-primary:active, .btn-turn:active { transform: none; }
}

/* ---------------- шапка и нижняя полка ----------------

   Верхняя плашка с валютами и нижняя полка — из того же камня, что и плиты:
   иначе резные вывески висят посреди «системного» интерфейса и спорят с ним. */

.topbar-plate,
.bottom-bar {
  background:
    linear-gradient(180deg, rgba(255, 236, 200, 0.07), transparent 46%),
    url('art/kit/stone.webp') center / 320px auto repeat,
    linear-gradient(180deg, #24222b, #131218);
  background-blend-mode: normal, soft-light, normal;
  border: 0;
  box-shadow:
    inset 0 1px 0 rgba(255, 240, 210, 0.2),
    inset 0 -2px 0 rgba(0, 0, 0, 0.5),
    inset 0 0 0 1px rgba(0, 0, 0, 0.55),
    0 8px 18px rgba(0, 0, 0, 0.45);
}

/* Кристаллы и пыль — вставки в металле, а не серые капсулы. */
.wallet-chip,
.currency-chip {
  box-shadow:
    inset 0 1px 0 rgba(255, 240, 210, 0.22),
    inset 0 -2px 0 rgba(0, 0, 0, 0.45),
    0 0 0 1px rgba(226, 186, 110, 0.3);
}

/* ---------------- панель госпожи ----------------

   Главная вывеска экрана. Камень здесь только по кромке — фаской и тенями,
   без заливки: заливка закрывала сцену стихии (`art/banner_*.webp` из
   styles-atmo.css), портрет упирался в тёмный прямоугольник, а справа
   оставалась пустота.

   По той же причине у панели нет внутреннего отступа, а у арта — обрезки:
   портрет обязан растворяться маской в баннере, и любая рамка вокруг него
   возвращает ту самую «картинка слева, стекло справа». */

.char-panel {
  box-shadow:
    inset 0 2px 0 rgba(255, 240, 210, 0.18),
    inset 0 -3px 0 rgba(0, 0, 0, 0.5),
    inset 0 0 0 1px rgba(0, 0, 0, 0.6),
    0 8px 0 -3px rgba(0, 0, 0, 0.5),
    0 18px 30px rgba(0, 0, 0, 0.5);
}

/* Золотой кант по кромке — поверх сцены, но под текстом. */
.char-panel > .panel-frame::before {
  content: '';
  position: absolute; inset: 6px;
  border: 1px solid rgba(226, 186, 110, 0.32);
  border-radius: 6px;
}

.panel-frame {
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 4;
}
.panel-frame .tf-corner {
  position: absolute;
  display: block;
  width: clamp(26px, 6vw, 40px);
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.75));
}

/* Имя — гравировка золотом. Плоский белый текст поверх арта выглядел
   подписью к картинке, а не именем госпожи. */
.char-name {
  background: linear-gradient(180deg, #fffaf0 0%, #f3d79a 52%, #c99748 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: none;
  filter:
    drop-shadow(0 2px 0 rgba(0, 0, 0, 0.72))
    drop-shadow(0 0 22px rgba(255, 190, 110, 0.35));
  letter-spacing: -0.01em;
}

/* Тонкая нить с ромбом между званием и цитатой: она отделяет «кто это» от
   «что о ней говорят» и держит колонку текста вместе. */
.char-title { position: relative; padding-bottom: 10px; }
.char-title::after {
  content: '';
  position: absolute; left: 0; bottom: 2px;
  width: min(220px, 70%); height: 1px;
  background:
    linear-gradient(90deg, rgba(226, 186, 110, 0.75), rgba(226, 186, 110, 0.05)),
    none;
}

.char-lore { text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8); }

/* Сила героя — медальон в металлической оправе, а не серая капсула. */
.ability-plate {
  border: 0;
  border-radius: 12px;
  background:
    linear-gradient(180deg, rgba(24, 20, 28, 0.92), rgba(10, 9, 12, 0.94));
  box-shadow:
    inset 0 1px 0 rgba(255, 240, 210, 0.22),
    inset 0 -2px 0 rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(226, 186, 110, 0.42),
    0 10px 20px -12px rgba(0, 0, 0, 0.9);
}
.ability-icon {
  border-radius: 50%;
  box-shadow:
    inset 0 1px 0 rgba(255, 240, 210, 0.3),
    inset 0 -2px 0 rgba(0, 0, 0, 0.5),
    0 0 0 1px rgba(226, 186, 110, 0.5);
}
.ability-cost {
  border: 0;
  border-radius: 10px;
  background:
    radial-gradient(70% 70% at 35% 25%, #8fd4ff, transparent 60%),
    linear-gradient(180deg, #3aa0ff, #0a5fc0);
  color: #fff;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -2px 0 rgba(0, 0, 0, 0.3),
    0 0 0 1px rgba(226, 186, 110, 0.35);
}
.ability-cost i { color: rgba(255, 255, 255, 0.75); }

/* «Сменить госпожу» остаётся служебной кнопкой, но из того же металла. */
.char-info .fbtn-wood {
  background: rgba(10, 9, 12, 0.55);
  border: 0;
  box-shadow:
    inset 0 1px 0 rgba(255, 240, 210, 0.16),
    0 0 0 1px rgba(226, 186, 110, 0.28);
  color: rgba(238, 230, 214, 0.9);
}

/* ---------------- меню: баннер, сетка, полка ----------------

   Экран собран по важности, а не одинаковыми полосками: баннер кампании
   («во что играть прямо сейчас»), сетка из четырёх режимов и узкая строка
   коллекции. Раньше все шесть строк выглядели одинаково, и главное действие
   терялось среди прочих. */

.menu-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ---- баннер кампании ---- */

.htile {
  position: relative;
  display: block;
  width: 100%;
  min-height: clamp(132px, 22vh, 168px);
  padding: 0;
  overflow: hidden;
  text-align: left;
  cursor: pointer;
}
.htile-art {
  position: absolute; inset: 6px;
  border-radius: 8px;
  background-position: center 24%;
  background-size: cover;
  filter: saturate(1.15) contrast(1.05);
}
/* Вуаль слева: текст ложится на тёмное, портрет соперницы остаётся видимым. */
.htile-veil {
  position: absolute; inset: 6px;
  border-radius: 8px;
  background:
    linear-gradient(96deg, rgba(8, 7, 10, 0.95) 30%, rgba(8, 7, 10, 0.72) 52%, rgba(8, 7, 10, 0.1) 78%),
    linear-gradient(0deg, rgba(8, 7, 10, 0.75), transparent 55%);
}
.htile-body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 16px 16px 14px 18px;
  max-width: 62%;
}
.htile-kicker {
  font-size: var(--fs-11, 11px);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(230, 196, 132, 0.85);
}
.htile-title {
  font-size: clamp(20px, 5.4vw, 27px);
  font-weight: 800;
  line-height: 1.05;
  color: #f7ecd6;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.75), 0 0 18px rgba(255, 200, 130, 0.25);
}
.htile-sub {
  font-size: var(--fs-13, 13px);
  color: rgba(226, 226, 232, 0.78);
}
/* Полоса прогресса кампании: строкой под подзаголовком, а не столбиком
   справа (в строке-плитке она стояла у правого края). */
.htile .row-progress {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}
.htile .progress-count { color: rgba(240, 226, 200, 0.9); }

/* Кнопка прижата к нижнему краю плиты: у главного действия должно быть
   постоянное место, а не «где закончился текст». */
.htile-cta {
  position: absolute;
  right: 16px; bottom: 14px;
  display: inline-flex; align-items: center;
  height: 40px;
  padding: 0 24px;
  font-size: var(--fs-15, 15px);
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  clip-path: polygon(12px 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 12px 100%, 0 50%);
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--accent, #ff6a3d) 88%, #fff),
      var(--accent, #ff6a3d) 46%,
      color-mix(in srgb, var(--accent, #ff6a3d) 70%, #000));
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.35),
    inset 0 -3px 0 rgba(0, 0, 0, 0.35),
    0 8px 18px -6px color-mix(in srgb, var(--accent, #ff6a3d) 75%, transparent);
}
.htile:active .htile-cta { transform: translateY(2px); }

/* ---- сетка режимов ---- */

.menu-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.gtile {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: clamp(116px, 19vh, 150px);
  padding: 0;
  overflow: hidden;
  cursor: pointer;
}
/* Арт занимает всю плиту целиком, а табличка лежит поверх затемнения. Так
   разная высота подписи (в две строки на узком экране) не двигает картинку и
   ряд плит не выглядит рваным. */
.gtile-art {
  position: absolute; inset: 6px;
  border-radius: 8px;
  background-position: center 38%;
  background-size: cover;
  filter: saturate(1.2) contrast(1.05);
  opacity: 0.9;
}
.gtile-fade {
  position: absolute; inset: 6px;
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(10, 9, 12, 0.28) 0 34%, rgba(8, 7, 10, 0.94) 80%);
}

/* Медальон значка — металлический кружок в верхнем левом углу. */
.gtile-medal {
  position: absolute; top: 12px; left: 12px;
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  color: #f4e3bd;
  background: linear-gradient(180deg, #3a3542, #1b1922);
  box-shadow:
    inset 0 1px 0 rgba(255, 240, 210, 0.35),
    inset 0 -2px 0 rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(226, 186, 110, 0.45),
    0 4px 10px rgba(0, 0, 0, 0.5);
}
.gtile-medal svg { width: 18px; height: 18px; }
.gtile-medal .badge {
  position: absolute; top: -5px; right: -5px;
  min-width: 18px; height: 18px;
  padding: 0 4px;
  border-radius: 999px;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 700;
  color: #fff;
  background: linear-gradient(180deg, #ff6a5a, #d02b1d);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
}

/* Заметка (жалость, забег, готовые задания) — лентой в правом верхнем углу. */
/* Лента-заметка прижата к верхнему краю таблички, а не к верху плиты: сверху
   она спорила с медальоном, а на узкой плите (четыре колонки на десктопе)
   налезала на название. */
.gtile-note {
  position: absolute; right: 0; bottom: 58px;
  max-width: 80%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 3px 10px 3px 12px;
  font-size: var(--fs-11, 11px);
  color: #1b1508;
  background: linear-gradient(180deg, #f4d98d, #c99a37);
  clip-path: polygon(8px 0, 100% 0, 100% 100%, 8px 100%, 0 50%);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45);
}

/* Табличка с названием — золотая гравировка на тёмном камне. Тонкая золотая
   нить сверху отделяет её от арта: без неё картинка и подпись сливались. */
.gtile-plate {
  position: relative;
  min-height: 46px;
  justify-content: flex-end;
  margin: 0 6px 6px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 12px 10px;
  text-align: left;
}
.gtile-title {
  font-size: var(--fs-15, 15px);
  font-weight: 700;
  line-height: 1.15;
  color: #f6e6c4;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.85);
}
.gtile-sub {
  font-size: var(--fs-11, 11px);
  line-height: 1.2;
  color: rgba(226, 226, 232, 0.62);
}

/* ---- строка коллекции ---- */

/* Единственная оставшаяся строка: её незачем делать высокой. */
.menu-tile-collection { min-height: 64px; }

/* На широком экране сетка становится четырёхколоночной, а баннер выше:
   в две колонки плиты растягивались в непомерные прямоугольники. */
@media (min-width: 720px) {
  .menu-grid { grid-template-columns: repeat(4, 1fr); }
  .htile { min-height: 186px; }
}

/* На телефоне полоса прогресса пряталась (в строке-плитке ей не хватало
   места). В баннере место есть — возвращаем. */
@media (max-width: 480px) {
  .htile .row-progress { display: flex; }
}

/* Нижняя полка: на средней ширине кнопка «Получить» налезала на подпись. */
.bar-slot { gap: 10px; min-width: 0; }
.bar-slot .slot-text { min-width: 0; }

/* ---------------- панель госпожи на широком экране ----------------

   На десктопе панель растягивается, а сцена стихии остаётся в середине —
   справа от текста получалась чёрная пустота (жалоба заказчика). Лечим
   двумя вещами: колонка текста больше не расползается, а на свободное место
   встаёт печать стихии и её отсвет. */

@media (min-width: 1024px) {
  .char-info { max-width: 620px; }

  .char-panel::after {
    content: '';
    position: absolute;
    right: 4%; top: 50%;
    width: min(230px, 19%);
    aspect-ratio: 1;
    transform: translateY(-50%);
    z-index: 0;
    pointer-events: none;
    background:
      url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'><g fill='none' stroke='rgb(255,236,200)' stroke-width='2'><circle cx='100' cy='100' r='84'/><circle cx='100' cy='100' r='58'/><path d='M100 16 L132 100 L100 184 L68 100 Z'/><path d='M16 100 L100 68 L184 100 L100 132 Z'/><circle cx='100' cy='100' r='14'/></g></svg>") center / contain no-repeat;
    opacity: 0.16;
  }

  /* Тёплый отсвет стихии из правого края: без него печать висит в пустоте. */
  .char-panel > .panel-frame::after {
    content: '';
    position: absolute; inset: 6px;
    border-radius: 6px;
    background: radial-gradient(46% 120% at 96% 50%,
      color-mix(in srgb, var(--accent, #0a84ff) 26%, transparent), transparent 72%);
  }
}

/* ---------------- существа внутри рамы ----------------

   Резная рама рисуется ПОВЕРХ стола (`.table-frame`, z-index 3), а ряды
   существ занимали всю ширину стола — крайние заезжали под кромку и выглядели
   срезанными. На телефоне это заметили на модерации ОК: «карты не помещаются
   на игровое поле».

   Поэтому ряд отступает на ширину кромки, а существа ужимаются по их числу:
   семеро — предел доски, и они обязаны поместиться. */
body.in-battle {
  --tf-w: clamp(16px, 3vh, 26px);
}
body.in-battle .board {
  padding-inline: calc(var(--tf-w) + 4px);
}
body.in-battle .minion {
  min-width: 0;
  width: min(clamp(52px, 7vh, 70px),
             calc((100% - 4px * (var(--n, 1) - 1)) / var(--n, 1)));
}

/* Рука не должна упираться в края экрана: карта у самой кромки читается как
   обрезанная, даже когда помещается целиком. */
body.in-battle .hand-player { padding-inline: 8px; }
