/* ═══════════════════════════════════════════════════════════════════════════
   КНИГИ · ВИТРИНА /book — РЕВИЗИЯ 2026-08-28
   ───────────────────────────────────────────────────────────────────────────
   Подключается ПОСЛЕ persona/assets/tokens.css, persona/assets/topbar.css и
   book/assets/book.css. Порядок обязателен: tokens даёт цвета, topbar —
   геометрию шапки (своих значений он не содержит вовсе), book.css — тосты,
   модалку и спиннер, которые здесь не переписываются заново.

   ══ ФАЙЛ НАПИСАН ОТ ТЕЛЕФОНА ═══════════════════════════════════════════════
   Все базовые правила — мобильные, десктоп добирается @media (min-width).
   Не наоборот: раздел смотрят с телефона, и раскладка, придуманная под
   монитор и ужатая медиазапросами, всегда проигрывает придуманной под ладонь.

   ══ ЧТО ИМЕННО УШЛО ИЗ ПРЕЖНЕЙ ВИТРИНЫ И ПОЧЕМУ ════════════════════════════

   1. АФИША С АВТОПРОЛИСТЫВАНИЕМ на 78vh. Кадр сменялся каждые 7 секунд —
      то есть под курсором. Айтрекинг NN/g: до пятого кадра доходят единицы,
      чаще виден только первый, а на стрелки не смотрят вовсе. Осталась одна
      книга и точки-переключатели без таймера.

   2. ВОСЕМЬ ГОРИЗОНТАЛЬНЫХ ПОЛОК. NN/g про горизонтальный скролл: высокая
      цена взаимодействия, слабый информационный запах и «иллюзия полноты» —
      человек уверен, что видит всё, и не листает. Плюс при четырнадцати
      опубликованных книгах одна обложка появлялась в четырёх полках подряд.
      Стало: одна сетка и лента чипов. Прокрутка вбок осталась ровно в двух
      местах, где элементы мелкие и ничего не теряется, — чипы и разделы.

   3. ЦИФРЫ ТОП-10 ВО ВЕСЬ РОСТ КАРТОЧКИ. Съедали половину её ширины ради
      украшения.

   4. РАЗНОБОЙ ПОДПИСЕЙ. «Читатели» показывались, только если их больше нуля,
      и ряд превращался в лоскуты. Теперь набор у всех один: название, жанр,
      возраст (Baymard: 64% каталогов нарушают это правило, и человек
      перестаёт сравнивать товары между собой).

   Цвета — только через токены раздела. Ни одного нового значения: витрина
   обязана ехать за темой сайта, а не быть островом.

   ОТКАТ: вернуть в book/index.php ссылки на старую шапку и catalog.js,
   удалить этот файл и home.js. book.css не тронут.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── СТРАНИЦА ──────────────────────────────────────────────────────────── */
body.bkh-body{
  background:var(--s0); color:var(--t1); font-family:var(--f-ui);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  /* Запас снизу под плавающий док сайта. Гостю дока не рисуют, и запас
     схлопывается до 16 пикселей — а плашка «Войти в YAZME» занимает нижние
     восемьдесят с лишним. Берём большее из двух. */
  padding-bottom:max(var(--nav-gap,88px),104px);
}
.bkh-body *,.bkh-body *::before,.bkh-body *::after{ box-sizing:border-box; }
.bkh-body a{ color:inherit; text-decoration:none; }
.bkh-body img{ display:block; max-width:100%; }

/* Полоса контента. 1180 — ровно как у персонажей (--wide), чтобы разделы
   стояли на одной сетке. Выше восьми колонок сетка перестаёт сканироваться,
   поэтому потолок не поднимаем. */
.bkh-wrap{ max-width:var(--wide); margin-inline:auto; padding-inline:16px; }

/* Чёлка и боковые вырезы: в установленном приложении (viewport-fit:cover)
   шапка заезжала под них — topbar.css про env() не знает. */
.bkh-body .pvh{
  padding-top:calc(var(--sp3) + env(safe-area-inset-top,0px));
  padding-left:max(var(--sp4),env(safe-area-inset-left,0px));
  padding-right:max(var(--sp4),env(safe-area-inset-right,0px));
}

/* ── ШАПКА: ТОЛЬКО ТО, ЧЕГО НЕТ В topbar.css ───────────────────────────
   Ни один размер оттуда здесь не переопределяется — иначе смысл общей
   шапки теряется. */
.bkh-logo em{ font-style:normal; color:var(--hero); }
.bkh-logo s{
  text-decoration:none; color:var(--t3);
  font:600 14px/1 var(--f-display); white-space:nowrap;
}
/* На очень узком экране уходит слово «yazme», а не приписка «Книги»:
   адрес раздела важнее названия сайта, когда места нет.
   Порог 360, а не 400: 390 — самая частая ширина телефона, и на ней всё
   помещается с запасом (логотип 139 + четыре действия 173 + отступы 32 =
   344). При 400 логотип терял слово ровно там, где место есть. */
@media (max-width:359px){ .bkh-logo .bkh-wm{ display:none; } }

.bkh-ava{
  width:var(--ctl-vis); height:var(--ctl-vis); flex:none;
  border-radius:var(--r-full); overflow:hidden; display:grid; place-items:center;
  background:var(--s3); border:1px solid var(--hair);
  font:700 13px/1 var(--f-ui); color:var(--t2);
}
.bkh-ava img{ width:100%; height:100%; object-fit:cover; display:block; }

/* Подпись поля для скринридера. Класс свой, а не .pv-sr из persona/ui.css:
   тянуть 773 строки правил чужого раздела ради одного объявления дорого.
   clip-path и clip держим оба — clip устарел, но inset() не поддерживался
   в Safari до 15.4. */
.bkh-sr{
  position:absolute!important; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%);
  white-space:nowrap; border:0;
}

/* Правило .pvh-acts span:empty отсюда убрано: зоны под кнопку админки в
   разметке больше нет (вход в неё — вкладка в строке разделов), а пустых
   спанов в ряду действий не осталось ни одного. Мёртвое правило в файле
   хуже отсутствующего: следующий читатель будет искать, что оно чинит. */

/* СТРОКА РАЗДЕЛОВ (Витрина · Каталог · Мои книги) ОТСЮДА УБРАНА.
   Она вела в /books — это соседний раздел со своей шапкой, своим каталогом
   и своим пониманием слова «книга». Показывать его пункты в шапке /book
   значило обещать, что это одно место. Внутри витрины навигация теперь
   ровно одна: чипы категорий, и они фильтруют то, что человек уже видит.

   Правила .bkh-tabs удалены целиком, а не закомментированы: мёртвый CSS в
   файле хуже отсутствующего — следующий читатель будет искать разметку,
   которой нет. */

/* ── КОЛОКОЛЬЧИК: СТИЛИ ОБЯЗАТЕЛЬНЫ, А НЕ ЖЕЛАТЕЛЬНЫ ───────────────────
   /assets/js/notifications.js САМ инжектит в <head> правило
   `#notif-dropdown { display:flex }`. Селектор по id сильнее любого набора
   классов, поэтому без двух строк с !important список уведомлений висел бы
   раскрытым поверх шапки и распирал её, а «0» из счётчика печаталось бы
   прямо в кружке кнопки. Тот же случай разобран в includes/
   yz_books_topbar.php — там он вылечен ровно так же. */
#notif-dropdown.hidden{ display:none!important; }
#notif-count.hidden{ display:none!important; }
.bkh-bell .notification-wrapper{ position:relative; }
.bkh-bell .notif-badge{
  position:absolute; top:-3px; right:-3px; min-width:18px; height:18px; padding:0 5px;
  border-radius:var(--r-full); background:var(--hero); color:var(--on-hero);
  font:700 11px/18px var(--f-ui); text-align:center; border:2px solid var(--s0);
}
.bkh-bell .notif-dropdown{
  position:absolute; right:0; top:calc(100% + 10px);
  width:min(340px,86vw); max-height:70vh; overflow:auto; z-index:70;
  background:var(--s2); border:1px solid var(--hair2);
  border-radius:var(--r-md); box-shadow:var(--sh-lg);
}
.bkh-bell .notif-dropdown.hidden{ display:none; }
.bkh-bell .notif-header{
  padding:12px 14px; font:700 14px/1 var(--f-ui); color:var(--t1);
  border-bottom:1px solid var(--hair);
}
.bkh-bell .notif-empty-box{ padding:26px 16px; text-align:center; color:var(--t3); font-size:13px; }
.bkh-bell .notif-empty-icon{ width:30px; height:30px; opacity:.5; margin-bottom:8px; }

/* ── ВЫПАДАШКА ОБЩЕГО ПОИСКА ───────────────────────────────────────────
   Одно поле ищет по двум каталогам, поэтому выдача ОБЯЗАНА быть
   сгруппированной с заголовками: без них человек не понимает, почему в
   одном списке лежат книга и живой человек. Форма тоже отвечает на этот
   вопрос раньше текста — обложка прямоугольная, лицо круглое. */
.bkh-body .pvh-find{ position:relative; }
.bkh-sug{
  position:absolute; left:0; right:0; top:calc(100% + 8px); z-index:60;
  max-height:min(66vh,540px); overflow-y:auto; overscroll-behavior:contain;
  background:var(--s2); border:1px solid var(--hair2);
  border-radius:var(--r-md); box-shadow:var(--sh-lg); padding:6px;
}
.bkh-sug .grp{
  display:block; padding:10px 12px 6px;
  font:700 10px/1 var(--f-ui); letter-spacing:var(--ls-over);
  text-transform:uppercase; color:var(--t3);
}
/* min-height 44 — это WCAG 2.2 «Target Size». Строка выдачи на телефоне
   нажимается пальцем, а не курсором. */
.bkh-sug .it{
  display:flex; align-items:center; gap:11px; min-height:var(--ctl);
  padding:8px 10px; border-radius:var(--r-sm); color:var(--t1);
}
.bkh-sug .it:hover,.bkh-sug .it.on{ background:var(--s3); }
.bkh-sug mark{ background:none; color:var(--hero-hi); font-weight:700; }
.bkh-sug .th{
  flex:none; width:32px; height:48px; border-radius:6px; overflow:hidden;
  background:var(--s3); display:grid; place-items:center;
  font:700 13px/1 var(--f-serif); color:var(--t3);
}
.bkh-sug .th.rnd{ width:40px; height:40px; border-radius:50%; }
.bkh-sug .th img{ width:100%; height:100%; object-fit:cover; display:block; }
.bkh-sug .tx{ min-width:0; }
.bkh-sug .tx b{ display:block; font:600 13.5px/1.25 var(--f-ui); }
.bkh-sug .tx i{
  display:block; font-style:normal; font-size:11.5px; color:var(--t3);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.bkh-sug .all{
  display:block; padding:11px 12px; color:var(--hero);
  font-size:12.5px; border-radius:var(--r-sm);
}
.bkh-sug .all:hover,.bkh-sug .all.on{ background:var(--s3); }
.bkh-sug .nores{ display:block; padding:14px 12px; font-size:13px; color:var(--t3); line-height:1.5; }
.bkh-sug .nores b{ color:var(--t1); }

/* ═══ ПРОДОЛЖИТЬ ═══════════════════════════════════════════════════════
   СТОИТ ВЫШЕ БАННЕРА И ВМЕСТО ЗАГОЛОВКА — и это главное решение страницы.
   Заголовок «Книги, где решает читатель» объясняет раздел тому, кто пришёл
   впервые. Тому, кто вчера бросил книгу на третьей главе, объяснять нечего:
   ему нужна кнопка «дальше», и она обязана быть первым, что он видит, а не
   третьим экраном прокрутки. Поэтому у страницы два первых экрана: гостю —
   заголовок и афиша, читающему — его недочитанное, афиша под ним.

   ДВЕ, И ИМЕННО ПОСЛЕДНИЕ. Не «сколько влезет»: ORDER BY последнее открытие
   DESC LIMIT 2 (см. action=home в book/api/catalog.php). Третья строка
   ничего не добавляет — к книге, брошенной месяц назад, возвращаются через
   «Мои книги», — зато отодвигает афишу и каталог ещё на сотню пикселей.

   Список, а не лента вбок: две карточки видны обе, лента спрятала бы вторую
   за край экрана ради экономии сорока пикселей.

   Время последнего открытия — подписью справа. Без неё порядок «сначала
   свежее» выглядит случайным: первая строка ничем не объясняет, почему она
   первая. */
.bkh-cont{ padding:var(--sp5) 16px 0; max-width:var(--wide); margin-inline:auto; }
.bkh-cont-h{ display:flex; align-items:center; gap:10px; margin-bottom:10px; }
.bkh-cont-h .bar{ width:3px; height:18px; border-radius:2px; flex:none; background:var(--hero); }
.bkh-cont-h b{ font:700 15px/1 var(--f-display); letter-spacing:-.02em; color:var(--t1); }
.bkh-cont-h a{ margin-left:auto; color:var(--t2); font:600 12.5px/1 var(--f-ui); padding:8px 0; }
.bkh-cont-h a:hover{ color:var(--hero); }
/* Не ссылка, а подпись: страницы «мои чтения» в проекте нет, и вести
   человека некуда. Почему именно так — в комментарии к contHtml(). */
.bkh-cont-h .rest{ margin-left:auto; color:var(--t3); font:500 12px/1 var(--f-ui); white-space:nowrap; }
/* grid-template-columns ОБЯЗАТЕЛЕН, и это была настоящая поломка.
   Без него у сетки одна неявная колонка шириной auto, то есть по
   max-content: длинное название внутри карточки (а оно в одну строку,
   nowrap) раздувало колонку шире экрана, и кнопка «играть» уезжала за
   правый край — на телефоне её просто не было видно.
   minmax(0,1fr) запрещает колонке расти дальше контейнера, а min-width:0
   на самой карточке разрешает её содержимому сжаться: без него флекс- и
   грид-элемент считает своим минимумом min-content и всё равно вылезает. */
.bkh-cont-list{ display:grid; gap:var(--sp2); grid-template-columns:minmax(0,1fr); }
.bkh-cont-it{ min-width:0; }
.bkh-cont-it{
  display:flex; align-items:center; gap:12px; padding:10px;
  border-radius:18px; background:var(--s1); border:1px solid var(--hair);
  transition:border-color var(--d-micro) var(--e-out);
}
.bkh-cont-it:hover{ border-color:var(--hero-line); }
.bkh-cont-it .c{
  flex:none; width:52px; aspect-ratio:2/3; border-radius:7px; overflow:hidden;
  background:var(--s3); box-shadow:var(--sh-sm);
  display:grid; place-items:center; font:700 15px/1 var(--f-serif); color:var(--t3);
}
.bkh-cont-it .c img{ width:100%; height:100%; object-fit:cover; }
.bkh-cont-it .tx{ min-width:0; flex:1; overflow:hidden; }
.bkh-cont-it b{
  display:block; font:600 14px/1.25 var(--f-ui); color:var(--t1);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.bkh-cont-it i{
  display:flex; align-items:baseline; gap:6px; font-style:normal;
  font-size:11.5px; color:var(--t3); margin:5px 0 8px;
}
/* Строка прогресса не переносится: «Глава 7 · 72%» и «3 дн назад» в две
   строки ломают высоту карточки и разъезжаются с соседней. Если места мало,
   уступает левая часть — она предсказуема, а дата коротка и нужна целиком. */
.bkh-cont-it i{ flex-wrap:nowrap; }
.bkh-cont-it i > span{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bkh-cont-it i s{ margin-left:auto; text-decoration:none; opacity:.75; white-space:nowrap; flex:none; }
/* display:block обязателен: .bkh-bar — это <span>, а у строчного элемента
   height и overflow не работают. Полоска не получала своих четырёх пикселей,
   а вложенная заливка с height:100% растягивалась по высоте всей карточки —
   вместо шкалы выходил оранжевый прямоугольник. */
.bkh-bar{ display:block; height:4px; border-radius:4px; background:var(--s4); overflow:hidden; }
.bkh-bar > i{ display:block; height:100%; margin:0; background:var(--hero); border-radius:4px; }
.bkh-cont-it .go{
  flex:none; width:42px; height:42px; border-radius:50%; display:grid; place-items:center;
  background:var(--hero); color:var(--on-hero); box-shadow:var(--sh-hero);
}
.bkh-cont-it .go svg{ width:16px; height:16px; }

/* ── ЗАГОЛОВОК СТРАНИЦЫ (только для гостя и для тех, кто ещё не читал) ── */
.bkh-head{ padding:var(--sp5) 16px 0; max-width:var(--wide); margin-inline:auto; }
.bkh-head h1{
  margin:0; font:800 24px/1.1 var(--f-display); letter-spacing:-.03em;
  color:var(--t1); text-wrap:balance;
}
.bkh-head em{ font-style:normal; color:var(--hero-hi); }
.bkh-head p{ margin:8px 0 0; font-size:13px; line-height:1.5; color:var(--t2); max-width:40ch; }

/* ═══ БАННЕР ═══════════════════════════════════════════════════════════
   На телефоне разворот кладётся набок: обложка слева, текст справа, кнопки
   строкой под ними во всю ширину. Вертикальная укладка съедала бы 520
   пикселей — весь первый экран ради одной книги.

   Надзаголовок вынесен НАД строкой «обложка + текст»: в правой колонке на
   200 пикселях он ломался на две строки и отжимал название. */
.bkh-ban{
  position:relative; overflow:hidden; margin:var(--sp5) 16px 0;
  max-width:calc(var(--wide) - 32px); margin-inline:auto;
  padding:var(--sp4); border-radius:var(--r-lg); border:1px solid var(--hair);
  background:radial-gradient(130% 150% at 88% 0%,var(--hero-lo),transparent 62%),var(--s1);
  display:grid; grid-template-columns:110px minmax(0,1fr); column-gap:var(--sp4);
}
/* Обёртка прозрачна, чтобы её дети попали прямо в сетку баннера. На
   десктопе она снова становится колонкой — так одна разметка обслуживает
   оба случая без второго набора элементов. */
.bkh-ban .side{ display:contents; }
.bkh-ban .c{
  grid-column:1; grid-row:2; width:110px; aspect-ratio:2/3;
  border-radius:10px; overflow:hidden; background:var(--s3);
  box-shadow:var(--sh-md); border:1px solid var(--hair2);
  display:grid; place-items:center; font:700 20px/1 var(--f-serif); color:var(--t3);
}
.bkh-ban .c img{ width:100%; height:100%; object-fit:cover; }
.bkh-ban .tx{ grid-column:2; grid-row:2; min-width:0; }
.bkh-ban .ov{
  grid-column:1/-1; grid-row:1; margin-bottom:var(--sp3);
  display:flex; align-items:center; gap:8px;
  font:700 9.5px/1.3 var(--f-ui); letter-spacing:.1em;
  text-transform:uppercase; color:var(--hero-hi);
}
.bkh-ban .ov s{ width:18px; height:2px; background:var(--hero); text-decoration:none; flex:none; }
.bkh-ban h2{
  margin:0; font:700 19px/1.15 var(--f-display); letter-spacing:-.03em; color:var(--t1);
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
}
.bkh-ban .qt{
  margin:9px 0 0; font:400 14px/1.45 var(--f-serif); font-style:italic; color:var(--hero-hi);
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
}
.bkh-ban .mt{
  margin-top:10px; display:flex; align-items:center; gap:9px; flex-wrap:wrap;
  font:600 11.5px/1 var(--f-ui); color:var(--t3);
}
.bkh-ban .mt b{
  padding:4px 7px; border:1px solid var(--hair2); border-radius:6px;
  font:800 10.5px/1 var(--f-ui); color:var(--t2);
}
.bkh-ban .act{ grid-column:1/-1; grid-row:3; display:flex; gap:var(--sp2); margin-top:var(--sp4); }
/* Точка-переключатель: полоска видимая 22×3, нажимаемая зона 30×24 —
   иначе это провал WCAG 2.2 «Target Size (Minimum)». Автопролистывания нет:
   выбор редакции — утверждение, а не слайд-шоу. */
.bkh-ban .dots{ grid-column:1/-1; grid-row:4; display:flex; gap:3px; justify-content:center; margin-top:var(--sp3); }
.bkh-ban .dots button{
  display:grid; place-items:center; width:30px; height:24px;
  background:none; border:0; border-radius:6px; cursor:pointer; padding:0;
}
.bkh-ban .dots button::before{
  content:''; display:block; width:22px; height:3px; border-radius:2px;
  background:var(--hair2); transition:background var(--d-std), width var(--d-std);
}
.bkh-ban .dots button.on::before{ background:var(--hero); width:30px; }
.bkh-ban .dots button:focus-visible{ outline:var(--focus-w) solid var(--focus); outline-offset:2px; }

/* ── КНОПКИ ────────────────────────────────────────────────────────────
   Своя пара вместо .bk-btn из book.css: там кнопка с бликом, внутренней
   подсветкой и подъёмом на два пикселя — язык прошлой витрины. Здесь то же,
   что у персонажей: заливка акцентом и тихая рамка. */
.bkh-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  height:var(--ctl); padding:0 18px; border:0; cursor:pointer; flex:1;
  border-radius:var(--r-full); background:var(--hero); color:var(--on-hero);
  font:700 14.5px/1 var(--f-ui); box-shadow:var(--sh-hero); text-decoration:none;
  transition:background var(--d-micro) var(--e-out);
}
.bkh-btn:hover{ background:var(--hero-hi); }
.bkh-btn svg{ width:17px; height:17px; }
.bkh-btn.gl{
  background:var(--s2); color:var(--t1); border:1px solid var(--hair2);
  box-shadow:none; flex:none; width:var(--ctl); padding:0;
}
.bkh-btn.gl:hover{ background:var(--s3); }
.bkh-btn.gl svg{ width:19px; height:19px; }
.bkh-btn.gl.on{ background:var(--hero-lo); border-color:var(--hero-line); color:var(--hero-hi); }
.bkh-btn:focus-visible,.bkh-card:focus-visible,.bkh-cont-it:focus-visible,
.bkh-chip:focus-visible,.bkh-more button:focus-visible{
  outline:var(--focus-w) solid var(--focus); outline-offset:var(--focus-off);
}

/* ── ЧИПЫ КАТЕГОРИЙ ────────────────────────────────────────────────────
   Единственное место витрины с прокруткой вбок, кроме строки разделов:
   элементы мелкие, ни одна книга за краем не прячется, а вертикально те же
   двенадцать категорий заняли бы три строки первого экрана. Счётчик в чипе
   не мельче 0.8 прозрачности: при 0.65 на тёмной теме выходило 4.19:1, а
   для одиннадцати пикселей нужно 4.5 — Lighthouse это ловит. */
.bkh-chips{
  display:flex; gap:var(--sp2); overflow-x:auto; scrollbar-width:none;
  -webkit-overflow-scrolling:touch; scroll-padding-left:16px;
  padding:var(--sp5) 16px 0; max-width:var(--wide); margin-inline:auto;
}
.bkh-chips::-webkit-scrollbar{ display:none; }
.bkh-chip{
  flex:none; white-space:nowrap; height:38px; padding:0 16px;
  display:inline-flex; align-items:center; gap:6px;
  background:var(--s2); border:1px solid var(--hair); border-radius:var(--r-full);
  color:var(--t2); font:600 13px/1 var(--f-ui); cursor:pointer;
  transition:background var(--d-micro) var(--e-out), color var(--d-micro) var(--e-out);
}
.bkh-chip:hover{ color:var(--t1); background:var(--s3); }
.bkh-chip.on{ background:var(--t1); border-color:var(--t1); color:var(--s0); }
.bkh-chip i{ font-style:normal; font-size:11px; opacity:.8; }

/* ── ЗАГОЛОВОК СЕКЦИИ ──────────────────────────────────────────────────
   Один тип на всю страницу. Раньше их было три — у афиши, у полки и у
   выдачи поиска, — и страница объясняла сама себя вместо того, чтобы иметь
   иерархию. */
.bkh-sec{ display:flex; align-items:center; gap:var(--sp3); margin:var(--sp6) 0 var(--sp4); }
.bkh-sec .bar{ width:3px; height:22px; border-radius:2px; flex:none; background:var(--hero); }
.bkh-sec h2{ margin:0; font:700 19px/1.1 var(--f-display); letter-spacing:-.03em; color:var(--t1); }
.bkh-sec .why{ color:var(--t3); font:500 12px/1.3 var(--f-ui); }
.bkh-sec .all{
  margin-left:auto; flex:none; color:var(--t2); font:600 12.5px/1 var(--f-ui);
  white-space:nowrap; padding:8px 0; cursor:pointer; background:none; border:0;
}
.bkh-sec .all:hover{ color:var(--hero); }
/* На витрине счётчик прячем: «14 книг» дублирует чип «Все 14». В выдаче он,
   наоборот, единственный ответ на вопрос «сколько нашлось», поэтому у
   заголовка результатов свой класс. */
@media (max-width:420px){
  .bkh-sec .why{ display:none; }
  .bkh-sec.res .why{ display:inline; }
}

/* ═══ КАТАЛОГ ══════════════════════════════════════════════════════════
   Две колонки на телефоне. Одна превращает выбор в бесконечное листание,
   три дают обложку в 108 пикселей — по ней уже ничего не разобрать.

   Подписи ПОД обложкой и одинаковые у всех: название, жанр, возраст есть у
   каждой книги, поэтому ряд не разъезжается по высоте и карточки можно
   сравнивать между собой. */
.bkh-grid{ display:grid; gap:var(--sp5) var(--sp3); grid-template-columns:repeat(2,minmax(0,1fr)); }
.bkh-card{ display:block; min-width:0; }
.bkh-card .ph{
  display:block; position:relative; aspect-ratio:2/3; border-radius:12px; overflow:hidden;
  background:var(--s2);
  /* Внутренний волосок обязателен: обложки часто светлые, и без него они
     «вываливаются» из карточки на тёмном фоне. */
  box-shadow:inset 0 0 0 1px var(--hair2), var(--sh-sm);
  transition:transform var(--d-std) var(--e-out), box-shadow var(--d-std) var(--e-out);
}
.bkh-card:hover .ph{ transform:translateY(-4px); box-shadow:inset 0 0 0 1px var(--hero-line), var(--sh-lg); }
.bkh-card .ph img{ width:100%; height:100%; object-fit:cover; display:block; }
/* Заглушка вместо обложки — не серый прямоугольник: название на ней
   читается, и карточка остаётся выбираемой.
   Селектор общий (.fb, а не .bkh-card .ph .fb): тот же класс подставляется в
   баннере и в шторке, и без стилей длинное название вываливалось из
   110-пиксельной обложки наружу. */
.bkh-card .ph,.bkh-ban .c,.bkh-sh-hero .c{ position:relative; }
.fb{
  position:absolute; inset:0; display:flex; align-items:flex-end; padding:12px;
  font:700 14px/1.25 var(--f-serif); color:var(--t1); overflow:hidden;
  background:radial-gradient(120% 90% at 80% 0%,var(--hero-lo),transparent 58%),var(--s3);
}
.bkh-ban .c .fb{ padding:9px; font-size:12px; }
/* Метка на обложке — не больше одной. На тач-экране наведения нет, поэтому
   всё, что раньше показывалось при hover, здесь либо видно сразу, либо не
   показывается вовсе. */
.bkh-card .bdg{
  position:absolute; left:8px; top:8px; height:22px; padding:0 8px; z-index:2;
  display:inline-flex; align-items:center; border-radius:var(--r-full);
  background:var(--glass); backdrop-filter:blur(10px); border:1px solid var(--hair2);
  font:700 10px/1 var(--f-ui); letter-spacing:.03em; color:var(--t1);
}
.bkh-card .bdg.hot{ background:var(--hero); color:var(--on-hero); border-color:transparent; }
.bkh-card .pg{ position:absolute; left:0; right:0; bottom:0; height:3px; background:rgba(0,0,0,.5); z-index:2; }
.bkh-card .pg > i{ display:block; height:100%; background:var(--hero); }
.bkh-card .nm{
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
  margin-top:9px; font:600 13.5px/1.3 var(--f-ui); color:var(--t1); min-height:35px;
}
.bkh-card .mt{ margin-top:3px; font-size:11.5px; color:var(--t3); }

/* ── ПОКАЗАТЬ ЕЩЁ ──────────────────────────────────────────────────────
   Кнопка, а не бесконечная лента. У бесконечной перестаёт работать кнопка
   «назад» и становится недостижим подвал; A/B-тест Etsy дал на ней −22% к
   конверсии — люди листали больше, а покупали меньше. */
.bkh-more{ margin-top:var(--sp6); }
.bkh-more button,.bkh-more a{
  display:block; width:100%; height:46px; line-height:44px; text-align:center;
  border:1px solid var(--hair2); border-radius:var(--r-full);
  background:none; color:var(--t1); font:600 14px/44px var(--f-ui); cursor:pointer;
  transition:border-color var(--d-micro) var(--e-out), color var(--d-micro) var(--e-out);
}
.bkh-more button:hover,.bkh-more a:hover{ border-color:var(--hero); color:var(--hero); }
.bkh-more.done button,.bkh-more.done a{ color:var(--t3); border-style:dashed; }
.bkh-more button:disabled{ cursor:default; }
.bkh-more button:disabled:hover{ border-color:var(--hair2); color:var(--t3); }

/* ── СОСТОЯНИЯ ─────────────────────────────────────────────────────────
   Пустой экран не бывает белым: он говорит, что искали, и даёт выход —
   иначе человек считает, что сломался сайт, а не запрос. */
.bkh-empty{ padding:44px 16px; text-align:center; color:var(--t3); }
.bkh-empty b{ display:block; margin-bottom:6px; font:700 17px/1.25 var(--f-display); color:var(--t1); }
.bkh-empty p{ margin:0 auto 16px; max-width:44ch; font-size:13.5px; line-height:1.55; }
.bkh-empty .bkh-btn{ flex:none; display:inline-flex; }

.bkh-skel{ position:relative; overflow:hidden; background:var(--s2); border-radius:12px; }
.bkh-skel::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(100deg,transparent 30%,color-mix(in srgb,var(--t1) 6%,transparent) 50%,transparent 70%);
  animation:bkhShim 1.4s infinite;
}
@keyframes bkhShim{ from{ transform:translateX(-100%); } to{ transform:translateX(100%); } }

.bkh-tail{ padding:var(--sp6) 0 0; color:var(--t3); font-size:11.5px; line-height:1.6; }

/* ── ЛЮДИ В ВЫДАЧЕ ПОИСКА ──────────────────────────────────────────────
   Персонажи в результатах — кружками, книги — обложками. Разные сущности
   обязаны выглядеть по-разному, иначе выдача читается как каша. */
.bkh-people{ display:flex; flex-wrap:wrap; gap:10px; }
.bkh-person{
  display:flex; align-items:center; gap:10px; min-height:var(--ctl);
  padding:8px 14px 8px 8px; border-radius:var(--r-full);
  background:var(--s1); border:1px solid var(--hair);
  transition:border-color var(--d-micro) var(--e-out);
}
.bkh-person:hover{ border-color:var(--hero-line); }
.bkh-person img,.bkh-person .mn{
  flex:none; width:38px; height:38px; border-radius:50%; object-fit:cover;
  background:var(--s3); display:grid; place-items:center;
  font:700 15px/1 var(--f-serif); color:var(--t3);
}
.bkh-person b{ font:600 13.5px/1.2 var(--f-ui); color:var(--t1); }
.bkh-person span{ display:block; font-size:11.5px; color:var(--t3); margin-top:2px; }

/* ═══ КАРТОЧКА КНИГИ (ШТОРКА) ══════════════════════════════════════════
   Своя, а не .bk-sheet из book.css: та писалась под десктопную витрину —
   разворот в две колонки с обложкой, вылезающей на 120 пикселей вверх, и
   на телефоне складывалась в столбик с отрицательным margin в 140. Здесь
   телефон первичен: обложка по центру на размытой подложке из неё же,
   дальше текст в одну колонку.

   Подложка — та же приёмная, что в афише персонажей: размытая обложка даёт
   цвет, из-за которого экран выглядит дорого, а плита поверх неё этот цвет
   как раз убивает. Затемняем ровно настолько, чтобы белый заголовок держал
   контраст. */
.bkh-sheet-bd{
  position:fixed; inset:0; z-index:1000; opacity:0;
  background:var(--overlay); backdrop-filter:blur(14px);
  transition:opacity var(--d-std) var(--e-out);
}
.bkh-sheet-bd.on{ opacity:1; }
.bkh-sheet{
  position:fixed; inset:0; z-index:1001; overflow-y:auto; overscroll-behavior:contain;
  background:var(--s0); opacity:0; transform:translateY(28px);
  transition:opacity var(--d-std) var(--e-out), transform var(--d-sheet,280ms) var(--e-out);
  -webkit-overflow-scrolling:touch;
}
.bkh-sheet.on{ opacity:1; transform:none; }
.bkh-sheet-in{ padding-bottom:max(var(--nav-gap,88px),104px); }

.bkh-sh-hero{ position:relative; height:280px; overflow:hidden; }
.bkh-sh-hero .blur{
  position:absolute; inset:-14%; width:128%; height:128%; object-fit:cover;
  filter:blur(34px) saturate(170%); opacity:.7;
}
.bkh-sh-hero::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(to top,var(--s0) 6%,rgba(0,0,0,.34) 60%,rgba(0,0,0,.2));
}
.bkh-sh-hero .c{
  position:absolute; left:50%; top:52px; transform:translateX(-50%); z-index:2;
  width:128px; aspect-ratio:2/3; border-radius:10px; overflow:hidden;
  box-shadow:var(--sh-lg); border:1px solid var(--hair2); background:var(--s3);
  display:grid; place-items:center; font:700 24px/1 var(--f-serif); color:var(--t3);
}
.bkh-sh-hero .c img{ width:100%; height:100%; object-fit:cover; }
.bkh-sh-x{
  position:absolute; right:14px; top:calc(14px + env(safe-area-inset-top,0px)); z-index:5;
  width:var(--ctl-vis); height:var(--ctl-vis); border-radius:50%; cursor:pointer;
  background:var(--glass); border:1px solid var(--hair2); color:var(--t1);
  display:grid; place-items:center;
}
.bkh-sh-x::after{ content:''; position:absolute; inset:-3px; }
.bkh-sh-x svg{ width:16px; height:16px; }

.bkh-sh-b{ position:relative; z-index:3; padding:0 16px var(--sp6); text-align:center; max-width:var(--wide); margin-inline:auto; }
.bkh-sh-b .ov{ font:700 9.5px/1 var(--f-ui); letter-spacing:var(--ls-over); text-transform:uppercase; color:var(--hero-hi); }
.bkh-sh-b h2{ margin:10px 0 0; font:700 21px/1.15 var(--f-display); letter-spacing:-.03em; color:var(--t1); text-wrap:balance; }
.bkh-sh-b .qt{ margin:10px 0 0; font:400 14.5px/1.5 var(--f-serif); font-style:italic; color:var(--hero-hi); }
.bkh-sh-b .mt{
  margin-top:12px; display:flex; justify-content:center; align-items:center;
  gap:9px; flex-wrap:wrap; font:600 11.5px/1 var(--f-ui); color:var(--t3);
}
.bkh-sh-b .mt b{ padding:4px 7px; border:1px solid var(--hair2); border-radius:6px; font:800 10.5px/1 var(--f-ui); color:var(--t2); }
.bkh-sh-b .p{ margin:14px 0 0; font-size:13.5px; line-height:1.6; color:var(--t2); text-align:left; max-width:68ch; }
/* На телефоне главная кнопка занимает свою строку, значки — следующую.
   В один ряд их пятеро («Читать», вдвоём, закладка, сердце, поделиться), и
   на 390 пикселях от подписи «Продолжить · стр. 7» оставалось полторы
   строки в 150 пикселях. Значки при этом ничего не теряют: у каждого своя
   aria-label и хит-зона 44. */
.bkh-sh-b .act{ display:flex; gap:var(--sp2); margin-top:var(--sp5); flex-wrap:wrap; justify-content:center; }
.bkh-sh-b .act .bkh-btn:not(.gl){ flex:1 1 100%; }

.bkh-st{ display:flex; margin-top:var(--sp5); border:1px solid var(--hair); border-radius:var(--r-md); overflow:hidden; background:var(--s1); }
.bkh-st div{ flex:1; padding:12px 6px; text-align:center; border-right:1px solid var(--hair); }
.bkh-st div:last-child{ border-right:0; }
.bkh-st b{ display:block; font:700 16px/1 var(--f-display); color:var(--t1); }
.bkh-st span{ display:block; margin-top:5px; font:600 9.5px/1 var(--f-ui); letter-spacing:.06em; text-transform:uppercase; color:var(--t3); }

.bkh-lbl{
  margin:var(--sp6) 0 var(--sp3); display:flex; align-items:center; gap:10px;
  font:700 10px/1 var(--f-ui); letter-spacing:var(--ls-over); text-transform:uppercase; color:var(--t3);
}
.bkh-lbl::after{ content:''; flex:1; height:1px; background:var(--hair); }

.bkh-heroes{ display:flex; gap:12px; overflow-x:auto; scrollbar-width:none; padding-bottom:4px; }
.bkh-heroes::-webkit-scrollbar{ display:none; }
/* 82, а не 74: подписи теперь приходят из персон («студент, который решил»
   вместо «студент»), и на 74 они разъезжались в три строки. Имя — максимум
   две строки, подпись — одна с многоточием: так плитки в ряду одинаковой
   высоты, а имя не режется на первом же слове. */
.bkh-heroes a{ flex:none; width:82px; text-align:center; }
.bkh-heroes span.av{
  display:grid; place-items:center; width:62px; height:62px; margin:0 auto; overflow:hidden;
  border-radius:50%; background:var(--s3); border:1px solid var(--hair2);
  font:700 22px/1 var(--f-serif); color:var(--t3);
}
.bkh-heroes span.av img{ width:100%; height:100%; object-fit:cover; }
.bkh-heroes b{
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
  margin-top:7px; font:600 11.5px/1.2 var(--f-ui); color:var(--t1);
}
.bkh-heroes i{
  display:block; font-style:normal; font-size:10px; color:var(--t3); margin-top:2px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

.bkh-chapters{ display:grid; gap:8px; text-align:left; }
.bkh-chapter{
  display:flex; align-items:center; gap:12px; padding:11px 14px;
  border:1px solid var(--hair); border-radius:14px; background:var(--s1);
}
.bkh-chapter .num{
  flex:none; width:32px; height:32px; border-radius:10px; display:grid; place-items:center;
  background:var(--hero-lo); color:var(--hero-hi); font:700 14px/1 var(--f-display);
}
.bkh-chapter b{ font:600 13.5px/1.3 var(--f-ui); color:var(--t1); min-width:0; }
.bkh-chapter span{ margin-left:auto; flex:none; font-size:11.5px; color:var(--t3); }

/* ═══ ДЕСКТОП ══════════════════════════════════════════════════════════
   Те же блоки шире, а не второй макет. Единственное, что действительно
   меняется, — число колонок и то, что баннер разворачивается в две. */
@media (min-width:700px){
  .bkh-wrap,.bkh-head,.bkh-chips,.bkh-cont{ padding-inline:20px; }
  .bkh-ban{ max-width:calc(var(--wide) - 40px); padding:var(--sp7); }

  .bkh-head h1{ font-size:34px; }
  .bkh-head p{ font-size:14px; max-width:56ch; }

  /* Баннер: обложка и колонка текста простым флексом. Сеткой со спанящей на
     все строки обложкой здесь не обойтись — спанящий элемент раздаёт свою
     высоту строкам, и между метаданными и кнопкой появляется дыра, которую
     align-content не убирает. */
  .bkh-ban{ display:flex; align-items:center; gap:var(--sp8); }
  .bkh-ban .side{ display:flex; flex-direction:column; align-items:flex-start; flex:1; min-width:0; }
  .bkh-ban .c{ width:210px; }
  .bkh-ban .ov{ margin-bottom:14px; }
  .bkh-ban .tx{ width:100%; }
  .bkh-ban h2{ font-size:36px; }
  .bkh-ban .qt{ font-size:17px; margin-top:14px; }
  .bkh-ban .act{ width:100%; max-width:400px; margin-top:var(--sp5); }
  .bkh-ban .dots{ justify-content:flex-start; margin-top:var(--sp4); }

  /* Две колонки, а не три: на 768 третья ужимала карточку до 230 пикселей,
     и от «Зов Ктулху. Шёпот глубин» оставалось «Зов Ктулху…». Три включаются
     ниже, с тысячи. */
  .bkh-cont-list{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .bkh-cont-h b{ font-size:19px; }

  .bkh-sec h2{ font-size:24px; }
  .bkh-grid{ grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--sp6) var(--sp4); }
  .bkh-more button,.bkh-more a{ max-width:340px; margin-inline:auto; }

  /* Шторка на широком экране — панель по центру, а не полный экран:
     строка в 1180 пикселей нечитаема, а книга это в первую очередь текст. */
  .bkh-sheet{ padding:clamp(0px,5vh,60px) 20px; }
  .bkh-sheet-in{
    max-width:820px; margin-inline:auto; padding-bottom:var(--sp8);
    background:var(--s1); border:1px solid var(--hair);
    border-radius:var(--r-lg); overflow:hidden;
  }
  .bkh-sh-hero{ height:320px; }
  .bkh-sh-hero .c{ width:150px; top:60px; }
  .bkh-sh-b{ padding-inline:var(--sp7); }
  .bkh-sh-b h2{ font-size:28px; }
  .bkh-sh-b .p{ margin-inline:auto; }
  .bkh-sh-b .act{ justify-content:center; }
  .bkh-sh-b .act .bkh-btn{ flex:none; min-width:200px; }
}
@media (min-width:1000px){
  .bkh-grid{ grid-template-columns:repeat(5,minmax(0,1fr)); }
  .bkh-card .nm{ font-size:14px; min-height:37px; }
  .bkh-cont-list{ grid-template-columns:repeat(3,minmax(0,1fr)); }
}

/* ── ПОЯВЛЕНИЕ ПРИ ПРОКРУТКЕ ───────────────────────────────────────────
   Scroll-driven animations (Interop 2026) — на компоситоре, без единой
   строки JavaScript и без библиотеки на 30 КБ. @supports гарантирует, что в
   браузере, который этого не умеет, мы не спрячем контент навсегда. */
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion: no-preference) and (min-width: 700px){
    .bkh-anim{ animation:bkhRise linear both; animation-timeline:view(); animation-range:entry 0% entry 32%; }
    @keyframes bkhRise{ from{ opacity:0; transform:translateY(14px); } to{ opacity:1; transform:none; } }
  }
}

@media (prefers-reduced-motion:reduce){
  .bkh-card .ph,.bkh-btn,.bkh-cont-it,.bkh-chip,.bkh-sheet,.bkh-sheet-bd{ transition:none; }
  .bkh-card:hover .ph{ transform:none; }
}
