  * { box-sizing: border-box; }
  body { margin: 0; background: var(--bg-page); color: var(--text-primary); font: var(--fs-base)/var(--lh) var(--font-ui); }
  a { color: var(--accent); text-decoration: none; transition: color var(--transition); }
  a:hover { color: var(--accent-hover); text-decoration: underline; }
  h1, h2, h3 { color: var(--text-primary); }
  .card > h1:first-child, .card > h2:first-child, .card > h3:first-child { margin-top: 0; }
  main > h1:first-child, main > h2:first-child { margin-top: 0; }
  :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

  header.top { position: sticky; top: 0; z-index: 500; border-bottom: 1px solid var(--border); background: rgba(14,17,19,.85); backdrop-filter: blur(8px); }
  header.top .header-inner { max-width: 1140px; margin: 0 auto; display: flex; align-items: center; gap: 16px; padding: 12px 24px; }
  header.top .logo { font-weight: 800; font-size: 20px; letter-spacing: .5px; color: var(--text-primary); white-space: nowrap; flex: 0 0 auto; }
  header.top .logo span { color: var(--accent); }
  header.top nav { display: flex; align-items: center; gap: 16px; flex: 0 0 auto; }
  .nav-link { color: var(--text-secondary); font-weight: 600; font-size: var(--fs-small); }
  .nav-link.desktop-only { display: inline; }

  /* Поиск в шапке: на десктопе — постоянная строка на всю ширину между лого
     и меню; на мобиле — сворачивается в иконку, разворачивается по клику
     (см. @media ниже). */
  .search-box { position: relative; flex: 1; min-width: 0; display: flex; align-items: center; }
  .search-toggle { display: none; background: none; border: none; color: var(--text-secondary); cursor: pointer; font-size: 16px; padding: 8px; text-decoration: none; border-radius: var(--radius-sm); transition: color var(--transition), background var(--transition); }
  .search-toggle:hover { color: var(--text-primary); text-decoration: none; background: var(--bg-card-hover); }
  .search-form { position: relative; flex: 1; min-width: 0; }
  .search-field { width: 100%; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 32px 8px 12px; margin-bottom: 0; color: var(--text-primary); min-height: 32px; box-sizing: border-box; }
  .search-clear { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); background: none; border: none; color: var(--text-secondary); cursor: pointer; font-size: 20px; line-height: 1; padding: 4px; }
  .search-clear:hover { color: var(--text-primary); }

  .avatar-menu { position: relative; }
  .avatar-btn { width: 26px; height: 26px; border-radius: 50%; cursor: pointer; border: 1px solid var(--border); display: block; }
  /* Селектор по прямому потомку .avatar-menu (а не по .avatar-frame), т.к.
     у юзеров без рамки оборачивающий span вообще без класса — top:1px должен
     двигать и картинку, и рамку вместе, одним и тем же блоком. */
  .avatar-menu > span { position: relative; top: 2px; }
  /* Рамка добавляет padding поверх картинки — без этого правила общий
     отпечаток аватара с рамкой крупнее кнопки/колокольчика (32px). */
  .avatar-menu .avatar-frame { width: 26px; height: 26px; box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; }
  .avatar-menu .avatar-frame .avatar-btn { width: 100%; height: 100%; }
  .avatar-dropdown { display: none; position: absolute; right: 0; top: 38px; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-pop); min-width: 180px; padding: 6px; z-index: 600; }
  .avatar-dropdown.open { display: block; }
  .avatar-dropdown a, .avatar-dropdown .link-btn { display: block; width: 100%; text-align: left; padding: 8px 10px; border-radius: var(--radius-sm); color: var(--text-secondary); font-size: var(--fs-small); background: none; border: none; font-family: inherit; cursor: pointer; }
  .avatar-dropdown a:hover, .avatar-dropdown .link-btn:hover { background: var(--bg-card-hover); color: var(--text-primary); text-decoration: none; }

  .layout { max-width: 1140px; margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 24px; padding: 24px; }
  @media (max-width: 800px) { .layout { grid-template-columns: minmax(0, 1fr); } }
  @media (max-width: 720px) { .nav-link.desktop-only, .btn-add-text { display: none; } }

  .tabs { display: flex; flex-wrap: nowrap; gap: 3px; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 3px; margin: 14px 0; width: fit-content; max-width: 100%; overflow-x: auto; scrollbar-width: thin; }
  .tabs::-webkit-scrollbar { height: 4px; }
  .tabs::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
  .tabs a { flex: 0 0 auto; color: var(--text-secondary); font-weight: 500; font-size: var(--fs-small); padding: 5px 12px; border-radius: 4px; text-decoration: none; white-space: nowrap; transition: color var(--transition), background var(--transition); }
  .tabs a:hover { color: var(--text-primary); text-decoration: none; }
  .tabs a.active { color: var(--text-on-accent); font-weight: 700; background: var(--accent); }
  .tabs-sub { display: flex; flex-wrap: nowrap; gap: 3px; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 3px; margin: 10px 0 14px; width: fit-content; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
  .tabs-sub::-webkit-scrollbar { display: none; }
  .tabs-sub a { flex: 0 0 auto; font-size: 12px; color: var(--text-secondary); padding: 4px 10px; border-radius: 4px; text-decoration: none; white-space: nowrap; transition: color var(--transition), background var(--transition); }
  .tabs-sub a:hover { color: var(--text-primary); text-decoration: none; }
  .tabs-sub a.active { color: var(--text-on-accent); font-weight: 700; background: var(--accent); }
  .card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; margin-bottom: 14px; box-shadow: var(--shadow-card); transition: background var(--transition), transform var(--transition), border-color var(--transition); }
  .counters { display: flex; gap: 14px; color: var(--text-secondary); font-size: var(--fs-small); margin-top: 8px; flex-wrap: wrap; }
  .skulls { display: inline-flex; gap: 1px; vertical-align: middle; }
  .icon { width: 16px; height: 16px; vertical-align: -3px; flex: 0 0 auto; }
  .stat-pill { display: inline-flex; align-items: center; gap: 5px; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 20px; padding: 5px 12px; }
  .stat-pill .icon { vertical-align: -2px; }
  /* Круглая кнопка-плюс в один ряд со stat-pill'ами (templates/game.php —
     "Добавить челлендж по этой игре" без текста, только иконка на акценте). */
  .stat-pill-add { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; flex: 0 0 auto; border-radius: 50%; background: var(--accent); color: var(--text-on-accent); cursor: pointer; transition: transform var(--transition); }
  .stat-pill-add:hover, .stat-pill-add:focus-visible { transform: scale(1.08); color: var(--text-on-accent); text-decoration: none; cursor: pointer; }
  .stat-pill-add .icon { width: 16px; height: 16px; vertical-align: 0; }
  [data-tooltip] { cursor: help; }
  .tooltip-bubble { position: fixed; z-index: 900; background: var(--bg-elevated); border: 1px solid var(--border); color: var(--text-primary); font-size: 12px; line-height: 1.4; padding: 8px 10px; border-radius: 8px; max-width: 240px; box-shadow: 0 8px 24px rgba(0,0,0,.4); pointer-events: none; opacity: 0; transform: translateY(4px); transition: opacity .12s ease, transform .12s ease; }
  .tooltip-bubble.show { opacity: 1; transform: translateY(0); }
  .icon-lg { width: 20px; height: 20px; vertical-align: -5px; }
  .skull-icon.filled { fill: var(--warning); }
  .skull-icon.empty { fill: none; stroke: var(--text-secondary); stroke-width: 1.5; }
  .modal-skulls-pick .skull-icon, #difficulty-pick .skull-icon { width: 24px; height: 24px; }
  .modal-skulls-pick .skull-icon:hover, #difficulty-pick .skull-icon:hover { fill: var(--warning); fill-opacity: .5; }

  .challenge-card { position: relative; display: flex; gap: 14px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; margin-bottom: 12px; box-shadow: var(--shadow-card); transition: background var(--transition), border-color var(--transition), box-shadow var(--transition); }
  .challenge-card:hover { background: var(--bg-card-hover); border-color: var(--border-accent); box-shadow: 0 0 0 1px var(--border-accent); }
  .cc-cover { flex: 0 0 101px; width: 101px; height: 150px; border-radius: 8px; border: 1px solid var(--border); object-fit: cover; }
  .cc-body { flex: 1; min-width: 0; }
  .cc-meta { font-size: var(--fs-small); }
  .cc-game-link { position: relative; z-index: 2; }
  .cc-tag { border: 1px solid var(--border); border-radius: 12px; padding: 1px 8px; margin-left: 6px; font-size: 11px; color: var(--text-secondary); white-space: nowrap; }
  a.cc-tag:hover { color: var(--accent); text-decoration: none; border-color: var(--border-accent); }

  /* Теги на странице челленджа — в одну строку со сложностью; если не
     помещаются, скроллятся горизонтально сами, а не переносят сложность
     на новую строку и не давят на неё. */
  .challenge-tags-scroll { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; min-width: 0; }
  .challenge-tags-scroll::-webkit-scrollbar { display: none; }
  .challenge-tags-scroll .cc-tag { flex: 0 0 auto; display: inline-flex; align-items: center; height: 22px; box-sizing: border-box; padding: 0 8px; }

  /* Карточка челленджа (challenge_card.php): на десктопе теги идут в общей
     строке с игрой/сложностью и переносятся на новую строку целиком (не
     разбивая слова — .cc-tag уже nowrap), только если реально не влезли.
     На узкой мобильной карточке (обложка съедает много ширины) такой перенос
     превращается в кашу из 1-2 слов на строку — там вместо этого показываем
     отдельный скроллящийся ряд ниже. */
  .cc-meta-tags-inline { display: inline; }
  .cc-meta-tags-mobile { display: none; }
  @media (max-width: 480px) {
    .cc-meta-tags-inline { display: none; }
    .cc-meta-tags-mobile { display: flex; }
  }

  /* Крупные чипы «игра (N)» на странице тега (/tags/{slug}) — заметнее
     мелких .cc-tag, т.к. тут это основная навигация по странице, а не
     второстепенная пометка внутри карточки. */
  .tag-game-chips { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 18px; }
  /* Модификатор для случаев, где чипов может быть много (теги игры на
     game.php — по одному на каждый использованный тег; топ игр тега на
     /tags/{slug} — тоже без верхнего предела): wrap растягивает страницу на
     пол-экрана до самого контента. Один скроллящийся ряд — тот же паттерн,
     что .tabs/.challenge-tags-scroll. */
  .tag-game-chips-scroll { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: thin; padding-bottom: 4px; }
  .tag-game-chips-scroll::-webkit-scrollbar { height: 4px; }
  .tag-game-chips-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
  .tag-game-chips-scroll .tag-game-chip { flex: 0 0 auto; }
  .tag-game-chip { display: inline-flex; align-items: center; gap: 8px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 20px; padding: 8px 16px; font-size: var(--fs-small); font-weight: 600; color: var(--text-primary); transition: background var(--transition), border-color var(--transition); white-space: nowrap; }
  .tag-game-chip:hover { background: var(--bg-card-hover); border-color: var(--border-accent); text-decoration: none; color: var(--text-primary); }
  .tag-game-chip-count { background: var(--bg-elevated); color: var(--text-secondary); border-radius: 10px; padding: 2px 8px; font-size: 12px; font-weight: 700; }
  .tag-game-chip:hover .tag-game-chip-count { background: var(--accent); color: var(--text-on-accent); }
  .cc-title { font-size: var(--fs-card-title); margin: 4px 0; }
  .cc-title a { color: var(--text-primary); }
  .cc-title a:hover { text-decoration: none; }
  .video-link:hover { text-decoration: none; color: var(--accent); }
  .video-link:hover span { text-decoration: underline; }
  .stretched-link::after { content: ""; position: absolute; inset: 0; z-index: 1; }
  .cc-remove-form { position: absolute; top: 8px; right: 8px; z-index: 2; margin: 0; }
  .cc-remove-btn { width: 26px; height: 26px; border-radius: 50%; background: var(--bg-elevated); border: 1px solid var(--border); color: var(--text-secondary); cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 13px; padding: 0; transition: background var(--transition), border-color var(--transition), color var(--transition); }
  .cc-remove-btn:hover { background: var(--danger); border-color: var(--danger); color: #fff; }
  .cc-status, .cc-vote { position: relative; z-index: 2; }
  .cc-want { color: var(--status-want); }
  .cc-doing { color: var(--status-doing); }
  .cc-done { color: var(--status-done); }
  .cc-fail { color: var(--status-fail); }

  .hero-card { background: var(--bg-card); border-color: var(--border-accent); position: relative; overflow: hidden; }
  .hero-card::before { content: ""; position: absolute; inset: 0; opacity: .05; background-image: repeating-linear-gradient(45deg, var(--accent) 0 2px, transparent 2px 14px); pointer-events: none; }
  .hero-picks { position: relative; margin-top: 16px; display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
  @media (max-width: 480px) { .hero-picks { grid-template-columns: 1fr; } }
  .hero-pick { margin-bottom: 0 !important; color: inherit; text-decoration: none; }
  .hero-pick:hover { text-decoration: none; color: inherit; border-color: var(--accent); background: var(--bg-card-hover); }

  .cod-banner { display: block; position: relative; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; margin-bottom: 14px; background-color: var(--bg-card); background-size: cover; background-position: center 30%; min-height: 110px; text-decoration: none; transition: box-shadow var(--transition); }
  .cod-banner:hover { text-decoration: none; box-shadow: var(--shadow-pop); }
  .cod-overlay { padding: 16px; background: linear-gradient(90deg, rgba(14,17,19,.96) 0%, rgba(14,17,19,.92) 55%, rgba(14,17,19,.55) 100%); height: 100%; }
  .cod-badge { display: inline-block; background: var(--warning); color: var(--text-on-accent); font-weight: 700; font-size: 12px; padding: 3px 10px; border-radius: var(--radius-sm); margin-bottom: 8px; }
  .cod-title { color: var(--text-primary); font-size: 19px; margin: 4px 0; }

  /* Two explicit rows (avatar+name+date / proof+status+vote) instead of one
     flex line — a single row wraps unpredictably on narrow screens (item
     order depends on available width, not on what belongs together). */
  .hof-item { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); margin-bottom: 6px; }
  .hof-row { display: flex; align-items: center; gap: 8px; }
  .hof-row-bottom { justify-content: space-between; }
  .hof-user { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .hof-date { margin-left: auto; flex: 0 0 auto; }
  .hof-proof { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* Status CTA (§4.1) */
  .cta-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
  .cta-btn { height: 44px; padding: 0 16px; border-radius: var(--radius-sm); font-weight: 700; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; font-family: inherit; font-size: var(--fs-base); transition: background var(--transition), color var(--transition), transform var(--transition), border-color var(--transition); border: 1px solid transparent; }
  .cta-btn:active { transform: scale(.97); }
  .cta-want { border-color: var(--status-want); color: var(--status-want); background: transparent; }
  .cta-want:hover:not(.active) { background: color-mix(in srgb, var(--status-want) 15%, transparent); }
  .cta-want.active { background: var(--status-want); color: var(--text-on-accent); }
  .cta-doing { border-color: var(--status-doing); color: var(--status-doing); background: transparent; }
  .cta-doing:hover:not(.active) { background: color-mix(in srgb, var(--status-doing) 15%, transparent); }
  .cta-doing.active { background: var(--status-doing); color: var(--text-on-accent); }
  .cta-done { border-color: var(--status-done); color: var(--status-done); background: transparent; }
  .cta-done:hover:not(.active) { background: color-mix(in srgb, var(--status-done) 15%, transparent); }
  .cta-done.active { background: var(--status-done); color: var(--text-on-accent); }
  .cta-fail { border-color: var(--danger); color: var(--danger); background: transparent; }
  .cta-fail:hover:not(.active) { background: color-mix(in srgb, var(--danger) 15%, transparent); }
  .cta-fail.active { background: var(--danger); color: var(--text-on-accent); }
  .cta-count { background: rgba(255,255,255,.12); border-radius: 10px; padding: 1px 7px; font-size: 12px; font-weight: 700; }

  .dropdown-search { width: 100%; margin-bottom: 6px; padding: 6px 8px; font-size: var(--fs-small); }
  .secondary-row { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
  /* height + inline-flex centering: some ghost-btn have an svg.icon (В цели,
     В подборку, В ивент), others are plain text (Форкнуть, Пожаловаться) —
     without a fixed height + centered content, the icon ones render taller. */
  .ghost-btn { background: transparent; border: 1px solid var(--border); color: var(--text-secondary); border-radius: var(--radius-sm); height: 30px; padding: 0 10px; font-size: var(--fs-small); cursor: pointer; font-family: inherit; display: inline-flex; align-items: center; justify-content: center; gap: 5px; box-sizing: border-box; }
  .ghost-btn:hover { color: var(--text-primary); border-color: var(--text-secondary); text-decoration: none; }
  .ghost-btn.active { color: var(--text-primary); border-color: var(--accent); }
  .report-toggle.active { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 15%, transparent); }

  /* Vote stepper */
  /* Единый компонент голосования/оценки — переиспользуется для голоса за
     челлендж, комментарии, гайды, модификаторы и лайк/дизлайк пруфа. Разный
     размер (.vote-stepper-sm) — тот же дизайн, просто компактнее. */
  .vote-stepper { display: inline-flex; align-items: center; gap: 2px; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 2px; height: 36px; box-sizing: border-box; }
  .vote-stepper button { display: inline-flex; align-items: center; justify-content: center; background: none; border: none; color: var(--text-secondary); cursor: pointer; font-size: 16px; width: 32px; height: 32px; border-radius: var(--radius-sm); transition: background var(--transition), color var(--transition), transform var(--transition); }
  .vote-stepper button:hover { color: var(--text-primary); background: var(--bg-card-hover); }
  .vote-stepper button:active { transform: scale(.9); }
  .vote-stepper button.vote-up.active { background: var(--accent); color: var(--text-on-accent); }
  .vote-stepper button.vote-down.active { background: var(--danger); color: var(--text-on-accent); }
  .vote-stepper .vote-count { min-width: 22px; text-align: center; font-weight: 700; font-size: var(--fs-base); }

  /* Кнопка "Поделиться" рядом с рейтингом — та же высота, что у .vote-stepper.
     Скоуп на .share-menu-vote, а не на все .share-menu — иначе "В подборку"/
     "В ивент" во втором ряду кнопок (.secondary-row) тоже ловили 36px и
     вылезали выше соседних 30px-кнопок (Форкнуть, В цели, Пожаловаться). */
  .share-menu-vote > .ghost-btn { height: 36px; }

  .vote-stepper-sm { height: 24px; padding: 1px; gap: 0; }
  .vote-stepper-sm button { width: 22px; height: 22px; font-size: 12px; }
  .vote-stepper-sm .vote-count { min-width: 16px; font-size: 12px; }

  /* Rules checklist */
  .rules-progress { height: 6px; background: var(--bg-elevated); border-radius: 3px; overflow: hidden; margin: 8px 0 14px; }
  .rules-progress-fill { height: 100%; background: var(--accent); width: 0; transition: width .3s ease; }
  .rules-list { list-style: none; padding: 0; margin: 0; }
  .rules-list li { padding: 6px 0; display: flex; gap: 8px; align-items: flex-start; }
  .rules-list input[type=checkbox] { width: auto; margin: 3px 0 0; }
  .rules-list li.done span { color: var(--text-secondary); text-decoration: line-through; }
  .rules-hint { color: var(--accent); font-size: var(--fs-small); margin-top: 6px; display: none; }

  /* Modal */
  .modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.6); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); z-index: 900; display: none; align-items: center; justify-content: center; padding: 16px; }
  .modal-backdrop.open { display: flex; }
  .modal { background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-pop); padding: 24px; max-width: 420px; width: 100%; }
  .modal h3 { margin-top: 0; }
  .modal-skulls-pick { display: flex; gap: 6px; margin: 8px 0 16px; cursor: pointer; }
  .modal-skulls-pick .skull-icon { cursor: pointer; }
  .modal-actions { display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap; }

  /* Share menu */
  .share-menu { position: relative; display: inline-block; }
  .share-dropdown { display: none; position: absolute; top: 100%; left: 0; margin-top: 4px; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-pop); min-width: 180px; padding: 6px; z-index: 600; }
  .share-dropdown.open { display: block; }
  .share-dropdown button, .share-dropdown a { display: block; width: 100%; text-align: left; background: none; border: none; padding: 8px 10px; border-radius: var(--radius-sm); color: var(--text-secondary); font-size: var(--fs-small); cursor: pointer; font-family: inherit; }
  .share-dropdown button:hover, .share-dropdown a:hover { background: var(--bg-card-hover); color: var(--text-primary); text-decoration: none; }
  .share-dropdown button:disabled { cursor: not-allowed; opacity: .6; }
  .share-dropdown button:disabled:hover { background: none; color: var(--text-secondary); }

  .report-wrap { position: relative; display: inline-block; }
  .report-panel { position: absolute; top: 100%; left: 0; margin-top: 4px; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-pop); padding: 10px; width: max(260px, 90vw); max-width: 320px; z-index: 600; }
  .report-panel input { margin-bottom: 0; }
  .report-backdrop { display: none; }

  /* Comments (modern composer + thread) */
  .comment-composer { display: flex; gap: 10px; align-items: flex-end; margin-bottom: 20px; }
  .comment-avatar { border-radius: 50%; flex: 0 0 auto; width: 36px; height: 36px; align-self: flex-end; }
  .comment-composer-body { flex: 1; min-width: 0; }
  .comment-composer-pill { display: flex; align-items: flex-end; gap: 6px; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 22px; padding: 6px 6px 6px 6px; transition: border-color var(--transition); }
  .comment-composer-pill:focus-within { border-color: var(--accent); }
  .comment-composer textarea { flex: 1; resize: none; overflow: hidden; min-height: 22px; max-height: 280px; margin: 6px 0; padding: 0; line-height: 1.4; background: none; border: none; outline: none; }
  .comment-composer-pill > .char-counter { flex: 0 0 auto; align-self: flex-end; margin: 0 0 8px !important; font-size: 11px; opacity: .7; }
  .comment-send-btn { flex: 0 0 auto; width: 36px; height: 36px; border-radius: 50%; border: none; background: var(--accent); color: var(--text-on-accent); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background var(--transition), transform var(--transition); }
  .comment-send-btn:hover { transform: scale(1.06); }
  .comment-send-btn:disabled { opacity: .5; cursor: default; transform: none; }
  .comment-reply-chip { background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 6px 10px; margin-bottom: 8px; display: flex; align-items: center; justify-content: space-between; }
  .comment-reply-chip button { background: none; border: none; color: var(--text-secondary); cursor: pointer; font-size: 16px; line-height: 1; padding: 0; }
  .comment-reply-ref { display: inline-flex; align-items: center; line-height: 1; opacity: 0; transition: opacity var(--transition); }
  .comment-reply-ref .icon { width: 1em; height: 1em; }
  .comment-item:hover .comment-reply-ref, .comment-reply-ref:focus-visible { opacity: 1; }
  .comment-reply-ref:hover { color: var(--accent); text-decoration: none; }
  @media (hover: none) { .comment-reply-ref { opacity: 1; } }
  .comment-item { display: grid; grid-template-columns: auto 1fr; column-gap: 10px; row-gap: 2px; padding: 14px 0; background: none; border-radius: 0; box-shadow: none; }
  .comment-item-body { display: contents; }
  .comment-item-meta { grid-column: 2; grid-row: 1; }
  .comment-item-date { grid-column: 2; grid-row: 2; font-size: 12px; line-height: 1.3; }
  /* span:first-child, а не .avatar-frame: у аватарок без рамки обёртка
     рендерится с пустым class="" и иначе выпадает из сетки. */
  .comment-item > span:first-child { grid-column: 1; grid-row: 1 / span 2; align-self: center; margin-top: 0 !important; }
  .comment-item-text, .comment-item-rating, .comment-item-actions, .comment-edit-form { grid-column: 1 / -1; min-width: 0; }
  .comment-item-rating { margin: 4px 0; }
  /* 28px на уровень: ствол ветки падает из центра родительской аватарки
     (16px от её левого края), плюс радиус локтя 8px и зазор 4px до аватарки
     ответа — меньший шаг не оставляет места скруглению. */
  .comment-item-reply { position: relative; margin-left: calc(var(--d, 0) * 28px + 20px); padding-left: 10px; }
  /* Thread lines (vertical trunk + horizontal tee into each reply's avatar)
     are drawn by layoutThreadLines() in JS, not CSS pseudo-elements — a
     comment's avatar can end up arbitrarily far from its parent's once deeper
     sub-threads render in between, and only actual measured positions get
     that right. See #comments-list below. */
  #comments-list { position: relative; }
  /* Reddit-style connectors: a thin trunk drops from under the parent's
     avatar, and each reply gets a rounded elbow ("└") curving into its
     avatar. Both are bordered boxes, not filled — so the elbow corner can
     round via border-bottom-left-radius. */
  .thread-line, .thread-elbow { position: absolute; pointer-events: none; }
  .thread-line { width: 0; border-left: 1.5px solid var(--border); }
  .thread-elbow { border-left: 1.5px solid var(--border); border-bottom: 1.5px solid var(--border); border-bottom-left-radius: 10px; }
  .comment-item-avatar { border-radius: 50%; flex: 0 0 auto; margin-top: 2px; }
  .comment-item > .avatar-frame { flex: 0 0 auto; align-self: flex-start; margin-top: 2px; }
  .comment-item > .avatar-frame .comment-item-avatar { margin-top: 0; }
  .comment-item-meta { display: flex; align-items: center; font-size: var(--fs-small); color: var(--text-secondary); line-height: 1.3; }
  .comment-item-meta > :first-child { color: var(--text-primary); font-weight: 700; }
  .comment-item-meta .comment-reply-ref { padding: 4px; }
  .comment-item-text { margin: 4px 0 10px; white-space: pre-wrap; word-break: break-word; line-height: 1.55; font-size: var(--fs-base); }
  .comment-item-text-hidden { color: transparent; border-radius: 4px; cursor: pointer; background: repeating-linear-gradient(-45deg, #1c1f26, #1c1f26 10px, #22262e 10px, #22262e 20px); width: fit-content; max-width: 100%; }
  .comment-item-text-hidden::selection { background: transparent; }
  .comment-item-actions { display: flex; align-items: center; gap: 16px; }
  .comment-reply-btn { background: none; border: none; color: var(--text-secondary); cursor: pointer; font-size: var(--fs-small); padding: 4px 0; font-family: inherit; font-weight: 600; }
  .comment-reply-btn:hover { color: var(--accent); }
  .comment-toggle-thread { color: var(--accent); }
  .comment-toggle-thread:hover { color: var(--accent); text-decoration: underline; }
  @keyframes comment-pop-in { from { opacity: 0; transform: translateY(-6px); background: var(--bg-card-hover); } to { opacity: 1; transform: translateY(0); } }
  .comment-item.just-posted { animation: comment-pop-in .5s ease; }
  @keyframes comment-highlight-flash { 0%, 100% { background: none; } 25%, 75% { background: color-mix(in srgb, var(--accent) 18%, transparent); } }
  .comment-item.comment-highlight { animation: comment-highlight-flash 1.5s ease; }

  /* Moderation */
  .mod-report { transition: border-color var(--transition); }
  /* Народная модерация — решённые скрыты по умолчанию (это аудит, не очередь),
     раскрываются кнопкой «Показать решённые» (templates/moderation.php). */
  #mod-audit-list .mod-audit-resolved { display: none; }
  #mod-audit-list.mod-audit-expanded .mod-audit-resolved { display: block; }
  .mod-report:hover, .mod-appeal:hover { border-color: color-mix(in srgb, var(--text-secondary) 30%, var(--border)); }
  .mod-report-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
  .mod-report-title { font-weight: 700; font-size: var(--fs-base); }
  .mod-weight-badge { flex: 0 0 auto; border-radius: 12px; padding: 3px 10px; font-size: 12px; font-weight: 600; white-space: nowrap; }
  .mod-weight-low { background: color-mix(in srgb, var(--status-doing) 18%, transparent); color: var(--status-doing); }
  .mod-weight-mid { background: color-mix(in srgb, var(--warning) 20%, transparent); color: var(--warning); }
  .mod-weight-high { background: color-mix(in srgb, var(--danger) 20%, transparent); color: var(--danger); }
  .mod-reasons { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
  .mod-reason-chip { background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 12px; padding: 3px 10px; font-size: 12px; color: var(--text-secondary); }
  .mod-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 10px; }
  .mod-decision-form { display: flex; gap: 8px; flex: 1; min-width: 220px; }
  .mod-decision-form input { flex: 1; margin-bottom: 0; box-sizing: border-box; height: 42px; }
  .mod-actions .btn, .mod-actions .ghost-btn { box-sizing: border-box; height: 42px; display: inline-flex; align-items: center; justify-content: center; }
  .mod-actions > form:not(.mod-decision-form) { margin-bottom: 0; }
  .mod-decision-form-body { position: relative; flex: 1; }
  .mod-decision-form-body input { width: 100%; padding-right: 56px; }
  .mod-decision-form-body .char-counter, .report-reason-wrap .char-counter { position: absolute; top: 50%; right: 10px; transform: translateY(-50%); margin: 0 !important; }
  .mod-decision-form-body, .report-reason-wrap { position: relative; }
  .mod-decision-form-body input, .report-reason-wrap input { padding-right: 48px; }
  .mod-merge { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
  .mod-merge summary { cursor: pointer; color: var(--text-secondary); font-size: var(--fs-small); }
  .mod-merge summary:hover { color: var(--text-primary); }
  .mod-merge form { display: flex; gap: 8px; margin-top: 8px; }
  .mod-merge input { max-width: 220px; margin-bottom: 0; }
  .mod-appeal-msg { margin: 8px 0 10px; padding: 8px 12px; border-left: 3px solid var(--border); color: var(--text-secondary); }

  /* Games index (/game) */
  .games-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 16px; }
  .games-grid-item { display: block; color: inherit; text-decoration: none; text-align: center; padding: 10px; border-radius: var(--radius); transition: background var(--transition); }
  .games-grid-item:hover { background: var(--bg-card-hover); text-decoration: none; }
  .games-grid-item img { width: 100%; height: auto; aspect-ratio: 101 / 150; object-fit: cover; border-radius: var(--radius); border: 1px solid var(--border); }
  .games-grid-title { margin-top: 8px; font-weight: 700; font-size: var(--fs-small); }
  .games-grid-count { font-size: 12px; margin-top: 2px; }

  /* Пагинация */
  .pagination { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 16px 0; flex-wrap: wrap; }
  .pagination-numbers { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
  .pagination-num { display: inline-flex; align-items: center; justify-content: center; min-width: 30px; height: 30px; border-radius: var(--radius-sm); border: 1px solid transparent; color: var(--text-secondary); text-decoration: none; font-size: var(--fs-small); }
  .pagination-num:hover { background: var(--bg-card-hover); text-decoration: none; color: var(--text-primary); }
  .pagination-num.active { border-color: var(--accent); color: var(--text-primary); font-weight: 700; }
  .pagination-ellipsis { color: var(--text-muted); padding: 0 2px; }
  .pagination-arrow { color: var(--text-secondary); text-decoration: none; font-size: var(--fs-small); }
  .pagination-arrow:hover { color: var(--text-primary); text-decoration: none; }
  .pagination-arrow.disabled { color: var(--text-muted); pointer-events: none; }

  /* Игроки (/profile) */
  .players-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
  .player-card { display: flex; align-items: center; gap: 10px; padding: 10px; border-radius: var(--radius); color: inherit; text-decoration: none; transition: background var(--transition); }
  .player-card:hover { background: var(--bg-card-hover); text-decoration: none; }
  .player-card-info { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
  .player-card-name { font-weight: 700; font-size: var(--fs-small); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .player-card-meta { font-size: 12px; }

  /* New-challenge form (§6) */
  .autocomplete-box { position: relative; }
  .autocomplete-list { position: absolute; top: 100%; left: 0; right: 0; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-pop); z-index: 50; max-height: 200px; overflow-y: auto; }
  #header-search-suggestions, #game-suggestions { display: none; }
  .autocomplete-item { padding: 8px 10px; cursor: pointer; font-size: var(--fs-small); }
  .autocomplete-item:hover { background: var(--bg-card-hover); }
  .rule-row { display: flex; gap: 6px; margin-bottom: 8px; }
  .rule-row input { margin-bottom: 0; }
  .rule-row .ghost-btn { flex: 0 0 auto; }

  /* Быстрая форма генератора (templates/new_challenge.php) — поля равномерно
     делят ширину и выровнены по нижнему краю с кнопкой независимо от того,
     насколько длинная подпись над каждым select'ом. */
  .gen-quickform { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-end; }
  .gen-field { display: flex; flex-direction: column; gap: 4px; flex: 1 1 140px; min-width: 140px; }
  .gen-field label { font-size: 12px; color: var(--text-secondary); font-weight: 600; }
  .gen-field select { margin-bottom: 0; }
  /* Кнопка — такая же колонка, что и селекты (с невидимой подписью той же
     высоты), а сама растягивается на всю высоту слота селекта — иначе
     .btn (min-height:32px) оказывается ниже select'а (padding:8px + border). */
  .gen-field-btn { flex: 0 0 auto; }
  .gen-field-btn label { visibility: hidden; }
  .gen-field-btn .btn { flex: 1; height: 100%; }

  /* aspect-ratio вместо фиксированной min-height — высота всегда пропорциональна
     ширине, поэтому на узком мобильном экране и на широком десктопе обложка
     сохраняет одни и те же пропорции (раньше высота была жёстко 179px при любой
     ширине, из-за чего на десктопе фон растягивался в тонкую полосу, а на
     мобиле получался почти квадрат). min-height — просто пол на случай очень
     узких экранов/браузеров без поддержки aspect-ratio. */
  /* transform:translateZ(0) — переводит элемент в отдельный composite-слой,
     иначе Chrome рисует сглаживание скруглённого угла overflow:hidden поверх
     фона страницы, а не поверх background-image, и по краю видна светлая
     кайма/линия. */
  .game-hero { position: relative; border-radius: var(--radius); overflow: hidden; margin-bottom: 14px; background-color: var(--bg-card); background-size: cover; background-position: center 30%; aspect-ratio: 21 / 9; min-height: 140px; transform: translateZ(0); }
  .game-hero::before { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(14,17,19,.95) 0%, rgba(14,17,19,.95) 40%, rgba(14,17,19,.1) 100%); }
  /* height:100% — теперь .game-hero сам задаёт свою высоту через aspect-ratio,
     оверлей просто заполняет её целиком (а не наоборот, как раньше), поэтому
     margin-top:auto на последнем блоке (панель статов в profile.php/game.php)
     всегда есть от чего отталкиваться. */
  .game-hero-overlay { position: relative; padding: 20px; height: 100%; box-sizing: border-box; display: flex; flex-direction: column; }
  .btn, a.btn { display: inline-flex; align-items: center; justify-content: center; min-height: 32px; background: var(--accent); color: var(--text-on-accent); border: none; border-radius: var(--radius-sm); padding: 8px 14px; font-weight: 700; cursor: pointer; transition: background var(--transition), transform var(--transition); font-family: inherit; font-size: inherit; gap: 6px; }
  .btn:disabled { background: var(--bg-elevated); color: var(--text-secondary); cursor: not-allowed; }
  .btn-lg, a.btn-lg { min-height: 44px; padding: 10px 20px; font-size: 1.05em; }
  .btn-sm, a.btn-sm { min-height: 28px; padding: 5px 10px; font-size: var(--fs-small); }
  .btn:hover, a.btn:hover { background: var(--accent-hover); color: var(--text-on-accent); text-decoration: none; }
  .btn.secondary, a.btn.secondary { background: transparent; border: 1px solid var(--border); color: var(--text-primary); }
  .btn.secondary:hover, a.btn.secondary:hover { background: var(--bg-card-hover); border-color: var(--text-secondary); color: var(--text-primary); }
  .btn.danger-ghost, a.btn.danger-ghost { background: transparent; border: 1px solid var(--border); color: var(--danger); }
  .btn.danger-ghost:hover, a.btn.danger-ghost:hover { background: var(--bg-card-hover); color: var(--danger); }
  input, textarea, select { width: 100%; background: var(--bg-elevated); border: 1px solid var(--border); color: var(--text-primary); border-radius: var(--radius-sm); padding: 8px; margin-bottom: 10px; font-family: inherit; font-size: 16px; }
  input:disabled, textarea:disabled, select:disabled { color: var(--text-secondary); cursor: not-allowed; background: repeating-linear-gradient(45deg, var(--bg-elevated), var(--bg-elevated) 8px, var(--bg-card, var(--bg-elevated)) 8px, var(--bg-card, var(--bg-elevated)) 16px); }
  .widget-title { display: block; font-size: 13px; font-weight: 700; text-transform: uppercase; color: var(--text-secondary); margin: 0 0 10px; }
  .h4-like { display: block; font-size: 1em; font-weight: 700; margin: 1.33em 0; color: var(--text-primary); }
  .sidebar-sticky { position: sticky; top: 76px; }
  .muted { color: var(--text-secondary); }
  .user-title { font-size: 12px; font-weight: 400; color: var(--text-secondary); }
  .verified-badge { font-size: 12px; }
  .avatar-frame { border-radius: 50%; padding: 2px; display: inline-block; line-height: 0; }

  /* Смена аватара — иконка-карандаш поверх аватарки, видна всегда (не только
     по наведению — на тач-устройствах до hover-only не добраться). При
     наведении/фокусе — лёгкий scale для отклика. Клик открывает модалку с
     кропом (openImageModal() в templates/profile.php). */
  .avatar-upload-btn { position: absolute; right: -4px; bottom: -4px; width: 20px; height: 20px; border-radius: 50%; background: var(--bg-elevated); border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: transform var(--transition), background var(--transition); padding: 0; }
  .avatar-upload-btn:hover, .avatar-upload-btn:focus-visible { background: var(--accent); border-color: var(--accent); transform: scale(1.12); }
  .avatar-upload-btn .icon { width: 12px; height: 12px; }

  /* Смена баннера — та же идея, что у аватара: видна всегда, лёгкий scale по
     наведению. Баннер — background-image всей .profile-hero карточки (см.
     templates/profile.php — тот же .game-hero, что у обложки игры). */
  .banner-upload-btn { position: absolute; right: 14px; bottom: 14px; width: 30px; height: 30px; border-radius: 50%; background: var(--bg-elevated); border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: transform var(--transition), background var(--transition); padding: 0; }
  .banner-upload-btn:hover, .banner-upload-btn:focus-visible { background: var(--accent); border-color: var(--accent); transform: scale(1.1); }
  .banner-upload-btn .icon { width: 16px; height: 16px; }
  /* На профиле (не на game.php) иконка баннера — под плашкой ID в правом
     верхнем углу, а не внизу справа, где теперь панель статов (см. profile.php,
     margin-top:auto прижимает статы к низу — иначе иконка налезала бы на них). */
  .banner-upload-btn-top { top: 44px; right: 14px; bottom: auto; }

  /* Модалка загрузки/кропа фото (avatar/banner) — templates/profile.php. */
  body.modal-open { overflow: hidden; }
  .image-modal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 4px; }
  .image-modal-head h3 { margin: 0; }
  .image-modal-close { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; border: none; background: transparent; color: var(--text-secondary); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background var(--transition), color var(--transition); }
  .image-modal-close:hover { background: var(--bg-card-hover); color: var(--text-primary); }
  .image-modal-close .icon { width: 16px; height: 16px; }
  .image-modal-status { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; color: var(--text-secondary); background: var(--bg-elevated); border-radius: 20px; padding: 4px 10px; margin: 2px 0 12px; }
  .image-modal-status .icon { width: 12px; height: 12px; }
  .image-modal-status-pending { color: var(--warning); }
  .image-modal-req { font-size: 11px; color: var(--text-secondary); margin: 0 0 10px; }
  /* Сцена показывает ЦЕЛОЕ фото (не обрезанное) вписанным в рамку модалки —
     .crop-box поверх неё двигается/меняет размер и определяет, что попадёт
     в сохранённый файл (см. openImageModal() выше). */
  .crop-stage { position: relative; display: flex; align-items: center; justify-content: center; height: min(52vh, 360px); border-radius: var(--radius); background: var(--bg-elevated); border: 1px solid var(--border); overflow: hidden; user-select: none; }
  .crop-stage img { display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; }
  .crop-empty { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--text-secondary); font-size: 13px; padding: 0 16px; text-align: center; }
  .crop-box { position: absolute; border: 2px solid #fff; box-shadow: 0 0 0 9999px rgba(0,0,0,.55); cursor: move; touch-action: none; }
  .crop-handle { position: absolute; right: -7px; bottom: -7px; width: 16px; height: 16px; border-radius: 50%; background: #fff; border: 2px solid var(--accent); cursor: nwse-resize; }
  .image-modal-actions { display: flex; gap: 8px; margin-top: 16px; flex-wrap: wrap; align-items: center; }
  .frame-lvl4 { background: linear-gradient(135deg, var(--status-doing), var(--border)); }
  .frame-lvl7 { background: linear-gradient(135deg, var(--warning), var(--danger)); }
  .frame-lvl10 { background: linear-gradient(135deg, var(--accent), var(--status-want), var(--warning)); }
  .frame-lvl20 { background: linear-gradient(135deg, #2980b9, #6aa5ff); }
  .frame-lvl30 { background: linear-gradient(135deg, #8e44ad, #d36aff); }
  .frame-lvl50 { background: linear-gradient(135deg, #c0392b, #ff8a4a); }
  .frame-lvl70 { background: linear-gradient(135deg, #16a085, #4adeaa); }
  .frame-lvl85 { background: linear-gradient(135deg, #f39c12, #ffd24a, #f39c12); }
  /* Легендарная рамка (ур.100): радужный конический градиент. */
  .frame-lvl100 { background: conic-gradient(from 0deg, #e84393, #f39c12, #4adeaa, #6aa5ff, #e84393); }

  /* Пикер рамок аватара (виджет "Уровень" в сайдбаре): цветной свотч вместо
     текстовой кнопки, показывается только ближайшая ещё не открытая рамка. */
  .frame-picker { display: flex; gap: 12px; flex-wrap: wrap; }
  .frame-option-form { margin: 0; }
  .frame-option, .frame-picker .frame-option { display: flex; flex-direction: column; align-items: center; gap: 4px; background: none; border: none; cursor: pointer; font-family: inherit; padding: 0; }
  .frame-swatch { width: 36px; height: 36px; border-radius: 10px; border: 2px solid var(--border); display: flex; align-items: center; justify-content: center; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.5); font-weight: 700; transition: border-color var(--transition), transform var(--transition); }
  .frame-swatch-none { background: var(--bg-elevated); border-style: dashed; color: var(--text-primary); text-shadow: none; }
  .frame-option:hover .frame-swatch { border-color: var(--text-secondary); }
  .frame-option.selected .frame-swatch { border-color: var(--text-primary); }
  .frame-swatch-locked { opacity: .4; border-style: dashed; font-size: 14px; }
  .frame-option-locked { cursor: default; }
  .frame-label { font-size: 11px; color: var(--text-secondary); }

  /* Титулы: цветные пилюли вместо однотонных кнопок */
  .title-picker { display: flex; flex-wrap: wrap; gap: 8px; }
  .title-pill { display: inline-flex; align-items: center; gap: 6px; background: color-mix(in srgb, var(--title-color) 12%, var(--bg-elevated)); border: 1.5px solid color-mix(in srgb, var(--title-color) 45%, var(--border)); color: var(--title-color); border-radius: 20px; padding: 7px 14px; font-weight: 700; font-size: var(--fs-small); cursor: pointer; font-family: inherit; transition: transform var(--transition), background var(--transition); }
  .title-pill:hover { background: color-mix(in srgb, var(--title-color) 22%, var(--bg-elevated)); }
  .title-pill.active { background: var(--title-color); color: var(--text-on-accent); border-color: var(--title-color); }
  .title-pill .icon { width: 14px; height: 14px; }
  /* border всегда 2px и всегда непрозрачный (не transparent-до-active) — иначе
     свотч "без цвета" с другой толщиной рамки визуально крупнее остальных.
     Выбранный отмечается галочкой (.icon ниже), не рамкой. */
  .color-swatch { width: 24px; height: 24px; border-radius: 50%; border: 2px solid var(--border); cursor: pointer; padding: 0; display: inline-flex; align-items: center; justify-content: center; transition: transform var(--transition); }
  .color-swatch:hover { transform: scale(1.1); }
  .color-swatch-none { background: var(--bg-elevated); }
  .color-swatch .icon { width: 12px; height: 12px; color: #000; }
  .title-pill-sm { padding: 5px 11px; font-size: 12px; }
  .color-swatch-sm { width: 18px; height: 18px; }
  .color-swatch-sm .icon { width: 10px; height: 10px; }
  /* Каждый свотч сидит в своей <form> (блочный элемент по умолчанию) — без
     display:contents форма участвует в раскладке flex-родителя своим боксом
     и сбивает выравнивание кружков по одной линии. */
  .color-swatch-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
  .color-swatch-row form { display: contents; }

  /* Бейджи: плитки с цветной иконкой вместо строки эмодзи */
  .badge-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 12px; }
  .badge-tile { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; padding: 10px 6px; border-radius: var(--radius); transition: background var(--transition); }
  .badge-tile:hover { background: var(--bg-card-hover); }
  .badge-icon { width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #fff; box-shadow: 0 2px 6px rgba(0,0,0,.3); }
  .badge-icon .icon-lg { width: 22px; height: 22px; }
  .badge-title { font-size: 12px; font-weight: 600; line-height: 1.2; }
  .badge-tile-locked { opacity: .45; }
  .badge-tile-locked .badge-icon { background: var(--bg-elevated); border: 1px dashed var(--border); box-shadow: none; color: var(--text-secondary); }
  .badge-tile-locked .badge-title { font-weight: 500; color: var(--text-secondary); }
  .badge-tile-extra { display: none; }
  .badge-grid-expanded .badge-tile-extra { display: flex; }

  /* Мини-карточки песочницы в сайдбаре: прогресс до публикации вместо голых цифр */
  .sandbox-mini-item { display: block; color: inherit; text-decoration: none; padding: 8px 0; border-bottom: 1px solid var(--border); }
  .sandbox-mini-item:hover { text-decoration: none; }
  .sandbox-mini-item:nth-last-child(2) { border-bottom: none; }
  .sandbox-mini-item:hover .sandbox-mini-title { color: var(--accent); }
  .sandbox-mini-title { font-size: var(--fs-small); font-weight: 600; margin-bottom: 4px; }
  .sandbox-mini-progress { height: 4px; background: var(--bg-elevated); border-radius: 2px; overflow: hidden; margin-bottom: 4px; }
  .sandbox-mini-progress-fill { height: 100%; background: var(--warning); }
  .sandbox-mini-votes { font-size: 11px; }
  .referral-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }

  .toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%) translateY(20px); background: var(--bg-elevated); border: 1px solid var(--accent); color: var(--text-primary); padding: 12px 20px 14px; border-radius: var(--radius); box-shadow: var(--shadow-pop); z-index: 1000; opacity: 0; pointer-events: none; transition: opacity .25s, transform .25s; max-width: calc(100vw - 32px); box-sizing: border-box; text-align: center; overflow: hidden; }
  .toast.show { opacity: 1; transform: translateX(-50%) translateY(0); pointer-events: auto; }
  .toast-bar { position: absolute; left: 0; bottom: 0; height: 3px; width: 100%; background: var(--accent); }
  .toast.show .toast-bar.running { animation-name: toast-shrink; animation-timing-function: linear; animation-fill-mode: forwards; }
  .toast:hover .toast-bar { animation-play-state: paused; }
  @keyframes toast-shrink { from { width: 100%; } to { width: 0%; } }
  @keyframes shake { 10%,90% { transform: translateX(-1px); } 20%,80% { transform: translateX(2px); } 30%,50%,70% { transform: translateX(-4px); } 40%,60% { transform: translateX(4px); } }
  .shake { animation: shake .5s; }
  @keyframes pulse { 0% { transform: scale(1); color: var(--accent); } 50% { transform: scale(1.15); color: var(--accent); } 100% { transform: scale(1); } }
  .pulse { display: inline-block; animation: pulse .4s; }
  .confetti-piece { position: fixed; top: -12px; width: 8px; height: 14px; z-index: 1100; pointer-events: none; animation: confetti-fall linear forwards; }
  @keyframes confetti-fall { to { transform: translateY(105vh) rotate(540deg); opacity: .3; } }

  /* Onboarding tooltip (§G) — 3-step "once" walkthrough on the challenge page */
  .onboard-tip { position: absolute; z-index: 900; background: var(--bg-elevated); border: 1px solid var(--accent); border-radius: var(--radius-sm); box-shadow: var(--shadow-pop); padding: 10px 14px; max-width: 220px; font-size: var(--fs-small); }
  .onboard-tip p { margin: 0 0 8px; color: var(--text-primary); }
  .onboard-tip .onboard-actions { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
  .onboard-tip button { background: none; border: none; color: var(--accent); font-weight: 600; cursor: pointer; padding: 0; font-size: var(--fs-small); }
  .onboard-highlight { position: relative; z-index: 901; outline: 2px solid var(--accent); outline-offset: 3px; border-radius: var(--radius-sm); }

  /* Mobile tab bar (§D of TZ-3) — hidden on desktop */
  .mobile-tabbar { display: none; }

  .notif-bell { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; color: var(--text-secondary); border-radius: var(--radius-sm); transition: color var(--transition), background var(--transition); }
  /* Тонкая иконка-обводка визуально мельче залитой аватарки того же порядка
     размера — увеличиваем just here, чтобы вес в шапке читался ровно. */
  .notif-bell .icon-lg { width: 24px; height: 24px; vertical-align: initial; }
  .notif-bell:hover { color: var(--text-primary); background: var(--bg-card-hover); text-decoration: none; }
  .notif-badge { position: absolute; top: 2px; right: 2px; min-width: 15px; height: 15px; padding: 0 3px; border-radius: 8px; background: var(--danger); color: var(--text-on-accent); font-size: 10px; font-weight: 700; line-height: 15px; text-align: center; }

  @media (max-width: 720px) {
    .layout { padding: 12px; gap: 0; }
    .sidebar > .card:nth-child(n+3) { display: none; }
    header.top nav > *:not(.avatar-menu):not(.notif-bell) { display: none; }
    header.top .header-inner { padding: 10px 16px; }

    /* Иконка поиска и аватар — в правый угол; сам блок position:static, чтобы
       раскрытое поле (position:absolute внутри) позиционировалось не по узкой
       иконке, а по header.top (он position:sticky — тоже валидный anchor,
       но во всю ширину шапки). */
    .game-hero::before { background: rgba(14,17,19,.9); }
    /* 21:9 (десктопное соотношение) на узком экране даёт слишком низкую
       шапку — нику/статам/кнопкам редактирования тесно и они наезжают друг
       на друга. На мобиле берём более "квадратное" соотношение, чтобы было
       куда развернуть контент по вертикали. */
    .game-hero { aspect-ratio: 4 / 3; }
    .search-box { flex: 0 0 auto; position: static; margin-left: auto; }
    .search-toggle { display: inline-flex; }
    .search-toggle .icon-lg { width: 24px; height: 24px; vertical-align: initial; }
    .search-form { display: none; position: absolute; left: 0; right: 0; top: 100%; margin-top: 0; z-index: 550; padding: 0 16px; }
    .search-box.search-open .search-form { display: block; }
    .search-form .search-field { border-radius: var(--radius); }

    /* Fixed bottom tab bar replaces the sidebar's "random challenge" and nav links */
    .mobile-tabbar { display: flex; align-items: center; justify-content: space-around; position: fixed; left: 0; right: 0; bottom: 0; z-index: 700; background: var(--bg-elevated); border-top: 1px solid var(--border); padding: 6px 4px calc(6px + env(safe-area-inset-bottom)); }
    .mobile-tabbar a { display: flex; flex-direction: column; align-items: center; gap: 2px; color: var(--text-secondary); font-size: 10px; min-width: 44px; min-height: 44px; justify-content: center; }
    .mobile-tabbar a:hover { text-decoration: none; }
    .mobile-tabbar a.active { color: var(--accent); }
    .mobile-tabbar-add { background: var(--accent); color: var(--text-on-accent) !important; width: 48px; height: 48px; border-radius: 50%; margin-top: -18px; box-shadow: var(--shadow-pop); }
    body { padding-bottom: calc(56px + env(safe-area-inset-bottom)); }

    .profile-avatar { width: 40px; height: 40px; }
    .profile-name { font-size: 20px; }

    /* Comments — flat stream now (see Comments::flatten), so depth no
       longer compounds padding/avatar width; just tighten for small screens. */
    .comment-item { padding: 12px 10px; column-gap: 6px; row-gap: 2px; }
    .comment-item-avatar { width: 24px; height: 24px; }
    /* Аватарка 24px → центр на 12px: шаг отступа можно ужать до 24px на
       уровень (12 + локоть 8 + зазор 4). База тоже 24px: у корневых
       комментариев есть свой padding-left 10px, который надо перекрыть. */
    /* min(): глубже 5-го уровня отступ упирается в потолок — на 375px экране
       дальше сдвигать уже некуда, линию для таких веток JS рисовать не будет
       (ствол лёг бы на контент), останется только отступ. */
    .comment-item-reply { margin-left: min(calc(var(--d, 0) * 24px + 24px), 120px); }
    .comment-item-meta { font-size: 11px; gap: 6px; }
    .comment-item-meta .comment-reply-ref { padding: 0; }
    .comment-item-text { font-size: 14px; margin-bottom: 8px; }
    .comment-item-rating { margin: 2px 0 8px; }
    .comment-item-actions { gap: 20px; }
    .comment-reply-btn { min-height: 40px; display: inline-flex; align-items: center; padding: 8px 0; }
    .vote-stepper-sm { height: 34px; }
    .vote-stepper-sm button { width: 32px; height: 32px; font-size: 14px; }

    /* Tap targets and spacing */
    .btn, a.btn, .ghost-btn, .cta-btn { min-height: 44px; }
    .cta-row { gap: 8px; }
    .secondary-row { display: flex; flex-wrap: wrap; gap: 8px; }

    /* Status buttons: true 2x2 grid. Fixed 16px padding + icon + count badge
       don't leave room for "Хочу пройти" on a ~170px half-width button, so
       it wraps to two lines — tighten padding/font instead of letting it wrap. */
    .cta-row { display: grid; grid-template-columns: 1fr 1fr; }
    .cta-btn { justify-content: center; padding: 0 8px; font-size: 13px; white-space: nowrap; overflow: hidden; }
    .cta-count { padding: 1px 5px; font-size: 11px; flex: 0 0 auto; }

    /* Feed cards: у обложки нет своей высоты — растягивается на всю высоту
       карточки (flex stretch), иначе при фиксированной высоте она остаётся
       маленькой, а вокруг неё пустует место под текстом. */
    .challenge-card { padding: 10px; gap: 10px; }
    .cc-cover { flex: 0 0 92px; width: 92px; height: auto; align-self: stretch; }
    .cc-title { font-size: 1.05em; margin: 2px 0; }
    .cc-rules-preview { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .counters { gap: 10px; margin-top: 6px; }

    /* Breadcrumbs: single line, ellipsis in the middle item. gap — иначе
       flex схлопывает пробельные текстовые узлы вокруг "→" и они слипаются. */
    .breadcrumbs { display: flex; gap: 4px; white-space: nowrap; overflow: hidden; }
    .breadcrumbs span { overflow: hidden; text-overflow: ellipsis; }

    /* Cards tighter on mobile — 16px padding eats too much of a 375px screen */
    .card { padding: 12px; }
    .stat-pill { padding: 4px 9px; font-size: 12px; gap: 4px; }

    /* Collections list covers, kept at the same 2:3 aspect ratio as desktop. */
    .collection-cover { width: 80px !important; height: 120px !important; }
    .collection-cover + .collection-cover { margin-left: -32px !important; }

    /* Event/collection header (title + status dot, avatar + name, actions):
       stack the action button under the title block instead of squeezing
       both into one row — a full-width "Участвовать"/"Сохранить" is also a
       bigger, easier tap target. */
    .event-header, .collection-header { flex-direction: column; align-items: stretch !important; }
    .event-header form, .collection-header form { width: 100%; }
    .event-header .btn, .event-header .ghost-btn, .collection-header .btn { width: 100%; }

    /* Leaderboard row: name + stats side by side gets tight — drop the stats
       to their own full-width line under the name instead of truncating both. */
    .leaderboard-stats { flex-basis: 100%; margin-left: 44px; }

    /* Vote + share in one row already (flex container) — just tighten gap */
    .vote-stepper, .share-menu { flex: 0 0 auto; }
    /* .btn/.ghost-btn min-height:44px above would break the row's alignment
       with .vote-stepper (36px) — keep this specific button matched. */
    .share-menu-vote > .ghost-btn { min-height: 36px; }

    /* Form: sticky publish button, larger skull picker */
    #new-form .btn-lg[type="submit"] { position: sticky; bottom: calc(56px + env(safe-area-inset-bottom) + 8px); width: 100%; z-index: 10; }
    #difficulty-pick .skull-icon { width: 32px; height: 32px; }

    /* Challenge-of-day hero: auto height, text pinned to bottom */
    .cod-banner { min-height: auto; }
    .cod-overlay { display: flex; flex-direction: column; justify-content: flex-end; min-height: 100px; background: linear-gradient(180deg, rgba(14,17,19,.2) 0%, rgba(14,17,19,.95) 100%); }

    /* Modals: bottom sheet */
    .modal-backdrop { align-items: flex-end; padding: 0; }
    .modal { width: 100%; max-width: 100%; border-radius: 16px 16px 0 0; padding-top: 10px; position: relative; }
    .modal::before { content: ""; position: absolute; top: 8px; left: 50%; transform: translateX(-50%); width: 36px; height: 4px; border-radius: 2px; background: var(--border); }
    .modal-actions { flex-direction: column; }
    .modal-actions .btn { width: 100%; }

    /* «Пожаловаться» на мобиле — нижний bottom sheet во всю ширину вместо
       узкого поповера (тот же паттерн, что у .modal выше: flex-end + скруглённый
       верх + хэндл). Триггер-кнопка не меняется, меняется только сама панель. */
    .report-backdrop { display: block; position: fixed; inset: 0; background: rgba(0,0,0,.6); z-index: 900; opacity: 0; pointer-events: none; transition: opacity .2s ease; }
    .report-backdrop.open { opacity: 1; pointer-events: auto; }
    .report-panel {
      position: fixed; left: 0; right: 0; bottom: 0; top: auto; margin: 0;
      width: 100%; max-width: 100%; border-radius: 16px 16px 0 0;
      padding: 20px 16px calc(16px + env(safe-area-inset-bottom));
      z-index: 901; box-sizing: border-box;
      transform: translateY(100%); transition: transform .25s ease;
    }
    .report-panel.open { transform: translateY(0); }
    .report-panel::before { content: ""; position: absolute; top: 8px; left: 50%; transform: translateX(-50%); width: 36px; height: 4px; border-radius: 2px; background: var(--border); }
    .report-reason-wrap { margin-top: 10px; }
    .report-reason-wrap input { width: 100%; box-sizing: border-box; font-size: 16px; padding: 12px; } /* 16px — iOS не зумит при фокусе */
    .report-panel .btn, .report-panel .ghost-btn { padding: 12px; font-size: 15px; }
  }

  /* Narrow phones (e.g. iPhone SE, 360px androids): even the tightened cta-btn
     text can't fit "Хочу пройти" + a 3-digit count next to an icon — drop the
     icon, text+count is what matters for deciding what to click. */
  @media (max-width: 360px) {
    .cta-btn svg.icon { display: none; }
    .cta-btn { gap: 4px; padding: 0 6px; font-size: 12px; }
  }
  .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
  .skip-link { position: absolute; left: 8px; top: -40px; z-index: 1000; background: var(--accent); color: var(--text-on-accent); padding: 8px 14px; border-radius: var(--radius-sm); font-weight: 700; text-decoration: none; transition: top var(--transition); }
  .skip-link:focus { top: 8px; }

  /* Интро игры (game.php) — визуально схлопнуто до 4 строк, но текст целиком
     остаётся в DOM (для СЕО/индексации), просто зажат line-clamp'ом. "Показать
     полностью" появляется через JS только если текст реально длиннее 3 строк
     (см. toggleGameIntro в main.js) — короткие интро кнопку не получают. */
  .game-intro-text { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; margin: 0; color: var(--text-secondary); }
  .game-intro-text.expanded { -webkit-line-clamp: unset; overflow: visible; }
  .game-intro-toggle { display: block; margin: 6px 0 14px; background: none; border: none; color: var(--accent); font-size: var(--fs-small); font-family: inherit; cursor: pointer; padding: 0; }
  .game-intro-toggle:hover { color: var(--accent-hover); text-decoration: underline; }
