/* ============================================================================
   alive.css — слой «страница живая». Подключается ВЕЗДЕ, поверх styles.css.

   Ни одного запроса наружу, ни байта JavaScript. Всё, что здесь есть, —
   возможности самого браузера, появившиеся в 2024–2026 годах.

   ГЛАВНОЕ ПРАВИЛО ЭТОГО ФАЙЛА, И ОНО НЕ ОБСУЖДАЕТСЯ:
   базовое состояние элемента — это ГОТОВОЕ состояние, а анимация лишь
   отматывает его назад. Написать `opacity: 0` и оживлять до единицы значит
   показать пустую страницу всем, у кого возможности нет. Здесь так не
   написано нигде, и если появится — это ошибка, а не стиль.

   Проверено по таблицам поддержки на сентябрь 2026, а не по памяти:
   scroll-driven анимации — Safari 26+, переходы между страницами —
   Safari 18.2+, text-wrap: pretty — Safari 26+. Всё падает мягко.
   ========================================================================== */

/* ── ПЕРЕХОД МЕЖДУ СТРАНИЦАМИ ────────────────────────────────────────────
   Обычная ссылка, обычная перезагрузка — но браузер сам сшивает старую
   страницу с новой. Никакого SPA, никакого роутера, две строки CSS.
   Там, где не поддержано, просто происходит обычный переход. */
@view-transition { navigation: auto; }

/* ПЕРЕХОД БЕЗ ПРОВАЛА.
   Кросс-фейд по умолчанию гасит старый кадр и проявляет новый
   ОДНОВРЕМЕННО. В середине их суммарная непрозрачность меньше единицы —
   и сквозь оба просвечивает подложка. Даже с непрозрачным фоном у html
   это читается как мигание, потому что яркость проседает на кадр-другой.

   Поэтому старый кадр НЕ гасим вовсе: он лежит внизу до самого конца.
   Новый проявляется поверх него и чуть подаётся вверх — движение
   подсказывает направление перехода, а провала нет ни на одном кадре. */
::view-transition-group(root) { animation-duration: .26s; }

::view-transition-old(root) {
  animation: none;
  opacity: 1;
}

::view-transition-new(root) {
  animation: siw-page-in .26s cubic-bezier(.2, 0, 0, 1) both;
}

@keyframes siw-page-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* Портрет персонажа переезжает со списка в статью как ОДИН И ТОТ ЖЕ
   предмет — имя перехода совпадает на обеих страницах, браузер видит это
   и ведёт его сам. Имя уникально для статьи (view-transition-name обязан
   быть единственным в документе), поэтому проставляется при сборке. */
::view-transition-group(.doll-vt) { animation-duration: .34s; }
::view-transition-old(.doll-vt),
::view-transition-new(.doll-vt) { mix-blend-mode: normal; height: 100%; }

/* Уважение к настройке ОС НЕ включается само: медиазапрос переходы не
   отменяет, корневое затухание продолжает идти. Гасим руками. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

/* ── ПОЛОСА ПРОЧИТАННОГО ─────────────────────────────────────────────────
   Привязана не к таймеру, а к самой прокрутке: тянется ровно настолько,
   насколько человек продвинулся. Раньше такое делали скриптом на каждый
   кадр прокрутки; теперь это свойство. */
@property --prog-a { syntax: "<color>"; inherits: false; initial-value: #e86a5c; }
@property --prog-b { syntax: "<color>"; inherits: false; initial-value: #4a7a7e; }

.progress {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  height: 2px;
  z-index: 60;
  background: var(--accent);
  background: linear-gradient(90deg, var(--prog-a), var(--prog-b));
  --prog-a: var(--accent);
  --prog-b: var(--teal);
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
}
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .progress {
      animation: siw-progress linear both;
      animation-timeline: scroll(root block);
    }
    @keyframes siw-progress { to { transform: scaleX(1); } }
  }
}

/* ── ПЕРСОНАЖИ ───────────────────────────────────────────────────────────
   Портреты рисует наш же движок кукол (scripts/book_faces.py): прозрачный
   фон, растворённый низ, ни одного прямоугольного среза. Картинка не
   лежит НА странице — она стоит В ней. */
.doll {
  display: block;
  height: auto;
  max-width: 100%;
  /* ТЕНИ НЕТ, И ЭТО РЕШЕНИЕ. drop-shadow идёт по альфе, а низ портрета
     нарочно растворён — тень расплывалась под фигурой серым пятном и
     выдавала «наклейку». Плоскому рисунку с жёстким контуром тень не
     нужна: его держит собственный контур. */
}

/* Появление при прокрутке. База — КОНЕЧНОЕ состояние: там, где
   возможности нет, персонаж просто стоит на месте. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .doll-in {
      animation: siw-doll-in linear both;
      animation-timeline: view();
      animation-range: entry 5% entry 65%;
    }
    @keyframes siw-doll-in {
      from { opacity: 0; translate: 0 26px; scale: .97; }
      to   { opacity: 1; translate: 0 0;    scale: 1; }
    }
  }
}

/* ── ТИПОГРАФИКА ─────────────────────────────────────────────────────────
   Самое дешёвое, что можно сделать для чтения с телефона после смены. */
h1, h2, h3, figcaption, .nt-deck { text-wrap: balance; }
p, li, dd { text-wrap: pretty; }

/* Переносы. Работают ТОЛЬКО при верном lang у <html> — он у нас есть.
   На экране в 390 точек это разница между рваным правым краем и текстом. */
.nt-body p, .nt-body li, .pay-body .wl-body { hyphens: auto; }

/* Читатель пришёл из поиска по ссылке на конкретное предложение —
   подсветим его нашим цветом, а не системным жёлтым. */
::target-text {
  background: color-mix(in oklab, var(--alert) 45%, transparent);
  background: rgba(244, 196, 48, .45);
  color: inherit;
}

/* ── ССЫЛКИ, КОТОРЫЕ ОТВЕЧАЮТ ───────────────────────────────────────────
   Подчёркивание растёт из-под слова, а не появляется целиком. Мелочь,
   которую замечают телом, а не глазом. */
.nt-body a,
.nt-lede a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in oklab, currentColor 35%, transparent);
  text-decoration-color: rgba(59, 99, 103, .4);
  transition: text-decoration-color .16s, text-decoration-thickness .16s;
}
.nt-body a:hover,
.nt-lede a:hover { text-decoration-color: currentColor; text-decoration-thickness: 2px; }

@media (prefers-reduced-motion: reduce) {
  .doll-in { animation: none; }
  .nt-body a, .nt-lede a { transition: none; }
}
