/* ================================================================
   LootRanger — единая тема, шапка и футер.

   Палитра: почти-чёрная база + кислотный лайм на ценах и кнопках
   + фиолетовый на интерфейсных акцентах + янтарный на предупреждениях.
   Лайм выбран сознательно: он читается как «выгода» и не похож
   на дефолтный синий, которым выглядит каждый второй сайт.

   ТЁМНАЯ ТЕМА — ВСЕГДА ПО УМОЛЧАНИЮ. Системную настройку не слушаем
   намеренно: сайт задуман тёмным, и человек с системной светлой темой
   получал белую версию, которую никто не рисовал как основную.
   Светлая включается ТОЛЬКО переключателем в шапке — он ставит
   [data-theme="light"] на <html>, и выбор запоминается в localStorage.
================================================================ */

:root{
  /* поверхности */
  --bg:#0a0c10;
  --bg-soft:#0f131a;
  --card:#151a22;
  --card-hi:#1c222c;
  --line:#232b36;
  --line-hi:#2f3946;

  /* текст */
  --text:#e9edf5;
  --text-dim:#b7c0cf;
  --muted:#7f8a9c;

  /* акценты */
  --accent:#b8f23c;          /* лайм: цены, главные кнопки */
  --accent-hi:#c9ff54;
  --accent-ink:#0a0c10;      /* текст НА лайме */
  --accent-soft:rgba(184,242,60,.13);
  /* Лайм как цвет ТЕКСТА. В тёмной теме совпадает с --accent (13:1 к фону),
     в светлой переопределён: #b8f23c на белом даёт 2.4:1 — цену не прочитать. */
  --accent-text:#b8f23c;
  --violet:#8b7cff;          /* ссылки и второстепенные акценты */
  --violet-soft:rgba(139,124,255,.14);

  /* смыслы */
  --good:#7ef0a8;  --good-bg:rgba(126,240,168,.12);
  --warn:#ffb340;  --warn-bg:rgba(255,179,64,.12);
  --heart:#ff5f7e;                 /* донат: тёплый розовый читается однозначно */
  --heart-soft:rgba(255,95,126,.14);

  --radius:14px;
  --radius-sm:10px;
  /* 1240, а не 1080: в таблице до двенадцати магазинов, и на странице игры
     рядом с ценами теперь стоит колонка «Об игре». На 1080 и то, и другое
     было тесно. Служебные страницы ограничены отдельно (.wrap--narrow):
     строка текста длиннее ~740px читается тяжело. */
  --maxw:1240px;
  --shadow:0 8px 24px rgba(0,0,0,.35);
  --shadow-hi:0 12px 34px rgba(0,0,0,.45);
}

/* Светлая тема. Включается только руками — других путей сюда нет. */
:root[data-theme="light"]{
  --bg:#f4f6f1;
  --bg-soft:#fbfcfa;
  --card:#ffffff;
  --card-hi:#f7f9f4;
  --line:#e2e6dd;
  --line-hi:#cfd6c8;

  --text:#111620;
  --text-dim:#39414f;
  --muted:#5f6a79;

  --accent:#7cb800;
  --accent-hi:#8fce00;
  --accent-ink:#0a0c10;
  --accent-soft:rgba(124,184,0,.14);
  --accent-text:#3d6b00;   /* 6.4:1 к белому */
  --violet:#5b4bdb;
  --violet-soft:rgba(91,75,219,.10);

  --good:#12855a;  --good-bg:rgba(18,133,90,.12);
  --warn:#9a5b00;  --warn-bg:rgba(154,91,0,.12);
  --heart:#e11d48;
  --heart-soft:rgba(225,29,72,.10);

  --shadow:0 6px 18px rgba(20,30,15,.10);
  --shadow-hi:0 12px 28px rgba(20,30,15,.16);
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}

/* ------------------------------------------------- полоса прокрутки

   Дефолтная виндовая полоса со стрелками выбивается из тёмной темы.
   Делаем свою: без кнопок-стрелок, скруглённая, с отступом от края —
   в покое приглушённая, под курсором подсвечивается фирменным градиентом.

   Ширину оставляем 12px, а не 4px «для красоты»: тонкую полосу мышью
   не поймать, и прокрутка из удобства превращается в задачу.            */
html{
  scrollbar-width:thin;                              /* Firefox */
  scrollbar-color:var(--line-hi) var(--bg-soft);
}
::-webkit-scrollbar{width:12px; height:12px}
::-webkit-scrollbar-track{background:var(--bg-soft)}
::-webkit-scrollbar-thumb{
  background:var(--line-hi);
  border:3px solid var(--bg-soft);   /* внутренний отступ, чтобы не липло к краю */
  border-radius:999px;
}
::-webkit-scrollbar-thumb:hover{
  background:linear-gradient(180deg, var(--accent), var(--violet));
  border-width:2px;
}
::-webkit-scrollbar-thumb:active{background:var(--accent)}
/* Стрелки вверх/вниз — то самое, что выдавало дефолт. */
::-webkit-scrollbar-button{display:none}
::-webkit-scrollbar-corner{background:transparent}
body{
  margin:0; background:var(--bg); color:var(--text);
  font:16px/1.6 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  display:flex; flex-direction:column;
  /* 100vh на мобильных считается по свёрнутому интерфейсу браузера,
     из-за этого низ страницы уезжает под адресную строку. */
  min-height:100vh; min-height:100dvh;
  letter-spacing:-.005em;
}

/* ------------------------------------------------- декор боковых полей

   Контент ограничен 1080px, и на широком мониторе по бокам оставались
   мёртвые чёрные поля. Заполняем их медленно ползущей сеткой и мягкими
   световыми пятнами: фон оживает, но ничего не мельтешит рядом с текстом.

   Показываем только когда поля реально есть (>1240px) — на ноутбуке и
   телефоне блоки просто не существуют и ничего не грузят.
   Всё под pointer-events:none, поэтому на клики не влияет.               */
.site-head, main, .site-foot{position:relative; z-index:1}

@media (min-width:1240px){
  body::before, body::after{
    content:""; position:fixed; top:0; bottom:0; width:calc((100% - var(--maxw)) / 2);
    z-index:0; pointer-events:none; opacity:.5;
    background-image:
      radial-gradient(circle at 50% 20%, var(--accent-soft), transparent 60%),
      radial-gradient(circle at 30% 75%, var(--violet-soft), transparent 60%),
      linear-gradient(var(--line) 1px, transparent 1px),
      linear-gradient(90deg, var(--line) 1px, transparent 1px);
    background-size:100% 100%, 100% 100%, 34px 34px, 34px 34px;
    /* Маска: сетка гаснет к краю экрана и к контенту, чтобы не было
       видно, где заканчивается блок. */
    -webkit-mask-image:linear-gradient(to right, transparent, #000 45%, transparent);
    mask-image:linear-gradient(to right, transparent, #000 45%, transparent);
  }
  body::before{left:0}
  body::after{right:0; transform:scaleX(-1)}

  @media (prefers-reduced-motion:no-preference){
    body::before, body::after{animation:drift 26s linear infinite}
  }
}
/* Сетка уползает вверх ровно на свой шаг — движение бесшовное. */
@keyframes drift{
  from{background-position:0 0, 0 0, 0 0, 0 0}
  to{background-position:0 0, 0 0, 0 -34px, 0 0}
}
a{color:var(--violet); text-decoration-thickness:1px; text-underline-offset:2px}
a:hover{color:var(--text)}
img{max-width:100%}
h1,h2,h3{letter-spacing:-.02em}

/* РАЗБИВКА СТРОК. Браузер по умолчанию ломает абзац жадно: набивает строку
   до отказа и переносит остаток, из-за чего в заголовке последняя строка
   выходит из одного слова, а в абзаце — короче остальных вдвое. Выглядит
   это как ошибка вёрстки, хотя вёрстка ни при чём.

     · balance — выравнивает строки заголовка по длине (до шести строк);
     · pretty  — следит, чтобы последняя строка абзаца не была висячей.

   Обе подсказки, а не правила: браузер, который их не знает, просто
   переносит как раньше, и ничего не ломается. */
h1,h2,h3,.section-title,.hero h1,.tile__label,.card__title{text-wrap:balance}
p,li,.tile__meta,.free-card__timer,.crosslinks li{text-wrap:pretty}
/* Короткие абзацы — подзаголовок под H1, подписи под блоками — выравниваем
   по длине строк, а не только защищаем от висячего слова: у абзаца из трёх
   строк «pretty» ничего не меняет, а «лесенка» из длинной, длинной и куцей
   строки — ровно то, что читается как кривая вёрстка. */
.hero p,.note,.search-hint,.wishlist-note{text-wrap:balance}

:focus-visible{outline:2px solid var(--accent); outline-offset:2px; border-radius:4px}
/* Уводим за верхний край трансформом, а не left:-9999px: тот хак
   в некоторых браузерах создаёт лишнюю прокрутку. */
.skip{
  position:absolute; left:0; top:0; z-index:20;
  background:var(--card); color:var(--text); text-decoration:none;
  padding:10px 14px; border-radius:0 0 var(--radius-sm) 0;
  transform:translateY(-200%);
}
.skip:focus{transform:none}

/* Видно только скринридеру: текст остаётся в дереве доступности,
   но не занимает места на экране. */
.sr-only{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;
}

/* Режим высокой контрастности Windows: текст, залитый градиентом через
   -webkit-text-fill-color, там становится невидимым. Возвращаем цвет. */
@media (forced-colors:active){
  .hero h1 em{-webkit-text-fill-color:currentColor; background:none}
  .card__strip{background:Canvas}
  .fav{background:Canvas; border-color:CanvasText}
}

/* ---------------------------------------------------------------- шапка */
.site-head{
  border-bottom:1px solid var(--line); background:var(--bg-soft);
  position:sticky; top:0; z-index:10;
}
.site-head__in{
  max-width:var(--maxw); margin:0 auto; padding:12px 16px;
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
}
.brand{
  display:flex; align-items:center; gap:9px; font-weight:800; font-size:18px;
  color:var(--text); text-decoration:none; white-space:nowrap; letter-spacing:-.03em;
}
.brand__logo{flex:none; border-radius:9px; display:block}
/* «Loot» жирно, «Ranger» полегче — знак читается как одно слово из двух частей,
   а не как ровная надпись. */
.brand__text--soft{font-weight:600; color:var(--text-dim)}
.nav{display:flex; align-items:center; gap:2px; margin-left:auto; flex-wrap:wrap}
.nav a,.nav button{
  font:inherit; font-size:14px; font-weight:500; padding:8px 12px; border-radius:var(--radius-sm);
  border:1px solid transparent; background:none; color:var(--muted);
  text-decoration:none; cursor:pointer; white-space:nowrap;
}
.nav a:hover,.nav button:hover{color:var(--text); background:var(--card)}
/* «Вишлист» со значком Steam. Значок приглушён сильнее текста: он поясняет,
   чей это список, а не спорит с подписью за внимание. */
.nav-wishlist{display:inline-flex; align-items:center; gap:6px}
.nav-icon{flex:none; opacity:.7}
.nav-wishlist:hover .nav-icon,
.nav-wishlist[aria-current="page"] .nav-icon{opacity:1}
.nav [aria-current="page"]{color:var(--text); background:var(--card); border-color:var(--line)}
.nav .theme-toggle, .nav-actions .theme-toggle{
  width:36px; padding:8px 0; text-align:center; font-size:15px;
  font:inherit; background:none; border:1px solid transparent;
  border-radius:var(--radius-sm); color:var(--muted); cursor:pointer;
}
.nav-actions .theme-toggle:hover{color:var(--text); background:var(--card)}

/* Постоянная часть шапки: донат, избранное, тема и бургер. */
.nav-actions{display:flex; align-items:center; gap:8px; margin-left:auto}
/* Донат стоит первым и выделен фоном: он должен читаться как действие,
   а не как ещё один пункт меню. */
.nav-actions .pill--donate{
  background:var(--heart-soft); border-color:var(--heart);
  font-weight:650;
}
.nav-actions .pill--donate:hover{background:var(--heart); color:#fff}
.nav-actions .pill--donate:hover .donate-link__heart{color:#fff}

/* Кнопка меню. На широком экране её нет — ссылки помещаются в строку. */
.nav-toggle{
  display:none; place-items:center; width:40px; height:40px; margin-left:auto;
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius-sm);
  cursor:pointer; padding:0;
}
.nav-toggle span, .nav-toggle span::before, .nav-toggle span::after{
  content:""; display:block; width:16px; height:2px; border-radius:2px;
  background:var(--text-dim);
}
.nav-toggle span{position:relative}
.nav-toggle span::before{position:absolute; top:-5px}
.nav-toggle span::after{position:absolute; top:5px}
.nav-toggle[aria-expanded="true"]{border-color:var(--accent)}


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

   Раскрытие делает <details>, поэтому здесь только вид. */
.lang{position:relative}
.lang__now{
  display:inline-flex; align-items:center; gap:4px; height:36px; padding:0 8px;
  border:1px solid transparent; border-radius:var(--radius-sm);
  color:var(--muted); cursor:pointer; list-style:none; user-select:none;
  font-size:12px; font-weight:600; letter-spacing:.04em;
}
/* Стрелку рисуем сами, поэтому убираем родной треугольник — в вебките
   он живёт отдельным псевдоэлементом и list-style его не берёт. */
.lang__now::-webkit-details-marker{display:none}
.lang__now:hover{color:var(--text); background:var(--card)}
.lang[open] .lang__now{color:var(--text); background:var(--card); border-color:var(--line)}
.lang[open] .lang__caret{transform:rotate(180deg)}
.lang__caret{flex:none; transition:transform .15s ease}
@media (prefers-reduced-motion:reduce){ .lang__caret{transition:none} }

.lang__menu{
  position:absolute; top:calc(100% + 6px); right:0; z-index:30;
  min-width:104px; display:flex; flex-direction:column; gap:2px; padding:6px;
  background:var(--card); border:1px solid var(--line-hi);
  border-radius:var(--radius); box-shadow:var(--shadow-hi);
}
.lang__item{
  display:block; padding:9px 10px; border-radius:var(--radius-sm);
  font-size:13px; font-weight:600; letter-spacing:.04em; color:var(--text-dim);
  text-decoration:none; white-space:nowrap;
}
a.lang__item:hover{color:var(--text); background:var(--card-hi)}
/* Текущий язык — с галочкой: в свёрнутом виде виден только код, и открыв
   список, человек должен сразу видеть, на чём он сейчас. */
.lang__item--on{color:var(--text); font-weight:600}
.lang__item--on::before{content:"✓ "; color:var(--accent-text)}

/* Разделитель между разделами каталога и личными действиями.
   Без него «Избранное» сливалось с «О проекте» и читалось как ещё одна
   служебная ссылка, а не как своя полка. */
.nav__sep{
  width:1px; height:22px; margin:0 8px; flex:none;
  background:var(--line-hi);
}

/* Пилюли — личные действия. Обе выделены рамкой, поэтому глаз видит их
   как отдельную группу, а не как продолжение списка ссылок. */
.pill{
  display:inline-flex; align-items:center; gap:7px;
  padding:7px 13px; border-radius:999px; white-space:nowrap;
  border:1px solid var(--line-hi); background:var(--card);
  color:var(--text); font-size:13.5px; font-weight:700; text-decoration:none;
}
.pill:hover{color:var(--text)}
.pill__icon{font-size:13px; line-height:1}

/* Избранное — лаймовое: тот же цвет, что у цен и скидок, то есть «моё, полезное». */
.pill--fav .pill__icon{color:var(--accent)}
.pill--fav:hover{border-color:var(--accent); background:var(--accent-soft)}
.pill--fav[aria-current="page"]{border-color:var(--accent); background:var(--accent-soft)}
.pill__count{
  background:var(--accent); color:var(--accent-ink);
  font-size:11px; font-weight:800; line-height:1;
  min-width:18px; padding:3px 5px; border-radius:999px; text-align:center;
}

/* Донат закреплён в шапке (она sticky), поэтому виден на любом экране и при
   любой прокрутке. Сердце «стучит» двойным ударом, как настоящее. */
.pill--donate:hover{border-color:var(--heart); background:var(--heart-soft)}
.pill--donate[aria-current="page"]{border-color:var(--heart); background:var(--heart-soft)}
.donate-link__heart{color:var(--heart); flex:none; transform-origin:center}

@media (prefers-reduced-motion:no-preference){
  .donate-link__heart{animation:beat 2s ease-in-out infinite}
}
/* Удар-удар-пауза: 8% и 20% — две систолы, дальше отдых. */
@keyframes beat{
  0%,32%,100%{transform:scale(1)}
  8%{transform:scale(1.3)}
  16%{transform:scale(1.02)}
  24%{transform:scale(1.18)}
}

/* ---------------------------------------------------------------- каркас */
main{flex:1 0 auto; width:100%}
.wrap{max-width:var(--maxw); margin:0 auto; padding:24px 16px 64px}
.wrap--narrow{max-width:740px}

/* Свечение за поиском — единственный «декор» на странице.
   Он же визуально центрирует главное действие. */
.hero{
  position:relative; text-align:center; padding:34px 0 6px;
  /* Предел в пикселях, а не в символах: он же держит и заголовок,
     и подпись под ним — блок читается как одна колонка. */
  max-width:760px; margin-inline:auto;
}
/* Подсветка за поиском. Отступы строго нулевые по горизонтали:
   отрицательные (-20%) вылезали за вьюпорт и давали горизонтальную
   прокрутку на телефоне — свечение растягиваем самим градиентом. */
.hero::before{
  content:""; position:absolute; inset:-60px 0 auto 0; height:260px; z-index:-1;
  background:radial-gradient(120% 100% at 50% 0,var(--accent-soft),transparent 68%);
  pointer-events:none;
}
.hero h1{margin:0 0 8px; font-size:clamp(26px,5vw,40px); line-height:1.1; font-weight:800}

/* Акцент в заголовке — «живой» градиент лайм→фиолетовый, который медленно
   течёт. Это единственная анимация на первом экране: она задаёт настроение,
   но не мешает читать. */
.hero h1 em{
  font-style:normal; color:var(--accent-text);
  background:linear-gradient(100deg,var(--accent),var(--violet),var(--accent));
  background-size:220% 100%;
  -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent;
}
@media (prefers-reduced-motion:no-preference){
  .hero h1 em{animation:flow 7s linear infinite}
  /* Свечение за поиском дышит — ощущение, что страница живая, а не картинка. */
  .hero::before{animation:breathe 6s ease-in-out infinite}
}
@keyframes flow{to{background-position:220% 0}}
@keyframes breathe{
  0%,100%{opacity:.75; transform:scale(1)}
  50%{opacity:1; transform:scale(1.04)}
}
/* Ширину ограничивает БЛОК, а не сам абзац. Мера в символах (max-width:50ch)
   стояла на тексте, и он ломался на три строки посреди пустой страницы —
   выглядело как случайный перенос, а не как решение. Теперь предел стоит
   на .hero, текст внутри занимает его целиком и переносится по краю блока. */
.hero p{color:var(--text-dim); font-size:clamp(14px,2vw,16px); margin:0 auto 24px}

/* На странице игры лозунг не нужен — он отжимает вниз то, за чем человек пришёл.
   Оставляем только поиск. */
.hero--compact{padding:16px 0 0}
.hero--compact h1,
.hero--compact p,
.hero--compact .search-hint{display:none}
.hero--compact::before{display:none}
.hero--compact .search{margin-bottom:18px}

/* ---------------------------------------------------------------- поиск */
.search{display:flex; gap:8px; max-width:600px; margin:0 auto 10px}
.search__field{position:relative; flex:1; min-width:0}
.search input{
  width:100%; padding:15px 16px 15px 44px; font:inherit; font-size:16px;
  border:1px solid var(--line-hi); border-radius:var(--radius); background:var(--card);
  color:var(--text); box-shadow:var(--shadow);
}
.search input::placeholder{color:var(--muted)}
.search input:focus{border-color:var(--accent); outline:none; box-shadow:0 0 0 3px var(--accent-soft)}
.search__icon{
  position:absolute; left:15px; top:50%; transform:translateY(-50%);
  color:var(--muted); pointer-events:none; display:grid; place-items:center;
}
.search button{
  padding:15px 22px; font:inherit; font-size:15px; font-weight:700;
  border:0; border-radius:var(--radius); background:var(--accent); color:var(--accent-ink);
  cursor:pointer; white-space:nowrap;
}
.search button:hover{background:var(--accent-hi)}
.search button[disabled]{opacity:.45; cursor:default}
.search-hint{text-align:center; color:var(--muted); font-size:12.5px; margin:0 0 26px}

/* ------------------------------------------------- сетка игр (постеры) */
.grid{
  display:grid; gap:16px;
  grid-template-columns:repeat(auto-fill,minmax(160px,1fr));
}
.card{
  position:relative; display:flex; flex-direction:column; width:100%;
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
  color:var(--text); overflow:hidden;
}
.card__link{display:flex; flex-direction:column; flex:1; color:inherit; text-decoration:none}
.card__link:hover{color:inherit}

/* Звезда «в избранное» поверх обложки. Тач-зона 40×40 — палец должен попадать
   без прицеливания, но она не должна закрывать арт. */
.fav{
  position:absolute; top:7px; right:7px; z-index:2; padding:0;
  width:40px; height:40px; display:grid; place-items:center; cursor:pointer;
  color:#fff; background:rgba(8,10,14,.55); border:1px solid rgba(255,255,255,.18);
  border-radius:999px; backdrop-filter:blur(4px);
}
.fav svg{opacity:.85}
.fav:hover{background:rgba(8,10,14,.82); border-color:var(--accent)}
.fav.is-on{color:var(--accent); border-color:var(--accent); background:rgba(8,10,14,.78)}
.fav.is-on svg{opacity:1}
.gamehead > .fav{top:12px; right:12px}
@media (prefers-reduced-motion:no-preference){
  .fav--pop{animation:favpop .32s cubic-bezier(.3,1.4,.5,1)}
}
@keyframes favpop{0%{transform:scale(1)} 45%{transform:scale(1.3)} 100%{transform:scale(1)}}
.card:hover{
  border-color:var(--accent); transform:translateY(-4px);
  box-shadow:var(--shadow-hi), 0 0 0 1px var(--accent-soft);
}
.card__art{position:relative; aspect-ratio:2/3; background:var(--card-hi); overflow:hidden}
.card__art img{width:100%; height:100%; object-fit:cover; display:block}

/* Обложка чуть наезжает при наведении — приём из игровых магазинов:
   карточка «отвечает» на курсор, и сетка перестаёт быть мёртвой. */
@media (hover:hover) and (prefers-reduced-motion:no-preference){
  .card__art img,
  .free-card__art img{transition:transform .45s cubic-bezier(.2,.7,.3,1)}
  .card:hover .card__art img,
  .free-card--link:hover .free-card__art img{transform:scale(1.07)}

  /* Блик, пробегающий по обложке. Косой градиент уезжает за край. */
  .card__art::after,
  .free-card__art::after{
    content:""; position:absolute; inset:0; pointer-events:none;
    background:linear-gradient(105deg,transparent 38%,rgba(255,255,255,.16) 50%,transparent 62%);
    transform:translateX(-120%);
  }
  .card:hover .card__art::after,
  .free-card--link:hover .free-card__art::after{
    transition:transform .7s ease; transform:translateX(120%);
  }
}

/* Ступенчатое появление карточек: «выкладываются» по очереди, а не вспыхивают
   все сразу. Задержка считается здесь по позиции в сетке, а НЕ атрибутом style
   из кода: карточки приходят и с сервера тоже, а инлайновый стиль запрещает
   наш же CSP (style-src без 'unsafe-inline'). Дальше 12-й ждать нет смысла —
   до них ещё надо доскроллить. */
@media (prefers-reduced-motion:no-preference){
  .card--reveal{animation:pop .42s cubic-bezier(.2,.8,.2,1) both}
  .card--reveal:nth-child(2){animation-delay:45ms}
  .card--reveal:nth-child(3){animation-delay:90ms}
  .card--reveal:nth-child(4){animation-delay:135ms}
  .card--reveal:nth-child(5){animation-delay:180ms}
  .card--reveal:nth-child(6){animation-delay:225ms}
  .card--reveal:nth-child(7){animation-delay:270ms}
  .card--reveal:nth-child(8){animation-delay:315ms}
  .card--reveal:nth-child(9){animation-delay:360ms}
  .card--reveal:nth-child(10){animation-delay:405ms}
  .card--reveal:nth-child(11){animation-delay:450ms}
  .card--reveal:nth-child(n+12){animation-delay:495ms}
}
@keyframes pop{
  from{opacity:0; transform:translateY(14px) scale(.97)}
  to{opacity:1; transform:none}
}
.card__art--wide{aspect-ratio:16/9}
/* Заглушка вместо обложки: наш знак вместо иконки битого файла.
   Битая картинка читается как поломка сайта, а «обложки нет» — как факт. */
.card__noart{
  width:100%; height:100%; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:8px;
  color:var(--line-hi);
  background:
    radial-gradient(120% 90% at 50% 0, var(--accent-soft), transparent 62%),
    linear-gradient(150deg, var(--card-hi), var(--card));
}
.card__noart svg{opacity:.55}
.card__noart span{font-size:11.5px; font-weight:600; color:var(--muted)}
.card__price{
  position:absolute; left:8px; bottom:8px;
  background:var(--accent); color:var(--accent-ink);
  font-size:13px; font-weight:800; padding:4px 9px; border-radius:999px;
  box-shadow:0 2px 10px rgba(0,0,0,.3);
}
/* Витрина скидок: арт шире, карточек в ряду меньше — обложку должно быть видно. */
/* Каталог: широкие карточки с баннером 16:9.

   На узких экранах колонки подбираются сами по минимальной ширине,
   а на широком заданы ЯВНО четыре: при auto-fill в контейнер 1080px
   влезало только три (4×255 + отступы = 1068 при доступных 1048),
   и ряд получался разреженным. Четыре — плотнее и ближе к витрине,
   с которой аудитория уже знакома по Steam. */
.grid--wide{grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
@media (min-width:1000px){
  .grid--wide{grid-template-columns:repeat(4,1fr)}
}

/* Полоса поверх нижней части арта: процент скидки + цена.
   Так делают Steam и Gamesplanet — цифра читается, не отрываясь от картинки. */
.card__strip{
  position:absolute; left:0; right:0; bottom:0;
  display:flex; align-items:center; gap:8px; padding:22px 11px 9px;
  background:linear-gradient(to top,rgba(6,8,11,.94),rgba(6,8,11,.72) 55%,transparent);
}
.card__off{
  background:var(--accent); color:var(--accent-ink);
  font-size:12.5px; font-weight:800; padding:3px 8px; border-radius:6px;
}
.card__now{color:#fff; font-weight:800; font-size:15px; text-shadow:0 1px 6px rgba(0,0,0,.6)}
.card__was{color:rgba(255,255,255,.62); font-size:12px; text-decoration:line-through}

/* Две строки максимум: длинные названия вроде «DOOM: The Dark Ages —
   Revelations Edition» давали карточки в 4 строки, и низ сетки шёл лестницей.
   Полное название остаётся в title и в разметке — обрезка только визуальная. */
.card__title{
  font-size:13.5px; font-weight:600; line-height:1.35; margin:0;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden;
}
/* Выравниваем высоту: у карточек с однострочным названием подпись магазина
   не должна прыгать вверх относительно соседей. */
.card__body{
  padding:10px 11px 12px; display:flex; flex-direction:column; gap:3px;
  min-height:62px;
}
.card__sub{font-size:11.5px; color:var(--muted); margin-top:3px}

/* ------------------------------------------------------- страница игры

   Страницу целиком отдаёт Worker по адресу /game/<id>, поэтому заголовок
   здесь h1, а не h2: это отдельный документ, и главный заголовок у него
   должен быть первого уровня. Раньше её рисовал скрипт внутри каталога,
   где h1 был уже занят лозунгом.
   «Назад» — обычная ссылка, а не кнопка: работает без JS и открывается
   в новой вкладке средним кликом.                                        */
.back{
  display:inline-block; color:var(--muted); font-size:14px;
  padding:6px 0; margin-bottom:10px; text-decoration:none;
}
.back:hover{color:var(--text)}

.gamehead{
  position:relative; border:1px solid var(--line); border-radius:var(--radius);
  overflow:hidden; margin-bottom:16px; background:var(--card);
}
.gamehead__art{display:block; width:100%; aspect-ratio:92/43; object-fit:cover}
.gamehead__veil{
  position:absolute; inset:0;
  background:linear-gradient(to top,rgba(6,8,11,.94) 0%,rgba(6,8,11,.55) 45%,rgba(6,8,11,.05) 100%);
}
.gamehead__text{position:absolute; left:0; right:0; bottom:0; padding:18px 20px}
.gamehead__text h1{margin:0; font-size:clamp(19px,3.4vw,28px); color:#fff; font-weight:800;
  text-shadow:0 2px 12px rgba(0,0,0,.6)}
.gamehead--plain{padding:18px 20px}
.gamehead--plain h1{margin:0; font-size:clamp(19px,3.4vw,26px)}

/* Две сводные цены: официальные магазины против серых.
   Главная мысль страницы — видно, сколько стоит принять риск. */
/* Обложка и цены рядом: картинка примерно на две трети, справа столбцом
   «Дешевле всего» и «Экономия». Так главный ответ страницы виден сразу,
   без прокрутки, — раньше цены уезжали под баннер высотой в пол-экрана.
   Плитки растягиваются на всю высоту обложки, поэтому их две-три,
   а не «сколько влезет». */
.gamehero{display:grid; grid-template-columns:minmax(0,7fr) minmax(260px,3fr); gap:16px; margin-bottom:18px}
.gamehero .gamehead{margin-bottom:0; height:100%}
.gamehero .gamehead__art{height:100%; object-fit:cover}
.summary{display:grid; gap:12px; align-content:start}
.gamehero .summary{align-content:stretch}

@media (max-width:900px){
  /* На узком экране в две колонки не влезает ничего осмысленного:
     обложка сверху, цены под ней. */
  .gamehero{grid-template-columns:1fr}
  .gamehero .gamehead{height:auto}
  .gamehero .gamehead__art{height:auto}
  .summary{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
}
.tile{
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
  padding:14px 16px; position:relative;
}
.tile--best{border-color:var(--accent); box-shadow:0 0 0 1px var(--accent-soft)}
.tile__label{font-size:11.5px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); font-weight:700}
.tile__price{font-size:clamp(24px,4vw,31px); font-weight:800; line-height:1.15; margin-top:6px}
.tile--best .tile__price{color:var(--accent-text)}
.tile__meta{font-size:12.5px; color:var(--muted); margin-top:4px}
.tile__flag{
  position:absolute; top:12px; right:12px; font-size:10.5px; font-weight:800;
  text-transform:uppercase; letter-spacing:.05em;
  background:var(--accent); color:var(--accent-ink); padding:3px 8px; border-radius:999px;
}
.tile--empty .tile__price{color:var(--muted); font-size:19px; font-weight:600}

.section-title{font-size:15px; margin:26px 0 12px; display:flex; align-items:center; gap:8px}
.section-title .count{color:var(--muted); font-weight:500; font-size:13px}
@media (prefers-reduced-motion:no-preference){
  /* Огонёк у заголовка каталога чуть подрагивает — как настоящее пламя. */
  .section-title__fire{display:inline-block; animation:flicker 2.4s ease-in-out infinite}
}
@keyframes flicker{
  0%,100%{transform:scale(1) rotate(0)}
  30%{transform:scale(1.14) rotate(-6deg)}
  60%{transform:scale(.96) rotate(5deg)}
}

/* ------------------------------------- свёртки (фильтры, будущие раздачи) */
/* Нативные details/summary: работают без JS, доступны с клавиатуры,
   и состояние «раскрыто» браузер берёт на себя. */
.fold{margin-bottom:18px}
.fold__head{
  display:flex; align-items:center; gap:8px; cursor:pointer; list-style:none;
  padding:11px 14px; font-size:14px; font-weight:700;
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
  color:var(--text-dim); min-height:44px;
}
.fold__head::-webkit-details-marker{display:none}
.fold__head:hover{color:var(--text); border-color:var(--line-hi)}
.fold__head::after{
  content:"▾"; margin-left:auto; font-size:12px; color:var(--muted);
}
.fold[open] > .fold__head{
  border-radius:var(--radius) var(--radius) 0 0; border-bottom:0; color:var(--text);
}
.fold[open] > .fold__head::after{content:"▴"}
.count--on{
  background:var(--accent-soft); color:var(--accent-text);
  padding:1px 7px; border-radius:999px; font-weight:800;
}
.fold--filters[open] .filters{border-radius:0 0 var(--radius) var(--radius)}
.fold .free-list{margin-top:14px}

/* ------------------------------------------------------------- фильтры */
.filters{
  display:flex; flex-wrap:wrap; gap:10px; align-items:flex-end;
  padding:14px;
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
}
.filter{display:flex; flex-direction:column; gap:5px; min-width:0; flex:1 1 165px}
.filter__label{
  font-size:10.5px; font-weight:700; text-transform:uppercase;
  letter-spacing:.06em; color:var(--muted);
}
/* Знак «?» рядом с подписью фильтра: термин без расшифровки человек
   просто не тронет. Работает и по наведению, и с клавиатуры. */
/* Кнопка-подсказка. Чуть крупнее прежнего: 15px — это меньше минимальной
   тач-зоны, в неё было не попасть пальцем. */
.filter__hint{
  display:inline-grid; place-items:center; width:18px; height:18px;
  margin-left:6px; padding:0; vertical-align:middle;
  background:var(--bg-soft); border:1px solid var(--line-hi); border-radius:999px;
  font:inherit; font-size:11px; font-weight:700; line-height:1; color:var(--muted);
  cursor:pointer; transition:background-color .15s, color .15s, border-color .15s;
}
.filter__hint:hover{background:var(--card-hi); color:var(--text); border-color:var(--accent)}
.filter__hint[aria-expanded="true"]{
  background:var(--accent); border-color:var(--accent); color:var(--accent-ink);
}
.filter__hint:hover, .filter__hint:focus-visible{color:var(--text); border-color:var(--accent)}

/* Своя подсказка вместо нативного title: тот не показывается на телефоне
   и исчезает, стоит увести курсор. Эта открывается по нажатию и остаётся,
   пока её не закроют. Позиционируется от подписи фильтра. */
.hintwrap{position:relative; display:inline-block}
/* Всплывающая подсказка. Хвостик указывает на кнопку — иначе непонятно,
   к чему относится текст, когда рядом четыре фильтра. */
.hintbox{
  position:absolute; top:calc(100% + 10px); left:-14px; z-index:15;
  width:min(330px, 78vw);
  background:var(--card-hi); color:var(--text-dim);
  border:1px solid var(--line-hi); border-radius:var(--radius);
  padding:12px 14px; font-size:13px; line-height:1.55; font-weight:400;
  text-transform:none; letter-spacing:normal;
  box-shadow:var(--shadow-hi);
}
/* Хвостик: два квадрата под 45° — верхний перекрывает границу нижнего,
   поэтому стык не виден ни в тёмной теме, ни в светлой. */
.hintbox::before, .hintbox::after{
  content:""; position:absolute; top:-6px; left:16px;
  width:10px; height:10px; transform:rotate(45deg);
}
.hintbox::before{background:var(--line-hi)}
.hintbox::after{background:var(--card-hi); top:-5px}

@media (prefers-reduced-motion:no-preference){
  .hintbox{animation:hintin .16s ease-out both}
}
@keyframes hintin{
  from{opacity:0; transform:translateY(-4px)}
  to{opacity:1; transform:none}
}

/* --------------------------------- мультивыбор магазинов */
.filter--stores{position:relative}
.stores{width:100%}
.stores__head{
  list-style:none; cursor:pointer; font-size:14px; padding:9px 11px; min-height:40px;
  display:flex; align-items:center;
  color:var(--text); background:var(--bg-soft);
  border:1px solid var(--line-hi); border-radius:var(--radius-sm);
}
.stores__head::-webkit-details-marker{display:none}
.stores__head::after{content:"▾"; margin-left:auto; color:var(--muted); font-size:11px}
.stores[open] .stores__head{border-color:var(--accent)}
.stores[open] .stores__head::after{content:"▴"}
/* Список раскрывается поверх контента, а не раздвигает панель:
   иначе при выборе магазина всё под фильтрами прыгает вниз. */
.stores__list{
  position:absolute; z-index:12; left:0; right:0; top:calc(100% + 4px);
  max-height:240px; overflow-y:auto; padding:6px;
  background:var(--card); border:1px solid var(--line-hi);
  border-radius:var(--radius-sm) var(--radius-sm) 0 0; box-shadow:var(--shadow-hi);
}
.stores__row{
  display:flex; align-items:center; gap:9px; padding:8px 9px; min-height:40px;
  font-size:13.5px; border-radius:8px; cursor:pointer;
}
.stores__row:hover{background:var(--card-hi)}
.stores__row input{width:17px; height:17px; accent-color:var(--accent); flex:none}
.stores__clear{
  position:absolute; z-index:12; left:0; right:0; top:calc(100% + 244px);
  font:inherit; font-size:12.5px; padding:9px; cursor:pointer;
  color:var(--muted); background:var(--card);
  border:1px solid var(--line-hi); border-top:0;
  border-radius:0 0 var(--radius-sm) var(--radius-sm);
}
.stores__clear:hover{color:var(--text); border-color:var(--heart)}

.filter__select{
  font:inherit; font-size:14px; padding:9px 11px; width:100%;
  color:var(--text); background:var(--bg-soft);
  border:1px solid var(--line-hi); border-radius:var(--radius-sm); cursor:pointer;
}
.filter__select:hover{border-color:var(--accent)}
.filter-reset{
  font:inherit; font-size:13.5px; font-weight:600; padding:9px 15px; cursor:pointer;
  color:var(--muted); background:none;
  border:1px solid var(--line-hi); border-radius:var(--radius-sm);
}
.filter-reset:hover{color:var(--text); border-color:var(--heart)}
@media (max-width:520px){
  .filters{gap:8px; padding:12px}
  .filter{flex:1 1 calc(50% - 4px)}
  /* Только сброс фильтров тянем на всю ширину. Без вложенности это правило
     ловило и «Очистить всё» в избранном — удаление всего списка не должно
     выглядеть главной кнопкой экрана. */
  .filters .filter-reset{flex:1 1 100%}
}

/* ---------------------------------------------------------- таблица цен */
.tbl-wrap{
  overflow-x:auto; -webkit-overflow-scrolling:touch;
  border:1px solid var(--line); border-radius:var(--radius); background:var(--card);
}
table{width:100%; border-collapse:collapse}
th,td{padding:12px 14px; text-align:left; border-bottom:1px solid var(--line); font-size:14px}
th{
  color:var(--muted); font-weight:700; font-size:11px; text-transform:uppercase;
  letter-spacing:.06em; background:var(--bg-soft);
}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover{background:var(--card-hi)}
tr.best{background:var(--accent-soft)}
tr.best:hover{background:var(--accent-soft)}
.store{display:flex; align-items:center; gap:9px; min-width:160px}
.store img{width:22px; height:22px; object-fit:contain; flex:none; border-radius:4px}
.store__name{text-decoration:none; font-weight:600}
.price{font-weight:800; font-size:15px; white-space:nowrap}
tr.best .price{color:var(--accent-text)}
.retail{color:var(--muted); text-decoration:line-through; font-size:12px; margin-left:7px; font-weight:500}

/* Свёрнутый хвост таблицы: показываем 5 лучших, остальное по кнопке. */
.tbl-wrap.is-collapsed .row-extra{display:none}
.more{
  display:block; width:100%; margin-top:12px; padding:13px 16px;
  font:inherit; font-size:14px; font-weight:600; cursor:pointer;
  background:var(--card); color:var(--text-dim);
  border:1px solid var(--line); border-radius:var(--radius);
}
.more:hover{border-color:var(--accent); color:var(--text); background:var(--card-hi)}

.badge{
  display:inline-block; font-size:11px; font-weight:700; padding:3px 8px;
  border-radius:999px; white-space:nowrap; line-height:1.45;
}
.badge--save{background:var(--good-bg); color:var(--good)}
.badge--official{background:var(--violet-soft); color:var(--violet)}
.badge--grey{background:var(--warn-bg); color:var(--warn)}


.buy{
  display:inline-block; padding:9px 16px; border-radius:var(--radius-sm);
  background:var(--accent); color:var(--accent-ink); font-weight:700;
  text-decoration:none; font-size:13px; white-space:nowrap;
}
.buy:hover{background:var(--accent-hi); color:var(--accent-ink)}
.buy--ghost{background:transparent; color:var(--text); border:1px solid var(--line-hi)}
.buy--ghost:hover{background:var(--card-hi); color:var(--text); border-color:var(--accent)}

/* ----------------------------------------------------- «сейчас бесплатно» */
/* auto-fit, а не auto-fill: раздач обычно две-три, и при auto-fill сетка
   держала четыре пустых колонки — справа зияла дыра. auto-fit сворачивает
   пустые дорожки, и карточки растягиваются на всю ширину. */
.free-list{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:16px; padding:0; margin:0; list-style:none;
}
/* «Скоро будут бесплатны» — отдельный раздел, а не продолжение сетки.
   Своего отступа у него не было, и он прилипал к последнему ряду карточек:
   читался как их часть, хотя говорит о другом — о том, чего ЕЩЁ нельзя
   забрать. Отступ сверху и делает из него отдельную мысль. */
.free-soon{margin-top:28px}

/* ---------------------------------------------------- свежесть данных

   «24 предложения · обновлено в 12:40» рядом с заголовком списка.
   Приглушённая и мелкая: она отвечает на вопрос, который человек задаёт
   один раз («это сегодняшние цены?»), и не должна спорить с карточками
   за внимание. */
.list-head{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:12px 16px; flex-wrap:wrap; margin-bottom:10px;
}
.list-head .section-title{margin:0}
.fresh{margin:0; font-size:12.5px; color:var(--muted); white-space:nowrap}
/* На странице игры подпись стоит под заголовком таблицы и переносится
   вместе с ним — там нельзя запрещать перенос. */
.offers-head .fresh{white-space:normal}
@media (max-width:520px){
  .list-head{gap:4px 12px}
  .fresh{font-size:12px; white-space:normal}
}

/* Порядок получения раздачи. Нумерация своя, а не браузерная: цифра должна
   стоять в акцентном кружке рядом с текстом, а не висеть за краем блока. */
.steps{list-style:none; counter-reset:step; margin:0; padding:0; display:grid; gap:10px}
.steps li{
  counter-increment:step; position:relative; padding-left:30px;
  font-size:14px; line-height:1.45; color:var(--text-dim);
}
.steps li::before{
  content:counter(step); position:absolute; left:0; top:0;
  width:21px; height:21px; display:grid; place-items:center;
  font-size:11.5px; font-weight:700; border-radius:999px;
  background:var(--accent-soft); color:var(--accent-text);
}
.free-card{
  display:flex; flex-direction:column; background:var(--card);
  border:1px solid var(--line); border-radius:var(--radius); overflow:hidden;
}
/* Наведение — ровно как у карточек каталога: подъём, акцентная рамка,
   наезд обложки и блик. Раньше здесь была своя, куда более вялая версия
   (только рамка потемнее), и раздачи выглядели неживыми рядом с каталогом.
   Значения не копируем на глаз — селекторы добавлены к тем же правилам. */
.free-card--link:hover{
  border-color:var(--accent); transform:translateY(-4px);
  box-shadow:var(--shadow-hi), 0 0 0 1px var(--accent-soft);
}
/* Нажимается вся карточка, а не кнопка в ней. Ссылка лежит в заголовке —
   у неё осмысленный текст для скринридера и поисковика, — а ::after
   растягивает её область нажатия на весь блок. */
.free-card--link{position:relative}
.free-card__link{color:inherit; text-decoration:none}
.free-card__link::after{content:""; position:absolute; inset:0; z-index:1}
.free-card--link:hover .free-card__link{color:var(--accent-text)}
/* Обводка фокуса должна очерчивать карточку, а не строку заголовка:
   иначе с клавиатуры непонятно, что выбран весь блок. */
.free-card--link:focus-within{outline:2px solid var(--accent); outline-offset:2px}
.free-card__link:focus-visible{outline:none}
/* Кнопка внутри кликабельной карточки — уже не кнопка, а подпись действия.
   Оставляем её вид, но убираем наведение: живого элемента здесь нет. */
.free-card .buy--flat{pointer-events:none}
.free-card__art{position:relative; aspect-ratio:16/9; background:var(--card-hi); overflow:hidden}
.free-card__art img{width:100%; height:100%; object-fit:cover; display:block}
.free-card__tag{
  position:absolute; top:9px; left:9px; z-index:1; font-size:11px; font-weight:800;
  padding:4px 9px; border-radius:999px;
  background:var(--accent); color:var(--accent-ink);
}
.free-card__tag--soon{background:var(--card); color:var(--text-dim); border:1px solid var(--line-hi)}
.free-card__body{padding:13px 14px 14px; display:flex; flex-direction:column; gap:9px; flex:1}
.free-card h3{margin:0; font-size:15px; line-height:1.3; font-weight:700}
.free-card__row{display:flex; align-items:center; gap:7px; flex-wrap:wrap}
.free-card__timer{font-size:12.5px; color:var(--muted)}
/* Кнопку прижимаем к низу, а не таймер: таймер есть не у каждой раздачи,
   и раньше кнопки в одном ряду стояли на разной высоте — у карточек без
   таймера выше, у карточек с таймером ниже. */
.free-card .buy--flat{margin-top:auto}
.free-card__timer strong{color:var(--text-dim)}

/* --------------------------------------------------------------- прочее */
.state{text-align:center; color:var(--muted); padding:40px 16px; font-size:14.5px}

/* Пустое избранное. Пустой экран без объяснения читается как поломка,
   поэтому здесь сразу сказано, что нажать. */
.empty{
  text-align:center; padding:48px 20px; max-width:44ch; margin:0 auto;
}
.empty__icon{
  font-size:38px; line-height:1; color:var(--accent-text);
  filter:drop-shadow(0 0 14px var(--accent-soft)); margin-bottom:14px;
}
.empty h2{margin:0 0 8px; font-size:19px}
.empty p{color:var(--muted); font-size:14.5px; margin:0 0 20px}

.fav-head{display:flex; align-items:center; gap:12px; margin-bottom:12px}
.fav-head .section-title{margin:0; flex:1; min-width:0}
.fav-head .filter-reset{flex:none; font-size:12.5px; padding:8px 12px; white-space:nowrap}
.notice{
  background:var(--card); border:1px solid var(--line); border-left:3px solid var(--warn);
  border-radius:var(--radius-sm); padding:14px 16px; font-size:14px; color:var(--text-dim);
  margin:16px 0;
}
/* ------------------------------------------------- хлебные крошки

   Стилей у них не было вообще, хотя разметка на странице автора стояла:
   выглядело как строка ссылок без всякого оформления. Не украшение —
   именно крошки показывают Google структуру, а человеку дают выход
   на уровень выше, кроме кнопки «назад» в браузере. */
.crumbs{
  font-size:13px; color:var(--muted); margin-bottom:12px;
  display:flex; flex-wrap:wrap; gap:6px; align-items:center;
}
.crumbs a{color:var(--muted); text-decoration:none}
.crumbs a:hover{color:var(--text); text-decoration:underline}
.crumbs [aria-current]{color:var(--text-dim)}

/* Заголовок хаба: тот же лозунг, но без свечения и лишнего воздуха —
   человек пришёл смотреть список, а не читать вступление. */
/* Заголовок хаба и вишлиста выровнен ПО ЛЕВОМУ КРАЮ целиком.
   Раньше абзац прижимался влево, а текст внутри оставался центрированным
   от общего .hero — строки рвались посередине и выглядели криво. */
/* Хаб шире главной: заголовок здесь короче, а подпись объясняет раздел,
   и ей нужно две строки вместо трёх. */
.hero--hub{margin-bottom:18px; text-align:left; max-width:900px; margin-inline:0}
.hero--hub h1{font-size:clamp(22px,3.6vw,32px); text-align:left}
.hero--hub p{margin-left:0; margin-right:0; text-align:left}

/* На вишлисте форма стоит не в центре страницы, а под заголовком слева —
   значит и подпись под ней должна быть слева, иначе она «плавает». */
body[data-page="wishlist"] .search-hint{text-align:left}

/* Список видов ссылки: моноширинный, чтобы адрес читался как адрес
   и не путался с обычным текстом. */
.linklist{margin:10px 0; padding-left:18px; display:grid; gap:6px}
.linklist code{
  font-size:13px; background:var(--bg-soft); border:1px solid var(--line);
  border-radius:6px; padding:2px 6px; word-break:break-all;
}

/* ------------------------------------- страница игры: цены и сайдбар

   Слева — ответ на вопрос, с которым человек пришёл: где дешевле.
   Справа — справка об игре: описание, жанры, кадры.

   Сайдбар фиксированной ширины, а не долей: на широком экране колонка
   в 340px читается, а растянутая на половину страницы — уже не справка,
   а второй контент, спорящий с ценами за внимание.

   На узком экране колонки складываются, и порядок задаёт разметка:
   сначала цены, потом описание. Мобильный трафик главный, двух колонок
   там быть не может. */
.game-grid{display:grid; grid-template-columns:minmax(0,1fr) 340px; gap:28px; align-items:start}
.game-side{min-width:0}
.game-side .about,
.game-side .shots{margin-bottom:18px}
/* В узкой колонке кадры идут в один столбец: две штуки в ряд по 160px —
   уже не иллюстрация, а марки. */
.game-side .shots__row{grid-template-columns:1fr}
.game-side .about__fact{grid-template-columns:1fr; gap:2px}

@media (max-width:900px){
  .game-grid{grid-template-columns:1fr; gap:0}
  .game-side .shots__row{grid-template-columns:1fr 1fr}
}

/* Ряды соседних игр под таблицей: «ещё в этом магазине» и «за те же деньги».
   Со страницы игры должно быть куда идти — иначе она тупик и для человека,
   и для робота. Карточки те же, что в каталоге, сетка чуть плотнее. */
.related{margin-top:26px}
.related .grid--wide{grid-template-columns:repeat(auto-fill,minmax(210px,1fr))}
/* Три, а не четыре: ряды стоят в левой колонке рядом с сайдбаром,
   и четыре карточки там ужимаются до 200px — мельче, чем в каталоге,
   хотя это те же карточки. */
@media (min-width:1000px){
  .related .grid--wide{grid-template-columns:repeat(3,1fr)}
}

/* Строка под сводкой: пересчёт валюты слева, «поделиться» справа.
   Кнопка неяркая: она полезна, но спорить с «Купить» за внимание
   не должна — это разные по важности действия. */
/* ------------------------------------------------------- список магазинов

   Страница /stores. Хабы магазинов существовали с самого начала, но ссылок
   из меню на них не было — человек про эти три десятка страниц не знал.

   Плитки, а не список строк: у магазинов есть логотипы, и по ним глаз
   находит нужный быстрее, чем по названию. */
.stores-bar{display:flex; align-items:flex-end; gap:14px; flex-wrap:wrap; margin-bottom:14px}
.stores-bar .filter{flex:1; min-width:220px; max-width:340px}
.stores-count{font-size:13px; color:var(--muted); padding-bottom:11px}

.stores-grid{
  display:grid; gap:10px; margin-bottom:8px;
  grid-template-columns:repeat(auto-fill,minmax(190px,1fr));
}
.store-card{
  display:flex; align-items:center; gap:11px; min-height:56px;
  padding:11px 13px; background:var(--card); color:var(--text-dim);
  border:1px solid var(--line); border-radius:var(--radius-sm);
  text-decoration:none; font-size:14.5px; font-weight:600;
}
.store-card img{flex:none; width:28px; height:28px; object-fit:contain; border-radius:6px}
.store-card span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.store-card:hover{
  color:var(--text); border-color:var(--accent); background:var(--card-hi);
  transform:translateY(-2px); box-shadow:var(--shadow);
}
@media (prefers-reduced-motion:no-preference){
  .store-card{transition:background-color .16s,border-color .16s,color .16s,transform .16s,box-shadow .16s}
}
@media (max-width:520px){
  /* На телефоне две колонки: одна даёт простыню на три экрана,
     а логотип с названием в половину ширины читаются нормально. */
  .stores-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:8px}
  .store-card{min-height:52px; padding:10px 11px; font-size:13.5px; gap:9px}
  .store-card img{width:24px; height:24px}
  .stores-bar .filter{max-width:none}
}

/* Плашка «эту игру сейчас раздают» на странице игры.

   Стилей у неё не было ВООБЩЕ: разметка стояла, а на экране это выглядело
   как две строки текста с кнопкой под ними — посреди оформленных плиток
   с ценами читалось как поломка вёрстки.

   Оформлена акцентом, а не как обычная карточка: это самая ценная новость
   на странице — игру можно не покупать вовсе, — и она должна перебивать
   собой таблицу цен, стоящую ниже. */
.giveaway{
  display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  margin:0 0 16px; padding:14px 16px;
  background:var(--accent-soft); border:1px solid var(--accent);
  border-radius:var(--radius);
}
.giveaway__text{display:flex; flex-direction:column; gap:3px; flex:1; min-width:0}
.giveaway__text strong{font-size:15.5px; line-height:1.25; color:var(--text)}
.giveaway__text span{font-size:13px; color:var(--text-dim)}
.giveaway .buy{flex:none}
@media (max-width:560px){
  /* Кнопка во всю ширину: узкая кнопка сбоку от двух строк текста
     складывается в лесенку и попасть в неё пальцем труднее, чем кажется. */
  .giveaway{gap:12px}
  .giveaway .buy{width:100%}
}

/* Кнопка подписки на карточке избранного. Занимает всю ширину карточки:
   в сетке она читается как действие над этой игрой, а не как ярлык. */
.fav-track{
  font:inherit; font-size:12.5px; font-weight:600; cursor:pointer;
  width:100%; min-height:40px; padding:9px 10px; margin-top:-1px;
  color:var(--text-dim); background:var(--card-hi);
  border:1px solid var(--line); border-top:0;
  border-radius:0 0 var(--radius) var(--radius);
}
.fav-track:hover{color:var(--text); border-color:var(--violet)}
.fav-track.is-on{color:var(--accent-text); border-color:var(--accent)}
.fav-track:disabled{opacity:.6; cursor:default}

/* ---------------------------------------------- подписка на цену

   Блок появляется под ценой и ведёт себя как один шаг за раз: сначала одна
   кнопка, потом поле с ценой, потом подтверждение. Показывать всё сразу
   значит спросить у человека решение до того, как он согласился в принципе. */
.track{
  margin:0 0 16px; padding:14px 16px;
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
}
.track__cta{
  font:inherit; font-size:14.5px; font-weight:650; cursor:pointer;
  padding:10px 16px; min-height:44px; border-radius:999px;
  background:var(--violet-soft); color:var(--text); border:1px solid var(--violet);
}
.track__cta:hover{background:var(--violet); color:#fff}
.track__hint{margin:8px 0 0; font-size:13px; color:var(--muted)}
.track__row{display:flex; flex-direction:column; gap:6px}
.track__label{font-size:12px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted)}
.track__price{
  font:inherit; font-size:16px; padding:11px 12px; min-height:44px; max-width:220px;
  background:var(--bg-soft); color:var(--text);
  border:1px solid var(--line-hi); border-radius:var(--radius-sm);
}
.track__price:focus{outline:2px solid var(--accent); outline-offset:1px}
.track__actions{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:12px}
.track__save{flex:none}
.track__stop{
  font:inherit; font-size:13px; padding:10px 12px; min-height:44px; cursor:pointer;
  background:none; color:var(--muted); border:1px solid transparent; border-radius:var(--radius-sm);
}
.track__stop:hover{color:var(--text); background:var(--card-hi)}
.track__done{margin:0 0 8px; font-size:14.5px; font-weight:600; color:var(--text)}
.track__note{margin:12px 0 0; font-size:12px; color:var(--muted)}
@media (max-width:520px){
  .track__cta, .track__save{width:100%}
  .track__price{max-width:none}
}

/* Отношение к историческому минимуму. Приглушено, пока цена выше минимума,
   и подсвечено, когда дошла: подсветка должна значить «вот оно», а не быть
   фоном для любого числа. */
.tile__low{
  display:inline-block; margin-top:8px; padding:4px 9px; border-radius:999px;
  font-size:12px; font-weight:600; color:var(--muted);
  background:var(--bg-soft); border:1px solid var(--line);
}
.tile__low--best{
  color:var(--accent-ink); background:var(--accent); border-color:var(--accent);
}

.pricebar{display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin-bottom:14px}
.pricebar .curbar{margin:0}
/* Отодвигает кнопку вправо ИМЕННО слот: флекс-элементы здесь — слоты,
   а не сама кнопка, поэтому margin:auto на .share ничего не делал. */
.pricebar #share-slot{margin-left:auto}
.share{
  background:var(--card); color:var(--text-dim);
  border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:9px 14px; font:inherit; font-size:13.5px; cursor:pointer;
  min-height:40px; transition:border-color .16s,color .16s;
}
.share:hover{border-color:var(--line-hi); color:var(--text)}
@media (max-width:520px){
  /* На телефоне кнопка во всю ширину: тач-зона важнее компактности. */
  .pricebar #share-slot{margin-left:0; width:100%}
  .share{width:100%}
}

/* Заголовок таблицы и свёртка «цены по странам» в одной строке:
   на широком экране рядом, на узком — друг под другом. */
.offers-head{display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin-bottom:10px}
.offers-head .section-title{margin:0}
.offers-head #regions-slot{margin-left:auto; min-width:0}
.offers-head .fold{margin-bottom:0}
@media (max-width:620px){
  .offers-head{display:block}
  .offers-head #regions-slot{margin:10px 0 0}
}

/* --------------------------------------------- вердикт о цене

   Главный ответ страницы. Цифра «$3.99» сама по себе ничего не решает:
   скидка 90% ничего не значит, если игра полгода столько же и стоила.
   Поэтому вывод стоит ДО таблицы и выделен цветом по смыслу:
   лайм — бери, янтарь — можно подождать. Цвета те же, что в остальном
   интерфейсе, так что учить их отдельно не нужно. */
.verdict{
  border:1px solid var(--line); border-left-width:3px;
  border-radius:var(--radius); background:var(--card);
  padding:14px 16px; margin-bottom:18px;
}
.verdict--best{border-left-color:var(--accent); background:var(--accent-soft)}
.verdict--near{border-left-color:var(--good); background:var(--good-bg)}
.verdict--wait{border-left-color:var(--warn); background:var(--warn-bg)}
.verdict__label{
  font-size:11.5px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); margin-bottom:6px;
}
.verdict__text{margin:0; font-size:15.5px; font-weight:650; color:var(--text)}
.verdict__meta{margin:6px 0 0; font-size:13px; color:var(--muted)}

/* ------------------------------------------------------ «Об игре»

   Описание, жанры и дата выхода — то, что отличает страницу игры
   от соседней НЕ только названием. Без них страницы выходят близнецами,
   а за это Google понижает весь сайт, а не только их. */
.about{margin-bottom:22px}
.about__text{margin:0 0 14px; color:var(--text-dim); line-height:1.6}
.about__facts{display:grid; gap:10px; margin:0}
.about__fact{display:grid; grid-template-columns:120px 1fr; gap:12px; align-items:baseline}
.about__fact dt{color:var(--muted); font-size:13px}
.about__fact dd{margin:0; color:var(--text-dim); font-size:14px}

.shots{margin-bottom:22px}
.shots__row{
  display:grid; gap:10px;
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
}
.shots__row img{
  width:100%; height:auto; display:block;
  border:1px solid var(--line); border-radius:var(--radius-sm);
}

/* Слайдер включается скриптом: без него выше остаётся обычный список кадров,
   и это правильный запасной вариант — картинки видны всем. */
.shots--slider .shots__row{display:block; position:relative}
.shots--slider .shots__row img{display:none; cursor:zoom-in}
.shots--slider .shots__row img.is-current{display:block}

.shots__nav{display:flex; align-items:center; gap:10px; margin-top:8px}
.shots__counter{font-size:12.5px; color:var(--muted); min-width:6ch; text-align:center}
.shots__arrow{
  width:32px; height:32px; display:grid; place-items:center;
  background:var(--card); color:var(--text-dim); cursor:pointer;
  border:1px solid var(--line); border-radius:999px;
  font:inherit; font-size:18px; line-height:1;
}
.shots__arrow:hover{border-color:var(--accent); color:var(--text)}

.shots__thumbs{display:grid; grid-auto-flow:column; gap:6px; margin-top:8px; justify-content:start}
.shots__thumb{
  padding:0; background:none; cursor:pointer; line-height:0;
  border:1px solid var(--line); border-radius:6px; overflow:hidden;
}
.shots__thumb img{width:56px; height:32px; object-fit:cover; border:0; border-radius:0}
.shots__thumb.is-current{border-color:var(--accent)}
.shots__thumb:hover{border-color:var(--line-hi)}

/* Крупный просмотр. Своё окно, а не новая вкладка: та уводит с сайта,
   и на телефоне возвращаться неудобно. */
.lightbox{
  position:fixed; inset:0; z-index:50; display:grid;
  grid-template-columns:auto minmax(0,1fr) auto; align-items:center; gap:10px;
  padding:20px; background:rgba(6,8,11,.92);
}
.lightbox img{
  max-width:100%; max-height:86vh; margin:0 auto; display:block;
  border-radius:var(--radius); box-shadow:var(--shadow-hi);
}
.lightbox__arrow{width:44px; height:44px; font-size:22px}
.lightbox__close{
  position:absolute; top:14px; right:16px; width:40px; height:40px;
  background:var(--card); color:var(--text); border:1px solid var(--line);
  border-radius:999px; font:inherit; font-size:22px; line-height:1; cursor:pointer;
}
.lightbox__close:hover{border-color:var(--accent)}

@media (max-width:520px){
  /* На телефоне стрелки по бокам съедают ширину кадра — убираем их,
     листать можно миниатюрами и свайпом по экрану. */
  .lightbox{grid-template-columns:1fr; padding:12px}
  .lightbox__arrow{display:none}
}

@media (max-width:520px){
  /* Подпись над значением: в две колонки на телефоне остаётся
     полоска в пару слов на строку. */
  .about__fact{grid-template-columns:1fr; gap:2px}
  .shots__row{grid-template-columns:1fr 1fr}
}

.note{color:var(--muted); font-size:12.5px; margin-top:20px; text-align:center}

/* Перелинковка внизу страниц: не декоративный блок, а рабочая навигация —
   через неё робот находит подборки, а человек не упирается в тупик. */
.crosslinks{
  margin-top:40px; padding-top:22px; border-top:1px solid var(--line);
}
.crosslinks ul{list-style:none; padding:0; margin:0; display:grid; gap:10px;
  grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
/* Кликабелен ВЕСЬ блок, а не только строчка заголовка: человек целится
   в карточку, а попадал мимо ссылки. Растягиваем ссылку псевдоэлементом —
   разметка остаётся семантичной, лишних обёрток не нужно. */
.crosslinks li{
  position:relative; font-size:13.5px; color:var(--muted); line-height:1.5;
  background:var(--card); border:1px solid var(--line);
  border-radius:var(--radius-sm); padding:12px 14px; cursor:pointer;
  transition:border-color .15s, background-color .15s;
}
.crosslinks li:hover{border-color:var(--accent); background:var(--card-hi)}
.crosslinks li:has(a:focus-visible){border-color:var(--accent)}
.crosslinks a{color:var(--text); font-weight:700; text-decoration:none; display:block}
.crosslinks a::after{content:""; position:absolute; inset:0; border-radius:inherit}
.crosslinks a:hover{color:var(--accent-text)}
.hidden{display:none !important}

/* Скелетоны: страница не должна прыгать и мигать текстом «Ищу…» */
.sk-grid{display:grid; gap:16px; grid-template-columns:repeat(auto-fill,minmax(160px,1fr))}
.sk{
  border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; background:var(--card);
}
.sk__art{aspect-ratio:2/3}
.sk__line{height:11px; margin:11px 11px 0; border-radius:6px}
.sk__line--short{width:52%; margin-bottom:13px}
.sk__art,.sk__line{
  background:linear-gradient(90deg,var(--card-hi) 25%,var(--line) 37%,var(--card-hi) 63%);
  background-size:400% 100%;
}
@media (prefers-reduced-motion:no-preference){
  .sk__art,.sk__line{animation:sheen 1.4s ease-in-out infinite}
}
@keyframes sheen{0%{background-position:100% 0}100%{background-position:0 0}}

/* ------------------------------------------------------- кошельки донатов */
.wallets{list-style:none; padding:0; margin:16px 0; display:grid; gap:12px}
.wallet{background:var(--card); border:1px solid var(--line); border-radius:var(--radius); padding:13px 15px}
.wallet__head{display:flex; align-items:center; gap:9px; margin-bottom:9px; flex-wrap:wrap}
.wallet__addr{
  font:13px/1.5 ui-monospace,SFMono-Regular,Consolas,monospace;
  width:100%; text-align:left; word-break:break-all; cursor:pointer;
  background:var(--bg); color:var(--text);
  border:1px dashed var(--line-hi); border-radius:var(--radius-sm); padding:11px 13px;
}
.wallet__addr:hover{border-color:var(--accent); border-style:solid}
.wallet__hint{display:block; font-size:12px; color:var(--accent-text); min-height:1.2em; margin-top:6px}
.wallet__todo{font-size:13px; color:var(--muted); margin:0}

/* ------------------------------------------------------- текстовые страницы */
.prose h1{font-size:clamp(24px,4.5vw,32px); margin:0 0 18px; font-weight:800}
.prose h2{font-size:19px; margin:30px 0 8px; font-weight:700}
.prose p,.prose li{color:var(--text-dim)}
.prose strong{color:var(--text)}
.prose ul{padding-left:22px}
.prose li{margin-bottom:6px}
.prose .updated{color:var(--muted); font-size:13px}

/* ------------------------------------------ плашка про данные в браузере */
/* Внизу и неблокирующая: не перекрывает контент модальным окном, потому что
   согласия она не требует — только сообщает. На телефоне складывается
   в столбик, кнопка на всю ширину. */
.notice-bar{
  position:fixed; left:12px; right:12px; bottom:12px; z-index:30;
  display:flex; align-items:center; gap:14px;
  max-width:var(--maxw); margin:0 auto; padding:14px 16px;
  background:var(--card); border:1px solid var(--line-hi);
  border-radius:var(--radius); box-shadow:var(--shadow-hi);
  font-size:13px; color:var(--text-dim); line-height:1.5;
}
.notice-bar__text{flex:1; min-width:0}
.notice-bar__text strong{color:var(--text)}
.notice-bar__ok{flex:none; min-height:42px}
.notice-bar.is-out{opacity:0; transform:translateY(10px)}
@media (prefers-reduced-motion:no-preference){
  .notice-bar{animation:slideup .35s cubic-bezier(.2,.8,.2,1) both}
  .notice-bar.is-out{transition:opacity .25s, transform .25s}
}
@keyframes slideup{from{opacity:0; transform:translateY(16px)} to{opacity:1; transform:none}}
@media (max-width:600px){
  .notice-bar{flex-direction:column; align-items:stretch; gap:11px; font-size:12.5px}
  .notice-bar__ok{width:100%}
}

/* ---------------------------------------------------------------- футер */
/* Футер: слева кто мы, справа разделы колонками. Раньше это была свалка
   из семи ссылок в строку и трёх абзацев подряд — на широком экране она
   растягивалась через весь экран и читалась как сноска, а не как навигация. */
.site-foot{border-top:1px solid var(--line); background:var(--bg-soft); font-size:13px}
.site-foot__in{max-width:var(--maxw); margin:0 auto; padding:34px 16px 30px; display:grid; gap:26px}
.site-foot a{color:var(--muted); text-decoration:none}
.site-foot a:hover{color:var(--text); text-decoration:underline}

.foot-top{display:grid; grid-template-columns:minmax(0,1fr) auto; gap:32px; align-items:start}
.foot-brand{max-width:38ch}
.foot-brand__name{font-weight:800; color:var(--text); font-size:15px; letter-spacing:-.02em}
.foot-brand__note{margin:6px 0 10px; color:var(--muted); line-height:1.6}
.foot-mail{margin:0; color:var(--muted)}
.foot-mail a{color:var(--violet)}

/* Колонки разделов прижаты вправо — там их и ищут взглядом,
   когда слева стоит блок с названием. */
.foot-nav{display:grid; grid-auto-flow:column; gap:40px; justify-content:end}
.foot-col{display:grid; gap:8px; align-content:start}
.foot-col__title{
  margin:0 0 2px; font-size:11px; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--text-dim);
}

.foot-bottom{
  display:grid; gap:8px; padding-top:18px; border-top:1px solid var(--line);
  color:var(--muted);
}
.site-foot .disclosure{margin:0; max-width:74ch; line-height:1.6}
.site-foot .disclosure strong{color:var(--text-dim)}
.site-foot .copy{margin:0; line-height:1.6}
.copy__sign{white-space:nowrap}

@media (max-width:760px){
  /* На телефоне колонки в ряд не помещаются: сначала бренд, потом разделы
     в две колонки — так они остаются списком, а не простынёй. */
  .foot-top{grid-template-columns:1fr; gap:22px}
  .foot-nav{grid-auto-flow:row; grid-template-columns:repeat(2,minmax(0,1fr)); gap:20px; justify-content:start}
}
/* Почта в футере — ненавязчиво, но чтобы её можно было найти:
   партнёрские сети проверяют наличие рабочего контакта. */
.foot-mail{margin:0; color:var(--muted); font-size:12.5px}
.foot-mail a{color:var(--muted); text-decoration:underline}
.foot-mail a:hover{color:var(--text)}

@media (prefers-reduced-motion:no-preference){
  .card,.buy,.nav a,.nav button,.free-card,.search input{
    transition:background-color .16s,border-color .16s,color .16s,transform .16s,box-shadow .16s;
  }
}

@media (max-width:520px){
  .grid{grid-template-columns:repeat(auto-fill,minmax(135px,1fr)); gap:12px}
  .grid--wide{grid-template-columns:1fr}
  .sk-grid{grid-template-columns:repeat(auto-fill,minmax(135px,1fr)); gap:12px}
  .search{flex-direction:column}
  .search button{width:100%}

  /* Донат в шапке остаётся при любой ширине — вместо него уходит «О проекте»
     (есть в футере), а «Избранное» сжимается до звезды со счётчиком. */
  /* Специфичность выше, чем у правила тач-зон `.nav a` ниже:
     иначе то правило вернёт display и ссылка снова появится. */
  /* На телефоне в строке остаются только донат и бургер: место кончается
     после трёх ссылок, а донат — единственный канал дохода, который работает
     с нулевым трафиком, поэтому он на виду и подписан словом, а не значком. */
  .nav-toggle{display:grid}
  .site-head__in{position:relative}
  /* Разделы — выпадающим списком под шапкой. */
  .nav{
    position:absolute; top:100%; right:16px; left:16px; z-index:20;
    display:none; flex-direction:column; align-items:stretch; gap:2px;
    background:var(--card); border:1px solid var(--line-hi);
    border-radius:var(--radius); padding:8px; box-shadow:var(--shadow-hi);
  }
  .nav.is-open{display:flex}
  .nav a{width:100%; text-align:left; padding:12px}
  .nav a.nav-about{display:block}      /* в меню помещается всё */
  /* В выпадающем меню переключатель — такая же строка, как разделы:
     вертикальная рамка слева там ни от чего не отделяет. */
  /* Язык остаётся в строке, поэтому его кнопка живёт по тем же правилам
     высоты, что донат, избранное и тема. */
  .lang__now{height:38px; padding:0 7px}
  .lang__item{padding:12px 12px; min-height:44px}
  /* Избранное подписью не нужно — звезда со счётчиком понятна и занимает
     втрое меньше. Донат, наоборот, подписан словом. */
  .nav-actions .pill--fav .pill__text{display:none}
  /* Подпись убираем только у избранного: звезда со счётчиком понятна сама.
     У доната слово остаётся — это единственный канал дохода, который работает
     с нулевым трафиком, и одно сердечко рядом с прочими значками теряется. */
  .pill--fav .pill__text{display:none}
  .pill--donate .pill__text{display:inline}
  /* Разделитель убираем: пилюли и так отделены рамками, а лишние 17px
     ширины уводят навигацию на вторую строку. */
  .nav__sep{display:none}
  /* Все кнопки в правой части шапки — одной высоты. Донат с подписью выше
     остальных не должен быть: разнобой в 4–6px читается как съехавшая вёрстка.
     Высоту задаём явно, а содержимое центрируем — иначе она набирается
     из padding и у каждой кнопки выходит своя. */
  .nav-actions > *{height:38px}
  /* details растягивать нельзя: его высота — это высота summary. */
  .nav-actions .lang{height:auto}
  .nav-actions .pill{display:inline-flex; align-items:center; padding:0 11px; gap:5px}
  .nav-actions .theme-toggle,
  .nav-actions .nav-toggle{width:38px; padding:0}
  .pill{padding:7px 10px; gap:5px}
  /* Шапка на телефоне должна занимать максимум две строки: бренд и одну
     полосу навигации. Поэтому отступы поджаты — иначе переключатель темы
     переносится на отдельную третью строку и ест высоту зря. */
  .site-head__in{gap:6px; padding:10px 12px}
  .brand{font-size:16px}
  /* Слово «LootRanger» на узком экране уводит навигацию на вторую строку и
     съедает 44px высоты. Оставляем знак — он остаётся ссылкой на главную. */
  .brand__text{
    position:absolute; width:1px; height:1px; overflow:hidden;
    clip-path:inset(50%); white-space:nowrap;
  }
  .nav{gap:0}
  .nav a, .nav button{padding:8px 9px; font-size:13px}
  .donate-link{padding:8px 10px; font-size:13px; margin-left:4px}
  .theme-toggle{width:34px}

  /* Mobile-first: пальцем надо попадать без прицеливания — минимум 44px.
     И 16px в полях: при меньшем размере iOS Safari зумит всю страницу
     при фокусе, и вернуть масштаб обратно человек уже не может. */
  .nav a, .nav button{min-height:44px; display:inline-flex; align-items:center}
  .filter__select{font-size:16px; padding:11px; min-height:44px}
  .filter-reset{min-height:44px}
  .more{min-height:46px}
  .buy{min-height:44px; display:flex; align-items:center; justify-content:center}
  /* Звезда сидит в углу обложки — самое неудобное место для большого пальца. */
  .fav{width:44px; height:44px}

  /* На странице игры экран должен начинаться с игры, а не с поиска.
     Кнопку прячем: отправка работает по Enter, плюс поиск идёт по мере ввода. */
  .hero--compact .search{flex-direction:row}
  .hero--compact .search button{display:none}
  .hero--compact .search input{padding-top:12px; padding-bottom:12px}
}

/* Таблица цен на телефоне превращается в список карточек.
   Причина конкретная: в виде таблицы кнопка «Купить» уезжала за правый край
   и до неё надо было доскроллить горизонтально — главное действие вне экрана. */
@media (max-width:560px){
  .tbl-wrap{border:0; background:none; overflow:visible}
  table{background:none}
  thead{display:none}
  tbody,tbody tr,tbody td{display:block; width:100%}
  tbody tr{
    background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
    padding:12px 14px; margin-bottom:10px;
  }
  tbody tr:hover{background:var(--card)}
  tbody tr.best{border-color:var(--accent); background:var(--accent-soft)}
  tbody td{border-bottom:0; padding:3px 0}
  /* цена и скидка — в одну строку, а не столбиком */
  tbody td:nth-child(2){display:inline-block; width:auto; margin-right:10px}
  tbody td:nth-child(3){display:inline-block; width:auto}
  tbody td:last-child{margin-top:10px}
  .buy{display:block; text-align:center; padding:12px}
  .store{min-width:0}
}

/* -------------------------------------- региональные цены Steam */
.regions{
  border:1px solid var(--line-hi); border-top:0;
  border-radius:0 0 var(--radius) var(--radius); padding:14px;
}
.regions .tbl-wrap{border:0}
.regions__local{color:var(--muted); font-size:13px; white-space:nowrap}
.regions .notice{margin:14px 0 0}

/* ---------------------------- пересчёт цены в свою валюту */
.curbar{
  display:flex; align-items:center; gap:11px; flex-wrap:wrap;
  margin:-6px 0 18px;
}
.curbar__select{width:auto; min-width:132px; font-size:13.5px; padding:8px 11px}
.curbar__out{font-size:13px; color:var(--muted)}
@media (max-width:520px){
  .curbar__select{width:100%}
  .curbar__out{font-size:12.5px}
}
