/* Стили полки книг и страницы книги.
   Раньше эти правила вклеивались из JS: медиазапросы и :hover нельзя
   выразить inline-атрибутами, а отдельного файла не было. Теперь файл есть. */
  /* Базово 2 колонки — как было и как удобно на телефоне. Дальше колонки
  добавляются по ширине: на планшете и десктопе две растянутые карточки
  выглядели бы огромными, а обложки — неестественно крупными. */
.bk-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px 12px;align-items:start}
@media(min-width:560px){.bk-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:20px 16px}}
@media(min-width:820px){.bk-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}
@media(min-width:1100px){.bk-grid{grid-template-columns:repeat(5,minmax(0,1fr))}}
  /* Лента: горизонтальная прокрутка вместо сетки. Включается только для
  длинных полок на телефоне (см. LANE_MIN_BOOKS) — так делают Apple Books
  и Storytel: короткая подборка остаётся плиткой, длинная превращается в
  карусель, иначе экран уезжает в бесконечный вертикальный скролл.
  Ширина 42% выбрана намеренно: видно 2 карточки целиком и край третьей —
  это единственный честный сигнал, что ленту можно листать.
  С 560px лента становится обычной сеткой: на широком экране всё влезает
  и прятать книги за горизонтальным скроллом незачем. */
.bk-lane{display:flex;gap:12px;overflow-x:auto;align-items:start;scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;padding-bottom:6px;scrollbar-width:none;-ms-overflow-style:none}
.bk-lane::-webkit-scrollbar{display:none}
.bk-lane>.bk-card{flex:0 0 42%;scroll-snap-align:start}
@media(min-width:560px){.bk-lane{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px 16px;overflow:visible;padding-bottom:0}.bk-lane>.bk-card{flex:auto}}
@media(min-width:820px){.bk-lane{grid-template-columns:repeat(4,minmax(0,1fr))}}
@media(min-width:1100px){.bk-lane{grid-template-columns:repeat(5,minmax(0,1fr))}}
.bk-card{display:flex;flex-direction:column;min-width:0}
  /* Пропорция 2:3 — книжный стандарт. Фиксируем её, чтобы разная высота
  картинок не рвала ряды и не было скачка вёрстки при догрузке. */
.bk-cover{position:relative;aspect-ratio:2/3;border-radius:12px;overflow:hidden;cursor:pointer;transition:transform .18s ease,box-shadow .18s ease}
  /* cover: все файлы обложек приведены к 600x900 (ровно 2:3), поэтому ничего
  не обрезается и градиент рамки не выглядывает по краям. Если когда-нибудь
  добавят обложку другой пропорции — она заполнит рамку с обрезкой, а не
  оставит цветные поля. Стандарт размера — в PROJECT_MAP.md. */
.bk-cover img{width:100%;height:100%;object-fit:cover;display:block}
@media(hover:hover){.bk-cover:hover{transform:translateY(-3px);box-shadow:0 10px 24px rgba(0,0,0,.45)}}
  /* Начатую книгу отмечает полоса прогресса на обложке (.bk-prog) и строка
  «Глава N» под ней. Рамки вокруг обложки нет намеренно: любая обводка
  спорит с собственной рамкой, нарисованной на самой обложке. */
  /* Подпись поверх обложки, когда картинка не загрузилась */
.bk-cover-fallback{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:10px;text-align:center;font-size:12px;line-height:1.3;color:rgba(255,255,255,.92)}
/* Плашка не переносится: в ней теперь цена, а «199 ₽», разорванное на две
   строки, читается как две разные цифры. */
.bk-badge{position:absolute;top:8px;left:8px;font-size:10px;padding:3px 7px;border-radius:6px;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);font-weight:600;letter-spacing:.2px;white-space:nowrap}
.bk-badge.free{background:rgba(46,204,113,.9);color:#06301b}
/* Золотая плашка = есть цена и можно купить прямо сейчас. */
.bk-badge.gated{background:rgba(212,175,55,.92);color:#2a1f00}
/* Нейтральная = книга идёт с подпиской и отдельной цены у неё нет. Отличать
   её от золотой обязательно: обещание «нажми и купи» здесь ложное. */
.bk-badge.subscription{background:rgba(255,255,255,.22);color:rgba(255,255,255,.95)}
  /* Полоса прогресса лежит НА обложке, а не под текстом: так читатель
  видит «начатую» книгу боковым зрением, не вчитываясь в подписи. */
.bk-prog{position:absolute;left:0;right:0;bottom:0;height:4px;background:rgba(0,0,0,.55)}
.bk-prog i{display:block;height:100%;background:var(--accent-1)}
.bk-meta{padding-top:8px}
.bk-title{font-size:13px;font-weight:600;color:var(--text);line-height:1.3;cursor:pointer;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.bk-sub{font-size:11px;color:var(--text-dim);line-height:1.35;margin-top:3px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  /* Объём книги. Один короткий факт под названием — приём Kindle/Storytel:
  он снимает главный вопрос «во что я ввязываюсь», не занимая строки. */
.bk-facts{font-size:10px;color:var(--text-muted);margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bk-facts.resume{color:var(--accent-1)}
.bk-authors{font-size:10px;color:var(--text-muted);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bk-about-btn{display:inline-flex;align-items:center;gap:4px;margin-top:6px;font-size:11px;color:var(--text-dim);cursor:pointer;user-select:none;padding:3px 8px;border:1px solid var(--border);border-radius:8px;background:transparent;transition:color .15s,border-color .15s}
.bk-about-btn .bk-chev{transition:transform .2s ease;font-size:9px}
.bk-card.is-open .bk-about-btn{color:var(--accent-1);border-color:var(--border-bright)}
.bk-card.is-open .bk-about-btn .bk-chev{transform:rotate(180deg)}
  /* Раскрытие через max-height: анимируется, в отличие от display:none */
.bk-about{max-height:0;opacity:0;overflow:hidden;font-size:11px;line-height:1.45;color:var(--text-dim);transition:max-height .28s ease,opacity .2s ease,margin-top .28s ease}
.bk-card.is-open .bk-about{max-height:420px;opacity:1;margin-top:6px}
  /* Наведение на текстовый блок под обложкой раскрывает описание — только
  там, где курсор реально есть. На тач-экранах hover эмулируется залипающим
  состоянием, поэтому для них остаётся тап по кнопке «О книге». */
@media(hover:hover) and (pointer:fine){.bk-meta:hover .bk-about{max-height:420px;opacity:1;margin-top:6px}.bk-meta:hover .bk-about-btn{color:var(--accent-1);border-color:var(--border-bright)}.bk-meta:hover .bk-about-btn .bk-chev{transform:rotate(180deg)}}
.bk-more{display:inline-block;margin-top:6px;font-size:11px;color:var(--accent-1);cursor:pointer}
.bk-shelf-title{font-size:13px;color:var(--text-dim);letter-spacing:1px;margin-bottom:12px}
  /* Контейнер шире 1200px смысла не имеет: обложки начинают раздуваться до
  неестественных размеров. Само приложение по ширине не ограничено, но
  для сетки книг это заметно сильнее, чем для колонки текста. */
.bk-shelf-wrap{padding:16px;max-width:1200px;margin:0 auto}

  /* --- Фильтр по доступу --- */
.bk-chips{display:flex;gap:8px;justify-content:center;flex-wrap:wrap;margin-bottom:20px}
.bk-chip{font-size:11px;padding:6px 14px;border-radius:999px;cursor:pointer;user-select:none;border:1px solid var(--border);color:var(--text-dim);background:transparent;transition:color .15s,border-color .15s,background .15s;font-family:inherit}
.bk-chip.on{color:var(--accent-1);border-color:var(--border-bright);background:rgba(212,175,55,.1)}
.bk-empty{text-align:center;padding:32px 16px;font-size:12px;color:var(--text-dim)}

  /* --- Страница книги --- */
.bk-back{display:inline-block;font-size:12px;color:var(--text-dim);cursor:pointer;padding:4px 10px;border:1px solid var(--border);border-radius:8px;margin-bottom:16px}
  /* На телефоне обложка над текстом, с 560px — рядом с ним. Так на узком
  экране обложка остаётся крупной, а на широком не съедает высоту. */
.bk-hero{display:grid;grid-template-columns:1fr;gap:16px;margin-bottom:20px}
@media(min-width:560px){.bk-hero{grid-template-columns:200px 1fr;gap:24px;align-items:start}}
.bk-hero-cover{position:relative;aspect-ratio:2/3;border-radius:14px;overflow:hidden;max-width:220px;margin:0 auto;width:100%}
.bk-hero-cover img{width:100%;height:100%;object-fit:cover;display:block}
.bk-hero-title{font-size:20px;font-weight:700;color:var(--text);line-height:1.25}
.bk-hero-sub{font-size:13px;color:var(--text-dim);margin-top:6px;line-height:1.4}
.bk-hero-authors{font-size:12px;color:var(--text-muted);margin-top:8px}
.bk-hero-facts{font-size:12px;color:var(--text-muted);margin-top:8px}
.bk-hero-badge{display:inline-block;font-size:10px;padding:3px 8px;border-radius:6px;font-weight:600;margin-top:10px}
.bk-cta{display:block;width:100%;margin-top:16px;padding:14px;border-radius:12px;border:none;background:linear-gradient(135deg,#D4AF37,#b8860b);color:#080808;font-size:15px;font-weight:700;cursor:pointer;font-family:inherit}
.bk-cta.secondary{background:transparent;border:1px solid var(--border);color:var(--text-dim);font-size:13px;font-weight:400;padding:11px;margin-top:8px}
/* Подпись под кнопкой скачивания. Без неё человек получает .html и не
   понимает, что с ним делать: PDF у монографии нет, файл печатается в PDF
   средствами браузера. Внутри Telegram текст другой — там файл приходит
   в чат, а не в папку загрузок. */
.bk-download-hint{font-size:12px;color:var(--text-dim);line-height:1.4;margin-top:6px;text-align:center}
.bk-download-hint.err{color:#f87171}
/* Скачивание — редкое действие, и стоять вплотную к «Читать» оно не должно:
   иначе три цели подряд спорят за одно и то же внимание. */
.bk-cta.download{margin-top:20px}
/* Нажатая кнопка гаснет. Файл собирается 1–2 секунды — ровно столько,
   чтобы решить «сломалось» и нажать ещё раз. disabled сам по себе на тёмной
   теме не виден. */
.bk-cta[disabled]{opacity:.55;cursor:default}
.bk-pagebar{margin-top:14px}
.bk-pagebar-track{height:6px;background:rgba(255,255,255,.06);border-radius:3px;overflow:hidden}
.bk-pagebar-fill{height:100%;background:var(--accent-1);border-radius:3px}
.bk-pagebar-text{display:flex;justify-content:space-between;font-size:11px;color:var(--text-dim);margin-bottom:5px}
.bk-section-h{font-size:12px;color:var(--text-dim);letter-spacing:1px;margin-bottom:8px}
.bk-page-about{font-size:14px;line-height:1.6;color:var(--text-dim);border-top:1px solid var(--border);padding-top:16px}

  /* --- Скелетоны --- */
  /* Свой шиммер, а не глобальный .skeleton из index.html: полка должна
  рисоваться и вне приложения (изолированная проверка вёрстки). */
@keyframes bkShimmer{0%,100%{opacity:.35}50%{opacity:.7}}
.bk-sk{background:rgba(255,255,255,.07);border-radius:8px;animation:bkShimmer 1.4s ease-in-out infinite}
.bk-sk-cover{aspect-ratio:2/3;border-radius:12px}
