/* Комикс стопкой карточек. Один файл на две страницы: песочницу app/komiks/index.html
   и блок на сайте app/index.html. Всё под префиксом km- и внутри .km, чтобы не спорить
   со стилями сайта (у него свои .btn, .label). Палитра — из app/css/styles.css.
   Состояние карточки задаёт cards.js классом: is-past, is-current, is-next1, is-next2. */

.km{
  --km-bg-0:#0d1a10;
  --km-bg-2:#17301d;
  --km-moss:#2c4a30;
  --km-accent:#9ecb6f;
  --km-cream:#f6f1e2;
  --km-cream-2:#efe6cd;
  --km-ink:#17241a;
  --km-ink-soft:#45543f;
  --km-paper:#eee7d3;
  --km-paper-dim:#b9c2ac;
  --km-kraft:#b9803e;
  --km-serif:'Lora', Georgia, 'Times New Roman', serif;
  --km-sans:'Manrope', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  /* Карточка 2:3 (такой кадр даёт Nano Banana Pro) во весь свободный экран:
     по ширине или по высоте, что упрётся раньше. --km-ratio — высота к ширине. */
  --km-ratio:1.5;
  --km-w:min(calc(100vw - 40px), calc((100dvh - 150px) / var(--km-ratio)), 440px);
  --km-ease:cubic-bezier(.2,.8,.25,1);

  display:flex; flex-direction:column;
  color:var(--km-ink);
  font-family:var(--km-sans);
  line-height:1.45;
  -webkit-tap-highlight-color:transparent;
  overflow-wrap:break-word;
}
.km *,.km *::before,.km *::after{ box-sizing:border-box; }
.km h1,.km h2{ font-family:var(--km-serif); font-weight:600; line-height:1.1; letter-spacing:0; margin:0; }
.km p{ margin:0; }

/* Песочница: стопка на весь экран */
.km-page{
  margin:0;
  height:100dvh;
  justify-content:center;
  overflow:hidden;
  -webkit-font-smoothing:antialiased;
}
/* Блок на сайте: отдельная секция сразу под первым экраном */
/* Шапка сайта прилипшая и накрывает верх секции: отступ сверху — с её запасом,
   и тот же запас при переходе по якорю #komiks. */
.km-section{ padding:96px 0 40px; scroll-margin-top:78px; }
/* На сайте по вертикали тесно: полоса и запас под сдвиг карточек в стопке — поуже. */
.km-section .km-bar{ padding-top:8px; }
.km-section .km-stage{ height:calc(var(--km-w) * var(--km-ratio) + 30px); }
/* На сайте над стопкой ещё шапка сайта и две строки — карточка меньше, чтобы кнопки влезали в экран. */
/* …но не уже 280 px: на невысоких экранах кадр и подсказка видны целиком, а кнопки ‹ ›
   уходят ниже края — листают пальцем и нажатием (решение оркестратора от 17.09). */
.km-section .km{ --km-w:max(min(calc(100vw - 40px), calc((100dvh - 340px) / var(--km-ratio)), 440px), min(calc(100vw - 40px), 280px)); }
/* Фон — фотография стола (app/komiks/stol.webp, снимок Леонида) в полную силу, без плёнки.
   Читаемость держат сами подписи: они светлые, с тенью, а полоса прогресса — светлая.
   Фон едет со страницей: background-attachment fixed на iOS дёргается.
   Пока картинка не загрузилась — прежний кремовый цвет. */
.km-page, .km-section{
  background-color:#0d1a10;
  /* Узкий экран: вертикальный кусок только с досками (stol-uzkiy.webp) — широкую картинку
     резало по бокам, и в кадр лезла светлая салфетка. Плёнка тёмная и слабая: притемняет,
     а не выбеливает. */
  background-image:
    linear-gradient(rgba(7,14,9,.22), rgba(7,14,9,.22)),
    url("stol-uzkiy.webp");
  background-size:auto, cover;
  background-position:center, center;
  background-repeat:repeat, no-repeat;
}
/* Шире телефона — квадратный кусок (stol-sredniy.webp): в нём тоже нет светлой салфетки.
   Исходная широкая stol.webp не подключена: её по краям режет так, что салфетка лезет в кадр. */
@media (min-width: 700px){
  .km-page, .km-section{
    background-image:
      linear-gradient(rgba(7,14,9,.22), rgba(7,14,9,.22)),
      url("stol-sredniy.webp");
  }
}
.km-bar{ padding-top:8px; }
.km-section .km-stage{ height:calc(var(--km-w) * var(--km-ratio) + 30px); }
/* На сайте над стопкой ещё шапка сайта и две строки — карточка меньше, чтобы кнопки влезали в экран. */
/* …но не уже 280 px: на невысоких экранах кадр и подсказка видны целиком, а кнопки ‹ ›
   уходят ниже края — листают пальцем и нажатием (решение оркестратора от 17.09). */
.km-section .km{ --km-w:max(min(calc(100vw - 40px), calc((100dvh - 340px) / var(--km-ratio)), 440px), min(calc(100vw - 40px), 280px)); }
.km-bar{
  flex:none;
  display:flex; justify-content:space-between; align-items:baseline; flex-wrap:wrap; gap:4px 12px;
  width:calc(var(--km-w) + 8px); margin:0 auto;
  padding:14px 0 0;
  font-size:13px;
}
.km-where{ font-weight:700; }
/* Строки над стопкой на сайте: что это за заглушки и как листать */
.km-top{ width:calc(var(--km-w) + 8px); margin:0 auto; }
.km .km-lead, .km .km-swipe{ font-size:14px; color:var(--km-ink-soft); }
.km .km-swipe{
  display:flex; align-items:center; gap:8px; margin-top:6px;
  /* Видна только на первой карточке (класс km-at-start ставит cards.js). Гаснет прозрачностью,
     место оставляет — иначе стопка под ней прыгала бы. */
  opacity:0; visibility:hidden;
  transition:opacity .5s var(--km-ease), visibility 0s linear .5s;
}
.km.km-at-start .km-swipe{ opacity:1; visibility:visible; transition:opacity .5s var(--km-ease), visibility 0s; }
.km-swipe-icon{ flex:none; overflow:visible; }
.km-sw-back{ fill:var(--km-cream-2); stroke:var(--km-ink-soft); stroke-width:1.2; }
.km-sw-front{ fill:var(--km-bg-2); stroke:var(--km-ink); stroke-width:1.2; }
.km-sw-finger{ fill:var(--km-cream); stroke:var(--km-ink); stroke-width:1.2; }
.km-sw-arrow{ display:none; fill:none; stroke:var(--km-ink-soft); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round; }
.km-sw-front, .km-sw-finger{ transform-box:fill-box; transform-origin:center; }
.km-sw-front{ animation:km-sw-card 3.2s ease-in-out infinite; }
.km-sw-finger{ animation:km-sw-finger 3.2s ease-in-out infinite; }
/* Пауза, палец ведёт карточку влево, она уходит, возвращается из воздуха — и снова пауза. */
@keyframes km-sw-card{
  0%, 25%{ transform:none; opacity:1; }
  60%{ transform:translateX(-16px) rotate(-10deg); opacity:0; }
  61%, 75%{ transform:none; opacity:0; }
  100%{ transform:none; opacity:1; }
}
@keyframes km-sw-finger{
  0%{ transform:none; opacity:0; }
  12%, 25%{ transform:none; opacity:1; }
  55%{ transform:translateX(-16px); opacity:1; }
  70%, 100%{ transform:translateX(-16px); opacity:0; }
}
.km-bar a{ color:var(--km-ink-soft); text-decoration:underline; }
.km-progress{ flex-basis:100%; height:4px; background:var(--km-cream-2); border:1px solid var(--km-ink); }
.km-progress i{ display:block; height:100%; width:0; background:var(--km-kraft); transition:width .35s var(--km-ease); }

.km-stage{
  position:relative;
  flex:none;
  height:calc(var(--km-w) * var(--km-ratio) + 44px);
  /* Вертикальную прокрутку страницы отдаём браузеру, горизонтальный жест — наш. */
  touch-action:pan-y;
  user-select:none; -webkit-user-select:none;
  cursor:pointer;
}

.km-card, .km-promo{
  position:absolute; inset:0; margin:auto;
  width:var(--km-w); height:calc(var(--km-w) * var(--km-ratio));
  border-radius:18px;
  overflow:hidden;
  opacity:0;
  transition:transform .45s var(--km-ease), opacity .45s var(--km-ease);
  pointer-events:none;
}
.km-card{
  box-shadow:0 18px 38px -16px rgba(7,14,9,.85);
  transform:translateY(30px) scale(.88);
}
.km-card.is-current{ opacity:1; transform:none; z-index:3; pointer-events:auto; }
.km-card.is-next1{ opacity:1; transform:translate(6px, 12px) rotate(2deg) scale(.96); z-index:2; }
.km-card.is-next2{ opacity:1; transform:translate(-6px, 22px) rotate(-2deg) scale(.92); z-index:1; }
/* Вариант К1, выбран 24.09: кадр уходит, поворачиваясь вокруг левого края, как лист книги.
   Изнанку не показываем — на обороте текст читался бы зеркально. Тень лежит на самом листе,
   а не на картинке: когда вместо заглушек придут кадры, переделывать не придётся. */
.km-card.is-past{
  opacity:1;
  transform:perspective(1400px) rotateY(-108deg);
  z-index:4;
  box-shadow:24px 0 40px -18px rgba(7,14,9,.65);
}
.km-card{ transform-origin:left center; backface-visibility:hidden; }
/* Тень у корешка и загиб угла — только у той карточки, что сейчас перед глазами. */
.km-card.is-current::after{
  content:""; position:absolute; inset:0; pointer-events:none; border-radius:inherit;
  background:
    linear-gradient(90deg, rgba(7,14,9,.32), transparent 8%),
    linear-gradient(225deg, rgba(246,241,226,.45) 0 14px, transparent 15px);
}
.km-card.is-dragging{ transition:none; }
.km-card.km-bump, .km-promo.km-bump{ animation:km-bump .3s; }
@keyframes km-bump{ 30%{ transform:translateX(-8px); } 70%{ transform:translateX(8px); } }

/* Титульная карточка */
.km-intro{
  display:flex; flex-direction:column; justify-content:center; gap:14px;
  padding:24px;
  background:var(--km-cream);
}
.km-label{ font-size:13px; color:var(--km-ink-soft); }
.km-intro h1{ font-size:30px; }
.km-note{
  padding:12px 14px;
  background:var(--km-cream-2); border-radius:10px;
  font-size:14px; color:var(--km-ink-soft);
}
.km-hint{ font-size:14px; font-weight:700; }

/* Обложка главы */
.km-cover{
  display:flex; align-items:center;
  padding:28px;
  background:linear-gradient(160deg, var(--km-moss), var(--km-bg-0));
  color:var(--km-paper);
}
.km-cover h2{ font-size:36px; }
.km-cover span{
  display:block; margin-bottom:10px;
  font-family:var(--km-sans); font-size:14px; font-weight:700;
  letter-spacing:.02em; text-transform:uppercase; color:var(--km-accent);
}

/* Кадр: заглушка картинки; реплика лежит снизу на дымке (вариант К3) */
.km-art{
  height:100%;
  display:flex; flex-direction:column; justify-content:flex-end; gap:8px;
  padding:16px;
  background:var(--km-moss);
  background-image:radial-gradient(120% 80% at 50% 0%, rgba(158,203,111,.16), transparent 60%);
  color:var(--km-paper-dim);
  padding-bottom:104px;
}
.km-art p{ font-size:14px; }
.km-art b{ color:var(--km-accent); font-size:12px; font-weight:600; }

.km-caption{
  position:absolute; left:0; right:0; bottom:0;
  padding:44px 16px 16px;
  background:linear-gradient(transparent, rgba(7,14,9,.92) 45%);
  font-size:15px; font-weight:700; line-height:1.3;
  text-transform:uppercase; color:var(--km-paper);
}

.km-frame:has(.km-cta) .km-art{ padding-bottom:88px; }
.km-cta{ position:absolute; left:0; right:0; bottom:22px; text-align:center; }
.km-buy{
  display:inline-block; padding:13px 38px;
  border:none; border-radius:100px;
  box-shadow:0 10px 22px -10px rgba(7,14,9,.9);
  background:var(--km-accent); color:#12220f;
  font-size:17px; font-weight:700;
  text-decoration:none;
}

/* Пасхалка: карточка под последней, до открытия видно только «?» */
.km-promo{
  display:flex; align-items:center; justify-content:center;
  padding:28px;
  background:linear-gradient(160deg, #f7f2e4, var(--km-cream-2));
  text-align:center;
  transform:translate(6px, 12px) rotate(2deg) scale(.96);
}
.km-promo.is-peek{ opacity:1; z-index:2; }
.km-promo.is-open{ opacity:1; transform:none; z-index:3; pointer-events:auto; }
.km-promo-q{ font-family:var(--km-serif); font-size:120px; color:rgba(23,36,26,.15); }
.km-promo-body{ display:none; }
.km-promo.is-open .km-promo-q{ display:none; }
.km-promo.is-open .km-promo-body{ display:flex; flex-direction:column; align-items:center; gap:14px; }
.km-promo-kicker{ font-size:14px; font-weight:700; text-transform:uppercase; color:var(--km-kraft); }
.km-promo-title{ font-size:40px; }
/* Приглашение — тише заголовка: читается подписью к скидке, а не спорит с ней. */
.km-promo-invite{ margin-top:-6px; font-family:var(--km-serif); font-style:italic; font-size:19px; line-height:1.25; color:var(--km-ink-soft); }
.km-promo-code{
  padding:14px 22px;
  border:2px dashed var(--km-ink); border-radius:10px;
  background:var(--km-cream); color:var(--km-ink);
  font-family:ui-monospace, Menlo, Consolas, monospace; font-size:26px; font-weight:700; letter-spacing:.06em;
  cursor:copy;
  user-select:text; -webkit-user-select:text;
}
.km-promo-status{ min-height:1.45em; font-size:14px; color:var(--km-ink-soft); }
.km-promo .km-buy{ margin-top:10px; }

.km mark{ background:var(--km-kraft); color:var(--km-cream); border-radius:4px; padding:0 3px; }

.km-nav{
  flex:none;
  display:flex; justify-content:space-between;
  width:calc(var(--km-w) + 8px); margin:0 auto;
  padding:0 0 16px;
}
.km-nav button{
  width:48px; height:48px; font-weight:700;
  border:none; border-radius:50%;
  box-shadow:0 8px 18px -8px rgba(7,14,9,.9);
  background:var(--km-cream); color:var(--km-ink);
  font-size:28px; line-height:1;
  cursor:pointer;
}
.km-nav button:disabled{ opacity:.3; cursor:default; }

.km-noscript{ margin:0 auto 12px; width:var(--km-w); padding:12px; background:var(--km-cream); border:2px solid var(--km-ink); }

/* ===== Поверх фотографии стола ===== */
/* Строки и полоса не висят прямо на досках: под ними своя тёмная подложка шириной со стопку,
   а не плёнка на весь блок. */
.km-page .km-lead, .km-section .km-lead,
.km-page .km-swipe, .km-section .km-swipe,
.km-page .km-bar, .km-section .km-bar{
  width:calc(var(--km-w) + 8px);
  margin:0 auto;
  padding:10px 12px;
  border-radius:10px;
  background:rgba(7,14,9,.82);
}
/* Подложка у подсказки исчезает вместе с ней, а место остаётся — стопка не прыгает. */
.km-page .km-swipe, .km-section .km-swipe{ margin-top:6px; }
.km-page .km-bar, .km-section .km-bar{ margin-top:8px; }
/* Значок жеста нарисован тёмным контуром для светлого фона. На тёмной подложке
   он превращался в белый прямоугольник — здесь ему своя раскраска. */
.km-page .km-sw-back, .km-section .km-sw-back{ fill:rgba(238,231,211,.22); stroke:var(--km-paper-dim); }
.km-page .km-sw-front, .km-section .km-sw-front{ fill:var(--km-moss); stroke:var(--km-paper); }
.km-page .km-sw-finger, .km-section .km-sw-finger{ fill:var(--km-paper); stroke:var(--km-bg-0); }
.km-page .km-sw-arrow, .km-section .km-sw-arrow{ stroke:var(--km-paper); }
/* Текст на подложке светлый, с мягкой тенью — как подпись логотипа в шапке сайта. */
.km-page .km .km-lead, .km-section .km .km-lead,
.km-page .km .km-swipe, .km-section .km .km-swipe,
.km-page .km .km-where, .km-section .km .km-where{
  color:var(--km-paper);
  text-shadow:0 1px 4px rgba(7,14,9,.8);
}
.km-page .km-bar a, .km-section .km-bar a{ color:var(--km-paper-dim); }
.km-page .km-progress, .km-section .km-progress{
  background:rgba(7,14,9,.5); border-color:rgba(238,231,211,.5);
}
.km-page .km-progress i, .km-section .km-progress i{ background:var(--km-accent); }
.km-page .km-swipe-icon, .km-section .km-swipe-icon{ filter:drop-shadow(0 1px 5px rgba(7,14,9,.8)); }
/* Карточку от досок отделяет собственная тень, а не плёнка. */
.km-page .km-card, .km-section .km-card,
.km-page .km-promo, .km-section .km-promo{
  box-shadow:0 20px 40px -16px rgba(7,14,9,.95);
}

@media (prefers-reduced-motion: reduce){
  .km-card, .km-promo, .km-progress i{ transition:none; }
  .km-card.km-bump, .km-promo.km-bump{ animation:none; }
  .km-sw-front, .km-sw-finger{ animation:none; }
  .km .km-swipe, .km.km-at-start .km-swipe{ transition:none; }
  .km-sw-finger{ display:none; }
  .km-sw-arrow{ display:inline; }
}
