/* ═══════════════════════════════════════════════════════════════════
   finargot.ru — общий компонентный слой поверх style.css
   Emerald Noir: ink #050807 · изумруд #34d399 · Onest · резкая геометрия

   Подключается на КАЖДОЙ странице сразу после style.css.
   Содержит:
     1. Мост токенов — имена, которые остались от прошлых версий дизайна
     2. Хлебные крошки .fx-crumbs — единый компонент для всего сайта
     3. Примитивы .fx-* — кнопки, поля, карточки, панели, чипы, модалка

   Правила именования: префикс fx- (finargot experience), чтобы слой
   никогда не конфликтовал с классами старых утилит.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── 1. Мост токенов ────────────────────────────────────────────────
   Старые страницы (патчи, смурф, прицелы, конфеты) обращаются к именам,
   которых нет в текущей дизайн-системе. Без этих алиасов border и
   border-radius разрешаются в пустоту: рамки пропадают, углы становятся
   прямыми. Именно из-за отсутствия --brd и --r1..--r3 «поплыла»
   страница патча 7.41 — единственная, где не было локального :root. */
:root {
  --brd:        var(--line-hair);
  --brd-hi:     var(--line-hair-hi);
  --brd-acc:    var(--line-accent);

  --r1:         var(--radius-md);   /* 3px  — чипы, мелкие элементы */
  --r2:         var(--radius-lg);   /* 4px  — кнопки, поля, карточки */
  --r3:         var(--radius-xl);   /* 6px  — крупные панели */

  --glass:      color-mix(in oklab, var(--color-ink-900) 72%, transparent);
  --glass-border: var(--line-hair);
  --card:       var(--color-ink-900);
  --shadow-acc: var(--glow-md);

  --txt-muted:  var(--color-bone-500);
  --text-muted: var(--color-bone-500);

  /* Семантика игровых данных: усиление / ослабление / стихии */
  --buff:       var(--color-jade-300);
  --nerf:       var(--color-rose-400);
  --str:        #ef5f52;
  --agi:        #6ee7b7;
  --int:        #4bc6d6;
  --uni:        #4bc6d6;
}

/* ─── 2. Хлебные крошки ──────────────────────────────────────────────
   Разметка (порядок и семантика важны для скринридеров и Яндекса):

   <nav class="fx-crumbs" aria-label="Хлебные крошки">
     <div class="fx-crumbs-in">
       <ol>
         <li><a href="/">Главная</a></li>
         <li><a href="/useful">Утилиты</a></li>
         <li><span aria-current="page">Трекер глифа</span></li>
       </ol>
     </div>
   </nav>

   Разделители рисует CSS — в разметке их нет, иначе скринридер зачитывал
   бы «больше» между каждым пунктом.                                    */

.fx-crumbs {
  position: relative;
  border-bottom: 1px solid var(--line-hair);
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-ink-900) 88%, transparent) 0%,
      transparent 100%);
}

/* Волосяная акцентная подсветка кромки — «дорогая» деталь отделки:
   градиент гаснет к краям, поэтому линия не выглядит наклеенной. */
.fx-crumbs::after {
  content: "";
  position: absolute;
  inset: auto 0 -1px;
  height: 1px;
  pointer-events: none;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in oklab, var(--accent) 26%, transparent) 32%,
    color-mix(in oklab, var(--accent) 26%, transparent) 68%,
    transparent 100%);
  opacity: .55;
}

.fx-crumbs-in {
  max-width: 76rem;
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

.fx-crumbs ol {
  display: flex;
  align-items: center;
  gap: .1rem;
  margin: 0;
  padding: 0;
  list-style: none;
  min-height: 2.875rem;               /* 46px — комфортная зона нажатия */
  overflow-x: auto;
  scrollbar-width: none;
  /* На узких экранах строка уезжает под правый край с мягким затуханием,
     это честнее, чем прятать середину пути под «…». */
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 2rem), transparent 100%);
          mask-image: linear-gradient(90deg, #000 calc(100% - 2rem), transparent 100%);
}
.fx-crumbs ol::-webkit-scrollbar { display: none; }

.fx-crumbs li {
  display: inline-flex;
  align-items: center;
  flex: none;
}

/* Шеврон-разделитель: тонкий, приглушённый, не спорит с текстом */
.fx-crumbs li + li::before {
  content: "";
  width: .5rem;
  height: .5rem;
  margin-inline: .55rem;
  flex: none;
  background-color: var(--color-bone-700);
  -webkit-mask: var(--fx-chevron) center / contain no-repeat;
          mask: var(--fx-chevron) center / contain no-repeat;
}

:root {
  --fx-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");
}

.fx-crumbs a,
.fx-crumbs [aria-current="page"] {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .5rem .1rem;
  font-size: .8125rem;
  line-height: 1.2;
  letter-spacing: .005em;
  white-space: nowrap;
  text-decoration: none;
}

.fx-crumbs a {
  color: var(--color-bone-500);
  transition: color var(--dur) var(--ease-out);
}
.fx-crumbs a:hover { color: var(--color-bone-50); }

/* Подчёркивание раскрывается от левого края — движение читается как
   «путь идёт дальше», а не как декоративная подсветка. */
.fx-crumbs a::after {
  content: "";
  position: absolute;
  inset: auto .1rem .3rem;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}
.fx-crumbs a:hover::after,
.fx-crumbs a:focus-visible::after { transform: scaleX(1); }

.fx-crumbs a svg {
  width: 14px;
  height: 14px;
  flex: none;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Текущая страница: плотнее по весу и помечена изумрудной искрой */
.fx-crumbs [aria-current="page"] {
  color: var(--color-bone-50);
  font-weight: 600;
  cursor: default;
}
.fx-crumbs [aria-current="page"]::before {
  content: "";
  width: 4px;
  height: 4px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: var(--glow-xs);
}

.fx-crumbs a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

@media (prefers-reduced-motion: reduce) {
  .fx-crumbs a::after { transition: none; }
}

/* ── Совместимость со старой разметкой крошек ────────────────────────
   Часть страниц (радар, блог, видео, прицелы, смурф) размечает путь
   плоским списком ссылок с текстовым разделителем «/» или «›». Пока
   разметка не переведена на <ol>, эти правила приводят её к тому же
   виду: разделитель заменяется шевроном, последний элемент получает
   акцентную искру. Скринридеру такой span уже не читается как «слэш» —
   символ прячется через font-size:0.                                   */
nav.crumbs > *,
nav.breadcrumbs > * {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .8125rem;
  line-height: 1.2;
  white-space: nowrap;
  text-decoration: none;
}

nav.crumbs,
nav.breadcrumbs {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: flex-start;
  gap: .1rem;
  min-height: 2.875rem;
  margin: 0;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 2rem), transparent 100%);
          mask-image: linear-gradient(90deg, #000 calc(100% - 2rem), transparent 100%);
}
nav.crumbs::-webkit-scrollbar,
nav.breadcrumbs::-webkit-scrollbar { display: none; }

nav.crumbs a,
nav.breadcrumbs a {
  position: relative;
  padding: .5rem .1rem;
  color: var(--color-bone-500);
  transition: color var(--dur) var(--ease-out);
}
nav.crumbs a:hover,
nav.breadcrumbs a:hover { color: var(--color-bone-50); }

nav.crumbs a::after,
nav.breadcrumbs a::after {
  content: "";
  position: absolute;
  inset: auto .1rem .3rem;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}
nav.crumbs a:hover::after,
nav.breadcrumbs a:hover::after,
nav.crumbs a:focus-visible::after,
nav.breadcrumbs a:focus-visible::after { transform: scaleX(1); }

/* Разделители: текст прячем, рисуем тот же шеврон, что в .fx-crumbs */
nav.crumbs > span:not(:last-of-type),
nav.breadcrumbs > .bc-sep {
  width: .5rem;
  margin-inline: .55rem;
  font-size: 0;
  color: transparent;
  background-color: var(--color-bone-700);
  -webkit-mask: var(--fx-chevron) center / contain no-repeat;
          mask: var(--fx-chevron) center / contain no-repeat;
}
nav.crumbs > span:not(:last-of-type)::before,
nav.breadcrumbs > .bc-sep::before { content: ""; display: block; height: .5rem; }

/* Текущая страница */
nav.crumbs > span:last-of-type,
nav.breadcrumbs > .bc-current {
  padding: .5rem .1rem;
  color: var(--color-bone-50);
  font-weight: 600;
}
nav.crumbs > span:last-of-type::before,
nav.breadcrumbs > .bc-current::before {
  content: "";
  width: 4px;
  height: 4px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: var(--glow-xs);
}

nav.crumbs a:focus-visible,
nav.breadcrumbs a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* ─── 3. Примитивы ───────────────────────────────────────────────── */

/* 3.1 Кнопки */
.fx-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 2.75rem;                /* 44px — минимум для пальца */
  padding: .7rem 1.15rem;
  border: 1px solid transparent;
  border-radius: var(--radius-lg);
  background: transparent;
  color: inherit;
  font-family: inherit;
  font-size: .875rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: .005em;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;         /* убирает 300 мс задержку тапа */
  transition:
    background-color var(--dur) var(--ease-out),
    border-color     var(--dur) var(--ease-out),
    color            var(--dur) var(--ease-out),
    box-shadow       var(--dur) var(--ease-out),
    transform        .12s        var(--ease-out);
}
.fx-btn svg { width: 16px; height: 16px; flex: none; stroke-width: 1.75; }

.fx-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.fx-btn:active { transform: translateY(1px); }

.fx-btn[disabled],
.fx-btn[aria-disabled="true"] {
  opacity: .42;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.fx-btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--color-ink-950);
}
.fx-btn--primary:hover:not([disabled]) {
  background: var(--accent-hi);
  border-color: var(--accent-hi);
  box-shadow: var(--glow-sm);
}

.fx-btn--line {
  border-color: var(--line-accent);
  background: var(--accent-wash);
  color: var(--accent-hi);
}
.fx-btn--line:hover:not([disabled]) {
  border-color: var(--accent);
  background: var(--accent-dim);
  box-shadow: var(--glow-xs);
}

.fx-btn--ghost {
  border-color: var(--line-hair);
  color: var(--color-bone-300);
}
.fx-btn--ghost:hover:not([disabled]) {
  border-color: var(--line-hair-hi);
  background: var(--color-ink-850);
  color: var(--color-bone-50);
}

.fx-btn--danger {
  border-color: color-mix(in oklab, var(--color-rose-400) 45%, transparent);
  background: color-mix(in oklab, var(--color-rose-400) 8%, transparent);
  color: var(--color-rose-400);
}
.fx-btn--danger:hover:not([disabled]) {
  background: color-mix(in oklab, var(--color-rose-400) 16%, transparent);
}

.fx-btn--sm { min-height: 2.25rem; padding: .5rem .8rem; font-size: .8125rem; }
.fx-btn--lg { min-height: 3.25rem; padding: .95rem 1.6rem; font-size: .9375rem; }
.fx-btn--block { width: 100%; }

/* Состояние загрузки: кольцо вместо подписи, ширина кнопки не скачет */
.fx-btn[data-loading="true"] {
  pointer-events: none;
  color: transparent;
  position: relative;
}
.fx-btn[data-loading="true"]::after {
  content: "";
  position: absolute;
  width: 1rem;
  height: 1rem;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: var(--color-ink-950);
  animation: fx-spin .7s linear infinite;
}
.fx-btn--ghost[data-loading="true"]::after,
.fx-btn--line[data-loading="true"]::after { color: var(--accent-hi); }

@keyframes fx-spin { to { transform: rotate(360deg); } }

/* 3.2 Поля ввода */
.fx-field { display: flex; flex-direction: column; gap: .4rem; }

.fx-label {
  font-size: .8125rem;
  font-weight: 500;
  color: var(--color-bone-300);
}
.fx-label [data-required] { color: var(--accent); margin-left: .15rem; }

.fx-input,
.fx-select,
.fx-textarea {
  width: 100%;
  min-height: 3rem;                   /* 48px */
  padding: .75rem .9rem;
  border: 1px solid var(--line-hair);
  border-radius: var(--radius-lg);
  background: var(--color-ink-900);
  color: var(--color-bone-50);
  font-family: inherit;
  font-size: 1rem;                    /* 16px: iOS не зумит поле при фокусе */
  line-height: 1.4;
  transition:
    border-color var(--dur) var(--ease-out),
    box-shadow   var(--dur) var(--ease-out);
}
.fx-textarea { min-height: 7rem; resize: vertical; }

.fx-input::placeholder,
.fx-textarea::placeholder { color: var(--color-bone-600); }

.fx-input:hover,
.fx-select:hover,
.fx-textarea:hover { border-color: var(--line-hair-hi); }

.fx-input:focus,
.fx-select:focus,
.fx-textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 16%, transparent);
}

.fx-input[aria-invalid="true"] {
  border-color: var(--color-rose-400);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-rose-400) 14%, transparent);
}

.fx-hint  { font-size: .75rem; color: var(--color-bone-600); }
.fx-error {
  display: flex;
  align-items: center;
  gap: .35rem;
  font-size: .8125rem;
  color: var(--color-rose-400);
}
.fx-error svg { width: 14px; height: 14px; flex: none; }

/* Поле с кнопкой действия справа (ввести ID → «Найти») */
.fx-inputrow { display: flex; gap: .5rem; flex-wrap: wrap; }
.fx-inputrow .fx-input { flex: 1 1 14rem; min-width: 0; }

/* 3.3 Поверхности */
.fx-panel {
  border: 1px solid var(--line-hair);
  border-radius: var(--radius-lg);
  background: var(--color-ink-900);
  box-shadow: var(--edge-in);
}
.fx-panel--pad { padding: clamp(1rem, 2.4vw, 1.5rem); }

.fx-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line-hair);
  border-radius: var(--radius-lg);
  background: var(--color-ink-900);
  box-shadow: var(--edge-in);
  transition:
    border-color var(--dur) var(--ease-out),
    transform    var(--dur) var(--ease-out),
    box-shadow   var(--dur) var(--ease-out);
}
a.fx-card { text-decoration: none; color: inherit; }
a.fx-card:hover,
.fx-card--hover:hover {
  border-color: var(--line-hair-hi);
  transform: translateY(-2px);
  box-shadow: var(--edge-in), 0 18px 40px -28px #000;
}
/* Кнопка карточки всегда прижата к низу — карточки в ряду ровные */
.fx-card .fx-card-foot { margin-top: auto; }

@media (prefers-reduced-motion: reduce) {
  a.fx-card:hover, .fx-card--hover:hover { transform: none; }
}

.fx-chip {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .3rem .55rem;
  border: 1px solid var(--line-hair);
  border-radius: var(--radius-md);
  background: color-mix(in oklab, var(--color-ink-850) 70%, transparent);
  color: var(--color-bone-300);
  font-size: .75rem;
  font-weight: 500;
  line-height: 1;
}
.fx-chip--accent {
  border-color: var(--line-accent);
  background: var(--accent-wash);
  color: var(--accent-hi);
}

/* 3.4 Заголовок раздела страницы */
.fx-head {
  padding-block: clamp(1.75rem, 4vw, 3rem) clamp(1.25rem, 2.5vw, 1.75rem);
}
.fx-head h1 {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4.2vw, 2.9rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -.03em;
  color: var(--color-bone-50);
}
.fx-head h1 span { color: var(--accent); }
.fx-head p {
  margin: .75rem 0 0;
  max-width: 62ch;                    /* читаемая длина строки */
  font-size: var(--text-lead);
  line-height: 1.55;
  color: var(--color-bone-300);
}

/* 3.5 Модальное окно */
.fx-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.fx-modal[hidden] { display: none; }

.fx-modal-scrim {
  position: absolute;
  inset: 0;
  background: #02040399;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: fx-fade .18s var(--ease-out);
}

.fx-modal-box {
  position: relative;
  width: min(30rem, 100%);
  max-height: calc(100dvh - 2rem);
  overflow-y: auto;
  padding: clamp(1.5rem, 4vw, 2rem);
  border: 1px solid var(--line-hair-hi);
  border-radius: var(--radius-xl);
  background: var(--color-ink-900);
  box-shadow:
    var(--edge-in),
    0 40px 90px -40px #000,
    var(--glow-md);
  animation: fx-rise .22s var(--ease-out);
}

/* Акцентная кромка сверху — тот же приём, что у хлебных крошек,
   благодаря чему модалка читается как часть одной системы */
.fx-modal-box::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  background: linear-gradient(90deg,
    transparent, color-mix(in oklab, var(--accent) 55%, transparent), transparent);
}

.fx-modal-title {
  margin: 0 0 .5rem;
  font-family: var(--font-display);
  font-size: 1.375rem;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--color-bone-50);
}
.fx-modal-text {
  margin: 0 0 1.5rem;
  font-size: .9375rem;
  line-height: 1.6;
  color: var(--color-bone-300);
}
.fx-modal-actions {
  display: flex;
  gap: .6rem;
  flex-wrap: wrap;
}
.fx-modal-actions .fx-btn { flex: 1 1 9rem; }

.fx-modal-close {
  position: absolute;
  top: .75rem;
  right: .75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-bone-500);
  cursor: pointer;
  transition: color var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out);
}
.fx-modal-close:hover {
  color: var(--color-bone-50);
  border-color: var(--line-hair);
}
.fx-modal-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.fx-modal-close svg { width: 18px; height: 18px; stroke-width: 1.75; }

@keyframes fx-fade { from { opacity: 0 } }
@keyframes fx-rise {
  from { opacity: 0; transform: translateY(10px) scale(.985); }
}

@media (prefers-reduced-motion: reduce) {
  .fx-modal-scrim,
  .fx-modal-box { animation: none; }
}

/* 3.6 Кнопка «наверх» на страницах патчей
   Видимостью управляет patch.js через data-show. Раньше на разных
   патчах она была то всегда видимой, то всегда прозрачной (скрипт
   падал раньше, чем доходил до неё). */
.jt[data-show] {
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--line-accent);
  border-radius: 50%;
  background: var(--color-ink-900);
  color: var(--accent-hi);
  box-shadow: var(--edge-in), var(--glow-sm);
  transition:
    opacity   var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out),
    color     var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out);
}
.jt[data-show="false"] { opacity: 0; pointer-events: none; transform: translateY(8px); }
.jt[data-show="true"]  { opacity: 1; pointer-events: auto; transform: none; }
.jt[data-show]:hover   { background: var(--accent); color: var(--color-ink-950); }
.jt[data-show]:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Коллизия имён: в style.css `.section` — секция лендинга главной, у неё
   padding-block: clamp(3.5rem, 7vw, 6.5rem). Страницы патчей размечают тем
   же классом свои разделы, из-за чего между блоками появлялись пустые
   провалы больше 100 px. Внутри колонки патча возвращаем плотный ритм. */
.patch-content > .section,
main.content > .section {
  padding-block: 0;
  margin-bottom: clamp(2rem, 3.5vw, 3rem);
}

/* Промо-строка на патчах приводится к общему виду: на 7.41 она была
   кислотным градиентом #16a34a с бесконечной анимацией свечения, на
   остальных патчах — своим вариантом. Селектор с тегом (0,1,1) перебивает
   инлайновый `<style>` страницы, не требуя правки пяти файлов. */
a.promo-bar {
  gap: .75rem;
  padding: .8rem 1rem;
  border: 1px solid var(--line-accent);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(100deg,
      color-mix(in oklab, var(--accent) 9%, var(--color-ink-850)) 0%,
      var(--color-ink-900) 62%);
  background-size: auto;
  animation: none;                        /* был promoGlow 4s infinite */
  color: var(--color-bone-50);
  box-shadow: var(--edge-in);
  transition:
    border-color var(--dur) var(--ease-out),
    box-shadow   var(--dur) var(--ease-out);
}
a.promo-bar:hover {
  border-color: var(--accent);
  box-shadow: var(--edge-in), var(--glow-xs);
  transform: none;
}
a.promo-bar .promo-bar-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  flex: none;
  border: 1px solid var(--line-accent);
  border-radius: var(--radius-md);
  background: var(--accent-wash);
  color: var(--accent-hi);
}
a.promo-bar .promo-bar-ico svg { width: 15px; height: 15px; stroke-width: 1.75; fill: none; stroke: currentColor; }
a.promo-bar .promo-bar-text { font-weight: 600; letter-spacing: -.005em; }
a.promo-bar .promo-bar-label {
  margin-left: auto;
  padding: .25rem .5rem;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--color-ink-950);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .06em;
  white-space: nowrap;
}
a.promo-bar .promo-bar-arr { color: var(--accent-hi); transition: transform var(--dur) var(--ease-out); }
a.promo-bar:hover .promo-bar-arr { transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
  a.promo-bar:hover .promo-bar-arr { transform: none; }
}

/* Та же коллизия у оглавления: `.toc` в style.css — список внутри поста
   блога, на патче 7.41 это липкий сайдбар. Убираем чужой верхний отступ. */
.layout > .toc { margin-top: 0; display: block; }

/* Якорные переходы не должны заезжать под липкую шапку */
.section[id],
[id].article-section { scroll-margin-top: 5.5rem; }

@media (prefers-reduced-motion: reduce) {
  .jt[data-show] { transition: opacity var(--dur) linear; }
  .jt[data-show="false"] { transform: none; }
}

/* 3.7 Служебное */
.fx-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.fx-wrap {
  max-width: 76rem;
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

/* ═══════════════════════════════════════════════════════════════════
   4. Промо пополнения Steam (промокод finarneon)

   Ссылки на battlepass.ru/service/steam разбросаны по шапке, подвалу,
   статьям и патчам и выглядели по-разному — от обычной обводки до
   кислотного зелёного баннера. Селектор по адресу приводит их к одному
   виду, не требуя правки разметки на трёх десятках страниц.
   ═══════════════════════════════════════════════════════════════════ */

a[href*="battlepass.ru/service/steam"].btn,
a[href*="battlepass.ru/service/steam"].fx-btn {
  position: relative;
  border-color: var(--line-accent);
  background: var(--accent-wash);
  color: var(--accent-hi);
  transition:
    background-color var(--dur) var(--ease-out),
    border-color     var(--dur) var(--ease-out),
    color            var(--dur) var(--ease-out),
    box-shadow       var(--dur) var(--ease-out);
}
a[href*="battlepass.ru/service/steam"].btn:hover,
a[href*="battlepass.ru/service/steam"].fx-btn:hover {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--color-ink-950);
  box-shadow: var(--glow-sm);
}

/* Кнопка в шапке — сплошная заливка: это главное действие страницы */
.site-head a[href*="battlepass.ru/service/steam"].btn {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--color-ink-950);
  font-weight: 600;
}
.site-head a[href*="battlepass.ru/service/steam"].btn:hover {
  background: var(--accent-hi);
  border-color: var(--accent-hi);
  box-shadow: var(--glow-sm);
}

/* Промо-строка «Свежий Промик»: по кромке раз в 9 секунд проходит блик.
   Он держится на @property-переменной, поэтому анимируется угол, а не
   перерисовка градиента — кадры остаются в композиторе. */
@property --fx-beam { syntax: "<angle>"; inherits: false; initial-value: 0deg; }

a.promo-bar {
  isolation: isolate;
}
a.promo-bar::before {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: -1;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--fx-beam),
    transparent 0deg,
    transparent 300deg,
    color-mix(in oklab, var(--accent) 85%, transparent) 340deg,
    transparent 360deg);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  animation: fx-beam-spin 9s linear infinite;
}
@keyframes fx-beam-spin { to { --fx-beam: 360deg; } }

/* Метка выгоды — заметнее прочего текста строки */
a.promo-bar .promo-bar-label {
  box-shadow: var(--glow-xs);
}

@media (prefers-reduced-motion: reduce) {
  a.promo-bar::before { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   5. Шапка утилиты по образцу /radar

   Утилиты собирали шапку каждая по-своему: центрированный блок,
   иконка со своим свечением, свои размеры шрифта. Теперь все
   пользуются готовыми классами дизайн-системы (.archive-head,
   .u-display, .u-lead, .figures), а здесь — только связки между ними.
   ═══════════════════════════════════════════════════════════════════ */

.fg-hero-title {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  max-width: 20ch;                    /* заголовок ломается по смыслу */
}
.fg-hero-lead  { margin-top: 1.25rem; max-width: 58ch; }
.fg-hero-figures { margin-top: clamp(2rem, 4.5vw, 3rem); }

/* Плашки и предупреждения, которые раньше жили внутри шапки */
.fg-hero-extra { padding-block: clamp(1.5rem, 3vw, 2.25rem) 0; }
/* Плашка идёт по левой колонке рабочей сетки, а не во всю ширину:
   строка длиной в весь экран читается хуже. */
.fg-hero-extra .glyph-merge-notice { margin-inline: 0; max-width: 44rem; }

/* Рабочая область утилиты выравнивается по той же сетке, что и шапка:
   раньше форма стояла по центру, а заголовок — по левому краю. */
.glyph-search-form,
.glyph-hint { max-width: 34rem; margin-inline: 0; }
.glyph-hint { text-align: left; }


/* ═══════════════════════════════════════════════════════════════════
   6. Правки доступности по итогам проверки контраста

   На фоне #050807 приглушённые тона палитры не дотягивали до нормы
   WCAG AA (4.5:1 для основного текста):

     bone-600  #62706b — 3.88:1  (подписи под цифрами, даты, сноски)
     bone-700  #44524d — 2.45:1  (пометка «свежий» в меню патчей)

   Тон поднят до ближайшего значения, которое проходит порог и на
   ink-950, и на более светлом ink-850. Разница на глаз минимальна,
   мелкий текст перестаёт «пропадать» на тёмном.
   ═══════════════════════════════════════════════════════════════════ */
:root {
  --color-bone-600: #72807b;   /* 4.87:1 на ink-950, 4.52:1 на ink-850 */
}

/* bone-700 остаётся для декоративных линий и разделителей, но текстом
   больше не работает: пометка свежего патча стала акцентной. */
.nav-dd-menu .dd-note,
.mnav .dd-note {
  color: var(--accent-hi);
  font-weight: 600;
  letter-spacing: .02em;
}

/* Зона нажатия логотипа: сама надпись высотой 29px, для пальца мало.
   Отрицательный внешний отступ компенсирует padding, поэтому в макете
   ничего не смещается. */
.site-head .wordmark {
  padding-block: .5rem;
  margin-block: -.5rem;
}

/* Ссылки и кнопки в шапке были высотой 31px — для пальца мало.
   Padding расширяет зону нажатия до 44px, отрицательный margin
   компенсирует его, поэтому высота самой шапки не меняется. */
.site-head .nav > a,
.site-head .nav-dd > button,
.site-head .head-actions > .btn {
  padding-block: .45rem;
  margin-block: -.45rem;
}

/* Логотип в подвале и текстовые ссылки-кнопки на главной были ниже
   44px — тот же приём с компенсирующим отрицательным отступом. */
.site-foot .wordmark {
  padding-block: .5rem;
  margin-block: -.5rem;
}
.site-foot .lnk,
.site-foot .lnk-quiet {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
}

/* Ссылки «Все видео», «Весь блог» и кнопки блоков главной были
   высотой 29–32px. Компенсированный padding поднимает зону нажатия
   до 44px, не сдвигая соседние элементы. */
.lnk, .lnk-quiet {
  display: inline-flex;
  align-items: center;
  padding-block: .5rem;
  margin-block: -.5rem;
}

/* ═══════════════════════════════════════════════════════════════════
   7. Сигнальная шкала

   Роза #e0568f стояла от изумруда на 177° — почти прямой комплемент.
   Две одинаково насыщенные краски на почти чёрном фоне спорят и дают
   неоновый вид; фиолетовый добавлял третий несвязанный тон.

   Здесь тона идут по кругу подряд: изумруд и циан — соседи (спокойный
   переход), дальше тёплая тройка складывается в привычную шкалу
   «зелёный → жёлтый → красный». Все значения проходят WCAG AA с
   запасом даже на самом тёмном фоне.
   ═══════════════════════════════════════════════════════════════════ */
:root {
  --sig-ok:     #34d399;   /* 10.5:1 — норма, успех   */
  --sig-info:   #4bc6d6;   /*  9.9:1 — нейтральный факт */
  --sig-warn:   #f5c451;   /* 12.4:1 — внимание       */
  --sig-risk:   #f2874b;   /*  8.0:1 — повышенный риск */
  --sig-danger: #ef5f52;   /*  6.2:1 — опасность      */

  /* Мост к прежним именам, чтобы старые файлы подхватили шкалу */
  --color-rose-400: var(--sig-danger);
  --red:     var(--sig-danger);
  --red-dim: color-mix(in oklab, var(--sig-danger) 12%, transparent);
}

/* ═══════════════════════════════════════════════════════════════════
   8. Карточка «Пополнить Steam» вне шапки

   Такие блоки стоят в смурфе, трекере глифа и на страницах патчей, и
   каждый был свёрстан по-своему: сине-стальной градиент Steam
   (#1b2838 → #0f1a26 с рамкой #2a475e), пульсирующая тень и бегущий
   блик — три разных ритма мигания на одной странице.

   Здесь общий вид: тёмная поверхность сайта, изумрудная кромка,
   спокойное свечение и один медленный блик по краю. Селекторы бьют по
   всем вариантам сразу, поэтому разметку править не нужно.
   ═══════════════════════════════════════════════════════════════════ */

.sm3-aegis .sm3-topup,
.glyph-topup,
.rtr-topup,
.rta-topup,
.fx-topup {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  gap: 1rem;
  width: 100%;
  padding: 1.1rem 1.35rem;
  border: 1px solid var(--line-accent);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(105deg,
      color-mix(in oklab, var(--accent) 10%, var(--color-ink-850)) 0%,
      var(--color-ink-900) 58%);
  color: var(--color-bone-300);
  text-decoration: none;
  overflow: visible;
  box-shadow: var(--edge-in), var(--glow-sm);
  animation: none;                       /* была пульсация тени 2,8 с */
  transition:
    border-color var(--dur) var(--ease-out),
    box-shadow   var(--dur) var(--ease-out),
    transform    var(--dur) var(--ease-out);
}
.sm3-aegis .sm3-topup:hover,
.glyph-topup:hover,
.rtr-topup:hover,
.rta-topup:hover,
.fx-topup:hover {
  transform: translateY(-1px);
  border-color: var(--accent);
  box-shadow: var(--edge-in), var(--glow-md);
}

/* Блик по кромке — тот же приём, что у промо-строки на патчах:
   один медленный оборот вместо мигающей тени. */
.sm3-aegis .sm3-topup::before,
.glyph-topup::before,
.rtr-topup::before,
.rta-topup::before,
.fx-topup::before {
  content: "";
  position: absolute;
  inset: -1px;
  top: -1px;
  left: -1px;
  width: auto;
  height: auto;
  z-index: -1;
  transform: none;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--fx-beam),
    transparent 0deg, transparent 296deg,
    color-mix(in oklab, var(--accent) 90%, transparent) 338deg,
    transparent 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  animation: fx-beam-spin 7s linear infinite;
  transition: none;
}
.sm3-aegis .sm3-topup:hover::before,
.glyph-topup:hover::before,
.rtr-topup:hover::before,
.rta-topup:hover::before,
.fx-topup:hover::before { left: -1px; }

/* Значок */
.sm3-aegis .sm3-topup-icon,
.glyph-topup-icon,
.rtr-topup-icon,
.rta-topup-icon,
.fx-topup-icon {
  width: 2.75rem;
  height: 2.75rem;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-accent);
  border-radius: var(--radius-md);
  background: var(--accent-wash);
  color: var(--accent-hi);
}
.sm3-aegis .sm3-topup-icon svg,
.glyph-topup-icon svg,
.fx-topup-icon svg { width: 22px; height: 22px; }

/* Текст */
.sm3-aegis .sm3-topup-title,
.glyph-topup-title,
.rtr-topup-title,
.rta-topup-title,
.fx-topup-title {
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -.015em;
  color: var(--color-bone-50);
  margin-bottom: .15rem;
}
.sm3-aegis .sm3-topup-sub,
.glyph-topup-sub,
.rtr-topup-sub,
.rta-topup-sub,
.fx-topup-sub {
  font-size: .8125rem;
  line-height: 1.45;
  color: var(--color-bone-300);
}

/* Бейдж выгоды */
.sm3-aegis .sm3-topup-badge,
.glyph-topup-badge,
.rtr-topup-badge,
.rta-topup-badge,
.fx-topup-badge {
  order: 3;
  margin-left: auto;
  position: static;
  display: inline-flex;
  align-items: center;
  flex: none;
  padding: .3rem .6rem;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--color-ink-950);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  box-shadow: var(--glow-xs);
  animation: none;                       /* было «подпрыгивание» 2,4 с */
}

.sm3-aegis .sm3-topup-arrow,
.glyph-topup-arrow,
.rtr-topup-arrow,
.rta-topup-arrow,
.fx-topup-arrow {
  order: 5;
  flex: none;
  color: var(--accent-hi);
  transition: transform var(--dur) var(--ease-out);
}
.sm3-aegis .sm3-topup:hover .sm3-topup-arrow,
.glyph-topup:hover .glyph-topup-arrow,
.rtr-topup:hover .rtr-topup-arrow,
.rta-topup:hover .rta-topup-arrow,
.fx-topup:hover .fx-topup-arrow { transform: translateX(4px); }

/* Пометка о новом промокоде: код виден до перехода, поэтому его можно
   просто скопировать, а «NEW» объясняет, почему блок подсвечен. */
.fx-promo-tag {
  order: 4;
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  flex: none;
  padding: .3rem .55rem;
  border: 1px dashed var(--line-accent);
  border-radius: var(--radius-sm);
  background: var(--accent-wash);
  color: var(--accent-hi);
  font-size: .6875rem;
  font-weight: 500;
  letter-spacing: .02em;
  white-space: nowrap;
}
.fx-promo-tag b {
  font-family: var(--font-mono);
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--color-bone-50);
}
.fx-promo-tag i {
  font-style: normal;
  padding: .1rem .3rem;
  border-radius: 2px;
  background: var(--accent);
  color: var(--color-ink-950);
  font-size: .5625rem;
  font-weight: 800;
  letter-spacing: .1em;
}

@media (max-width: 720px) {
  .sm3-aegis .sm3-topup,
  .glyph-topup,
  .rtr-topup,
  .rta-topup,
  .fx-topup { flex-wrap: wrap; }
  .fx-promo-tag { order: 5; }
}

@media (prefers-reduced-motion: reduce) {
  .sm3-aegis .sm3-topup::before,
  .glyph-topup::before,
  .rtr-topup::before,
  .rta-topup::before,
  .fx-topup::before { animation: none; }
  .sm3-aegis .sm3-topup:hover,
  .glyph-topup:hover,
  .rtr-topup:hover,
  .rta-topup:hover,
  .fx-topup:hover { transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   9. Рабочая панель утилиты

   На конвертере и трекере глифа поле ввода стояло само по себе между
   рядом цифр и текстовым блоком: без рамки, без подписи (placeholder
   подписью не считается — он исчезает при первом же символе) и без
   понятной границы рабочей области. Из-за этого страница читалась как
   «заголовок, цифры, потом что-то в пустоте».

   Панель даёт форме опору: видимую метку, свою поверхность и плотный
   ритм между шапкой и следующим блоком.
   ═══════════════════════════════════════════════════════════════════ */
.fx-workbench {
  max-width: 44rem;
  margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
  padding: clamp(1.1rem, 2.4vw, 1.5rem);
  border: 1px solid var(--line-hair);
  border-radius: var(--radius-xl);
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--accent) 4%, var(--color-ink-900)) 0%,
      var(--color-ink-900) 70%);
  box-shadow: var(--edge-in);
}

.fx-workbench-label {
  display: block;
  margin-bottom: .55rem;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-bone-500);
}

.fx-workbench .sid-hint,
.fx-workbench .glyph-hint { margin-top: .6rem; margin-bottom: 0; }
.fx-workbench .sid-error:empty { display: none; }

/* Ритм страницы: шапка → панель → содержимое без провалов */
.archive-head + .sid-main,
.archive-head + .glyph-page { padding-top: 0; }
.sid-main { padding-top: clamp(.5rem, 1.5vw, 1rem); }
.sid-seo  { padding-top: clamp(1.5rem, 3vw, 2.25rem); }

@media (max-width: 640px) {
  .fx-workbench { padding: 1rem; }
}

/* ═══════════════════════════════════════════════════════════════════
   10. Двухколоночная рабочая зона

   На конвертере форма занимала левую половину экрана, а правая
   оставалась пустой: страница читалась как незаконченная. Рядом с
   вводом встаёт карточка с тем, что вернёт сервис — она объясняет
   ценность до первого запроса и держит правую колонку.
   ═══════════════════════════════════════════════════════════════════ */
.fx-worksplit {
  display: grid;
  gap: clamp(1rem, 2.4vw, 1.75rem);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 62rem) {
  .fx-worksplit { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); }
}
.fx-worksplit .fx-workbench { max-width: none; margin-top: 0; }

.fx-aside {
  padding: clamp(1.1rem, 2.4vw, 1.5rem);
  border: 1px solid var(--line-hair);
  border-radius: var(--radius-xl);
  background: var(--color-ink-900);
  box-shadow: var(--edge-in);
}
.fx-aside-title {
  margin: 0 0 .9rem;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-bone-500);
}
.fx-aside-list { margin: 0; padding: 0; list-style: none; }
.fx-aside-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .5rem;
  padding: .55rem 0;
  border-top: 1px solid var(--line-hair);
}
.fx-aside-list li:first-child { border-top: 0; padding-top: 0; }
.fx-aside-list b {
  font-family: var(--font-mono);
  font-size: .8125rem;
  font-weight: 700;
  color: var(--accent-hi);
}
.fx-aside-list span {
  font-size: .8125rem;
  color: var(--color-bone-500);
}
.fx-aside-note {
  margin: .9rem 0 0;
  padding-top: .9rem;
  border-top: 1px solid var(--line-hair);
  font-size: .8125rem;
  line-height: 1.55;
  color: var(--color-bone-300);
}

/* Блоки под рабочей зоной шли вплотную друг к другу: между карточками
   и баннером пополнения не было воздуха. Задаём общий вертикальный шаг
   и ставим их на ту же сетку, что шапка и форма. */
.glyph-page > .wrap:not(.fg-hero-extra):not(.glyph-topup-section),
.glyph-page > section.wrap:not(.fg-hero-extra):not(.glyph-topup-section) { padding-block: 0; }

.fx-worksplit + *,
.fx-workbench + * { margin-top: clamp(1.5rem, 3vw, 2.25rem); }

.glyph-topup-section,
.fg-hero-extra + .fx-worksplit { margin-top: clamp(1.25rem, 2.5vw, 1.75rem); }

/* Блок пополнения выравнивается по той же колонке, что шапка страницы */
.glyph-topup-section,
.sm3-aegis .sm3-topup-section {
  max-width: 76rem;
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

/* Колонки сплита начинаются на одной высоте: собственные верхние
   отступы вложенных панелей сдвигали правую колонку на 36px вниз. */
.fx-worksplit > * { margin-top: 0; }

/* Рабочая зона утилиты и блоки под ней идут по одной сетке с шапкой */
.glyph-page .fg-hero-extra {
  max-width: 76rem;
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}
.glyph-page .fg-hero-extra .fx-worksplit { padding-inline: 0; max-width: none; }
.glyph-topup-section { margin-top: clamp(1.5rem, 3vw, 2.25rem); padding-bottom: clamp(2rem, 4vw, 3rem); }

/* Единый вертикальный шаг между блоками страницы утилиты: зазоры шли
   36 / 18 / 84 px и читались как случайные. Рабочая сетка вложена в
   ту же секцию, что плашка о переезде, поэтому шаг задаётся на самих
   блоках, а не соседними селекторами. */
.glyph-page .glyph-merge-notice { margin-bottom: clamp(1.5rem, 2.6vw, 2rem); }
.glyph-page .glyph-topup-section { margin-top: 0; padding-top: clamp(1.5rem, 2.6vw, 2rem); }

/* ═══════════════════════════════════════════════════════════════════
   11. Единая шапка

   Кнопка в шапке была то 39, то 40 px высотой: на страницах, где
   подключён legacy.css, у .btn свои padding и line-height. Разница в
   пиксель заметна при переходе между разделами — шапка «дёргается».
   Фиксируем высоту и внутренние отступы явно.
   ═══════════════════════════════════════════════════════════════════ */
.site-head .btn-sm {
  min-height: 2.5rem;
  padding-block: 0;
  line-height: 1;
  align-items: center;
}
.site-head .head-actions { display: flex; align-items: center; gap: .5rem; }
