/* AEGIS — новые разделы сайта: вики, обращения, эфиры, кабинет.
   Подключается ПОСЛЕ style.css и ничего в нём не переопределяет:
   переменные, кнопки, шапку и подвал берём оттуда как есть. */

/* ============================================================ общее */

.page-wrap { padding: 34px 0 90px; }

/* Хлебные крошки и подзаголовок раздела */
.crumbs {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--gold); }
.crumbs span { opacity: .5; }
@media (max-width: 760px) {
  /* «Главная» в крошках — 21 px в высоту, а это единственный путь назад в
     шапке страницы. Поле сверху и снизу даёт 39 px нажимаемых; отрицательный
     внешний отступ снимает прибавку, чтобы строка крошек не разъехалась. */
  .crumbs { margin: -9px 0 5px; }
  .crumbs a { padding: 9px 0; }
}

/* Плашка «пока не работает» — честная, а не спрятанная */
.nbox {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  background: var(--panel-2);
  border-radius: 14px;
  padding: 16px 18px;
  color: var(--ink);
  font-size: 14.5px;
  line-height: 1.6;
  box-shadow: inset 3px 0 0 var(--or);
}
.nbox.warn { box-shadow: inset 3px 0 0 var(--red); }
.nbox.ok { box-shadow: inset 3px 0 0 #58C271; }
.nbox b { color: var(--gold); }
.nbox .n-ic {
  flex: none;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  opacity: .9;
}

/* Пустое состояние: список пуст, и это нормально */
.empty {
  text-align: center;
  padding: 54px 20px;
  color: var(--muted);
}
.empty h4 {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 19px;
  color: var(--ink);
  margin-bottom: 8px;
}
.empty p { font-size: 14.5px; line-height: 1.6; max-width: 460px; margin: 0 auto; }

/* Загрузка: три точки, без спиннеров-«крутилок» */
.loading {
  display: flex;
  gap: 7px;
  justify-content: center;
  padding: 60px 0;
}
.loading i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--brass);
  animation: dotpulse 1.1s ease-in-out infinite;
}
.loading i:nth-child(2) { animation-delay: .15s; }
.loading i:nth-child(3) { animation-delay: .3s; }
@keyframes dotpulse {
  0%, 60%, 100% { opacity: .25; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-5px); }
}

/* Метки-пилюли */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  padding: 0 10px;
  border-radius: 999px;
  background: var(--panel-3);
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.pill.gold { background: rgba(250, 212, 107, .14); color: var(--gold); }
.pill.red { background: rgba(255, 64, 64, .14); color: #FF7A7A; }
.pill.green { background: rgba(88, 194, 113, .14); color: #7BD692; }
.pill.live {
  background: var(--red);
  color: #fff;
  font-family: var(--f-disp);
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-size: 11px;
}
.pill.live::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #fff;
  animation: livedot 1.4s ease-in-out infinite;
}
@keyframes livedot { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }

/* Поле поиска */
.search {
  position: relative;
  display: block;
}
.search input {
  width: 100%;
  height: 44px;
  padding: 0 38px 0 40px;
  border: 0;
  border-radius: 12px;
  background: var(--panel-3);
  color: var(--ink);
  font-family: var(--f-text);
  font-size: 14.5px;
  outline: none;
  transition: box-shadow .18s ease, background .18s ease;
}
.search input::placeholder { color: #6f6c66; }
/* У каждого поля поиска есть свой крестик .s-clear. Chrome и Safari рисуют
   поверх него ещё и собственный — получалось два крестика подряд, а в Firefox
   был один. Прячем браузерный: тогда вид одинаковый везде. */
.search input::-webkit-search-cancel-button,
.search input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
.search input:focus {
  background: #26252b;
  box-shadow: 0 0 0 2px rgba(245, 134, 32, .55);
}
.search .s-ic {
  position: absolute;
  left: 13px;
  top: 50%;
  transform: translateY(-50%);
  width: 17px;
  height: 17px;
  opacity: .5;
  pointer-events: none;
}
.search .s-clear {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--muted);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  display: none;
}
.search.has .s-clear { display: block; }
.search .s-clear:hover { color: var(--ink); background: var(--panel-2); }

/* ====================================================== вики: каркас */

.doc {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr) 220px;
  gap: 44px;
  align-items: start;
}

/* левая колонка */
.doc-side {
  position: sticky;
  top: 92px;
  max-height: calc(100vh - 112px);
  overflow-y: auto;
  padding-right: 6px;
  scrollbar-width: thin;
  scrollbar-color: #33323a transparent;
}
.doc-side::-webkit-scrollbar { width: 6px; }
.doc-side::-webkit-scrollbar-thumb { background: #33323a; border-radius: 3px; }

.doc-nav { margin-top: 20px; }
/* Здесь и ещё в пяти местах этого файла стоял вписанный руками серый #74716c —
   заголовки разделов в боковом меню вики, подписи в оглавлении, шапки колонок
   обязанностей, разделы обращений, метка набора на плитке лавки и счётчик в
   меню кабинета. На панелях это 3,7–4,0:1 при кегле 11,5–12, то есть ниже
   порога читаемости, а никакого отдельного оттенка тут и не задумывалось: это
   ровно третья ступень текста, у которой на сайте есть свой цвет. Переведено на
   --steel, чтобы такие подписи чинились в одном месте, а не в шести. */
/* Подписи групп в боковом меню были h5 и стояли в разметке ПЕРЕД заголовком
   страницы — читалка выдавала «Начало, Правила, Игра, Команда», а потом уже
   название статьи, и список заголовков переставал быть оглавлением текста.
   Это подписи навигации, а не текста, поэтому они простые блоки, а сами nav и
   aside подписаны через aria-label — landmark всё равно называется. */
.doc-nav .dn-t {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 11.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--steel);
  margin: 22px 0 9px;
}
.doc-nav .dn-t:first-child { margin-top: 0; }
.doc-nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 10px;
  color: var(--ink);
  opacity: .82;
  font-size: 14.5px;
  line-height: 1.35;
  transition: background .15s ease, opacity .15s ease, color .15s ease;
}
/* Слово овнера 17.09.2026: «когда выбрал одну подкатегорию и навелся на
   соседнюю, то у них эти формы прям впритык к друг другу». Плашки стояли
   без зазора: пока подсвечена одна, границы не видно, а как только рядом
   загорается вторая — два прямоугольника слипаются в один. Разводим их
   на четыре пикселя; отступ только между соседними ссылками, чтобы под
   подписью раздела ничего лишнего не появилось. */
.doc-nav a + a { margin-top: 4px; }
.doc-nav a:hover { background: var(--panel-2); opacity: 1; }
.doc-nav a.active {
  background: var(--panel-3);
  color: var(--gold);
  opacity: 1;
  font-weight: 600;
}
.doc-nav a .dn-ic { width: 17px; height: 17px; flex: none; opacity: .75; }
.doc-nav a.active .dn-ic { opacity: 1; }

/* ================== ЗНАЧКИ БОКОВОЙ: наведение ==================
   Слово овнера 17.09.2026: «сделай еще значки у подкатегорий слева в вики
   анимированным когда наводишься на них. Каждый по своему смыслу, по смыслу
   значка пусть будет анимирован».

   Поэтому общей тряски тут нет: у каждого значка своё движение, и оно про то,
   что значок означает. Монета переворачивается, карта разворачивается, стрелки
   обмена расходятся, сумка качается, график дорисовывается и ставит стрелку,
   щит держит удар, у страницы отгибается угол, правила дописываются строкой,
   в чате правил сообщения прилетают одно за другим, ящик сборки поворачивается
   боком, вопрос подпрыгивает точкой, дежурный кивает.

   Движение проходит ОДИН раз за наведение и длится меньше секунды: это
   подсказка «ты сюда попал», а не мигалка в углу экрана. Куски значка —
   .p1, .p2, … в том порядке, в каком они перечислены в js/wiki.js.

   Заводит движение не :hover, а метка .ani — её ставит js/wiki.js на входе
   курсора, а снимает сам значок, когда всё доиграл. Раньше тут стоял :hover,
   и стоило увести курсор на середине движения, как рисунок бросал позу и
   вставал на место одним кадром — овнер назвал это подёргиванием. Теперь
   курсор можно уводить когда угодно: начатое движение доходит до конца. */
.doc-nav a .dn-ic path { transform-box: fill-box; transform-origin: 50% 50%; }

/* страница начала — отгибается угол */
@keyframes dni-fold { 40% { transform: rotate(-16deg) translate(-.5px, .4px); } }
.doc-nav a.ani .dn-ic[data-i="start"] .p2 {
  transform-origin: 0% 100%;
  animation: dni-fold .5s ease-in-out;
}

/* календарь сезона — дужки качнулись, верхняя линия прочертилась */
@keyframes dni-tick { 30% { transform: translateY(-1.6px); } 65% { transform: translateY(0); } }
@keyframes dni-line {
  from { stroke-dasharray: 16; stroke-dashoffset: 16; }
  to   { stroke-dasharray: 16; stroke-dashoffset: 0; }
}
.doc-nav a.ani .dn-ic[data-i="season"] .p2 { animation: dni-line .45s ease-out .08s both; }
.doc-nav a.ani .dn-ic[data-i="season"] .p3 { animation: dni-tick .45s ease-in-out; }
.doc-nav a.ani .dn-ic[data-i="season"] .p4 { animation: dni-tick .45s ease-in-out .07s; }

/* правила игры — строки дописываются */
.doc-nav a.ani .dn-ic[data-i="rules-game"] .p2 { animation: dni-line .3s ease-out both; }
.doc-nav a.ani .dn-ic[data-i="rules-game"] .p3 { animation: dni-line .3s ease-out .14s both; }

/* правила дискорда — сообщения прилетают одно за другим */
@keyframes dni-msg {
  from { opacity: 0; transform: translateX(-3px); }
  to   { opacity: 1; transform: translateX(0); }
}
.doc-nav a.ani .dn-ic[data-i="rules-discord"] .p2 { animation: dni-msg .26s ease-out both; }
.doc-nav a.ani .dn-ic[data-i="rules-discord"] .p3 { animation: dni-msg .26s ease-out .16s both; }

/* экономика — монета переворачивается */
@keyframes dni-flip { to { transform: rotateY(360deg); } }
.doc-nav a.ani .dn-ic[data-i="economy"] { animation: dni-flip .7s ease-in-out; }

/* заработок — линия дорисовывается, стрелка встаёт на место */
@keyframes dni-draw {
  from { stroke-dasharray: 48; stroke-dashoffset: 48; }
  to   { stroke-dasharray: 48; stroke-dashoffset: 0; }
}
@keyframes dni-pop {
  from { opacity: 0; transform: scale(.4); }
  70%  { opacity: 1; transform: scale(1.12); }
  to   { transform: scale(1); }
}
.doc-nav a.ani .dn-ic[data-i="earn"] .p1 { animation: dni-draw .42s ease-out both; }
.doc-nav a.ani .dn-ic[data-i="earn"] .p2 {
  transform-origin: 0% 100%;
  animation: dni-pop .3s ease-out .36s both;
}

/* лавка — сумку качнули, будто её несут */
@keyframes dni-swing {
  25% { transform: rotate(7deg); }
  60% { transform: rotate(-5deg); }
  to  { transform: rotate(0); }
}
.doc-nav a.ani .dn-ic[data-i="market"] {
  transform-origin: 50% 12%;
  animation: dni-swing .6s ease-in-out;
}

/* обмен — стрелки разъезжаются каждая в свою сторону */
@keyframes dni-swap-r { 40% { transform: translateX(2.4px); } to { transform: translateX(0); } }
@keyframes dni-swap-l { 40% { transform: translateX(-2.4px); } to { transform: translateX(0); } }
.doc-nav a.ani .dn-ic[data-i="trade"] .p1 { animation: dni-swap-r .5s ease-in-out; }
.doc-nav a.ani .dn-ic[data-i="trade"] .p2 { animation: dni-swap-l .5s ease-in-out; }

/* державы — щит принимает удар и держит */
@keyframes dni-brace {
  30% { transform: scale(.9); }
  65% { transform: scale(1.06); }
  to  { transform: scale(1); }
}
.doc-nav a.ani .dn-ic[data-i="states"] { animation: dni-brace .5s ease-out; }

/* земля — карта разворачивается, сгибы проступают */
@keyframes dni-unfold {
  from { transform: scaleX(.55); }
  65%  { transform: scaleX(1.05); }
  to   { transform: scaleX(1); }
}
@keyframes dni-crease { from { opacity: .2; } to { opacity: 1; } }
.doc-nav a.ani .dn-ic[data-i="land"] { animation: dni-unfold .5s ease-out; }
.doc-nav a.ani .dn-ic[data-i="land"] .p2,
.doc-nav a.ani .dn-ic[data-i="land"] .p3 { animation: dni-crease .5s ease-out; }

/* сборка — ящик поворачивается боком */
@keyframes dni-turn {
  35% { transform: rotateY(-38deg); }
  75% { transform: rotateY(22deg); }
  to  { transform: rotateY(0); }
}
.doc-nav a.ani .dn-ic[data-i="modpack"] { animation: dni-turn .65s ease-in-out; }

/* частые вопросы — точка подпрыгивает, крючок клонится */
@keyframes dni-ask-dot {
  30% { transform: translateY(-2.2px); }
  60% { transform: translateY(0); }
  78% { transform: translateY(-.8px); }
  to  { transform: translateY(0); }
}
@keyframes dni-ask-hook {
  35% { transform: rotate(-9deg); }
  70% { transform: rotate(5deg); }
  to  { transform: rotate(0); }
}
.doc-nav a.ani .dn-ic[data-i="faq"] .p1 { animation: dni-ask-dot .55s ease-in-out; }
.doc-nav a.ani .dn-ic[data-i="faq"] .p2 {
  transform-origin: 50% 100%;
  animation: dni-ask-hook .55s ease-in-out;
}

/* команда — дежурный кивает */
@keyframes dni-nod {
  30% { transform: translateY(1.4px) rotate(-5deg); }
  65% { transform: translateY(-.6px) rotate(3deg); }
  to  { transform: none; }
}
.doc-nav a.ani .dn-ic[data-i="duties"] .p1 {
  transform-origin: 50% 100%;
  animation: dni-nod .5s ease-in-out;
}

/* карта мира — планета поворачивается. Крутить весь значок нельзя: круг
   поехал бы вместе с ним, а поворот глобуса видно как раз по меридианам.
   Поэтому сжимаются только они, каждый к своему краю — к линии полюсов. */
@keyframes dni-globe { 50% { transform: scaleX(.12); } to { transform: scaleX(1); } }
.doc-nav a .dn-ic[data-i="map"] .p3 { transform-origin: 0 50%; }
.doc-nav a .dn-ic[data-i="map"] .p4 { transform-origin: 100% 50%; }
.doc-nav a.ani .dn-ic[data-i="map"] .p3,
.doc-nav a.ani .dn-ic[data-i="map"] .p4 { animation: dni-globe .7s ease-in-out; }

/* вера — огонь под сводом качается. Свод и опора стоят: движется то, что
   и должно двигаться. */
@keyframes dni-flame {
  35% { transform: scaleY(1.3) scaleX(.9); }
  70% { transform: scaleY(.94) scaleX(1.04); }
  to  { transform: none; }
}
.doc-nav a.ani .dn-ic[data-i="faith"] .p3 {
  transform-origin: 50% 100%;
  animation: dni-flame .6s ease-in-out;
}

/* Кому движение мешает — тому его нет: системная настройка, не наша. */
@media (prefers-reduced-motion: reduce) {
  .doc-nav a.ani .dn-ic,
  .doc-nav a.ani .dn-ic path { animation: none !important; }
}

/* результаты поиска вместо списка страниц */
.doc-found { margin-top: 18px; }
.doc-found .df-n {
  font-size: 12.5px;
  color: var(--muted);
  padding: 0 4px 10px;
}
.doc-found a {
  display: block;
  padding: 10px 12px;
  border-radius: 10px;
  color: var(--ink);
  transition: background .15s ease;
}
.doc-found a:hover { background: var(--panel-2); }
.doc-found a b {
  display: block;
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 3px;
}
.doc-found a s {
  display: block;
  font-size: 12.5px;
  color: var(--muted);
  text-decoration: none;
  line-height: 1.45;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.doc-found mark {
  background: rgba(250, 212, 107, .22);
  color: var(--gold-hi);
  border-radius: 3px;
  padding: 0 2px;
}

/* правая колонка «на этой странице» */
.doc-toc {
  position: sticky;
  top: 92px;
  max-height: calc(100vh - 112px);
  overflow-y: auto;
  font-size: 13.5px;
  scrollbar-width: none;
}
.doc-toc::-webkit-scrollbar { display: none; }
.doc-toc .dn-t {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 11.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--steel);
  margin-bottom: 12px;
}
.doc-toc a {
  display: block;
  padding: 6px 0 6px 14px;
  color: var(--muted);
  line-height: 1.45;
  box-shadow: inset 2px 0 0 rgba(255, 255, 255, .07);
  transition: color .15s ease, box-shadow .15s ease;
}
.doc-toc a:hover { color: var(--ink); }
.doc-toc a.active {
  color: var(--gold);
  box-shadow: inset 2px 0 0 var(--or);
}

/* ====================================================== вики: текст */

.doc-body { min-width: 0; padding-bottom: 40px; }
/* Слово овнера 17.09.2026: «переход между категориями должен плавно
   осуществляться, а не резко». Текст и оглавление гаснут, текст при этом
   чуть съезжает вниз — как будто страница уступает место следующей. Пока
   их не видно, js/wiki.js подменяет разметку и рывком возвращает окно к
   началу: сам прыжок наверх на экран не попадает.
   Метку .is-swap ставит и снимает js/wiki.js; в «спокойном режиме» он её
   вообще не ставит, но переход снимаем и здесь — на случай, если разметку
   поменяет что-то ещё. */
.doc-body, .doc-toc { transition: opacity .16s ease, transform .16s ease; }
.doc-body.is-swap { opacity: 0; transform: translateY(8px); }
.doc-toc.is-swap { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .doc-body, .doc-toc { transition: none; }
}

.doc-body > .dh { margin-bottom: 28px; }
.doc-body .dh h1 {
  font-family: var(--f-disp);
  font-weight: 900;
  font-size: clamp(30px, 4vw, 44px);
  line-height: 1.08;
  letter-spacing: -.01em;
  margin-bottom: 14px;
}
.doc-body .dh p {
  font-size: 16px;
  line-height: 1.7;
  color: #c9c5bd;
  max-width: 62ch;
}

.doc-h2 {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 23px;
  line-height: 1.25;
  margin: 40px 0 16px;
  scroll-margin-top: 96px;
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.doc-h2 .anchor {
  opacity: 0;
  color: var(--brass);
  font-size: 17px;
  font-family: var(--f-text);
  transition: opacity .15s ease;
}
.doc-h2:hover .anchor,
.doc-h2 .anchor:focus-visible { opacity: 1; }
/* На телефоне наведения не бывает — значок «ссылка на раздел» там не появлялся
   вообще. При грубом указателе показываем его сразу, приглушённым.
   Раз он виден, в него будут тыкать, а сама решётка — 11 пикселей шириной:
   пальцем в неё не попасть. Расширяем область нажатия полями и снимаем их
   отрицательным отступом, чтобы зазор до заголовка остался прежним. */
@media (hover: none) {
  .doc-h2 .anchor {
    opacity: .5;
    padding: 6px 8px;
    margin: -6px -8px;
  }
}
/* Заголовок — гибкая строка, и решётка в ней последняя. Пока текст влезал в одну
   строку, всё было ровно; на телефоне длинные заголовки («Что нужно, чтобы
   играть», «Как получить страну») переносятся, и решётку выдавливало за правый
   край колонки — она вылезала из карточки на 3-8 пикселей. Переносить её нечем:
   wiki.js клеит ссылку к тексту без пробела, а значит браузеру негде разорвать
   строку. На узком экране убираем гибкую раскладку и прибиваем решётку к верхнему
   правому углу заголовка, а место под неё держим полем справа — текст в неё не
   упирается, куда бы ни перенёсся. */
@media (max-width: 760px) {
  .doc-h2 {
    display: block;
    position: relative;
    padding-right: 32px;
  }
  .doc-h2 .anchor {
    position: absolute;
    right: 0;
    top: -5px;
    margin: 0;
    /* Поле слева, а не по кругу: нажимаемая область получается 39×39, но наружу
       за край колонки не выходит ни на пиксель. */
    padding: 9px 2px 9px 26px;
  }
}

.doc-p {
  font-size: 15.5px;
  line-height: 1.75;
  color: #cbc7bf;
  margin: 0 0 14px;
  max-width: 70ch;
}
.doc-p b, .doc-li b { color: var(--ink); font-weight: 700; }
.doc-p a, .doc-li a, .doc-body .qa-a a { color: var(--gold); }
.doc-p a:hover, .doc-li a:hover, .doc-body .qa-a a:hover { color: var(--gold-hi); }
.doc-p code, .doc-li code, .qa-a code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: .89em;
  background: var(--panel-3);
  color: var(--spark);
  padding: 2px 6px;
  border-radius: 6px;
}
.doc-ul { list-style: none; margin: 0 0 14px; padding: 0; max-width: 70ch; }
.doc-li {
  position: relative;
  padding-left: 20px;
  font-size: 15.5px;
  line-height: 1.7;
  color: #cbc7bf;
  margin-bottom: 7px;
}
.doc-li::before {
  content: '';
  position: absolute;
  left: 3px;
  top: 11px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brass);
}
/* Нумерованный список: порядок шагов важен, точками его не передать. */
.doc-ol { counter-reset: dstep; padding-left: 4px; }
.doc-ol .doc-li { counter-increment: dstep; padding-left: 30px; }
.doc-ol .doc-li::before {
  content: counter(dstep);
  top: 0;
  left: 0;
  width: 21px;
  height: 21px;
  border-radius: 7px;
  background: var(--panel-3);
  color: var(--gold);
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 11.5px;
  line-height: 21px;
  text-align: center;
}

/* Правила: номер, сам пункт и мера под ним. Мера бывает длинной
   («предупреждение → мут → бан»), поэтому отдельной колонкой её не делаем —
   она бы съела всю ширину и текст правила встал бы столбиком. */
.rule {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 4px 12px;
  align-items: start;
  background: var(--panel);
  border-radius: 13px;
  padding: 15px 17px;
  margin-bottom: 9px;
  position: relative;
  overflow: hidden;
  transition: background .16s ease;
}
/* Пункт правил не съезжает вбок под курсором — вместо сдвига слева
   загорается полоска акцента. Строк много, и любое движение в списке
   читается как дрожь. */
.rule::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--grad);
  transform: scaleY(0);
  transform-origin: center top;
  transition: transform .18s ease;
}
.rule:hover { background: var(--panel-2); }
.rule:hover::before { transform: scaleY(1); }
.rule .r-n {
  grid-row: 1 / span 2;
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 13px;
  color: var(--brass);
  padding-top: 3px;
}
.rule .r-t { font-size: 15px; line-height: 1.65; color: #cbc7bf; }
.rule .r-t b { color: var(--ink); }
.rule .r-p {
  justify-self: start;
  max-width: 100%;
  margin-top: 6px;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.45;
  color: #FF8A8A;
  background: rgba(255, 64, 64, .1);
  border-radius: 8px;
  padding: 5px 10px;
}
.rule .r-p::before {
  content: 'мера: ';
  color: #b06060;
  font-weight: 500;
}

/* должности */
.duty {
  background: var(--panel);
  border-radius: 15px;
  padding: 20px 22px;
  margin-bottom: 12px;
}
.duty-h {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.duty-h h3 {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 18px;
}
.duty-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.duty-cols h6 {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 11.5px;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--steel);
  margin-bottom: 8px;
}
.duty-cols .doc-li { font-size: 14.5px; }

/* сборка модов */
.mods-groups { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.mod-group {
  background: var(--panel);
  border-radius: 15px;
  padding: 18px 20px;
}
.mod-group h3 {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 16px;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 9px;
}
.mod-group h3 em {
  font-style: normal;
  font-family: var(--f-text);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
}
.mod-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 6px 0;
  font-size: 14px;
}
.mod-row + .mod-row { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .045); }
.mod-row span { color: #cbc7bf; }
.mod-row em {
  margin-left: auto;
  font-style: normal;
  font-size: 12px;
  color: #6f6c66;
  font-family: ui-monospace, Consolas, monospace;
}

/* частые вопросы — аккордеон */
.qa {
  background: var(--panel);
  border-radius: 13px;
  margin-bottom: 9px;
  overflow: hidden;
}
.qa-q {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 17px 20px;
  background: none;
  border: 0;
  color: var(--ink);
  font-family: var(--f-text);
  font-size: 15.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background .15s ease;
}
.qa-q:hover { background: var(--panel-2); }
.qa-q .qa-x {
  margin-left: auto;
  flex: none;
  width: 13px;
  height: 13px;
  position: relative;
  transition: transform .25s cubic-bezier(.2, .8, .3, 1);
}
.qa-q .qa-x::before, .qa-q .qa-x::after {
  content: '';
  position: absolute;
  background: var(--brass);
  border-radius: 2px;
}
.qa-q .qa-x::before { left: 0; right: 0; top: 5.5px; height: 2px; }
.qa-q .qa-x::after { top: 0; bottom: 0; left: 5.5px; width: 2px; transition: opacity .2s ease; }
.qa.open .qa-x { transform: rotate(180deg); }
.qa.open .qa-x::after { opacity: 0; }
.qa-wrap {
  display: grid;
  grid-template-rows: 0fr;
  /* Свёрнутый ответ имеет нулевую высоту, но остаётся на странице: без
     visibility табуляция проваливалась в двадцать восемь невидимых ссылок
     внутри закрытых вопросов. Переключается скачком в конце перехода —
     раскрытие и сворачивание остаются плавными. */
  visibility: hidden;
  transition: grid-template-rows .28s cubic-bezier(.2, .8, .3, 1), visibility .28s;
}
.qa.open .qa-wrap { grid-template-rows: 1fr; visibility: visible; }
.qa-a { overflow: hidden; }
.qa-a > div { padding: 0 20px 19px; }
.qa-a .doc-p, .qa-a .doc-li { font-size: 15px; }
.qa-a .doc-p:last-child, .qa-a .doc-ul:last-child { margin-bottom: 0; }

/* мобильная кнопка «содержание» */
.doc-open {
  display: none;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: 46px;
  padding: 0 16px;
  border: 0;
  border-radius: 12px;
  background: var(--panel-2);
  color: var(--ink);
  font-family: var(--f-text);
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
  margin-bottom: 20px;
}
.doc-open svg { width: 18px; height: 18px; opacity: .7; }

/* ==================================================== обращения */

/* Заголовок кучки тем. Тем девятнадцать, и без разбивки это стена, в которой
   не найти свою. */
.tk-gt {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 15px;
  letter-spacing: .01em;
  color: var(--muted);
  margin: 30px 0 12px;
}
.tk-gt:first-of-type { margin-top: 4px; }

.tk-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 12px;
}
.tk-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  text-align: left;
  background: var(--panel);
  border: 0;
  border-radius: 15px;
  padding: 18px 19px;
  cursor: pointer;
  font-family: var(--f-text);
  color: var(--ink);
  transition: background .18s ease, box-shadow .18s ease;
}
.tk-card:hover,
.tk-card:focus-visible {
  background: var(--panel-2);
  box-shadow: 0 12px 26px rgba(0, 0, 0, .35),
              inset 0 0 0 1px rgba(245, 134, 32, .34);
}
/* С клавиатуры карточка выглядела ровно как под курсором — тонкая рамка внутри
   и тень. Понять, где сейчас стоит фокус, по ней нельзя: полсотни тем, и все
   одинаковые. Ставим ту же сплошную рамку в два пикселя, что у плиток китов и
   кейсов, — по сайту это уже привычный знак «ты здесь». */
.tk-card:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--or), 0 12px 26px rgba(0, 0, 0, .35);
}
/* Значок темы рисуется своим пером (js/tickets.js), а не шрифтом эмодзи.
   Размер задаётся кеглем — так же, как раньше эмодзи, поэтому правила ниже
   про 22 и 30 пикселей работают без изменений. */
.tk-e { display: block; color: var(--or); }
.tk-e svg { width: 1em; height: 1em; display: block; }
.tk-card .tk-e { font-size: 22px; line-height: 1; }
.tk-card h3 { font-family: var(--f-disp); font-weight: 800; font-size: 16px; }
.tk-card p { font-size: 13.5px; line-height: 1.55; color: var(--muted); }

/* Форма и колонка-подсказка. Колонка держится у верха экрана, пока листают
   длинную форму: «когда ответят» должно быть видно в момент сомнения, а не
   только если долистать до низа. */
.tk-two {
  display: grid;
  /* Левая колонка забирает остаток, а не ровно 720px: иначе справа от
     подсказки оставалась ничейная полоса в сотню пикселей — читается как
     недоделка. Саму форму держит узкой .tk-form. */
  grid-template-columns: minmax(0, 1fr) minmax(230px, 290px);
  gap: 40px;
  align-items: start;
}
.tk-side {
  position: sticky;
  top: 92px;
  display: grid;
  gap: 14px;
}
.tk-sc {
  background: var(--panel-2);
  border-radius: 14px;
  padding: 18px 20px;
}
.tk-sc h3 {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 11.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--steel);
  margin-bottom: 12px;
}
.tk-sc ul { display: grid; gap: 10px; list-style: none; }
.tk-sc li {
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--muted);
  padding-left: 14px;
  position: relative;
}
.tk-sc li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--or);
}
.tk-sc b { color: var(--ink); font-weight: 700; }

.tk-form { max-width: 720px; }
.tk-form .tk-head {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 8px;
}
.tk-form .tk-head .tk-e { font-size: 30px; line-height: 1; }
.tk-form .tk-head h2 {
  font-family: var(--f-disp);
  font-weight: 900;
  font-size: 28px;
}
.tk-form .tk-long {
  font-size: 15px;
  line-height: 1.7;
  color: #c9c5bd;
  margin-bottom: 24px;
}

.field { margin-bottom: 18px; }
.field label {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 7px;
}
.field label em {
  font-style: normal;
  font-size: 12px;
  font-weight: 500;
  color: #6f6c66;
  margin-left: auto;
}
.field label .req { color: var(--or); }
.field input, .field textarea, .field select {
  width: 100%;
  border: 0;
  border-radius: 12px;
  background: var(--panel-3);
  color: var(--ink);
  font-family: var(--f-text);
  font-size: 15px;
  line-height: 1.6;
  padding: 12px 14px;
  outline: none;
  transition: box-shadow .18s ease, background .18s ease;
}
.field textarea { min-height: 118px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: #66635e; }
.field input:focus, .field textarea:focus, .field select:focus {
  background: #26252b;
  box-shadow: 0 0 0 2px rgba(245, 134, 32, .55);
}
.field.bad input, .field.bad textarea { box-shadow: 0 0 0 2px rgba(255, 64, 64, .6); }

/* Галочка — не поле ввода. Правило выше тянет любой input во всю строку, и
   квадратик оставался у левого края, а подпись уезжала на полстроки вправо:
   выглядело сломанной вёрсткой. Здесь ширина своя, строка выравнивается по
   центру (по базовой линии квадратик сползал вниз), а сама строка сделана
   нормальной целью для пальца — нажимается вся, а не квадратик 13 пикселей. */
.field input[type=checkbox], .field input[type=radio] {
  width: auto;
  flex: none;
  margin: 0;
}
.field label:has(input[type=checkbox]), .field label:has(input[type=radio]) {
  align-items: center;
  min-height: 36px;
  font-weight: 500;
  cursor: pointer;
}

/* Safari на айфоне сам увеличивает страницу, когда палец встаёт в поле со
   шрифтом мельче 16px. Человек нажимает «Ник» — страница прыгает, разъезжается
   вширь, и сводить её обратно приходится пальцами; на вход в кабинет и на
   поиск обращения это ложится хуже всего, там это первое действие. Шестнадцать
   пикселей — порог самого Safari, меньше нельзя. Трогаем только сенсорные
   экраны: на мониторе размеры полей остаются прежними. */
@media (pointer: coarse) {
  .field input, .field textarea, .field select,
  .search input { font-size: 16px; }
}
.field .err {
  display: none;
  font-size: 12.5px;
  color: #FF8A8A;
  margin-top: 6px;
}
.field.bad .err { display: block; }
.field .cnt {
  font-size: 12px;
  color: #6f6c66;
  text-align: right;
  margin-top: 5px;
}
.field .cnt.over { color: #FF8A8A; }

.form-go {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 26px;
}
.form-go .fg-note { font-size: 13px; color: var(--muted); line-height: 1.5; }

.tk-back { margin-top: 26px; font-size: 14px; }
.tk-back a { color: var(--muted); }
.tk-back a:hover { color: var(--gold); }

/* Проверка обращения по номеру. Стоит в самом низу витрины тем: тем, кто
   пришёл писать, она не мешает, а тем, кто пришёл узнать — находится. */
.tk-status { margin-top: 46px; max-width: 620px; }
.tk-st-p { font-size: 14px; line-height: 1.6; color: var(--muted); margin-bottom: 14px; }
.tk-st-form { display: flex; gap: 10px; flex-wrap: wrap; }
.tk-st-form .search { flex: 1 1 240px; }
.tk-st-say { margin-top: 12px; font-size: 14px; line-height: 1.6; color: #cbc7bf; min-height: 20px; }
.tk-st-say b { color: var(--gold); }

/* ======================================================== эфиры */

.lv-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px 20px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}
.lv-head .live-tabs { margin-bottom: 0; }
.lv-when { font-size: 13px; color: var(--muted); line-height: 1.5; }

.lv-gt {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 15px;
  color: var(--muted);
  margin: 34px 0 12px;
}
.lv-gt:first-of-type { margin-top: 0; }

.lv-cta {
  margin-top: 40px;
  padding: 22px 24px;
  background: var(--panel);
  border-radius: 16px;
  max-width: 640px;
}
.lv-cta h4 {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 17px;
  margin-bottom: 8px;
}
.lv-cta p { font-size: 14px; line-height: 1.65; color: var(--muted); }
.lv-cta p + p { margin-top: 10px; }
.lv-cta a { color: var(--gold); }

/* min(280px, 100%), а не просто 280px: minmax не умеет быть уже своего минимума,
   и на телефоне, где колонка под контейнером всего 327 пикселей, карточка вылезала
   за правый край — слева отступ 24, справа ноль. Ограничение сотней процентов
   разрешает колонке сжаться до ширины контейнера, а на широком экране ничего
   не меняет. */
.live-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 16px;
}
.live-card {
  display: block;
  background: var(--panel);
  border-radius: 16px;
  overflow: hidden;
  transition: background .2s ease, box-shadow .2s ease;
}
/* Карточка эфира стоит на месте, приближается только само превью — так
   заметно, что она «живая», и курсор с неё не соскакивает. */
.live-card:hover,
.live-card:focus-visible {
  background: var(--panel-2);
  box-shadow: 0 16px 34px rgba(0, 0, 0, .42),
              inset 0 0 0 1px rgba(245, 134, 32, .3);
}
.live-thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--panel-3);
  overflow: hidden;
}
.live-thumb img {
  position: relative;   /* поверх буквы-подложки .lv-noimg */
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* как у .shot img на главной: явный покой и свой слой, иначе картинка
     дёргается на последнем кадре возврата */
  transform: scale(1);
  will-change: transform;
  transition: transform .45s ease;
}
.live-card:hover .live-thumb img { transform: scale(1.04); }
/* Метки поверх превью: у картинки свой слой, иначе она их перекроет. */
.live-thumb .pill,
.live-thumb .lv-st,
.live-thumb .l-plat,
.live-thumb .l-view { z-index: 2; }
.live-thumb .pill { position: absolute; left: 10px; top: 10px; }
.live-thumb .l-plat {
  position: absolute;
  right: 10px;
  top: 10px;
  height: 24px;
  padding: 0 9px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .62);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.live-thumb .l-view {
  position: absolute;
  right: 10px;
  bottom: 10px;
  height: 24px;
  padding: 0 9px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .62);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
}
.live-meta { padding: 14px 16px 16px; }
/* Название эфира пишет сам стример — это обычный текст, а не заголовок
   раздела: капс и «дисплейный» шрифт тут только мешали бы читать. */
.live-meta h3 {
  font-family: var(--f-text);
  text-transform: none;
  letter-spacing: 0;
  color: var(--ink);
  transition: color .15s ease;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.4;
  margin-bottom: 8px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
a.live-card:hover .live-meta h3 { color: var(--gold); }
.live-who { display: flex; align-items: center; gap: 9px; }
.live-who img { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; }
.live-who .lw-n { font-size: 13.5px; color: var(--muted); }
.live-who .lw-off { margin-left: auto; font-size: 12.5px; color: var(--muted-2, #6f6a61); }
.live-card.off { opacity: .82; }
.live-card.off:hover { opacity: 1; }
.live-card.off .live-thumb img { filter: grayscale(.85) brightness(.6); }
.live-card.off .live-meta h3 { color: var(--muted); font-weight: 500; }

/* Превью нет — вместо дыры буква канала на спокойном фоне. */
.lv-noimg {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 34px;
  letter-spacing: .04em;
  color: rgba(255, 255, 255, .13);
  background: linear-gradient(140deg, var(--panel-2), var(--panel-3));
}
.live-thumb .lv-st {
  position: absolute;
  left: 10px;
  top: 10px;
  height: 24px;
  padding: 0 10px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .62);
  color: #ded9d1;
  font-size: 11.5px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
}

/* Ряд каналов без превью — строкой, а не сеткой пустых прямоугольников.
   auto-fit вместо auto-fill: пустые колонки схлопываются, и один канал
   занимает всю ширину строкой, а не жмётся в угол широкой пустой сетки.
   Разметку компактной карточки собирает live.js. */
.live-grid.slim { grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); }
.live-card.slim {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
}
.live-card.slim .lv-mark {
  width: 46px;
  height: 46px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 19px;
  color: rgba(255, 255, 255, .22);
  background: linear-gradient(140deg, var(--panel-2), var(--panel-3));
}
.live-card.slim .live-meta { padding: 0; }
.live-card.slim .live-meta h3 { margin-bottom: 5px; }
.live-card.slim .lv-side {
  display: flex;
  align-items: center;
  gap: 9px;
  white-space: nowrap;
}
.live-card.slim .l-plat,
.live-card.slim .lv-st {
  height: 24px;
  padding: 0 10px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  font-size: 11.5px;
  font-weight: 700;
  background: var(--panel-3);
  color: var(--muted);
}
.live-card.slim .lv-st { font-weight: 600; }
/* На узком экране состояние и площадка не помещаются третьей колонкой —
   уводим их под название, к имени канала. */
@media (max-width: 560px) {
  .live-card.slim { grid-template-columns: 46px minmax(0, 1fr); }
  .live-card.slim .lv-side { grid-column: 2; margin-top: 2px; }
  /* Третьей колонкой эти две плашки жались по ширине, и 11.5 пикселя были платой
     за место. Под названием места хватает, а «не в эфире» — это единственное, что
     на странице вообще надо прочитать, когда никто не стримит. */
  .live-card.slim .l-plat,
  .live-card.slim .lv-st { font-size: 12.5px; height: 26px; }
}

.live-tabs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}
.live-tabs button {
  height: 36px;
  padding: 0 15px;
  border: 0;
  border-radius: 999px;
  background: var(--panel);
  color: var(--muted);
  font-family: var(--f-text);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.live-tabs button:hover { background: var(--panel-2); color: var(--ink); }
.live-tabs button.on { background: var(--grad); color: #201203; }

/* ==================================================== кабинет */

.cab {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: 40px;
  align-items: start;
}
.cab-side { position: sticky; top: 92px; }
.cab-me {
  display: flex;
  align-items: center;
  gap: 13px;
  background: var(--panel);
  border-radius: 15px;
  padding: 15px 16px;
  margin-bottom: 16px;
}
.cab-me img {
  width: 46px;
  height: 46px;
  border-radius: 11px;
  background: var(--panel-3);
  image-rendering: pixelated;
}
/* Голова скина. Служба отдаёт целый скин 64×64 — вырезаем из него голову
   рамкой и увеличением, чтобы не тащить в браузер холст и чужие рендеры. */
.cab-me .cm-av {
  position: relative;
  flex: none;
  width: 46px;
  height: 46px;
  border-radius: 11px;
  overflow: hidden;
  background: linear-gradient(150deg, #2a2830, #1a191d);
}
.cab-me .cm-av .cm-let {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--f-disp);
  font-weight: 900;
  font-size: 19px;
  color: #6b6862;
}
.cab-me .cm-av img {
  position: absolute;
  left: -46px;
  top: -46px;
  width: 368px;
  height: 368px;
  max-width: none;
  border-radius: 0;
  image-rendering: pixelated;
}
.cab-me .cm-n { font-family: var(--f-disp); font-weight: 800; font-size: 16px; }
.cab-me .cm-s { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

.cab-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; }
.tile {
  background: var(--panel);
  border-radius: 16px;
  padding: 19px 20px;
}
.tile .t-k {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--steel);
  margin-bottom: 9px;
}
.tile .t-v {
  font-family: var(--f-disp);
  font-weight: 900;
  font-size: 30px;
  line-height: 1;
  color: var(--gold);
}
.tile .t-s { font-size: 13px; color: var(--muted); margin-top: 8px; line-height: 1.5; }

.cab-block { margin-top: 34px; }
/* Заголовок раздела внутренней страницы. На главной над каждым разделом стоит
   короткая черта — здесь та же черта, только меньше и слева от текста: блоки
   кабинета идут плотно один за другим, и черта над строкой съела бы воздух
   между ними. Рисуем псевдоэлементом, поэтому она появляется и в заголовках,
   которые собирает скрипт (кабинет, панель), — разметку менять не пришлось. */
.cab-block > h2 {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 21px;
  margin-bottom: 14px;
}
.cab-block > h2::before {
  content: '';
  flex: 0 0 auto;
  width: 22px;
  height: 3px;
  border-radius: 2px;
  background: var(--grad-h);
}

/* строки списков (наказания, история, сообщения) */
.row-list { background: var(--panel); border-radius: 15px; overflow: hidden; }
.row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 14px 18px;
}
.row + .row { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .045); }
.row .rw-t { font-size: 14.5px; line-height: 1.5; }
.row .rw-s { font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.row .rw-r { text-align: right; font-size: 13px; color: var(--muted); white-space: nowrap; }
/* Значение перед кнопкой в правой ячейке («свой» → «Поменять»). Зазор держит
   сам текст: у кнопки отступ слева на узком экране снимается, и без этого
   слово упиралось бы в кнопку. */
.row .rw-v { margin-right: 10px; }
.row .rw-v + .btn { margin-left: 0; }

/* лог чата сервера */
.chatlog {
  background: #131316;
  border-radius: 15px;
  padding: 14px 16px;
  max-height: 460px;
  overflow-y: auto;
  font-size: 14px;
  line-height: 1.65;
}
.chatlog .cl {
  display: grid;
  grid-template-columns: 62px 150px minmax(0, 1fr);
  gap: 10px;
  padding: 3px 0;
}
.chatlog .cl-t { color: #5f5c57; font-family: ui-monospace, Consolas, monospace; font-size: 12.5px; }
.chatlog .cl-n { color: var(--gold); font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
.chatlog .cl-m { color: #cbc7bf; word-break: break-word; }
.chatlog .cl.sys .cl-m { color: var(--muted); font-style: italic; }

/* панель действий администратора */
.adm-bar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
  background: var(--panel);
  border-radius: 15px;
  padding: 14px 16px;
  margin-bottom: 16px;
}
.adm-bar .search { flex: 1 1 220px; }
.adm-bar select {
  height: 44px;
  border: 0;
  border-radius: 12px;
  background: var(--panel-3);
  color: var(--ink);
  font-family: var(--f-text);
  font-size: 14px;
  padding: 0 12px;
  outline: none;
}

/* меню кабинета */
.cab-nav { display: flex; flex-direction: column; gap: 2px; }
.cab-nav button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  border: 0;
  background: none;
  color: var(--muted);
  font-family: var(--f-text);
  font-size: 14.5px;
  font-weight: 600;
  padding: 11px 14px;
  border-radius: 12px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.cab-nav button:hover { background: var(--panel); color: var(--ink); }
.cab-nav button.on { background: var(--panel-2); color: var(--ink); }
.cab-nav .cn-b {
  margin-left: auto;
  font-size: 12px;
  font-weight: 700;
  color: var(--steel);
}
.cab-nav button.on .cn-b { color: var(--gold); }
.cab-nav .cn-t {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: #5f5c57;
  margin: 20px 0 6px;
  padding: 0 14px;
}
.cab-out {
  margin-top: 18px;
  padding: 0 14px;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.6;
}
.cab-out button {
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.cab-out button:hover { color: var(--gold); }

/* вход в кабинет */
.cab-login {
  max-width: 430px;
  background: var(--panel);
  border-radius: 18px;
  padding: 26px 26px 24px;
}
.cab-login h2 {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 21px;
  margin-bottom: 8px;
}
.cab-login .cl-lead {
  font-size: 14px;
  color: var(--muted);
  line-height: 1.6;
  margin-bottom: 20px;
}
.cab-login .form-go { margin-top: 20px; }
.cab-why { margin-top: 26px; max-width: 620px; font-size: 14px; line-height: 1.65; color: var(--muted); }
/* Заголовок стал h3 вместо h4 — на странице шли h1, h2 и сразу h4, а это для
   читалки пропущенный уровень. Вид обязан остаться прежним: общее правило
   h1,h2,h3 поднимает капс, плотную строку и отрицательный трекинг, а h4 их не
   получал, поэтому все три свойства возвращаются сюда обратно. */
.cab-why h3 {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: 15px;
  color: var(--ink);
  margin-bottom: 8px;
  text-transform: none;
  line-height: inherit;
  letter-spacing: normal;
}
.cab-why ul { list-style: none; padding: 0; margin: 0; }
.cab-why li { position: relative; padding-left: 18px; margin-bottom: 6px; }
.cab-why li::before { content: '—'; position: absolute; left: 0; color: var(--or); }

/* На широком экране окно входа стояло одно у левого края, а справа оставалась
   пустая половина страницы — выглядело как незагрузившийся кусок. Ставим рядом
   вторую колонку из подсказок, которые и так рисуются ниже. Одинокую карточку
   без подсказок (например, «прав нет») просто ставим по центру.
   :has() выбран, чтобы не трогать разметку: тот же контейнер после входа
   держит уже весь кабинет, и сетку там включать нельзя. Браузер без :has()
   покажет прежнюю стопку — она тоже читается. */
@media (min-width: 900px) {
  #cbBody:has(> .cab-login):has(> .cab-why),
  #adBody:has(> .cab-login):has(> .cab-why) {
    display: grid;
    grid-template-columns: minmax(0, 430px) minmax(0, 1fr);
    gap: 30px;
    align-items: start;
  }
  #cbBody:has(> .cab-login):has(> .cab-why) > .cab-login,
  #adBody:has(> .cab-login):has(> .cab-why) > .cab-login { max-width: none; }
  #cbBody:has(> .cab-login):has(> .cab-why) > .cab-why,
  #adBody:has(> .cab-login):has(> .cab-why) > .cab-why {
    margin-top: 0;
    max-width: none;
    background: var(--panel-2);
    border-radius: 18px;
    padding: 24px 26px;
  }
  /* Полоска ответа сверху относится к обеим колонкам сразу. */
  #cbBody:has(> .cab-login) > .cb-msg,
  #adBody:has(> .cab-login) > .cb-msg { grid-column: 1 / -1; }
  #cbBody:has(> .cab-login):not(:has(> .cab-why)) > .cab-login,
  #adBody:has(> .cab-login):not(:has(> .cab-why)) > .cab-login { margin-inline: auto; }
}

/* полоска ответа: получилось / не получилось */
.cb-msg {
  border-radius: 12px;
  padding: 12px 15px;
  font-size: 14px;
  line-height: 1.55;
  margin-bottom: 16px;
}
.cb-msg.ok { background: rgba(88, 194, 113, .12); color: #9FE0AF; }
.cb-msg.bad { background: rgba(255, 64, 64, .12); color: #FF9A9A; }

.cab-hint { font-size: 13.5px; color: var(--muted); line-height: 1.6; margin-bottom: 14px; max-width: 640px; }
.row .rw-r .btn { margin-left: 12px; }
/* Строка без значка слева — не держим под него пустую колонку. */
.row.r2 { grid-template-columns: minmax(0, 1fr) auto; }

/* Ссылка в меню кабинета (управление сайтом) — выглядит как пункт меню,
   но уводит на другую страницу, поэтому и подчёркнута стрелкой. */
.cab-nav .cn-go {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  padding: 11px 14px;
  border-radius: 11px;
  font-family: var(--f-text);
  font-weight: 600;
  font-size: 14px;
  color: var(--gold);
  background: var(--panel);
  transition: background .15s ease;
}
.cab-nav .cn-go::after { content: '→'; margin-left: auto; opacity: .7; }
.cab-nav .cn-go:hover { background: var(--panel-2); }

/* варианты ответа в экзамене */
.ex-opts { display: flex; flex-direction: column; gap: 2px; margin-bottom: 14px; }
.ex-o {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 10px;
  font-size: 14.5px;
  line-height: 1.5;
  color: #cbc7bf;
  cursor: pointer;
  transition: background .15s ease;
}
.ex-o:hover { background: var(--panel-2); }
.ex-o input { margin-top: 3px; accent-color: var(--or); flex: none; }
.ex-o input:checked + span { color: var(--ink); }
.ex-note { font-size: 12.5px; color: var(--muted); padding: 0 12px 14px; }

/* ==================================================== управление (admin.html)

   Панель нарочно построена на той же мебели, что кабинет: .cab / .cab-side /
   .cab-nav / .tile / .row-list / .field. Ниже — только то, чего в кабинете нет:
   вкладки внутри раздела, формы в две колонки и разбор экзамена. */

/* вкладки внутри раздела: состояние обращений, вид содержимого */
.ad-sub {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 22px;
}
.ad-sub button {
  font-family: var(--f-text);
  font-weight: 600;
  font-size: 13.5px;
  color: var(--muted);
  background: var(--panel);
  border: 0;
  border-radius: 10px;
  padding: 10px 16px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.ad-sub button:hover { color: var(--ink); background: var(--panel-2); }
.ad-sub button.on { background: var(--grad); color: #241203; }

/* приписка справа от заголовка блока: кто и когда правил.
   Заголовок блока выложен флексом (см. .cab-block > h2), а во флексе обтекание
   не работает — отодвигаем приписку к правому краю отступом. */
.ad-h-r {
  margin-left: auto;
  padding-left: 14px;
  font-family: var(--f-text);
  font-weight: 500;
  font-size: 12.5px;
  color: var(--muted);
  letter-spacing: 0;
  text-transform: none;
}

/* пояснение под заголовком блока: как работает то, что лежит ниже */
.ad-hint {
  margin: -8px 0 14px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--muted);
  max-width: 76ch;
}

.ad-form { background: var(--panel); border-radius: 15px; padding: 22px 22px 6px; }
.ad-form .form-go { margin: 0 0 18px; }
.ad-two { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.ad-mono {
  font-family: ui-monospace, Consolas, monospace;
  font-size: 13.5px;
  line-height: 1.7;
}
.ad-form .field label input[type="checkbox"] { margin-right: 8px; vertical-align: -1px; }

/* должность рядом с ником */
.ad-role {
  font-family: var(--f-text);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: .06em;
  color: var(--gold);
  margin-left: 8px;
}

/* переписка по обращению */
.ad-msg {
  background: var(--panel);
  border-radius: 13px;
  padding: 14px 16px;
  margin-bottom: 10px;
  font-size: 14.5px;
  line-height: 1.6;
}
.ad-msg.me { box-shadow: inset 3px 0 0 var(--or); }
.ad-msg-h { font-size: 12.5px; color: var(--muted); margin-bottom: 6px; }

/* разбор экзамена */
.ad-q {
  background: var(--panel);
  border-radius: 14px;
  padding: 18px 20px 6px;
  margin-bottom: 12px;
}
.ad-q-h {
  font-family: var(--f-disp);
  font-weight: 700;
  font-size: 15.5px;
  line-height: 1.5;
  margin-bottom: 12px;
}
.ad-opts { list-style: none; padding: 0; margin: 0 0 14px; }
.ad-opts li {
  position: relative;
  padding: 7px 12px 7px 30px;
  border-radius: 9px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--muted);
}
.ad-opts li::before {
  content: '';
  position: absolute;
  left: 11px;
  top: 13px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #3a3840;
}
/* что выбрал кандидат и что было правильно — двумя разными признаками,
   чтобы «выбрал верно» и «верный ответ, но не выбран» не сливались. */
.ad-opts li.pick { background: var(--panel-2); color: var(--ink); }
.ad-opts li.pick::before { background: var(--or); }
.ad-opts li.right { color: #9FE0AF; }
.ad-opts li.right::after {
  content: '✓';
  position: absolute;
  right: 12px;
  color: #7BD692;
  font-size: 13px;
}
.ad-ans {
  background: var(--panel-2);
  border-radius: 11px;
  padding: 12px 14px;
  margin-bottom: 14px;
  font-size: 14.5px;
  line-height: 1.65;
  color: #cbc7bf;
  white-space: pre-wrap;
}
.ad-ans i { color: var(--muted); }
.ad-mark { font-size: 13px; color: var(--muted); padding-bottom: 14px; }

@media (max-width: 720px) {
  .ad-two { grid-template-columns: 1fr; }
  /* Узко — приписка уходит под заголовок целой строкой. */
  .cab-block > h2:has(.ad-h-r) { flex-wrap: wrap; }
  .ad-h-r { margin-left: 34px; padding-left: 0; flex-basis: 100%; margin-top: 4px; }
}

/* ====================================================== земли: витрина цен */

.ln-bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 190px 180px;
  gap: 10px;
  margin-bottom: 12px;
}
.ln-bar select {
  height: 44px;
  border: 0;
  border-radius: 12px;
  background: var(--panel-3);
  color: var(--ink);
  font-family: var(--f-text);
  font-size: 14px;
  padding: 0 12px;
  outline: none;
  cursor: pointer;
}
.ln-bar select:focus { box-shadow: 0 0 0 2px rgba(245, 134, 32, .55); }

.ln-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.ln-chips button {
  border: 0;
  border-radius: 999px;
  padding: 7px 14px;
  background: var(--panel-2);
  color: var(--muted);
  font-family: var(--f-text);
  font-size: 13px;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.ln-chips button:hover { color: var(--ink); }
.ln-chips button.on { background: rgba(245, 134, 32, .16); color: var(--gold-hi); }

.ln-sum { font-size: 13.5px; color: var(--muted); margin-bottom: 12px; }
.ln-sum b { color: var(--ink); font-weight: 600; }

/* Провинции без ценника. Не тревога и не ошибка — просто то, о чём человек
   иначе не узнает; поэтому тем же приёмом, что и остальные пояснения сайта:
   панель с полоской акцента слева, без окантовок и без красного. */
.ln-note {
  background: var(--panel-2);
  border-left: 2px solid rgba(245, 134, 32, .5);
  border-radius: 10px;
  padding: 11px 14px;
  margin-bottom: 14px;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--muted);
}

/* Правая колонка строки в две строки: цена крупно, налог подписью. */
.ln-r { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.ln-r b { font-size: 15px; color: var(--gold); font-weight: 700; }
.ln-r span { font-size: 12px; color: var(--muted); }

.ln-more { text-align: center; margin-top: 16px; }

@media (max-width: 720px) {
  .ln-bar { grid-template-columns: minmax(0, 1fr); }
  /* Отборы стояли 30 px в высоту при зазоре 8 — на телефоне палец накрывает
     сразу два, а промах молча меняет выборку. 38 px, вид прежний. */
  .ln-chips button { padding: 11px 14px; }
}

/* На телефоне строка складывается в столбик, и цена оказывается под названием —
   там ей уместнее стоять в одну строку с налогом, а не двумя этажами. */
@media (max-width: 640px) {
  .ln-r { flex-direction: row; align-items: baseline; gap: 8px; }
}

/* ==================================================== адаптив */

@media (max-width: 1180px) {
  .doc { grid-template-columns: 234px minmax(0, 1fr); gap: 34px; }
  .doc-toc { display: none; }
}

/* Двум колонкам обращений нужно 720 + 230 + отступы. Как только перестаёт
   хватать — подсказка уходит ПОД форму, а не сжимается в столбик из двух слов.
   Там же снимаем прилипание: липкий блок внизу страницы только мешает. */
@media (max-width: 1040px) {
  .tk-two { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .tk-side { position: static; grid-auto-flow: row; }
}

@media (max-width: 900px) {
  .doc { display: block; }
  .doc-open { display: flex; }
  .doc-side {
    position: fixed;
    z-index: 95;
    top: 0;
    bottom: 0;
    left: 0;
    width: 300px;
    max-height: none;
    background: #131316;
    padding: 22px 18px 30px;
    transform: translateX(-104%);
    /* Закрытая панель уезжает за левый край, но остаётся на странице: без
       visibility табуляция с кнопки уходила в поиск и весь список статей,
       которых на экране нет. Значение переключается скачком в конце
       перехода, поэтому выезд остаётся плавным. */
    visibility: hidden;
    transition: transform .26s cubic-bezier(.2, .8, .3, 1), visibility .26s;
    box-shadow: 22px 0 44px rgba(0, 0, 0, .5);
  }
  .doc-side.open { transform: none; visibility: visible; }
  .doc-scrim {
    position: fixed;
    inset: 0;
    z-index: 94;
    background: rgba(0, 0, 0, .55);
    opacity: 0;
    pointer-events: none;
    transition: opacity .26s ease;
  }
  .doc-scrim.on { opacity: 1; pointer-events: auto; }
  .cab { display: block; }
  .cab-side { position: static; margin-bottom: 26px; }
  /* На узком экране меню кабинета ложится в строку и листается вбок —
     колонкой оно съедало бы весь первый экран. */
  .cab-nav { flex-direction: row; gap: 6px; overflow-x: auto; padding-bottom: 4px; }
  .cab-nav button { white-space: nowrap; background: var(--panel); }
  .cab-nav button.on { background: var(--grad); color: #241203; }
  .cab-nav button.on .cn-b { color: #241203; }
  .cab-nav .cn-t { display: none; }
  /* Счётчики в строке меню: 12 пикселей рядом с крупной надписью читались
     как мелкий шрифт в углу, а это единственное место, где видно, сколько
     наград ждёт и сколько червонцев на счету. */
  .cab-nav .cn-b { font-size: 12.5px; }
  .cab-out { padding: 0; }
  /* Разделитель нужен, только пока «Кабинет» и «Выйти» стоят в одной строке. */
  .cab-out .cab-sep { display: none; }
  /* «Выйти» было подчёркнутым словом в хвосте фразы — 40 на 21 пиксель.
     Попасть пальцем трудно, а мимо кнопки лежит обычный текст, так что
     промах просто ничего не делает, и человек жмёт ещё раз. На телефоне
     это отдельная кнопка под фразой, как везде на сайте. */
  .cab-out button {
    display: block;
    margin-top: 10px;
    height: 40px;
    padding: 0 16px;
    border-radius: 10px;
    background: var(--panel);
    color: var(--ink);
    text-decoration: none;
  }
  .duty-cols, .mods-groups { grid-template-columns: 1fr; gap: 16px; }
  /* На двух колонках эти подписи были мелкими по делу — места не было. В одну
     колонку место есть, а 11.5 и 12 пикселей на телефоне читаются с прищуром. */
  .duty-cols h6 { font-size: 13px; }
  .mod-row em { font-size: 13px; }
  /* Те же 11.5 пикселей в подписях колонки-подсказки под формой обращения. */
  .tk-sc h3 { font-size: 13px; }
  /* Счётчик знаков говорит, сколько осталось до предела, — в него смотрят,
     когда текст длинный, и 12 пикселей на телефоне для этого мало. */
  .field .cnt { font-size: 13px; }
  /* «← ко всем темам» — единственный путь со страницы формы обратно к списку,
     а нажимаемых у него было 17 пикселей. Поле сверху и снизу даёт 37;
     отрицательный внешний отступ съедает прибавку, чтобы отбивка от формы
     осталась прежней. */
  .tk-back { margin-top: 16px; margin-bottom: -10px; }
  .tk-back a { display: inline-block; padding: 10px 0; }
}

@media (max-width: 640px) {
  .page-wrap { padding: 24px 0 70px; }
  .rule { grid-template-columns: 26px minmax(0, 1fr); padding: 13px 14px; }
  .row, .row.r2 { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .row .rw-r { text-align: left; }
  .row .rw-r .btn { margin-left: 0; }
  /* Правая колонка строки не переносится: на широком экране кнопки стоят в ряд
     справа, и перенос там не нужен. На телефоне строка идёт во всю ширину, и
     три элемента подряд (метка + две кнопки) вылезали за край экрана — сами по
     себе они не переносятся, между ними в разметке нет ни одного пробела.
     Поэтому там, где внутри есть кнопки, колонка становится гибкой строкой с
     переносом и своим зазором. Строки с одним текстом остаются как были. */
  .row .rw-r:has(.btn) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    white-space: normal;
  }
  .chatlog .cl { grid-template-columns: 54px minmax(0, 1fr); }
  .chatlog .cl-m { grid-column: 1 / -1; }
  .doc-body .dh h1 { font-size: 27px; }
  .tk-form .tk-head h2 { font-size: 22px; }
  /* Плитки кабинета и панели: на телефоне колонкой по одной они съедают весь
     первый экран, и до самого содержимого приходится долго листать. По две в
     ряд числа читаются так же, а экран остаётся рабочим. */
  .cab-tiles { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; }
  /* В плитке бывает не только число, но и слово («ждёт проверки», ник):
     переносим по словам и рвём слово только если оно само не влезло. */
  .tile .t-v { overflow-wrap: break-word; }
  .tile { padding: 15px 14px; }
  .tile.wide { grid-column: 1 / -1; }
  .tile .t-v { font-size: 22px; }
  .tile .t-s { font-size: 12.5px; margin-top: 6px; }
  /* Подпись над числом — 12 пикселей капсом с разрядкой. На мониторе это
     читается, на телефоне капс с разрядкой на таком кегле уже щурится, а
     подпись говорит, что за число под ней. */
  .tile .t-k { font-size: 12.5px; }
  /* Метки-пилюли («ждём оплату», «не в эфире»): 12 пикселей на цветной
     подложке — самое мелкое, что есть на странице, а в них состояние заказа
     и наказания. */
  .pill { font-size: 12.5px; height: 26px; }
}

@media (prefers-reduced-motion: reduce) {
  .loading i, .pill.live::before { animation: none; }
  .qa-wrap { transition: none; }
  .doc-side, .doc-scrim { transition: none; }
  .live-card, .tk-card, .rule { transition: none; }
  .live-card:hover .live-thumb img { transform: none; }
  .rule::before { transition: none; }
}
