/* ============================================================================
   BubbleSMP.su
   Страница — это одно погружение. Всё оформление подчинено вертикали:
   сверху небо, внизу дно, между ними толща воды, которая темнеет по скроллу.
   ========================================================================= */

/* --------------------------------------------------------------------------
   1. Токены
   ----------------------------------------------------------------------- */
:root {
  /* Небо и вода — палитра снята с ванильных текстур Minecraft */
  --sky-1: #1a56b8;
  --sky-2: #2f83d6;
  --sky-3: #6dbdee;
  --shallow-1: #1f9ccd;      /* сама кромка воды остаётся прежней */
  --shallow-2: #1178b4;
  --shallow-3: #0a5296;
  --mid-1: #084488;
  --mid-2: #042a63;
  --deep-1: #021438;
  --deep-2: #01060f;

  /* Интерфейс: блочные панели с фасками */
  --panel: #14294b;
  --panel-2: #1b3563;
  --edge-hi: #335c98;
  --edge-lo: #0b1c38;
  --line: #071227;

  /* Акценты */
  --ice: #a8ecff;
  --gold: #ffc53d;
  --prism: #52e0d6;
  --sand: #dfcf9e;

  --text: #eaf5ff;
  --muted: #9dbcd8;
  --muted-2: #7897b5;

  /* Mojangles — настоящие глифы Minecraft, собранные из атласов клиента
     скриптом tools/fetch-mc-assets.mjs. Пока их нет, работают запасные. */
  --f-display: 'Mojangles', 'Pixelify Sans', 'Trebuchet MS', sans-serif;
  --f-pixel: 'Mojangles', 'Press Start 2P', monospace;
  --f-body: 'Mojangles', 'Rubik', 'Segoe UI', system-ui, sans-serif;

  /* Управляются скроллом из main.js */
  --depth: 0;
  --o-sky: 1;
  --o-shallow: 0;
  --o-mid: 0;
  --o-deep: 0;
  --o-rays: 0;
  --o-murk: 0;
  --o-weeds: 0;
  --o-bubbles: 0;

  --wrap: 1120px;
}

@property --rot {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

/* --------------------------------------------------------------------------
   2. База
   ----------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  background: var(--deep-2);           /* фон холста: под всеми фиксированными слоями */
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  position: relative;         /* система координат для слоя с рыбами */
  margin: 0;
  background: transparent;
  color: var(--text);
  font-family: var(--f-body);
  font-size: 16px;
  line-height: 1.55;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

body.is-locked { overflow: hidden; }

/* Системную полосу прокрутки прячем: её роль играет глубиномер справа, и
   две вертикальные шкалы рядом читались как дубль. Заодно уходит рывок
   вёрстки на ширину полосы (15 px), когда модалка ставит overflow: hidden.
   Прокрутка колесом, клавишами и пальцем не задета. Правило нарочно
   ограничено страницей — вложенным областям прокрутки полоса ещё нужна. */
html, body {
  scrollbar-width: none;        /* Firefox, Chromium 121+ */
  -ms-overflow-style: none;     /* старый Edge */
}
html::-webkit-scrollbar,
body::-webkit-scrollbar { width: 0; height: 0; }

img, svg { display: block; max-width: 100%; }
h1, h2, h3, p, dl, dd, ul { margin: 0; }
ul { padding: 0; list-style: none; }

a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 3px solid var(--ice);
  outline-offset: 3px;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: clamp(16px, 4vw, 32px);
}

.pixicon { image-rendering: pixelated; }

/* --------------------------------------------------------------------------
   3. Толща воды
   ----------------------------------------------------------------------- */
.water {
  position: fixed;
  inset: 0;
  z-index: -5;
  overflow: hidden;           /* лучи вылезают за края — не даём им растянуть документ */
  pointer-events: none;
}

.water__l {
  position: absolute;
  inset: 0;
}

/* Небо лежит поверх воды и обрезано по кромке: выше неё — небо, ниже —
   его свет, уходящий под воду. Свечение подчёркивает горизонт, но гаснет
   раньше, чем дойдёт до нижнего края экрана: у самой кромки окна оно
   складывалось с затухающей волной в белёсую полосу.
   --waterline (кромка в координатах окна) и --sky-glow (сколько свечения
   помещается под ней, не доставая до низа) считает main.js. */
.water__l--sky {
  background: linear-gradient(180deg, var(--sky-1) 0%, var(--sky-2) 52%, var(--sky-3) 86%, #9ed6f2 100%);
  opacity: var(--o-sky);
  -webkit-mask-image: linear-gradient(180deg,
    #000 0 var(--waterline, 100%),
    rgba(0, 0, 0, .62) calc(var(--waterline, 100%) + var(--sky-glow, 0px) * .25),
    rgba(0, 0, 0, .32) calc(var(--waterline, 100%) + var(--sky-glow, 0px) * .5),
    rgba(0, 0, 0, .11) calc(var(--waterline, 100%) + var(--sky-glow, 0px) * .75),
    transparent calc(var(--waterline, 100%) + var(--sky-glow, 0px)));
  mask-image: linear-gradient(180deg,
    #000 0 var(--waterline, 100%),
    rgba(0, 0, 0, .62) calc(var(--waterline, 100%) + var(--sky-glow, 0px) * .25),
    rgba(0, 0, 0, .32) calc(var(--waterline, 100%) + var(--sky-glow, 0px) * .5),
    rgba(0, 0, 0, .11) calc(var(--waterline, 100%) + var(--sky-glow, 0px) * .75),
    transparent calc(var(--waterline, 100%) + var(--sky-glow, 0px)));
}

/* Мелководье — основа под всем остальным: видно всегда, сверху его
   закрывают небо (до кромки) и более глубокие слои (по мере погружения). */
.water__l--shallow  { background: linear-gradient(180deg, var(--shallow-3) 0%, #08498b 100%); opacity: var(--o-shallow); }
.water__l--mid      { background: linear-gradient(180deg, var(--mid-1) 0%, var(--mid-2) 100%); opacity: var(--o-mid); }
.water__l--deep     { background: linear-gradient(180deg, var(--deep-1) 0%, var(--deep-2) 100%); opacity: var(--o-deep); }

/* Солнечные лучи пробиваются только у поверхности.
   Каждый луч — отдельный элемент: повторяющийся градиент давал одинаковый
   шаг и одинаковую длину, а нужен неровный ритм. */
.water__rays {
  position: absolute;
  inset: -25% -20% auto -20%;
  height: 125%;
  opacity: var(--o-rays);
  animation: rayDrift 17s ease-in-out infinite alternate;
}

.ray {
  position: absolute;
  top: 0;
  left: var(--x);
  width: var(--w);
  height: var(--h);
  background: linear-gradient(180deg,
    rgba(255, 255, 255, var(--a)) 0%,
    rgba(255, 255, 255, calc(var(--a) * .45)) 55%,
    rgba(255, 255, 255, 0) 100%);
  transform: skewX(13deg);
  animation: raySway var(--dur) ease-in-out infinite alternate;
  animation-delay: var(--delay);
}

/* Шаг между лучами, ширина и длина — все разные */
.ray--1 { --x: 4%;  --w: 46px; --h: 58%; --a: .10; --dur: 13s; --delay: -2s; }
.ray--2 { --x: 15%; --w: 30px; --h: 86%; --a: .07; --dur: 17s; --delay: -9s; }
.ray--3 { --x: 27%; --w: 64px; --h: 42%; --a: .09; --dur: 15s; --delay: -5s; }
.ray--4 { --x: 41%; --w: 38px; --h: 95%; --a: .11; --dur: 19s; --delay: -13s; }
.ray--5 { --x: 55%; --w: 54px; --h: 64%; --a: .08; --dur: 14s; --delay: -6s; }
.ray--6 { --x: 71%; --w: 34px; --h: 78%; --a: .10; --dur: 21s; --delay: -16s; }
.ray--7 { --x: 86%; --w: 58px; --h: 50%; --a: .07; --dur: 16s; --delay: -3s; }

@keyframes raySway {
  from { transform: skewX(15deg) translateX(-10px); }
  to   { transform: skewX(10deg) translateX(10px); }
}

/* Виньетка: чем глубже, тем плотнее сжимается видимость */
.water__murk {
  position: absolute;
  inset: 0;
  opacity: var(--o-murk);
  background: radial-gradient(125% 95% at 50% 22%, transparent 28%, rgba(1,8,18,.55) 72%, rgba(1,6,14,.9) 100%);
}

@keyframes rayDrift {
  from { transform: translateX(-3%) skewX(-1deg); }
  to   { transform: translateX(3%) skewX(2deg); }
}

/* --------------------------------------------------------------------------
   4. Пузыри, рыбы, водоросли
   ----------------------------------------------------------------------- */

/* Пузырьковые колонны идут поверх интерфейса: под водой они между
   зрителем и всем остальным. Держатся у самых краёв экрана. */
.bubbles {
  position: fixed;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  opacity: var(--o-bubbles);
  transition: opacity .5s ease;
  pointer-events: none;
}

/* Слой с рыбами привязан к странице, а не к окну: рыба остаётся там,
   где появилась, и прокрутка проносит нас мимо неё. Появляются они
   только ниже линии воды, поэтому гасить слой по глубине не нужно. */
.fishtank {
  position: absolute;
  inset: 0;
  z-index: -3;
  overflow: hidden;
  pointer-events: none;
}

.fish {
  position: absolute;
  top: var(--top);
  left: 0;
  opacity: var(--fade, .8);
  animation: swim var(--dur, 30s) linear forwards;
  will-change: transform;
}

.fish--still { animation: none; }
.fish--glow { filter: drop-shadow(0 0 10px rgba(64, 232, 220, .55)); }

.fish__body {
  animation: bob var(--bobdur, 2s) ease-in-out infinite alternate;
}

.fish__svg {
  image-rendering: pixelated;
  /* tilt доворачивает диагональную предметную иконку до горизонтали,
     scaleX затем разворачивает рыбу по направлению движения */
  transform: scaleX(var(--face, 1)) rotate(var(--tilt, 0deg)) scale(var(--scale, 1));
  transform-origin: center;
}

/* Ход по диагонали: за время пути рыба смещается по вертикали на --dy */
@keyframes swim {
  from { transform: translate(var(--from, -24vw), 0); }
  to   { transform: translate(var(--to, 112vw), var(--dy, 0px)); }
}

@keyframes bob {
  from { transform: translateY(calc(var(--bob, 4px) * -1)); }
  to   { transform: translateY(var(--bob, 4px)); }
}

/* Тёмные силуэты водорослей в нижних углах — дно чувствуется раньше, чем видно */
.weeds {
  position: fixed;
  inset: auto 0 0 0;
  z-index: -2;
  height: 260px;
  opacity: var(--o-weeds);
  pointer-events: none;
  filter: brightness(.32) saturate(.5);
}

.weeds__side {
  position: absolute;
  bottom: -40px;
  width: min(240px, 26vw);
  height: 100%;
}

.weeds__side--l { left: 0; }
.weeds__side--r { right: 0; transform: scaleX(-1); }

/* --------------------------------------------------------------------------
   5. Ламинария и живность (общие правила для дна и краёв)
   ----------------------------------------------------------------------- */
.kelp {
  position: absolute;
  bottom: 0;
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  transform-origin: bottom center;
  animation: sway var(--sway, 3s) ease-in-out infinite alternate;
  animation-delay: var(--delay, 0s);
}

.kelp--ghost { bottom: 40px; }

.kelp__seg {
  display: block;
  line-height: 0;
  transform: scaleX(var(--flip, 1));
}

.kelp__seg .pixicon { image-rendering: pixelated; }

@keyframes sway {
  from { transform: rotate(-4deg) scale(var(--k, 1)); }
  to   { transform: rotate(4deg) scale(var(--k, 1)); }
}

.coral {
  position: absolute;
  bottom: 0;
  line-height: 0;
  transform-origin: bottom center;
  animation: sway 4.4s ease-in-out infinite alternate;
  animation-delay: var(--delay, 0s);
}

.critter { position: absolute; line-height: 0; }

.critter--turtle {
  bottom: 0;
  left: 7%;
  animation: bob 3.2s ease-in-out infinite alternate;
  --bob: 3px;
}

/* --------------------------------------------------------------------------
   6. Приборная панель ныряльщика
   ----------------------------------------------------------------------- */
.hud {
  position: fixed;
  right: clamp(14px, 2.4vw, 30px);
  top: 50%;
  z-index: 6;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  opacity: 0;
  transition: opacity .45s ease;
  pointer-events: none;
}

/* Пока приборка скрыта, ловить по ней клики нельзя */
body.is-submerged .hud { opacity: 1; pointer-events: auto; }

.hud__gauge {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.hud__rail {
  position: relative;
  width: 14px;
  height: min(260px, 30vh);
  padding: 0;
  background: rgba(4, 20, 38, .55);
  border: 2px solid rgba(168, 236, 255, .35);
  cursor: pointer;
  touch-action: none;              /* перетаскивание не должно листать страницу */
  transition: border-color .15s, box-shadow .15s;
}

.hud__rail:hover,
.hud__rail:focus-visible {
  border-color: var(--ice);
  box-shadow: 0 0 0 3px rgba(168, 236, 255, .22);
}

.hud__fill {
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--fill, 0%);
  background: linear-gradient(180deg, var(--ice), var(--prism));
}

.hud__read {
  font-family: var(--f-pixel);
  font-size: 16px;
  color: var(--ice);
  text-shadow: 0 2px 0 rgba(2, 12, 26, .8);
  white-space: nowrap;
}

.hud__unit { opacity: .65; margin-left: 3px; }

/* Полоска кислорода: пузырьки лопаются по мере погружения */
.hud__oxygen {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 3px;
}

.oxy {
  width: 9px;
  height: 9px;
  background: #dff6ff;
  box-shadow: inset -2px -2px 0 rgba(60, 140, 190, .8), 0 0 0 2px rgba(4, 20, 38, .5);
  transition: opacity .25s steps(2), transform .25s steps(2);
}

.oxy.is-empty {
  opacity: .28;
  transform: scale(.62);
}

.oxy:hover,
.oxy:focus-visible {
  opacity: 1;
  transform: scale(1.18);
}

/* --------------------------------------------------------------------------
   7. Шапка
   ----------------------------------------------------------------------- */
.topbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 8;
  display: flex;
  align-items: center;
  gap: clamp(12px, 3vw, 28px);
  padding: 10px clamp(14px, 4vw, 30px);
  background: #071428;
  border-bottom: 3px solid var(--line);
  box-shadow: inset 0 3px 0 rgba(80, 130, 190, .25);
  transform: translateY(-110%);
  transition: transform .35s ease;
}

body.is-submerged .topbar { transform: translateY(0); }

/* Знак и логотип — фирменные изображения: не выделяются и не таскаются */
.topbar__mark { line-height: 0; }

.navmark-svg,
.logo-svg {
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;      /* клик достаётся ссылке, а не картинке */
}
.navmark-svg { width: auto; height: 34px; image-rendering: pixelated; }

.topbar__nav {
  display: flex;
  gap: clamp(10px, 2.4vw, 26px);
  margin-right: auto;
  font-family: var(--f-display);
  font-size: 16px;
  font-weight: 600;
}

.topbar__nav a {
  color: var(--muted);
  padding: 4px 2px;
  border-bottom: 3px solid transparent;
  transition: color .15s, border-color .15s;
}

.topbar__nav a:hover { color: var(--ice); border-bottom-color: var(--prism); }

/* --------------------------------------------------------------------------
   8. Панели и кнопки — общий блочный стиль
   ----------------------------------------------------------------------- */
.panel {
  position: relative;
  background: var(--panel);
  border: 4px solid var(--line);
  box-shadow:
    inset 4px 4px 0 var(--edge-hi),
    inset -4px -4px 0 var(--edge-lo),
    0 6px 0 rgba(2, 10, 22, .45);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--f-display);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.1;
  color: var(--text);
  background: #2a5da0;
  border: 3px solid var(--line);
  box-shadow:
    inset 3px 3px 0 #4b83cf,
    inset -3px -3px 0 #17376b,
    0 4px 0 rgba(2, 10, 22, .5);
  padding: .68em 1.3em;
  white-space: nowrap;        /* подпись кнопки не должна переноситься */
  cursor: pointer;
  transition: filter .15s ease, transform .07s steps(1);
}

.btn:hover { filter: brightness(1.14); }

.btn:active {
  transform: translateY(3px);
  box-shadow:
    inset 3px 3px 0 #4b83cf,
    inset -3px -3px 0 #17376b,
    0 1px 0 rgba(2, 10, 22, .5);
}

.btn--buy {
  background: #17836f;
  box-shadow:
    inset 3px 3px 0 #34b79b,
    inset -3px -3px 0 #0c5346,
    0 4px 0 rgba(2, 10, 22, .5);
}

.btn--buy:active {
  box-shadow:
    inset 3px 3px 0 #34b79b,
    inset -3px -3px 0 #0c5346,
    0 1px 0 rgba(2, 10, 22, .5);
}

.btn--gold {
  background: #d99a15;
  color: #2a1c00;
  box-shadow:
    inset 3px 3px 0 #ffd463,
    inset -3px -3px 0 #92640a,
    0 4px 0 rgba(2, 10, 22, .5);
}

.btn--gold:active {
  box-shadow:
    inset 3px 3px 0 #ffd463,
    inset -3px -3px 0 #92640a,
    0 1px 0 rgba(2, 10, 22, .5);
}

.btn--ghost {
  background: rgba(12, 30, 58, .7);
  box-shadow:
    inset 3px 3px 0 rgba(90, 140, 200, .4),
    inset -3px -3px 0 rgba(4, 14, 30, .8),
    0 4px 0 rgba(2, 10, 22, .4);
}

.btn--ghost:active {
  box-shadow:
    inset 3px 3px 0 rgba(90, 140, 200, .4),
    inset -3px -3px 0 rgba(4, 14, 30, .8),
    0 1px 0 rgba(2, 10, 22, .4);
}

.btn--wide { width: 100%; }

.btn--ip {
  flex-direction: column;
  gap: 2px;
  padding: .5em .9em;
}

.btn__ip {
  font-family: var(--f-pixel);
  font-size: 16px;
  letter-spacing: 0;
}

.btn__hint {
  font-family: var(--f-body);
  font-size: .7rem;
  color: var(--muted);
  line-height: 1;
}

/* --------------------------------------------------------------------------
   9. Небо и первый экран
   ----------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(80px, 12vh, 130px) clamp(16px, 4vw, 32px) clamp(345px, 40vh, 430px);
  text-align: center;
}

.sky {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  opacity: var(--o-sky);
  /* Своя система слоёв: иначе z-index облаков считается наравне с
     содержимым героя и они проходят поверх текста */
  isolation: isolate;
  z-index: 0;
}

/* Солнце в Minecraft — обычный квадрат. Уводим его в сторону:
   по центру оно засвечивает логотип и надзаголовок. */
.sun {
  position: absolute;
  z-index: 1;                 /* облака проходят поверх — см. .cloud */
  top: 6%;
  left: 17%;
  width: 84px;
  height: 84px;
  background: #fffbe8;
  box-shadow:
    0 0 0 12px rgba(255, 251, 220, .18),
    0 0 90px 44px rgba(255, 245, 190, .42);
}

/* Облака — плоские плиты, как в игре. Идут выше солнца, поэтому
   проплывают поверх него и гасят его свечение. */
.cloud {
  position: absolute;
  z-index: 2;
  left: 0;
  background: #ffffff;
  box-shadow: 0 9px 0 rgba(198, 224, 246, .95);
  animation: drift linear infinite;
}

.cloud--1 { width: 232px; height: 26px; top: 4%;  animation-duration: 78s;  animation-delay: -12s; }
.cloud--2 { width: 148px; height: 20px; top: 10%; animation-duration: 104s; animation-delay: -60s; opacity: .95; }
.cloud--3 { width: 300px; height: 30px; top: 7%;  animation-duration: 92s;  animation-delay: -34s; opacity: .9; }
.cloud--4 { width: 120px; height: 18px; top: 13%; animation-duration: 120s; animation-delay: -88s; opacity: .85; }
.cloud--5 { width: 196px; height: 22px; top: 2%;  animation-duration: 110s; animation-delay: -20s; opacity: .8; }
.cloud--6 { width: 264px; height: 24px; top: 12%; animation-duration: 86s;  animation-delay: -48s; opacity: .92; }
.cloud--7 { width: 172px; height: 18px; top: 6%;  animation-duration: 132s; animation-delay: -104s; opacity: .78; }
.cloud--8 { width: 132px; height: 16px; top: 15%; animation-duration: 98s;  animation-delay: -70s; opacity: .72; }

@keyframes drift {
  from { transform: translateX(-340px); }
  to   { transform: translateX(calc(100vw + 340px)); }
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(20px, 2.8vh, 30px);
  width: 100%;
}

/* До подстановки SVG внутри лежит обычный текст — он и служит фолбэком,
   если скрипты не загрузились. Блочный SVG вытесняет его целиком. */
.hero__logo {
  width: min(880px, 94vw);
  margin: 0;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: clamp(2.2rem, 8vw, 5rem);
  line-height: 1;
  text-transform: uppercase;
  color: var(--ice);
  text-shadow: 0 6px 0 rgba(6, 32, 66, .8);
  animation: floatLogo 6s ease-in-out infinite alternate;
}

.logo-svg {
  width: 100%;
  height: auto;
  image-rendering: pixelated;
  filter: drop-shadow(0 10px 0 rgba(6, 26, 52, .28));
}

@keyframes floatLogo {
  from { transform: translateY(-5px); }
  to   { transform: translateY(5px); }
}

.hero__lead {
  max-width: 44ch;
  font-size: 16px;
  color: #ffffff;
  text-shadow: 0 3px 0 rgba(6, 32, 66, .72);
}

/* Карточка IP — главный призыв к действию на первом экране */
.ipcard {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  padding: 0;
  overflow: hidden;
}

.ipcard__ip {
  display: flex;
  align-items: center;
  gap: 12px;
  white-space: nowrap;
  padding: 14px clamp(14px, 3vw, 24px);
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  font: inherit;
  transition: background .15s;
}

.ipcard__ip:hover { background: rgba(90, 160, 230, .16); }

.ipcard__label {
  font-family: var(--f-pixel);
  font-size: 16px;
  color: var(--muted);
}

.ipcard__value {
  font-family: var(--f-pixel);
  font-size: 20px;
  color: var(--ice);
  letter-spacing: .02em;
}

.ipcard__copy {
  font-size: .82rem;
  color: var(--prism);
  border-bottom: 2px solid rgba(82, 224, 214, .4);
}

.online {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px clamp(14px, 3vw, 22px);
  border-left: 4px solid var(--line);
  background: rgba(6, 18, 38, .5);
  font-size: .95rem;
  color: var(--muted);
  white-space: nowrap;
}

.online b {
  font-family: var(--f-pixel);
  font-size: 24px;
  color: #7df08a;
}

.ipcard__label,
.ipcard__value,
.ipcard__copy,
.online,
.online b,
.hud__read,
.depth-label,
.price__rub,
.pack__amount,
.btn__ip { line-height: 1; }

.online__dot {
  flex: none;
  align-self: center;
  width: 9px;
  height: 9px;
  background: #7df08a;
  box-shadow: 0 0 0 3px rgba(125, 240, 138, .18);
  animation: pulse 2.4s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .35; }
}

.hero__meta {
  font-size: .88rem;
  color: rgba(255, 255, 255, .92);
  text-shadow: 0 3px 0 rgba(6, 32, 66, .62);
}

.dive {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  margin-top: clamp(6px, 2vh, 22px);
  font-family: var(--f-pixel);
  font-size: 16px;
  letter-spacing: 0;
  text-transform: uppercase;
  color: #ffffff;
  text-shadow: 0 3px 0 rgba(5, 24, 52, .95), 0 0 14px rgba(5, 24, 52, .55);
}

.dive__arrow {
  line-height: 0;
  animation: nudge 1.9s ease-in-out infinite;
}

.dive:hover .dive__arrow { animation-duration: 1s; }

@keyframes nudge {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(7px); }
}

/* Граница двух миров. Полоса длинная и гаснет постепенно: если оборвать
   её резко, на стыке с фоном страницы видна горизонтальная линия. */
.surface {
  position: absolute;
  inset: auto 0 0 0;
  height: 320px;
  pointer-events: none;
}

.surface__foam {
  position: absolute;
  inset: auto 0 auto 0;
  top: 0;
  height: 16px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='16' shape-rendering='crispEdges'%3E%3Crect x='0' y='8' width='8' height='8' fill='%23ffffff'/%3E%3Crect x='8' y='4' width='8' height='12' fill='%23ffffff'/%3E%3Crect x='16' y='0' width='8' height='16' fill='%23ffffff'/%3E%3Crect x='24' y='4' width='8' height='12' fill='%23ffffff'/%3E%3Crect x='32' y='8' width='8' height='8' fill='%23ffffff'/%3E%3Crect x='40' y='4' width='8' height='12' fill='%23ffffff'/%3E%3Crect x='48' y='0' width='8' height='16' fill='%23ffffff'/%3E%3Crect x='56' y='4' width='8' height='12' fill='%23ffffff'/%3E%3C/svg%3E") repeat-x;
  background-size: 128px 16px;
  opacity: .9;
  animation: foamShift 9s linear infinite;
}

/* Настоящая текстура воды на поверхности. Лента кадров тайлится только
   по горизонтали (repeat-x), поэтому по вертикали видно ровно один кадр;
   три полосы с разной задержкой дают живую рябь. */
.surface .surface__tex {
  --mc-size: 64px;
  position: absolute;
  left: 0;
  right: 0;
  height: var(--mc-size);
  /* Лента кадров тайлится только по горизонтали, иначе по вертикали
     встали бы все 32 кадра подряд. Правило должно перебить animated.css,
     поэтому селектор с дополнительным предком. */
  background-repeat: repeat-x;
  opacity: .55;
  mix-blend-mode: overlay;
  pointer-events: none;
}

.surface .surface__tex--1 { top: 12px; }
.surface .surface__tex--2 { top: calc(12px + var(--mc-size)); animation-delay: -1.1s; opacity: .44; }
.surface .surface__tex--3 { top: calc(12px + var(--mc-size) * 2); animation-delay: -2.2s; opacity: .32; }

/* Последние полосы растворяются, чтобы фактура не обрывалась ступенькой */
.surface .surface__tex--4 {
  top: calc(12px + var(--mc-size) * 3);
  animation-delay: -0.6s;
  opacity: .2;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, transparent 100%);
}

.surface__wave {
  position: absolute;
  inset: 12px 0 0 0;
  background: linear-gradient(180deg, var(--shallow-1) 0%, var(--shallow-2) 42%, var(--shallow-3) 100%);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 90%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, #000 90%, transparent 100%);
}

/* Рыбак на плоту. Низ картинки уходит на 36px ниже кромки воды: плот
   слегка утоплен, а поплавок оказывается на самой поверхности. */
.angler {
  position: absolute;
  right: clamp(12px, 6vw, 110px);
  bottom: calc(100% - 132px);  /* ниже кромки: плот ближе к зрителю */
  width: clamp(150px, 17vw, 240px);
  animation: raft 5.2s ease-in-out infinite alternate;
  pointer-events: none;
}

.angler__img {
  display: block;
  width: 100%;
  height: auto;
  image-rendering: pixelated;
  -webkit-user-drag: none;
  user-select: none;
  filter: drop-shadow(0 6px 0 rgba(4, 30, 52, .28));
}

@keyframes raft {
  from { transform: translateY(-4px) rotate(-.6deg); }
  to   { transform: translateY(4px) rotate(.6deg); }
}

/* Круги от поплавка. Он приходится на 6.9% ширины и 88.8% высоты картинки —
   координаты сняты по красным пикселям самого поплавка. */
.ripple {
  position: absolute;
  left: 6.9%;
  top: 88.8%;
  width: 26px;
  height: 11px;
  margin: -5.5px 0 0 -13px;
  border: 2px solid rgba(214, 245, 255, .6);
  border-radius: 50%;
  opacity: 0;
  animation: ripple 3.6s linear infinite;
}

.ripple--2 { animation-delay: 1.2s; }
.ripple--3 { animation-delay: 2.4s; }

@keyframes ripple {
  0%   { transform: scale(.35); opacity: 0; }
  12%  { opacity: .7; }
  100% { transform: scale(3.4); opacity: 0; }
}

@keyframes foamShift {
  from { background-position-x: 0; }
  to   { background-position-x: 128px; }
}

/* --------------------------------------------------------------------------
   10. Секции
   ----------------------------------------------------------------------- */
.section {
  position: relative;
  padding-block: clamp(72px, 12vh, 132px);
  scroll-margin-top: 72px;              /* переход по якорю не должен нырять под шапку */
}

.section__title {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: clamp(28px, 4.4vw, 48px);
  line-height: 1.02;
  text-transform: uppercase;
  letter-spacing: .01em;
  text-align: center;
  text-shadow: 0 5px 0 rgba(3, 14, 30, .55);
  margin-bottom: 14px;
}

.section__lead {
  max-width: 56ch;
  margin: 0 auto clamp(34px, 5vh, 54px);
  text-align: center;
  color: #d9ecfb;                       /* текст лежит прямо на воде — нужен запас контраста */
  font-size: 16px;
  text-shadow: 0 2px 0 rgba(4, 28, 58, .55);
}

.section__note {
  margin-top: 26px;
  text-align: center;
  color: #c3dcf0;
  font-size: .88rem;
  text-shadow: 0 2px 0 rgba(4, 28, 58, .5);
}

/* Надзаголовок секции — её настоящая глубина. Совпадает с глубиномером справа. */
.depth-label {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  margin-bottom: 16px;
  font-family: var(--f-pixel);
  font-size: 16px;
  letter-spacing: 0;
  color: var(--prism);
}

.depth-label::before {
  content: '';
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 7px solid currentColor;
}

.depth-label__unit { opacity: .6; }
.depth-label--floor { color: var(--sand); margin-bottom: 34px; }

.grid { display: grid; gap: clamp(14px, 2vw, 22px); }
.grid--ranks { grid-template-columns: repeat(auto-fit, minmax(min(272px, 100%), 1fr)); }
/* Две колонки: под широким кейсом с привилегиями — шарды и валюта в ряд */
.grid--cases { grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); }
.grid--packs { grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr)); }

/* Появление сделано анимацией, а не переходом. Переход тут проигрывал:
   у .portal есть свой `transition` для наведения, он объявлен ниже и с той
   же специфичностью — и целиком перебивал переход появления, отчего
   оглавление возникало рывком, без проявления. Анимация лежит в каскаде
   отдельно и ничьему `transition` не мешает.
   Заливка `backwards`, а не `both`: после проигрывания анимация перестаёт
   навязывать `transform`, и подъём карточки под курсором снова работает. */
[data-reveal] { opacity: 0; }

[data-reveal].is-in {
  opacity: 1;
  animation: reveal .5s ease var(--reveal-delay, 0ms) backwards;
}

@keyframes reveal {
  from { opacity: 0; transform: translateY(22px); }
}

/* --------------------------------------------------------------------------
   11. Три двери вниз
   ----------------------------------------------------------------------- */
.portals {
  display: grid;
  gap: 16px;
  max-width: 760px;
  margin-inline: auto;
}

.portal {
  display: flex;
  align-items: center;
  gap: clamp(14px, 3vw, 22px);
  padding: clamp(16px, 3vw, 22px);
  transition: transform .16s ease, filter .16s ease;
}

.portal:hover {
  transform: translateY(-4px);
  filter: brightness(1.1);
}

.portal:active { transform: translateY(0); }

.portal__icon {
  flex: none;
  line-height: 0;
  filter: drop-shadow(0 4px 0 rgba(3, 14, 30, .5));
}

.portal__icon--gold   { filter: drop-shadow(0 0 14px rgba(255, 197, 61, .35)) drop-shadow(0 4px 0 rgba(3, 14, 30, .5)); }
.portal__icon--violet { filter: drop-shadow(0 0 14px rgba(150, 100, 220, .35)) drop-shadow(0 4px 0 rgba(3, 14, 30, .5)); }
.portal__icon--cyan   { filter: drop-shadow(0 0 14px rgba(82, 224, 214, .4)) drop-shadow(0 4px 0 rgba(3, 14, 30, .5)); }

.portal__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.portal__title {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: clamp(20px, 2.4vw, 28px);
  text-transform: uppercase;
  line-height: 1.1;
}

.portal__desc {
  color: var(--muted);
  font-size: 16px;
  line-height: 1.45;
}

.portal__from {
  margin-top: 4px;
  font-family: var(--f-pixel);
  font-size: 16px;
  color: var(--gold);
}

.portal__go {
  flex: none;
  margin-left: auto;
  line-height: 0;
  transition: transform .16s ease;
}

.portal:hover .portal__go { transform: translateX(5px); }

/* --------------------------------------------------------------------------
   12. Привилегии
   ----------------------------------------------------------------------- */
.rank {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: clamp(18px, 2.4vw, 24px);
  border-top: 4px solid var(--tint);
}

.rank__flag {
  position: absolute;
  top: -14px;
  right: 12px;
  padding: 5px 9px;
  background: var(--gold);
  color: #2b1c00;
  border: 3px solid var(--line);
  font-family: var(--f-pixel);
  font-size: 16px;
  letter-spacing: 0;
}

.rank__head {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

/* Шлем — знак привилегии. Кожаный в игре окрашиваемый: его базовый слой
   серый, поэтому умножаем на стандартный кожаный цвет, а накладку
   с ремешком кладём поверх без подкраски. */
.helm {
  display: block;
  width: 80px;
  height: 80px;
  margin: 0 auto 8px;         /* знак привилегии стоит по центру карточки */
  background-repeat: no-repeat;
  background-size: 100% 100%;
  image-rendering: pixelated;
  filter: drop-shadow(0 4px 0 rgba(3, 14, 30, .5));
}

/* Кожаный: базовый слой серый и красится цветом. Просто залить фон нельзя —
   цвет проступит и там, где текстура прозрачна, поэтому подкрашенный слой
   обрезаем маской по самой текстуре. Накладку с ремешком кладём поверх. */
.helm--1 {
  position: relative;
  background-image: url("../textures/mc/helm_1_overlay.png");
}

.helm--1::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: #a06540;
  background-image: url("../textures/mc/helm_1.png");
  background-size: 100% 100%;
  background-blend-mode: multiply;
  -webkit-mask: url("../textures/mc/helm_1.png") no-repeat center / 100% 100%;
  mask: url("../textures/mc/helm_1.png") no-repeat center / 100% 100%;
}

.helm--2 { background-image: url("../textures/mc/helm_2.png"); }
.helm--3 { background-image: url("../textures/mc/helm_3.png"); }
.helm--4 { background-image: url("../textures/mc/helm_4.png"); }
.helm--5 { background-image: url("../textures/mc/helm_5.png"); }
.helm--6 { background-image: url("../textures/mc/helm_6.png"); }
.helm--7 { background-image: url("../textures/mc/helm_7.png"); }
.helm--8 { background-image: url("../textures/mc/helm_8.png"); }

/* Имя пишется тем же цветом, что и префикс в игре. Тень нужна: часть
   цветов (тот же синий у PRO) на тёмной призмариновой подложке иначе
   теряет контраст. */
.rank__name {
  display: flex;
  align-items: center;   /* по базовой линии подстрочный «₊» у PLUS уезжал вниз */
  gap: 8px;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 28px;
  line-height: 1.05;
  text-transform: uppercase;
  color: var(--tint);
  text-shadow: 0 0 12px rgba(255, 255, 255, .16), 0 2px 0 rgba(3, 14, 30, .55);
}

/* Значок ступени — ячейка вроде инвентарной: тёмное гнездо с рамкой в цвете
   привилегии. Глифы в игровых префиксах несопоставимы по кеглю (★ ✦ ₊ ●):
   кружок огромный, подстрочный плюс крошечный. Поэтому размер выравнивается
   множителем --mark-scale у каждой ступени, а не подбором других символов. */
.rank__badge {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  font-size: var(--mark-fs, 23px);
  line-height: 1;
  color: var(--tint);
  background: rgba(4, 20, 38, .55);
  border: 3px solid var(--tint);
  box-shadow:
    inset 2px 2px 0 rgba(255, 255, 255, .14),
    inset -2px -2px 0 rgba(2, 10, 22, .5);
  text-shadow: none;
}

/* Сдвиг вешаем на вложенный элемент: у текстового узла его не задать */
.rank__badge > i,
.rank__mark > i {
  display: block;
  font-style: normal;
  transform: translateY(var(--mark-dy, 0));
}

/* В строке выпадения ячейка была бы тяжеловата — там просто глиф */
.rank__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  font-size: var(--mark-fs, 16px);
  line-height: 1;
}

/* У LEGEND и ELITE префикс в игре залит градиентом — повторяем.
   Заливка по тексту работает не везде, поэтому включаем её только там,
   где она поддерживается: иначе имя осталось бы прозрачным. */
.rank__name--grad .rank__label {
  background-image: linear-gradient(100deg, var(--g1), var(--g2) 52%, var(--g3));
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .rank__name--grad .rank__label {
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    text-shadow: none;
    filter: drop-shadow(0 2px 0 rgba(3, 14, 30, .55));
  }
}

.rank__blurb { color: var(--muted); font-size: .92rem; }

/* Список идёт сразу за шапкой. Прижимать его вниз (margin-top: auto)
   было можно, пока у всех ступеней было поровну строк; теперь их от двух
   до семи, и у коротких между именем и списком зиял провал. Свободное
   место собирается ниже — его забирает подвал с ценами. */
.rank__perks {
  display: flex;
  flex-direction: column;
  gap: 9px;
  font-size: 16px;
  color: #d5e7f7;
}

.rank__perks li {
  display: flex;
  gap: 9px;
  line-height: 1.4;
}

.rank__perks li::before {
  content: '';
  flex: none;
  width: 8px;
  height: 8px;
  margin-top: 4px;
  background: var(--tint);
  box-shadow: inset -2px -2px 0 rgba(0, 0, 0, .35);
}

/* Три срока — три кнопки в ряд: все цены видны сразу, без переключателя,
   и каждая кнопка сама несёт свой срок в окно оформления. */
.rank__foot {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin-top: auto;
  padding-top: 16px;
  border-top: 3px solid rgba(120, 170, 225, .18);
}

.btn--period {
  flex-direction: column;
  gap: 3px;
  padding: .55em .4em;
}

.btn__period {
  font-family: var(--f-body);
  font-size: .74rem;
  font-weight: 400;
  opacity: .82;
}

.btn__price {
  font-family: var(--f-pixel);
  font-size: 15px;
  line-height: 1;
}

.price { display: flex; flex-direction: column; gap: 2px; }

.price__rub {
  font-family: var(--f-pixel);
  font-size: 24px;
  color: var(--gold);
}

/* --------------------------------------------------------------------------
   13. Кейсы
   ----------------------------------------------------------------------- */
.case {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: clamp(18px, 2.4vw, 24px);
  border-top: 4px solid var(--tint);
}

.case__top { display: flex; align-items: center; gap: 16px; }

.case__icon {
  flex: none;
  line-height: 0;
  filter: drop-shadow(0 4px 0 rgba(3, 14, 30, .5));
}

.case__name {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 24px;
  line-height: 1.1;
  text-transform: uppercase;
  color: var(--tint);
}

.case__hint { font-size: .84rem; color: var(--muted-2); }

.case__loot {
  display: flex;
  flex-direction: column;
  gap: 7px;
  font-size: 16px;
  color: #d5e7f7;
}

.case__loot li { display: flex; gap: 9px; }

.case__loot li::before {
  content: '';
  flex: none;
  width: 8px;
  height: 8px;
  margin-top: 4px;
  background: var(--tint);
  box-shadow: inset -2px -2px 0 rgba(0, 0, 0, .35);
}

/* Кейс с привилегиями — на всю ширину, шарды и валюта — под ним в ряд */
.case--wide { grid-column: 1 / -1; gap: 22px; }

.drops {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.drop {
  display: grid;
  grid-template-columns: minmax(0, 11rem) 1fr auto;
  align-items: center;
  gap: 14px;
}

/* Цвет — игровой, менять его нельзя, поэтому читаемость на текстурной
   подложке вытягиваем тёмным ореолом, а не подкраской. */
.drop__name {
  font-family: var(--f-display);
  font-size: 16px;
  color: var(--tint);
  text-shadow: 0 0 7px rgba(2, 10, 22, .95), 0 2px 0 rgba(3, 14, 30, .7);
}

/* Здесь строка не флексовая, поэтому отступ у значка свой */
.drop__name .rank__mark { margin-right: 6px; font-size: .85em; }

.drop__bar {
  height: 12px;
  background: #0a1c36;
  border: 3px solid var(--line);
}

.drop__fill {
  display: block;
  height: 100%;
  background: var(--tint);
  box-shadow: inset 0 -3px 0 rgba(0, 0, 0, .3);
}

.drop__chance {
  font-family: var(--f-pixel);
  font-size: 16px;
  line-height: 1;
  color: var(--ice);
  min-width: 4.5rem;
  text-align: right;
}

.odds { margin-top: auto; }

.odds__bar {
  display: flex;
  height: 14px;
  border: 3px solid var(--line);
  background: #0a1c36;
  overflow: hidden;
}

.odds__seg--0 { background: #8fa5bb; }
.odds__seg--1 { background: #56b7f0; }
.odds__seg--2 { background: #a877ee; }
.odds__seg--3 { background: #ffc53d; }

.odds__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: 10px;
  font-size: .78rem;
  color: var(--muted);
}

.odds__legend li { display: flex; align-items: center; gap: 6px; }
.odds__legend b { color: #dfeeff; font-weight: 500; }

.odds__dot {
  width: 9px;
  height: 9px;
  box-shadow: inset -2px -2px 0 rgba(0, 0, 0, .35);
}

/* В кейсе и наборах шардов кнопка шире обычного: туда попадают
   и название, и цена, и они не должны обрезаться */
.case__foot .btn { min-width: 190px; }

.case__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding-top: 16px;
  border-top: 3px solid rgba(120, 170, 225, .18);
}

/* --------------------------------------------------------------------------
   14. Шарды
   ----------------------------------------------------------------------- */
.pack {
  display: flex;
  min-width: 0;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: clamp(18px, 2.4vw, 22px) 16px;
  text-align: center;
}

.pack--best {
  border-color: #0d2b4f;
  box-shadow:
    inset 4px 4px 0 #3f6fb4,
    inset -4px -4px 0 var(--edge-lo),
    0 0 0 3px rgba(82, 224, 214, .35),
    0 6px 0 rgba(2, 10, 22, .45);
}

.pack__tag {
  position: absolute;
  top: -13px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  padding: 5px 9px;
  background: var(--prism);
  color: #04302c;
  border: 3px solid var(--line);
  font-family: var(--f-pixel);
  font-size: 16px;
  letter-spacing: 0;
}

.pack__icon {
  line-height: 0;
  filter: drop-shadow(0 0 12px rgba(82, 224, 214, .45));
  animation: bob 2.8s ease-in-out infinite alternate;
  --bob: 3px;
}

.pack__amount {
  font-family: var(--f-pixel);
  font-size: 24px;
  color: var(--ice);
}

.pack__unit {
  margin-top: -4px;
  font-size: .84rem;
  color: var(--muted);
}

.pack__rate {
  margin-bottom: 6px;
  font-size: .76rem;
  color: var(--muted-2);
}

.pack .btn { margin-top: auto; padding-inline: .8em; }

/* --------------------------------------------------------------------------
   15. Дно
   ----------------------------------------------------------------------- */
.seabed {
  position: relative;
  padding-top: clamp(90px, 14vh, 160px);
  padding-bottom: 470px;      /* подвал должен стоять выше ламинарии */
  overflow: hidden;
}

.seabed__scene {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* Толща воды над дном: без неё песок и камень светятся как на суше */
.seabed__scene::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 460px;
  background: linear-gradient(180deg,
    rgba(8, 52, 96, 0) 0%,
    rgba(8, 52, 96, .16) 34%,
    rgba(6, 42, 82, .24) 72%,
    rgba(5, 34, 68, .26) 100%);
  pointer-events: none;
}

.seabed__life {
  position: absolute;
  inset: auto 0 242px 0;      /* корни уходят в песок: грунт рисуется поверх */
  height: 200px;
}

/* Три слоя грунта по 48px — ровно блок игры в масштабе 3x */
.seabed__ground {
  position: absolute;
  inset: auto 0 0 0;
  height: 256px;
}

.seabed__sand,
.seabed__gravel,
.seabed__stone {
  position: absolute;
  left: 0;
  right: 0;
  background-repeat: repeat;
}

.seabed__sand {
  top: 0;
  height: 128px;              /* два блока песка */
  background-color: var(--sand);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' shape-rendering='crispEdges'%3E%3Crect x='3' y='2' width='3' height='3' fill='%23000' opacity='.07'/%3E%3Crect x='14' y='6' width='2' height='2' fill='%23fff' opacity='.28'/%3E%3Crect x='8' y='13' width='3' height='2' fill='%23000' opacity='.06'/%3E%3Crect x='19' y='17' width='3' height='3' fill='%23000' opacity='.08'/%3E%3Crect x='2' y='19' width='2' height='2' fill='%23fff' opacity='.22'/%3E%3Crect x='17' y='2' width='2' height='2' fill='%23000' opacity='.05'/%3E%3C/svg%3E"),
    repeating-linear-gradient(90deg, rgba(0,0,0,.09) 0 2px, transparent 2px 24px),
    repeating-linear-gradient(0deg, rgba(0,0,0,.09) 0 2px, transparent 2px 24px);
  background-size: 24px 24px, 24px 24px, 24px 24px;
  box-shadow: inset 0 5px 0 rgba(255, 255, 255, .22);
}

.seabed__gravel {
  top: 128px;
  height: 64px;
  background-color: #8b8580;
  background-image:
    repeating-linear-gradient(90deg, rgba(0,0,0,.12) 0 2px, transparent 2px 24px),
    repeating-linear-gradient(0deg, rgba(0,0,0,.12) 0 2px, transparent 2px 24px);
  background-size: 24px 24px, 24px 24px;
  filter: brightness(.78) saturate(.7);
}

.seabed__stone {
  top: 192px;                 /* один блок камня */
  bottom: 0;
  background-color: #6f7c86;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' shape-rendering='crispEdges'%3E%3Crect x='4' y='4' width='4' height='3' fill='%23000' opacity='.12'/%3E%3Crect x='15' y='9' width='3' height='3' fill='%23fff' opacity='.12'/%3E%3Crect x='7' y='16' width='4' height='3' fill='%23000' opacity='.1'/%3E%3Crect x='18' y='19' width='3' height='2' fill='%23000' opacity='.13'/%3E%3Crect x='2' y='11' width='2' height='2' fill='%23fff' opacity='.1'/%3E%3C/svg%3E"),
    repeating-linear-gradient(90deg, rgba(0,0,0,.14) 0 2px, transparent 2px 24px),
    repeating-linear-gradient(0deg, rgba(0,0,0,.14) 0 2px, transparent 2px 24px);
  background-size: 24px 24px, 24px 24px, 24px 24px;
  filter: brightness(.62) saturate(.7);
}

.seabed__content { position: relative; z-index: 1; }

.footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 26px;
  flex-wrap: wrap;
  padding-bottom: 26px;
  border-bottom: 3px solid rgba(120, 170, 225, .16);
}

.footer__brand { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }

.footer__title {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 24px;
  text-transform: uppercase;
  color: var(--ice);
}

.socials { display: flex; gap: 10px; flex-wrap: wrap; }

.social {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 14px;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: 16px;
  transition: transform .14s ease, filter .14s ease;
}

.social span { line-height: 0; }
.social:hover { transform: translateY(-3px); filter: brightness(1.15); }

/* Плашка без ссылки: видно, что сообщество есть, но вести пока некуда */
.social--off {
  opacity: .45;
  cursor: default;
}

.social--off:hover { transform: none; filter: none; }

.legal {
  margin-top: 22px;
  font-size: 16px;
  line-height: 1.7;
  text-align: center;
  color: var(--muted-2);
}

/* --------------------------------------------------------------------------
   16. Уведомление и модальное окно
   ----------------------------------------------------------------------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  z-index: 20;
  transform: translate(-50%, 24px);
  padding: 13px 20px;
  background: var(--panel);
  border: 4px solid var(--line);
  box-shadow: inset 3px 3px 0 var(--edge-hi), inset -3px -3px 0 var(--edge-lo);
  font-family: var(--f-pixel);
  font-size: 16px;
  letter-spacing: 0;
  color: var(--ice);
  opacity: 0;
  pointer-events: none;
  transition: opacity .22s ease, transform .22s ease;
}

.toast.is-on { opacity: 1; transform: translate(-50%, 0); }

.modal {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: grid;
  place-items: center;
  padding: 20px;
}

/* display:grid перебивает атрибут hidden — возвращаем скрытие явно,
   иначе закрытое окно перехватывает клики по всей странице */
.modal[hidden] { display: none; }

.modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(2, 10, 22, .74);
  opacity: 0;
  transition: opacity .2s ease;
}

.modal.is-on .modal__backdrop { opacity: 1; }

.modal__box {
  position: relative;
  width: min(460px, 100%);
  padding: clamp(22px, 4vw, 30px);
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .2s ease, transform .2s ease;
}

.modal.is-on .modal__box { opacity: 1; transform: none; }

.modal__heading {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 24px;
  text-transform: uppercase;
  margin-bottom: 18px;
}

.modal__row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px 16px;
  padding-bottom: 18px;
  margin-bottom: 18px;
  border-bottom: 3px solid rgba(120, 170, 225, .18);
  font-size: .95rem;
}

.modal__row dt { color: var(--muted); }
.modal__row dd { margin: 0; text-align: right; color: var(--ice); }
.modal__row dd#modalPrice { font-family: var(--f-pixel); font-size: 24px; color: var(--gold); }

.modal__form { display: flex; flex-direction: column; gap: 16px; }

.field { display: flex; flex-direction: column; gap: 7px; }

.field__label {
  font-family: var(--f-pixel);
  font-size: 16px;
  color: var(--muted);
}

.field__input {
  padding: 12px 14px;
  background: #071527;
  border: 3px solid var(--line);
  box-shadow: inset 2px 2px 0 rgba(0, 0, 0, .5);
  color: var(--text);
  font-family: var(--f-display);
  font-size: 16px;
}

.field__input::placeholder { color: #4d6b8a; }
.field__input:focus { outline: 3px solid var(--prism); outline-offset: 1px; }

.modal__actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  flex-wrap: wrap;
}

/* Ошибка заказа — прямо в окне, под полем ника: чаще всего её надо
   исправить там же (опечатка в нике), и всплывашка тут неуместна */
.modal__error {
  margin: -4px 0 12px;
  padding: 8px 10px;
  font-size: .86rem;
  line-height: 1.4;
  color: #ffd2d2;
  background: rgba(120, 20, 30, .35);
  border: 2px solid rgba(255, 110, 120, .45);
}

.modal__note {
  margin: -4px 0 12px;
  padding: 8px 10px;
  font-size: .86rem;
  line-height: 1.4;
  color: var(--ice);
  background: rgba(20, 60, 90, .35);
  border: 2px solid rgba(120, 200, 255, .3);
}

.modal__form.is-busy .btn { opacity: .6; pointer-events: none; }

.modal__x {
  position: absolute;
  top: 8px;
  right: 10px;
  width: 34px;
  height: 34px;
  background: none;
  border: 0;
  color: var(--muted);
  font-size: 1rem;
  cursor: pointer;
}

.modal__x:hover { color: var(--ice); }

.noscript {
  position: relative;
  z-index: 10;
  max-width: 640px;
  margin: 20px auto;
  padding: 16px;
  background: var(--panel);
  border: 4px solid var(--line);
  text-align: center;
}

/* --------------------------------------------------------------------------
   16-бис. Оформление: подложка, кнопка, активная кнопка

   Набор — это только переменные, а правила, которые их применяют, одни на
   всех. Призмарин действует по умолчанию; секции достаточно повесить класс
   набора, чтобы всё внутри неё сменило оформление (так сделано у шардов).
   ----------------------------------------------------------------------- */

.has-mc {
  --sk-panel: url("../textures/mc/dark_prismarine.png");
  --sk-panel-tint: rgba(12, 40, 50, .86);
  --sk-line: #06232b;
  --sk-hi: rgba(120, 210, 205, .34);
  --sk-lo: rgba(3, 28, 34, .88);
  --sk-btn: url("../textures/mc/prismarine_bricks.png");
  --sk-btn-tint: rgba(20, 72, 78, .58);
  --sk-btn-on: url("../textures/mc/sea_lantern.png");
  --sk-btn-on-tint: rgba(140, 235, 225, .12);
  --sk-btn-on-frames: 5;          /* морской фонарь — лента из пяти кадров */
  --sk-text: #ddfffa;
  --sk-shadow: rgba(1, 22, 26, .9);
}

.has-mc .skin--amethyst {
  --sk-panel: url("../textures/mc/deepslate.png");
  --sk-panel-tint: rgba(24, 22, 34, .8);
  --sk-line: #0b0a12;
  --sk-hi: rgba(170, 140, 220, .3);
  --sk-lo: rgba(8, 7, 14, .9);
  --sk-btn: url("../textures/mc/amethyst_block.png");
  --sk-btn-tint: rgba(74, 46, 122, .45);
  --sk-btn-on: url("../textures/mc/amethyst_budding.png");
  --sk-btn-on-tint: rgba(190, 150, 255, .14);
  --sk-btn-on-frames: 1;
  --sk-text: #f4ecff;
  --sk-shadow: rgba(24, 10, 44, .9);
}

.has-mc .panel {
  background-color: transparent;
  background-image: linear-gradient(var(--sk-panel-tint), var(--sk-panel-tint)), var(--sk-panel);
  background-size: auto, 40px 40px;
  background-repeat: repeat, repeat;
  border-color: var(--sk-line);
  box-shadow:
    inset 4px 4px 0 var(--sk-hi),
    inset -4px -4px 0 var(--sk-lo),
    0 6px 0 rgba(2, 10, 22, .45);
  image-rendering: pixelated;
}

/*
 * Плитка на кнопке подгоняется под её размер:
 *   auto 100%      — блок ровно во всю высоту кнопки, значит квадратный;
 *   round no-repeat — по ширине укладывается ЦЕЛОЕ число блоков, лишнее
 *                     не обрезается, а плитка чуть тянется под размер.
 * Без этого с краю торчал кусок лампы.
 */
.has-mc .btn {
  background-color: transparent;
  background-image: linear-gradient(var(--sk-btn-tint), var(--sk-btn-tint)), var(--sk-btn);
  background-size: auto, auto 100%;
  background-repeat: repeat, round no-repeat;
  border: 3px solid var(--sk-line);
  box-shadow:
    inset 3px 3px 0 var(--sk-hi),
    inset -3px -3px 0 var(--sk-lo),
    0 5px 0 rgba(2, 10, 22, .5);
  color: var(--sk-text);
  text-shadow: 0 3px 0 var(--sk-shadow);
  image-rendering: pixelated;
}

/* У активной текстуры может быть несколько кадров: высоту умножаем на их
   число, тогда в кнопку попадает ровно первый кадр. */
.has-mc .btn:hover,
.has-mc .btn:focus-visible,
.has-mc .btn:active {
  background-image: linear-gradient(var(--sk-btn-on-tint), var(--sk-btn-on-tint)), var(--sk-btn-on);
  background-size: auto, auto calc(100% * var(--sk-btn-on-frames, 1));
  filter: none;
}

.has-mc .btn:active {
  transform: translateY(3px);
  box-shadow:
    inset 3px 3px 0 var(--sk-hi),
    inset -3px -3px 0 var(--sk-lo),
    0 2px 0 rgba(2, 10, 22, .5);
}

/* --------------------------------------------------------------------------
   16-тер. Тёмная плашка — карточка IP под логотипом и кнопка копирования
   в шапке. Раньше в этот же вид была одета надпись сезона, её убрали.
   ----------------------------------------------------------------------- */
.has-mc .ipcard,
.has-mc .topbar .btn--ip {
  background: rgba(7, 22, 44, .82);
  background-image: none;
  border: 3px solid rgba(5, 16, 34, .9);
  box-shadow: inset 2px 2px 0 rgba(126, 182, 240, .22);
  color: var(--ice);
  text-shadow: none;
}

.has-mc .topbar .btn--ip:hover,
.has-mc .topbar .btn--ip:focus-visible {
  background: rgba(14, 40, 74, .92);
  background-image: none;
  border-color: rgba(126, 182, 240, .5);
}

.has-mc .topbar .btn--ip:active {
  transform: translateY(2px);
  box-shadow: inset 2px 2px 0 rgba(126, 182, 240, .22);
}

/* --------------------------------------------------------------------------
   17. Текстуры Minecraft

   Класс has-mc ставит main.js, когда папка assets/textures/mc распакована
   (см. tools/fetch-mc-assets.mjs). Без неё всё остаётся на пиксель-арте,
   который рисует pixel.js, — сайт полностью работоспособен в обоих режимах.
   ----------------------------------------------------------------------- */

/* Вуаль воды поверх слоёв, но под содержимым */
.watertex {
  position: fixed;
  inset: 0;
  z-index: -4;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* — Грунт дна: песок, гравий, камень — */
.has-mc .seabed__sand,
.has-mc .seabed__gravel,
.has-mc .seabed__stone {
  background-image: none;
  background-size: 64px 64px;
  background-repeat: repeat;
  image-rendering: pixelated;
  filter: none;
  box-shadow: none;
}

.has-mc .seabed__sand {
  background-image: url("../textures/mc/sand.png");
  /* Песок должен оставаться песком: толща воды над дном его обесцвечивает,
     поэтому возвращаем теплоту насыщенностью */
  filter: saturate(1.25) brightness(1.06);
  box-shadow: inset 0 4px 0 rgba(255, 255, 255, .18);
}

.has-mc .seabed__gravel { background-image: url("../textures/mc/gravel.png"); }

.has-mc .seabed__stone {
  background-image: url("../textures/mc/stone.png");
  filter: brightness(.64) saturate(.82);
}

/* — Ламинария и морская трава: кадры крутит animated.css — */
.kelp--mc .kelp__seg {
  width: var(--mc-size, 48px);
  height: var(--mc-size, 48px);
  transform: none;
  margin-bottom: -2px;              /* сегменты стыкуются без шва */
}

.kelp--mc { animation-name: swayMc; }

@keyframes swayMc {
  from { transform: rotate(-2deg); }
  to   { transform: rotate(2deg); }
}

.grass {
  position: absolute;
  bottom: 0;
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
}

/* Высокая трава стоит позади мелкой, иначе перекрывает её целиком */
.grass--tall { opacity: .92; }

.grass__seg {
  display: block;
  width: var(--mc-size, 48px);
  height: var(--mc-size, 48px);
  margin-bottom: -2px;
}

.coral--mc {
  position: absolute;
  bottom: 0;
  height: auto;
  image-rendering: pixelated;
  transform-origin: bottom center;
  animation: sway 4.4s ease-in-out infinite alternate;
  animation-delay: var(--delay, 0s);
}

.prop {
  position: absolute;
  bottom: 2px;
  height: auto;
  image-rendering: pixelated;
  opacity: .95;
}

/* — Кислород: иконки из игрового интерфейса.
     В игре они лежат на тёмном HUD, у нас — на синей воде, поэтому
     добавляем тень, иначе кольцо теряется в фоне. — */
.has-mc .oxy {
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  cursor: pointer;
  background: url("../textures/mc/air.png") no-repeat center / contain;
  box-shadow: none;
  image-rendering: pixelated;
  filter: drop-shadow(0 2px 0 rgba(2, 12, 26, .85));
}

.has-mc .oxy.is-empty {
  background-image: url("../textures/mc/air_empty.png");
  opacity: .55;
  transform: none;
}

/* — Шард как валюта: предмет prismarine_shard — */
.has-mc .pixicon--tex { image-rendering: pixelated; }

/* Закрытый голубой ящик шалкера. У блоков нет плоской иконки — собираем переднюю
   грань из развёртки модели: корпус (16,44) 16x8 снизу, поверх него крышка
   (16,16) 16x12. В крышке есть прозрачный вырез, сквозь который корпус
   и должен просвечивать, поэтому порядок слоёв важен. --s задаёт масштаб. */
.chestico {
  position: relative;
  display: block;
  width: calc(16px * var(--s, 4));
  height: calc(16px * var(--s, 4));
  image-rendering: pixelated;
}

.chestico i {
  position: absolute;
  left: 0;
  background-image: url("../textures/mc/shulker.png");
  background-size: calc(64px * var(--s, 4)) calc(64px * var(--s, 4));
  background-repeat: no-repeat;
  width: calc(16px * var(--s, 4));
}

.chestico__base {
  top: calc(8px * var(--s, 4));
  height: calc(8px * var(--s, 4));
  background-position: calc(-16px * var(--s, 4)) calc(-44px * var(--s, 4));
}

.chestico__lid {
  top: 0;
  height: calc(12px * var(--s, 4));
  background-position: calc(-16px * var(--s, 4)) calc(-16px * var(--s, 4));
}

/* Остальные кейсы — шалкеры своих цветов, как иконки в меню плагина */
.chestico--purple i { background-image: url("../textures/mc/shulker_purple.png"); }
.chestico--lime i { background-image: url("../textures/mc/shulker_lime.png"); }

/* --------------------------------------------------------------------------
   18. Адаптив
   ----------------------------------------------------------------------- */
@media (max-width: 860px) {
  .hud { right: 8px; gap: 10px; }
  .hud__rail { height: 130px; width: 8px; }
  .hud__oxygen { gap: 2px; }
  .oxy { width: 7px; height: 7px; }
  .topbar__nav { font-size: .95rem; }
}

@media (max-width: 620px) {
  .helm { width: 64px; height: 64px; }

  /* Узкий экран: шкала глубины переезжает в шапку и ложится горизонтально,
     иначе она встаёт поверх карточек у правого края */
  .hud {
    top: 13px;
    right: auto;
    left: 60px;
    z-index: 9;
    transform: none;
    flex-direction: row;
    align-items: center;
    gap: 9px;
  }

  .hud__gauge { flex-direction: row-reverse; align-items: center; gap: 8px; }
  .hud__rail { width: 56px; height: 9px; }
  .hud__fill { inset: 0 auto 0 0; height: 100%; width: var(--fill, 0%); }
  .hud__read { font-size: .55rem; }
  .hud__oxygen { display: none; }

  .topbar__nav { display: none; }
  .topbar { justify-content: space-between; }
  .topbar__mark { margin-right: auto; }

  .ipcard { flex-direction: column; align-items: stretch; }
  .online { border-left: 0; border-top: 4px solid var(--line); justify-content: center; }
  .ipcard__ip { justify-content: center; flex-wrap: wrap; }

  .hero { padding-bottom: 300px; }
  .surface { height: 270px; }

  .portal { gap: 14px; padding: 15px; }
  .portal__desc { font-size: .88rem; }

  /* На узком экране полоска шанса не помещается рядом — уводим её
     под строку, во всю ширину */
  .drop {
    grid-template-columns: 1fr auto;
    gap: 6px 10px;
  }

  .drop__bar { grid-column: 1 / -1; }
  /* В разметке шанс стоит после полосы — без явного места он уезжал
     третьей строкой, а должен стоять справа от названия */
  .drop__chance { grid-row: 1; grid-column: 2; }

  .rank__foot, .case__foot { flex-direction: column; align-items: stretch; }
  .rank__foot .btn, .case__foot .btn { width: 100%; }
  .price { align-items: center; }

  .footer { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 420px) {
  .hud__oxygen { display: none; }
  .grid--packs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --------------------------------------------------------------------------
   19. Уважение к настройкам движения
   ----------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }

  .fish { position: absolute; }
  [data-reveal] { opacity: 1; transform: none; animation: none; }
}
