/* Koban · Valheim — сцена: небо, лес, логотип и контейнер страницы.
 *
 * Общая для главной и настроек. Небо рисует v-sky-full.js (canvas,
 * закреплён), лес — четыре слоя WebP с параллаксом от мыши
 * (forest-parallax.js). Цвета и стекло — в theme.css.
 */

:root {
  --forest-height: 30vh;
  --forest-bleed: 8vw;
}

/* Полоса прокрутки появляется, когда страница вырастает при раскрытии плитки;
   без резерва под неё вся страница сдвигается на её ширину и дёргается. */
html { scrollbar-gutter: stable; }
html {
  margin: 0;
  min-height: 100%;
  /* Цвет, которым заканчивается градиент неба (#E1F6F4 в v-sky-full.js).
     Холст неба закрывает не всю высоту окна, и ниже видно этот фон;
     раньше он был заметно темнее и давал резкую горизонтальную границу. */
  background: #e1f6f4;
}

/* Static sky is used for embedded previews and reduced-power fallbacks. */
html.sky-static body,
html.sky-error body {
  background-image: linear-gradient(to top, #e1f6f4 40%, #07588a 100%);
  background-size: cover;
}

/*
  Не 400vw/400vh: в демо CodePen так «раздвигали» скролл для параллакса.
  У нас margin: 0 auto на .page центрировал в 400vw — контент уезжал в ~200vw от левого края.
*/
body {
  margin: 0;
  font-family: "Source Sans 3", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--text-main);
  background: transparent;
  width: 100%;
  max-width: 100%;
  min-height: 100vh;
  position: relative;
  overflow-x: hidden;
  z-index: 0;
  cursor: auto;
}

html[data-embedded="true"],
html[data-embedded="true"] body {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

html[data-embedded="true"] .home-logo {
  display: none;
}

a,
button,
[role="button"] {
  cursor: pointer;
}

/* Только не-canvallax canvas (если появятся) */
canvas:not(.bg-canvas) {
  display: block;
  margin: 2em;
}

.bg-canvas {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  display: block;
  pointer-events: none;
}

.home-logo {
  position: fixed;
  top: clamp(0.55rem, 1.8vw, 1rem);
  right: clamp(0.55rem, 1.8vw, 1rem);
  z-index: 40;
  display: block;
  width: clamp(14.4rem, 36vw, 25rem);
  aspect-ratio: 900 / 353;
  filter:
    drop-shadow(0 12px 32px rgba(0, 0, 0, 0.5))
    drop-shadow(0 0 18px rgba(200, 164, 90, 0.16));
  transform: translate3d(0, 0, 0);
  animation: homeLogoFloat 4.8s ease-in-out infinite;
}

.home-logo::after {
  content: "POWERED BY";
  position: absolute;
  top: calc(100% - 0.1rem);
  left: 0;
  right: 0;
  color: rgba(236, 228, 214, 0.94);
  font: 900 clamp(0.72rem, 1.55vw, 1.08rem) "Cinzel", Georgia, serif;
  letter-spacing: 0.26em;
  text-align: center;
  text-shadow:
    0 2px 14px rgba(0, 0, 0, 0.72),
    0 0 18px rgba(200, 164, 90, 0.24);
}

.home-logo__img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Слои логотипа. static — полный рисунок художника (logo-body.png).
   glasses — только сами очки, вырезанные по своим пикселям, без единого
   пикселя шерсти; при наведении едут вверх на 28 px исходника (7.93%
   высоты). eyes — глаза из второго рисунка, видны ровно в полосе, которую
   очки освобождают. Больше ничего не двигается.
   Старое имя logo-static.png осталось на диске с дырой под очками: его ещё
   просят давно открытые вкладки со старым кодом, подменять его нельзя. */
.home-logo__img--static { z-index: 1; opacity: 1; }

.home-logo__img--eyes {
  z-index: 2;
  opacity: 0;
  transition: opacity 0s linear 1400ms;
}

.home-logo:hover .home-logo__img--eyes,
.home-logo:focus-visible .home-logo__img--eyes,
.home-logo.is-logo-peeking .home-logo__img--eyes {
  opacity: 1;
  transition: opacity 0s linear 0s;
}

.home-logo__img--glasses {
  z-index: 3;
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: transform 1400ms cubic-bezier(0.2, 0.8, 0.18, 1);
}

.home-logo:hover .home-logo__img--glasses,
.home-logo:focus-visible .home-logo__img--glasses,
.home-logo.is-logo-peeking .home-logo__img--glasses {
  transform: translate3d(0, -7.93%, 0);
}

.home-logo:focus-visible {
  outline: 2px solid rgba(224, 187, 107, 0.74);
  outline-offset: 0.25rem;
  border-radius: 0.75rem;
}

@keyframes homeLogoFloat {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(-0.45deg); }
  50% { transform: translate3d(0, -0.72rem, 0) rotate(0.55deg); }
}

/* Below this width the .page (max 1040px, centered) and the floating logo
   (up to 25rem wide, pinned top-right) start overlapping the hero panel.
   Drop the logo into the normal flow at the very top so it sits ABOVE the
   hero instead of crashing into it. The logo element already comes before
   .page in the DOM, so flipping to position: relative is enough — the
   absolutely-positioned <img>s inside it stay anchored to it. */
@media (max-width: 1840px) {
  .home-logo {
    position: relative;
    top: auto;
    right: auto;
    margin: clamp(0.55rem, 1.4vw, 1rem) auto 0;
    width: clamp(11rem, 38vw, 19rem);
  }
  .home-logo::after {
    position: static;
    top: auto;
    display: block;
    margin-top: 0.4rem;
  }
}

.forest-parallax {
  position: fixed;
  left: 0;
  right: 0;
  bottom: -12px;
  height: var(--forest-height);
  z-index: 2;
  overflow: hidden;
  pointer-events: none;
  /* Затухание верхнего края запечено в сами SVG слоёв.
     CSS-маска здесь пересчитывала прозрачность на каждый кадр прокрутки и
     держала колесо на 30 fps; в картинке она растеризуется один раз. */
}

/* Слои — готовые WebP, а не SVG.
   Исходники весили 5.2 МБ векторных путей на четыре штуки, и браузер
   растеризовал их сам. По диагностике на живой машине: fps 8, худший кадр
   250 мс, при этом долгих задач ноль и обработчики по 0 мс — то есть
   JavaScript ни при чём, время уходило в отрисовку. Готовые текстуры
   весят 308 КБ и растеризации не требуют. */
.forest-parallax__layer {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(-1 * var(--forest-bleed));
  right: calc(-1 * var(--forest-bleed));
  background-repeat: repeat-x;
  background-position: left bottom;
  background-size: auto 100%;
  will-change: transform;
  transform: translate3d(0, 0, 0);
}

.forest-parallax__layer--1 {
  background-image: url("/v/assets/forest-tile-far.webp");
  filter: blur(1.4px) saturate(0.88);
}

.forest-parallax__layer--2 {
  background-image: url("/v/assets/forest-tile-mid.webp");
  filter: blur(0.95px) saturate(0.94);
}

.forest-parallax__layer--3 {
  background-image: url("/v/assets/forest-tile-mid2.webp");
  filter: blur(0.45px) saturate(1);
}

.forest-parallax__layer--4 {
  background-image: url("/v/assets/forest-tile-front.webp");
  filter: saturate(1.02);
}

/* —— Page —— */
.page {
  position: relative;
  z-index: 10;
  /* Раньше страница была зажата в 1040px и на широком мониторе висела
     узкой колонкой посередине. Теперь тянется до краёв; предел стоит лишь
     затем, чтобы на очень больших экранах строки не уезжали в бесконечность. */
  max-width: 2000px;
  margin: 0 auto;
  padding: clamp(0.85rem, 2.5vw, 1.35rem) clamp(1rem, 2.5vw, 2.5rem) clamp(1.25rem, 3vw, 2rem);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: clamp(0.9rem, 2.5vw, 1.35rem);
  transform: translateZ(0);
}

html.fx-no-forest .forest-parallax { display: none; }

@media (prefers-reduced-motion: reduce) {
  .home-logo { animation: none; }
  .forest-parallax__layer { transform: translate3d(0, 0, 0) !important; }
}

@media (hover: none) and (pointer: coarse) {
  :root { --forest-bleed: 5vw; }
}

@media (max-width: 420px) {
  :root { --forest-bleed: 5vw; }
}
