/* shacalls.com - та же единая тёмная тема, что в приложении.

   Цвет - из логотипа: лаймовый градиент (#CCFF00 → #80E800) на почти
   чёрном листе с зеленоватым оттенком. Лайм - единственный яркий цвет;
   текст на нём тёмный. Обводок нет, блок отделяется собственным цветом;
   одно яркое пятно на блок; ничего не отвечает на наведение; движется
   только transform и opacity.

   Контраст проверен числом (WCAG):
     --ink   на --bg          17,3 : 1
     --ink-2 на --surface      7,6 : 1
     --accent на --bg         15,3 : 1
     --on-accent на лайме     13,8 : 1
   --ink-3 (4,1 : 1) - только для третьестепенного, на главный текст не ставить. */

@font-face {
  font-family: Onest;
  font-style: normal;
  font-weight: 400 700;
  font-display: block;
  src: url(onest-cyrillic.68e5e01d.woff2) format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: Onest;
  font-style: normal;
  font-weight: 400 700;
  font-display: block;
  src: url(onest-latin.052df745.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: dark;

  --accent:     #9BFA00;
  --accent-btn: #9BFA00;
  /* Заливка главной кнопки - переход знака логотипа, как есть. Цвета
     логотипа - в sRGB (исходники в Adobe RGB, см. app/scripts/color-profile.js). */
  --accent-grad: linear-gradient(160deg, #CCFF00 0%, #84EA00 100%);
  --on-accent:  #101700;
  --red:        #FF5C72;

  /* Лист глубже карточки: разница между ними и есть граница. */
  --bg:        #0B0D09;
  --surface:   #141711;
  --surface-2: #1D2119;
  --surface-3: #272C22;

  --ink:   #EEF3E6;
  --ink-2: #A2AB97;
  --ink-3: #6D7664;

  --t-h1:    clamp(30px, 6vw, 44px);
  --t-lead:  clamp(17px, 2vw, 19px);
  --t-base:  16px;
  --t-small: 14px;

  --r-lg: 24px;

  /* Движение - та же шкала, что в приложении (app/src/renderer/style.css). */
  --ease-out:   cubic-bezier(.23, 1, .32, 1);
  --ease-inout: cubic-bezier(.45, 0, .55, 1);
  --ease-in:    cubic-bezier(.4, 0, 1, 1);
  --d-m: 240ms;
  --d-l: 320ms;

  --pad: 24px;
  --col: 560px;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  /* Место под полосу прокрутки - всегда: иначе при переходе с длинной
     главной на короткую страницу входа всё, вместе с шапкой, съезжало бы
     вбок на её ширину. */
  scrollbar-gutter: stable;
  /* Ссылка подвала «Возможности» - плавной прокруткой. */
  scroll-behavior: smooth;
  /* Серая вспышка под пальцем - то же наведение, только на телефоне. */
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
  background: var(--bg);
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--ink);
  font-family: Onest, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: var(--t-base);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-variant-numeric: proportional-nums;
  /* Наклонённое пятно света шире экрана: без этого страница уезжала бы вбок.
     clip, а не hidden: hidden делает body прокручиваемым, и закреплённая
     шапка (sticky) переставала бы держаться сверху. */
  overflow-x: clip;
  /* Свет (.glow, z-index: -1) рисуется внутри body, над его фоном. Без
     этого он уходил под фон body и был не виден вовсе. */
  isolation: isolate;
}

/* Заглушка: кнопка на месте и выглядит как обычно, но не нажимается -
   ни курсора, ни отклика на нажатие, ни перехода. */
.is-stub { pointer-events: none; cursor: default; }

/* Без этого ссылки становятся синими и подчёркнутыми по всей странице. */
a { color: inherit; text-decoration: none; }

/* Спрятанное прячется всегда - даже у кнопок, которым задан свой display. */
[hidden] { display: none !important; }

/* Видно только читалке экрана. */
.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

button, input { font: inherit; color: inherit; }
button { cursor: pointer; }
button:disabled { cursor: default; }

img {
  max-width: 100%;
  user-select: none;
  -webkit-touch-callout: none;
  pointer-events: none;
}

/* Единственное состояние на странице - кольцо фокуса с клавиатуры. */
:focus-visible {
  outline: 2.5px solid var(--accent);
  outline-offset: 3px;
  border-radius: 8px;
}

h1, h2 { margin: 0; font-weight: 600; }

/* ── Свет вместо картинки ──────────────────────────────────────────────
   Снимка у проекта нет, поэтому фон собран из двух мягких пятен в цвете
   акцента. Маска гасит их снизу, чтобы они растворялись в листе без шва. */
.glow {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 30%, transparent 85%);
          mask-image: linear-gradient(to bottom, #000 30%, transparent 85%);
}
.glow::before,
.glow::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
}
.glow::before {
  width: 620px; height: 420px;
  left: 50%; top: -220px;
  transform: translateX(-60%) rotate(-8deg);
  background: radial-gradient(closest-side, rgba(132, 234, 0, .22), transparent);
}
.glow::after {
  width: 420px; height: 320px;
  left: 50%; top: -120px;
  transform: translateX(10%);
  background: radial-gradient(closest-side, rgba(204, 255, 0, .11), transparent);
}

/* ── Рама ─────────────────────────────────────────────────────────────── */

/* Шапка - скруглённая панель-пузырь, закреплённая сверху: под ней видно
   страницу размытой (backdrop-filter), по краю - та же светлая кромка у
   верхнего левого и нижнего правого углов, что у кнопок. Одна на все
   страницы: знак, разделы посередине, вход или имя справа. Высота панели
   постоянная, поэтому шапка не прыгает при переходе между страницами. */
.top {
  position: sticky;
  top: 12px;
  z-index: 40;
  width: min(100% - var(--pad) * 2, 1120px);
  margin: 12px auto 0;
}
.top__bar {
  position: relative;
  /* Знак слева, «Авторизоваться» или имя - справа. */
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  height: 58px;
  /* Поля по краям равные - иначе середина панели и середина разделов
     расходились бы; знак отодвинут от края своим отступом. */
  padding: 0 10px;
  border-radius: 999px;
  background: rgba(20, 23, 17, .62);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
          backdrop-filter: blur(18px) saturate(150%);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .28);
  font-weight: 600;
  font-size: 17px;
}
.top__bar::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  pointer-events: none;
  background:
    radial-gradient(220px 90% at 0 0, rgba(214, 255, 160, .22), transparent 100%),
    radial-gradient(220px 90% at 100% 100%, rgba(214, 255, 160, .13), transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
/* Переход к разделу по ссылке - раздел встаёт под панелью, а не за ней. */
[id] { scroll-margin-top: 96px; }
@media (max-width: 720px) { .top__brand { margin-left: 8px; } }

/* Логотип в шапке - вектором: он одинаково чист и на обычном экране, и на
   экране с удвоенными точками. Высота задаётся здесь, ширина идёт за ней;
   в разметке у картинки проставлены её собственные размеры - место под
   логотип занято до того, как он загрузится, и шапка не дёргается. */
/* Надпись shacalls - 20px: крупнее спорит с кнопкой справа. Буквы с
   высокими h и l, а тело надписи ниже середины её рамки - на глаз она
   стояла ниже надписи кнопки; поднята на полтора пикселя. */
.top__logo { display: block; height: 20px; width: auto; transform: translateY(-1.5px); }
/* Отступ надписи от края панели - как у текста кнопки справа (поле панели
   10px + поле кнопки 18px): края шапки симметричны. */
.top__brand { display: inline-flex; align-items: center; margin-left: 18px; }
/* Справа в шапке - «Контакты» простой текстовой кнопкой и вход (или имя
   вошедшего) тихой кнопкой. */
.top__nav { display: flex; align-items: center; gap: 4px; min-width: 0; }
.top__link {
  display: inline-flex;
  align-items: center;
  height: 38px;
  padding: 0 14px;
  color: var(--ink);
  font-size: 14.5px;
  font-weight: 500;
  white-space: nowrap;
}
/* На телефоне знак, «Контакты» и вход с надписью в шапку не помещаются -
   вход (или профиль) становится круглой кнопкой со значком. Надпись
   остаётся для читалки экрана, только не видна. */
@media (max-width: 520px) {
  .top__link { padding: 0 10px; }
  .top__nav .btn, .top__nav .btn:has(> .icon) { width: 38px; padding: 0; justify-content: center; }
  .top__nav .btn > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
/* У вошедшего - значок и имя; длинное имя обрезается многоточием внутри
   своей строки, значок остаётся целым. */
.top__nav .btn {
  gap: 8px;
  min-height: 0;
  height: 38px;
  max-width: min(240px, 50vw);
  padding: 0 18px;
  font-size: 14.5px;
  white-space: nowrap;
}
.top__nav .btn:has(> .icon) { padding-left: 14px; }
.top__nav .btn > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.top__nav .btn > .icon { width: 19px; height: 19px; }

main {
  flex: 1;
  width: min(100% - var(--pad) * 2, var(--col));
  margin: 0 auto;
  padding: clamp(56px, 12vh, 120px) 0 56px;
}


/* ── Текст ────────────────────────────────────────────────────────────── */

.eyebrow { margin: 0 0 12px; color: var(--ink-2); font-size: var(--t-small); }

/* ── Первый экран ─────────────────────────────────────────────────────
   Печатающаяся фраза, под ней строка регистрации и картинка - по
   середине экрана (.hero--center ниже). */
.hero {
  padding: 0;
  display: grid;
  justify-items: center;
  align-content: center;
  text-align: center;
  padding-bottom: 10vh;
}
.hero__line { margin: 0; font-weight: 400; }
/* Печатающаяся фраза (home.js) - одной строкой, белым. Все «мерки» и
   сама строка лежат в одной клетке сетки: размер места задаёт самая
   длинная фраза, строка печатается от его середины в обе стороны. */
.type {
  display: grid;
  justify-items: center;
  color: var(--ink);
  font-size: 24px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -.005em;
  text-align: center;
  white-space: nowrap;
}
.type > * { grid-area: 1 / 1; }
.type__size { visibility: hidden; }
/* Сама строка места не задаёт (лежит поверх мерок): буквы печатаются по
   одной, у отдельных букв кернинг чуть другой, и готовая фраза выходила
   на доли пикселя шире мерки - всё вокруг вздрагивало. */
.type { position: relative; }
.type__line { position: absolute; left: 50%; top: 0; transform: translateX(-50%); display: inline-flex; align-items: center; }
/* Каждая новая буква проявляется, а не выскакивает. */
.type__ch { visibility: hidden; }
.type__ch.is-on { visibility: visible; animation: type-in 220ms var(--ease-out) both; }
@keyframes type-in { from { opacity: 0; filter: blur(3px); } to { opacity: 1; filter: none; } }
/* Курсор - тонкая лаймовая черта: мигает, пока фраза стоит, и горит ровно,
   пока печатается или стирается. */
.type__caret {
  position: absolute;
  left: 0;
  top: 0;
  width: 2px;
  height: 1.15em;
  border-radius: 1px;
  background: var(--accent);
  animation: caret 1.05s steps(1) infinite;
}
.type.is-typing .type__caret { animation: none; }
@keyframes caret { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .type__ch, .type__caret { animation: none; }
}
/* Первый экран - одной колонкой по центру: крупная печатающаяся фраза,
   под ней строка регистрации, под ней картинка (котёнок на кресле). Фраза
   переносится по ширине колонки; место под неё - по самой длинной фразе
   (мерки переносятся так же), так что строка и картинка под ней не
   прыгают. Строки фразы - по центру, буквы разложены заранее (home.js):
   печать строку не сдвигает. Фраза - белая. */
.hero--center { grid-template-columns: minmax(0, 1fr); }
.hero__stack { position: relative; z-index: 1; display: grid; justify-items: center; width: 100%; max-width: 1000px; min-width: 0; margin: 0 auto; }
.hero--center .hero__line { width: 100%; }
.hero--center .type {
  width: 100%;
  color: var(--ink);
  white-space: normal;
  font-size: clamp(32px, 4.6vw, 58px);
  font-weight: 650;
  line-height: 1.14;
  letter-spacing: -.024em;
  text-wrap: balance;
}
/* Строка печати - той же ширины, что мерки, и переносится так же. */
.hero--center .type__line { left: 0; transform: none; width: 100%; display: block; text-wrap: balance; }
/* Регистрация - подчёркнутой строкой под фразой, светлым салатовым (почти
   белым, в тон курсору и знаку). */
.hero__reg { margin-top: 22px; color: #E6F7C9; font-size: 19px; font-weight: 600; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 6px; }
/* Картинка под строкой: крупная, но первый экран всё равно целиком - не
   выше 42 % окна. */
.hero__cat { display: block; width: min(640px, 100%); height: auto; max-height: 42vh; object-fit: contain; margin-top: 28px; }
/* Крупинки у фразы (home.js) - холст на весь первый экран, под текстом,
   мимо мыши. */
.hero__dust { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
@media (max-width: 720px) {
  /* Самое длинное слово фраз («шумоподавление.») на 32 px в 320 px экрана
     не влезало - шрифт мельчает вместе с экраном: 32 на 390, 26 на 320. */
  .hero--center .type { font-size: clamp(26px, 8.2vw, 32px); }
  .hero__reg { font-size: 17px; margin-top: 18px; }
  .hero__cat { margin-top: 24px; }
}

/* Фон первого экрана главной - картинка во всю ширину сверху. Нижняя
   часть растворяется маской в цвет страницы, так что края у картинки нет:
   фон просто темнеет и переходит в обычный. Прокручивается вместе со
   страницей. Под шапкой (z-index: -1 внутри body). */
.herobg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: -1;
  /* Только первый экран: на очень высоком окне фон не тянется ниже. */
  height: clamp(680px, 100vh, 960px);
  background: url("/assets/hero-bg.e1125f9f.jpg") center top / cover no-repeat;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 45%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 45%, transparent 100%);
}

/* Главная: первый экран и под ним - возможности, по карточке на каждую. */
main.home { width: min(100% - var(--pad) * 2, 1120px); padding: 0 0 40px; }
/* Первый экран - ровно во всю высоту окна под шапкой: при заходе видна
   только верхушка, возможности начинаются ниже края. Содержимое - по
   середине. Высота шапки со всеми отступами - --top-h (замер: 12 + 58 +
   отступ под ней). */
.home .hero {
  --top-h: 82px;
  position: relative;
  min-height: calc(100svh - var(--top-h));
  padding: 24px 0 72px;
  box-sizing: border-box;
}
/* Подсказка внизу первого экрана: «Возможности» и стрелка, которая мягко
   качается вниз. Неяркая - не спорит с кнопками. */
.hero__more {
  position: absolute;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  display: grid;
  justify-items: center;
  gap: 2px;
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 500;
  transition: color var(--d-m) var(--ease-inout);
}
.hero__more:hover { color: var(--ink); }.hero__chev { width: 22px; height: 22px; animation: chev 2.2s var(--ease-inout) infinite; }
@keyframes chev { 0%, 100% { transform: translateY(0); opacity: .7; } 50% { transform: translateY(5px); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .hero__chev { animation: none; } }
.feats { display: grid; margin-top: clamp(56px, 10vh, 96px); }
.feat { background: var(--surface); display: grid; align-content: start; }
.feat h2 { font-weight: 600; }
.feat p { color: var(--ink-2); }

/* Возможности с картинкой - блоки во всю ширину, один под другим, списком.
   Стороны чередуются: в нечётных картинка слева, в чётных - справа. Сетка -
   зеркальная: колонка картинки одной ширины, картинка - по центру своей
   колонки, текст - по центру своей (по ширине самой длинной строки). Раньше текст был
   от левого края широкого столбца - в одном блоке он стоял у картинки, в
   другом у края карточки, и список выглядел неровным. */
.feats--art { grid-template-columns: 1fr; gap: 0; }
/* Стрелка с блока на блок - поверх них, а не в промежутке: начинается в
   нижней части одного блока, пересекает промежуток и указывает в верх
   следующего, к его картинке (стороны чередуются - вторая зеркальная).
   Мягкая, пухлая, со скруглёнными концами и лёгким свечением. Блоки -
   с обычным промежутком 20 px, стрелка их не раздвигает (отрицательные
   поля), нажатиям по блокам не мешает. */
.feat__arrow { position: relative; z-index: 2; display: block; width: 220px; height: 130px; margin: -55px auto; overflow: visible; pointer-events: none; filter: drop-shadow(0 0 10px rgba(150, 240, 20, .35)); }
.feat__arrow--back { transform: scaleX(-1); }
/* Линия - толстая, со скруглённым началом; конец уходит под наконечник.
   Наконечник - сплошной треугольник строго по направлению линии
   (стороны под 31° к ней с обеих сторон), углы скруглены обводкой того же
   цвета: мягкий, без «слипшихся» концов. Свечение - одно на всю стрелку. */
.feat__shaft { fill: none; stroke: var(--accent); stroke-width: 9; stroke-linecap: round; }
.feat__head { fill: var(--accent); stroke: var(--accent); stroke-width: 7; stroke-linejoin: round; }
@media (max-width: 960px) { .feat__arrow { width: 150px; height: 88px; margin: -38px auto; } }
.feat--art {
  grid-template-columns: 400px minmax(0, 1fr);
  align-items: center;
  column-gap: 56px;
  padding: 36px 56px;
  border-radius: 28px;
}
/* Картинки обрезаны по самому предмету (scripts/feat-art.js), одной
   ширины и по центру своей колонки; полоса под картинку одной высоты у
   всех блоков - пропорции у картинок чуть разные (4:3 и 7:5), а блоки
   должны быть одной высоты. */
.feat__media { position: relative; display: grid; justify-items: center; align-content: center; min-width: 0; min-height: 250px; }
.feat__art { position: relative; display: block; width: 100%; max-width: 320px; height: auto; }
/* Под картинкой - мягкое лаймовое свечение-пузырь: полузаметное, чтобы
   предмет не висел на плоской подложке. Размыто сильно, без краёв. */
.feat__media::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  /* Шире картинки - свечение выглядывает из-за предмета ореолом. */
  width: min(440px, 100%);
  aspect-ratio: 1.6;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(150, 240, 20, .5), rgba(150, 240, 20, .16) 60%, transparent);
  filter: blur(28px);
  pointer-events: none;
}
.feat__text { min-width: 0; width: fit-content; max-width: 480px; justify-self: center; }
.feat--art:nth-of-type(even) { grid-template-columns: minmax(0, 1fr) 400px; }
.feat--art:nth-of-type(even) .feat__media { order: 2; }
.feat--art h2 { margin: 0 0 14px; font-size: 30px; letter-spacing: -.02em; line-height: 1.15; }
.feat--art h2 + p { margin: 0; font-size: 17px; line-height: 1.6; }
@media (max-width: 960px) {
  .feat--art { grid-template-columns: 1fr; row-gap: 20px; padding: 28px; text-align: center; }
  .feat--art:nth-of-type(even) { grid-template-columns: 1fr; }
  .feat--art:nth-of-type(even) .feat__media { order: 0; }
  .feat__text, .feat--art:nth-of-type(even) .feat__text { justify-self: center; }
  .feat__art { max-width: 280px; }
}

/* ── Подвал ───────────────────────────────────────────────────────────
   Полосой во всю ширину, чуть светлее листа, на всех страницах одинаковый.
   Четыре части стоят по ширине с равными промежутками - умеренными: на
   широком экране ряд не растягивается дальше 1200px, иначе между частями
   зияли бы пустоты: знак с мягким лаймовым светом и имя, права и кто
   продаёт, навигация, документы. Строки не переносятся. Ссылки белые и
   ничего не меняют при наведении - как и кнопки; реквизиты - серым. */
.foot {
  margin-top: clamp(56px, 10vh, 96px);
  background:
    radial-gradient(420px 220px at 6% 0%, rgba(155, 250, 0, .07), transparent 70%),
    #10130D;
  border-top: 1px solid rgba(238, 243, 230, .06);
  color: var(--ink-3);
  font-size: 14px;
  line-height: 1.6;
}
.foot__in {
  max-width: 1280px;
  margin: 0 auto;
  padding: 44px clamp(24px, 4vw, 40px) calc(44px + env(safe-area-inset-bottom));
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 36px 32px;
}
.foot__in > * { flex: none; }
/* Четыре в ряд не помещаются - две пары друг под другом, ровной сеткой,
   а не рваным переносом последней колонки. */
@media (max-width: 1120px) and (min-width: 721px) {
  .foot__in { display: grid; grid-template-columns: repeat(2, max-content); justify-content: space-between; gap: 36px 48px; }
}
.foot a { color: var(--ink); }

/* Знак и имя: знак со светом за ним, справа имя и строка о сервисе. */
.foot__brand { display: flex; align-items: center; gap: 14px; }
.foot__mark {
  display: block;
  height: 44px;
  width: auto;
  filter: drop-shadow(0 0 18px rgba(155, 250, 0, .35));
}
.foot__names { display: grid; gap: 6px; }
.foot__word { display: block; height: 22px; width: auto; }
.foot__tag { color: var(--ink-2); font-size: 13px; line-height: 1.3; white-space: nowrap; }
/* На самых узких телефонах (320 px) строка в одну линию не влезала и
   страница уезжала вбок - там она переносится. */
@media (max-width: 380px) { .foot__names { min-width: 0; } .foot__tag { white-space: normal; } }

.foot__legal { display: grid; gap: 14px; white-space: nowrap; }
.foot__legal p { margin: 0; }
.foot__copy { color: var(--ink); font-weight: 500; }

.foot__col { display: grid; align-content: start; justify-items: start; gap: 11px; white-space: nowrap; }
.foot__head { margin: 0 0 3px; color: var(--ink); font-size: 15.5px; font-weight: 650; letter-spacing: .01em; }
.foot__col a { font-weight: 500; line-height: 1.4; }

/* На узком - друг под другом, длинные строки переносятся. До 720 px: уже
   на 700 две пары колонок в строку не помещались и уезжали вбок. */
@media (max-width: 720px) {
  .foot__in { flex-direction: column; gap: 32px; padding-top: 36px; }
  .foot__legal, .foot__col { white-space: normal; }
}

.title { font-size: var(--t-h1); letter-spacing: -.02em; line-height: 1.15; }

.lead { margin: 12px 0 0; font-size: var(--t-lead); color: var(--ink-2); }

/* ── Кнопки ───────────────────────────────────────────────────────────
   Ничего не меняют ни при наведении, ни при нажатии. */

.actions { margin-top: 32px; display: flex; flex-wrap: wrap; gap: 12px; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 22px;
  border: 0;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--ink);
  font: inherit;
  font-size: 15.5px;
  font-weight: 500;
  cursor: pointer;
  user-select: none;
}
.btn--primary { background: var(--accent-btn) var(--accent-grad); color: var(--on-accent); font-weight: 600; }
.btn--lg { min-height: 54px; padding: 0 28px; font-size: 17px; }
/* Значки - залитые, со скруглёнными углами (Material Symbols Rounded), как в приложении. */
.icon {
  display: block;
  width: 20px;
  height: 20px;
  flex: none;
  fill: currentColor;
}
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Подпись под кнопками - по центру под ними: у левого края она выглядела
   обрывком чужого текста. */
.hint {
  margin: 12px 0 0;
  color: var(--ink-2);
  font-size: var(--t-small);
  text-align: center;
}
.hint a { color: var(--accent); font-weight: 500; }

/* ── Карточка «приложения нет» ────────────────────────────────────────
   Появляется, только если после нажатия ничего не открылось. */
.card {
  margin-top: 32px;
  padding: 22px;
  border-radius: var(--r-lg);
  background: var(--surface);
}
.card h2 { font-size: 17px; }
.card p { margin: 8px 0 0; color: var(--ink-2); }
.card .actions { margin-top: 20px; }
.card.is-in { animation: rise 420ms var(--ease-out) both; }


.reveal { animation: rise 520ms var(--ease-out) both; }
.reveal:nth-child(2) { animation-delay: 60ms; }
.reveal:nth-child(3) { animation-delay: 120ms; }
.reveal:nth-child(4) { animation-delay: 180ms; }
.reveal:nth-child(n+5) { animation-delay: 240ms; }

@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* ── Вход ─────────────────────────────────────────────────────────────
   Сайт - для компьютера: вход - широкая карточка на две части. Слева -
   что такое shacalls, справа - форма. Узкой колонкой посреди пустого
   экрана это не было: так делают для телефона. На узком экране левая
   часть уходит, форма остаётся одна. */

main.auth {
  width: min(100% - var(--pad) * 2, 920px);
  padding: clamp(16px, 4vh, 48px) 0 40px;
}
/* Экраны входа (не кабинет) - только карточка: без подвала, ровно по
   центру под шапкой; страница не листается, пока всё помещается (на низком
   экране прокрутка возвращается сама - ничего не обрезается). Реквизиты
   продавца - в подвале главной и кабинета. is-gate ставит auth.js. */
body.is-gate .foot { display: none; }
body.is-gate main.auth { display: grid; align-content: center; margin-top: -70px; padding: 80px 0; }
.auth__card {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  /* Одна высота на все шаги (вход, регистрация, код, возврат): карточка
     не прыгает, когда один шаг сменяет другой. Самый высокий -
     регистрация (со строкой о капче); высота - ровно под неё, без пустоты
     сверху и снизу. */
  min-height: 664px;
  border-radius: 28px;
  background: var(--surface);
  overflow: hidden;
}
/* Знак, имя и строка под ними стоят одной колонкой по центру: логотип
   посередине, а подпись, прижатая к краю, выглядела бы оторванной. */
/* Левая часть - одна картинка: знак Shacalls и котёнок на кресле. Кадр
   вертикальный, как и часть; заполняет её (cover), срезаются только поля
   сверху и снизу, оба героя целиком. Фон под ней - тёмный край картинки,
   чтобы до загрузки не мигало. */
.auth__art {
  position: relative;
  overflow: hidden;
  background: #070905;
}
.auth__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
}

.auth__pane {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 36px 52px;
}
/* Смена «Вход / Регистрация»: форма тает, в этой же части карточки
   проявляется круг загрузки, потом форма поднимается уже в новом виде.
   Остальная страница не трогается. */
.pane__load {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--d-m) var(--ease-inout), visibility 0s linear var(--d-m);
}
.auth__pane.is-loading .pane__load { opacity: 1; visibility: visible; transition: opacity var(--d-m) var(--ease-inout), visibility 0s; }
.auth__pane .view { transition: opacity 180ms var(--ease-inout); }
.auth__pane.is-loading .view { opacity: 0; pointer-events: none; }
.auth__pane .view { width: 100%; max-width: 400px; }
/* Форма входа - собранная, без громоздкости: заголовок, поля и кнопка
   одного масштаба, промежутки одинаковые. Только в карточке входа -
   кабинет и окна живут со своими размерами. */
.auth__pane .title { font-size: 28px; }
.auth__pane .lead { margin-top: 8px; font-size: 15px; }
.auth__pane .seg { margin-top: 18px; }
.auth__pane .seg__btn { min-height: 38px; font-size: 14.5px; }
.auth__pane .form { gap: 10px; margin-top: 20px; }
.auth__pane .field__label { margin-bottom: 6px; font-size: 13px; }
.auth__pane .input { height: 46px; }
.auth__pane .input--code { height: 56px; }
.auth__pane .pass__eye { top: 1px; right: 1px; }
.auth__pane .btn--lg { min-height: 48px; font-size: 16px; }
.auth__pane .form .btn--wide { margin-top: 4px; }
.auth__pane .form .btn--primary.btn--wide + .btn--quiet.btn--wide { margin-top: 2px; }
.auth__pane .legalnote { font-size: 12.5px; }
.auth__pane .links { margin-top: -4px; }
/* VK ID и Яндекс ID - две кнопки рядом, над почтой; под ними тонкая линия
   с «или по почте». Значки - в своих фирменных цветах, кнопки - наши. */
.oauth { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 14px; }
.oauth--one { grid-template-columns: 1fr; }
.oauth__btn { min-height: 46px; gap: 10px; font-size: 15px; }
.oauth__icon { display: block; width: 22px; height: 22px; flex: none; }
.oauth__btn.is-stub .oauth__icon { opacity: .55; }
.oauth__or {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 12px 0 0;
  color: var(--ink-3);
  font-size: 13px;
}
.oauth__or::before, .oauth__or::after { content: ""; flex: 1; height: 1px; background: rgba(238, 243, 230, .08); }
.oauth__or + .form { margin-top: 10px; }

@media (max-width: 860px) {
  .auth__card { grid-template-columns: 1fr; min-height: 0; }
  .auth__art { display: none; }
  .auth__pane { padding: 36px 28px; }
  .auth__pane .view { max-width: none; }
}

.view.is-in > * { animation: rise 460ms var(--ease-out) both; }
.view.is-in > :nth-child(2) { animation-delay: 40ms; }
.view.is-in > :nth-child(3) { animation-delay: 80ms; }
.view.is-in > :nth-child(4) { animation-delay: 120ms; }
.view.is-in > :nth-child(n+5) { animation-delay: 160ms; }

.form { display: grid; gap: 14px; margin-top: 24px; }
.form .btn--wide { margin-top: 6px; }
.form { position: relative; }

.field { display: block; min-width: 0; }
.field__label { display: block; margin-bottom: 8px; font-size: var(--t-small); color: var(--ink-2); }
.field__hint { display: block; margin: 8px 0 0; font-size: 13px; color: var(--ink-3); }

.input {
  display: block;
  width: 100%;
  height: 52px;
  padding: 0 22px;
  border: 0;
  /* Скругление - как у кнопок: поле и кнопка под ним - одна пилюля. */
  border-radius: 999px;
  background: var(--surface-2);
  /* 16px и не меньше: на iPhone поле мельче этого увеличивает всю страницу. */
  font-size: 16px;
  transition: background-color 320ms ease;
}
.input::placeholder { color: var(--ink-3); }
/* Вместо кольца фокуса поле чуть светлеет - кольцо Chromium рисовал бы
   даже у поля, получившего фокус само. */
.input:focus-visible { outline: none; background-color: var(--surface-3); }
/* Автозаполнение Chromium красит поле в свой светлый цвет - возвращаем наш. */
.input:-webkit-autofill,
.input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--ink);
  -webkit-box-shadow: 0 0 0 40px var(--surface-2) inset;
  caret-color: var(--ink);
}
.input.is-bad { animation: bad 1.5s ease; }
@keyframes bad {
  0%, 100% { background-color: var(--surface-2); }
  30%, 60% { background-color: #45202A; }
}

/* Код - крупно и вразрядку, цифры одной ширины: так его сверяют с письмом.
   Разрядка добавляет пустоту справа от последней цифры - компенсируем её
   слева, иначе число стоит не по центру. Пока поле пустое, в нём серая
   подсказка «Введите код» - обычным текстом, без разрядки. */
.input--code {
  height: 60px;
  font-size: 24px;
  font-weight: 500;
  letter-spacing: .18em;
  text-align: center;
  font-variant-numeric: tabular-nums;
  padding-left: calc(22px + .18em);
}
.input--code:placeholder-shown { font-size: 17px; font-weight: 400; letter-spacing: 0; padding-left: 22px; }
.input--code::placeholder { color: var(--ink-3); }

/* Поле пароля с глазом внутри. */
.pass { position: relative; }
.pass .input { padding-right: 56px; }
.pass__eye {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--ink-2);
}
.pass__eye .icon { width: 22px; height: 22px; }

/* Вход или регистрация - два сегмента одной плашки. */
.seg {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  margin-top: 24px;
  padding: 4px;
  border-radius: 999px;
  background: var(--surface-2);
}
.seg__btn {
  min-height: 42px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--ink-2);
  font-size: 15px;
  font-weight: 500;
  transition: background-color 320ms ease, color 320ms ease;
}
.seg__btn[aria-selected="true"] { background: var(--surface-3); color: var(--ink); }
.seg + .form { margin-top: 20px; }

/* Экран возврата в приложение - это сообщение, а не форма: всё по центру,
   включая строчку о том, что страницу можно закрыть. */
#vReturn { display: grid; justify-items: center; text-align: center; }
/* Заголовок со значком впереди: значок - по средней линии заглавных букв. */
.title--icon { display: inline-flex; align-items: center; gap: 10px; white-space: nowrap; }
.title--icon .icon { width: 26px; height: 26px; flex: none; color: var(--accent); margin-top: -2px; }
/* В одну строку и на узкой карточке: шрифт уменьшается по ширине колонки
   (замер: строка - 12,74 px ширины на 1 px шрифта, плюс 36 px значок с
   промежутком), а не вылезает за край и не обрезается. В полной карточке
   (400 px) - прежние 28 px. */
#vReturn { container-type: inline-size; }
#vReturn .title--icon { font-size: min(28px, calc((100cqi - 36px) / 12.9)); }
#vReturn .stack { width: 100%; }

/* Приглашение в звонок - своя карточка по центру окна: картинка, код звонка
   с бликом из мерцающих точек (room.js рисует их на холсте поверх кода),
   кто в звонке и кнопка. Фон ровный, по углам - та же кромка, что у кнопок. */
main.invitep { width: min(100% - var(--pad) * 2, 540px); display: grid; align-content: center; margin-top: -70px; padding: 80px 0; }
.invitep__card { position: relative; display: grid; justify-items: center; padding: 36px 44px 40px; border-radius: 32px; background: var(--surface); text-align: center; }
.invitep__art { display: block; width: 140px; height: auto; margin-bottom: 18px; }
.invitep__body { display: grid; justify-items: center; width: 100%; }
.invitep__code { position: relative; margin: 0; color: var(--accent); font-size: 44px; font-weight: 700; letter-spacing: -.01em; line-height: 1.15; overflow-wrap: anywhere; }
/* Обёртка ровно по коду - облако точек ложится точно на него. */
.invitep__codebox { position: relative; display: inline-block; }
.invitep__sparkle { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.invitep__title { margin: 0; font-size: 30px; font-weight: 650; letter-spacing: -.015em; line-height: 1.2; }
.invitep__status { min-height: 1.5em; margin: 10px 0 0; color: var(--ink-2); font-size: 16px; line-height: 1.5; text-wrap: pretty; }
.invitep__body .btn--wide { margin-top: 28px; }
.invitep__body .hint { margin-top: 14px; }
.invitep__body .eyebrow { margin: 0 0 8px; }
.invitep .card { width: 100%; margin-top: 24px; text-align: left; }
.invitep .card .actions { display: block; }
@media (max-width: 560px) {
  .invitep__card { padding: 28px 22px 30px; }
  .invitep__code { font-size: 34px; }
}

/* Ссылка-кнопка: второстепенное действие, без подложки. */
.link {
  min-height: 40px;
  padding: 0 12px;
  border: 0;
  background: none;
  color: var(--accent);
  font-size: 15px;
  font-weight: 500;
}
.link:disabled { color: var(--ink-3); }
/* Второстепенное - под главной кнопкой, по центру. Ссылка сама высотой 40:
   сдвиг вверх оставляет между кнопкой и текстом ровно столько же, сколько
   между полями формы. */
.links { display: flex; justify-content: center; margin-top: -6px; }

.lead b { color: var(--ink); font-weight: 600; overflow-wrap: anywhere; }

.who {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 24px;
  padding: 18px 20px;
  border-radius: 20px;
  background: var(--surface-2);
}
.who__text { min-width: 0; display: grid; }
.who__text b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.who__text span { color: var(--ink-2); font-size: var(--t-small); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Кружок ───────────────────────────────────────────────────────────
   Своя аватарка - картинкой, иначе первая буква имени на цветном фоне. */
.avatar {
  position: relative;
  flex: none;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #475262;
  color: #fff;
  font-size: 19px;
  font-weight: 600;
}
/* Своя аватарка - картинкой на весь кружок. */
.avatar.has-img { background-size: cover; background-position: center; }
.avatar--xl { width: 88px; height: 88px; font-size: 34px; }
.avatar--lg { width: 72px; height: 72px; font-size: 28px; }

/* Фото в окне «Редактировать профиль»: кружок и рядом кнопки. */
.avedit { display: flex; align-items: center; gap: 18px; margin-bottom: 6px; }
/* Кнопки фото - той же высоты, что «Отмена» и «Сохранить» (44 px). */
.avedit__acts { display: flex; align-items: center; gap: 10px; }
.avedit__acts .btn .icon { width: 20px; height: 20px; }
.btn--round { width: 44px; min-width: 44px; padding: 0 !important; }
#avDrop { transition: opacity var(--d-m) var(--ease-inout), scale var(--d-m) var(--ease-inout), visibility 0s linear 0s; }
#avDrop.is-gone { opacity: 0; scale: .8; visibility: hidden; pointer-events: none; transition: opacity var(--d-m) var(--ease-inout), scale var(--d-m) var(--ease-inout), visibility 0s linear var(--d-m); }

.stack { display: grid; gap: 12px; margin-top: 24px; }
.stack + .hint { margin-top: 16px; }

.btn--wide { width: 100%; }
.btn--quiet { background: var(--surface-2); }
.btn:disabled { opacity: .6; }

/* Кнопка занята: надпись гаснет, на её месте крутится дуга. Ширина та же -
   ничего вокруг не сдвигается. */
.btn { position: relative; }
.btn .spin { position: absolute; inset: 0; margin: auto; opacity: 0; transition: opacity var(--d-m) var(--ease-out); }
.btn__text { transition: opacity 200ms ease; }
/* Занятая кнопка чуть темнеет, как «Создать звонок» в приложении, но не
   бледнеет, как выключенная. */
.btn.is-busy { opacity: 1; filter: brightness(.86); cursor: default; }
.btn.is-busy .btn__text, .btn.is-busy > .icon { opacity: 0; }
.btn.is-busy .spin { opacity: 1; }

/* ── Круг загрузки - тот же, что в приложении (app/src/renderer/style.css,
   .loader) ─────────────────────────────────────────────────────────────
   Дуга с прозрачным хвостом и скруглённой головой. Крутится только
   поворотом (transform) - его крутит видеокарта отдельно от страницы, и
   круг не запинается, даже когда страница занята. Два поворота вложены:
   внешний ровный, внутренний с мягким разгоном и торможением - дуга то
   чуть догоняет, то чуть отпускает. Цвет - переменными: лайм логотипа,
   тёмный на лаймовой кнопке. */
.spin {
  --size: 18px;
  --w: 2.25px;                /* толщина дуги */
  --c1: #84EA00;              /* хвост */
  --c2: #CCFF00;              /* голова */
  position: relative;
  display: block;
  flex: none;
  width: var(--size);
  height: var(--size);
  animation: spin 1.2s linear infinite;
  will-change: transform;
}
.spin__arc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0deg 110deg, color-mix(in srgb, var(--c1) 30%, transparent) 200deg, var(--c1) 300deg, var(--c2) 360deg);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--w) - .5px), #000 calc(100% - var(--w)));
          mask: radial-gradient(farthest-side, transparent calc(100% - var(--w) - .5px), #000 calc(100% - var(--w)));
  animation: spin-ease 2.4s cubic-bezier(.45, 0, .55, 1) infinite;
}
.spin__arc::after {
  content: "";
  position: absolute;
  top: 0;
  left: calc(50% - var(--w) / 2);
  width: var(--w);
  height: var(--w);
  border-radius: 50%;
  background: var(--c2);
}
@keyframes spin { to { transform: rotate(1turn); } }
@keyframes spin-ease { to { transform: rotate(1turn); } }
.spin--lg { --size: 32px; --w: 3px; }
/* На лаймовой кнопке - тёмный. */
.btn--primary .spin { --c1: var(--on-accent); --c2: var(--on-accent); }

.seg__btn, .link, .pass__eye { transition: background-color 320ms ease, color 320ms ease; }

/* ── Нажатие и кромка - как в приложении ──────────────────────────────
   Нажатие у всех кнопок одно: не темнеют, а вжимаются (press.js). Свой
   слой у видеокарты - постоянно: если он появляется только на время
   движения, надпись в начале и в конце перерисовывается и вздрагивает. */
button:not(.modal__x), .btn, .nav__item { will-change: scale; }

/* Кромка - тонкая светлая линия только у верхнего левого и нижнего правого
   углов, к середине сторон сходит на нет. Сама кнопка не меняется - кромка
   отдельным слоем поверх, мимо мыши. На ярких (лаймовых) кнопках - белая,
   на тёмных - светло-лаймовая. Без кромки - кнопки без подложки (крестик,
   ссылки-кнопки, глаз в поле пароля) и невыбранные вкладки и пункты меню:
   у них кромка прозрачная и проявляется вместе с заливкой. */
.btn, .seg__btn, .nav__item, .contacts__row, .feat--art, .profile, .tile, .invitep__card { position: relative; }
.btn::after, .seg__btn::after, .nav__item::after, .contacts__row::after, .feat--art::after, .profile::after, .tile::after, .invitep__card::after {
  --rim-a: rgba(214, 255, 160, .2);
  --rim-b: rgba(214, 255, 160, .12);
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  pointer-events: none;
  background:
    radial-gradient(45% 70% at 0 0, var(--rim-a), transparent 100%),
    radial-gradient(45% 70% at 100% 100%, var(--rim-b), transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  /* Цвет кромки перетекает вместе с заливкой кнопки, а не раньше неё. */
  transition: --rim-a var(--d-l) var(--ease-inout), --rim-b var(--d-l) var(--ease-inout);
}
.btn--primary::after {
  --rim-a: rgba(255, 255, 255, .5);
  --rim-b: rgba(255, 255, 255, .28);
}
.seg__btn:not([aria-selected="true"])::after, .nav__item:not(.is-on)::after {
  --rim-a: transparent;
  --rim-b: transparent;
}
/* Кромка задана в долях ширины: у широких (кнопки во всю
   ширину формы) она растянулась бы и поблёкла. Пятна - того же размера,
   что у широкой кнопки приложения (45 % от 224 px). */
.btn--wide::after, .contacts__row::after {
  background:
    radial-gradient(100px 70% at 0 0, var(--rim-a), transparent 100%),
    radial-gradient(100px 70% at 100% 100%, var(--rim-b), transparent 100%);
}
/* Подложки возможностей - большие: пятна кромки крупнее, чтобы на
   блоке во всю ширину уголки читались так же, как у кнопок. */
.feat--art::after, .profile::after, .tile::after, .invitep__card::after {
  background:
    radial-gradient(320px 75% at 0 0, var(--rim-a), transparent 100%),
    radial-gradient(320px 75% at 100% 100%, var(--rim-b), transparent 100%);
}
@property --rim-a { syntax: "<color>"; inherits: false; initial-value: transparent; }
@property --rim-b { syntax: "<color>"; inherits: false; initial-value: transparent; }

/* ── Кабинет ──────────────────────────────────────────────────────────
   Как личный кабинет на компьютере: слева меню разделов, справа раздел.
   Раздел пока один - «Профиль»: кто вы и приложение. */

.cab {
  flex: 1;
  width: min(100% - var(--pad) * 2, 1120px);
  margin: 0 auto;
  padding: 32px 0 56px;
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 40px;
  align-items: start;
}
/* Разделы и «Выйти» - одним столбиком с небольшим зазором; пункты - круглые,
   как все кнопки сайта. */
.cab__side { position: sticky; top: 24px; display: grid; gap: 6px; }
.nav { display: grid; gap: 2px; }
.nav__item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  height: 46px;
  padding: 0 18px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--ink-2);
  font-size: 15.5px;
  font-weight: 500;
  text-align: left;
  transition: background-color 240ms ease, color 240ms ease;
}
.nav__item .icon { width: 22px; height: 22px; }
.nav__item.is-on { background: var(--surface-2); color: var(--ink); }
.nav__item.is-on .icon { color: var(--accent); }
.cab__main { min-width: 0; }
.cab .tab.is-in > * { animation: rise 420ms var(--ease-out) both; }
.cab .tab.is-in > :nth-child(2) { animation-delay: 50ms; }
.cab .tab.is-in > :nth-child(n+3) { animation-delay: 100ms; }

/* Кто вы: крупный кружок, имя, почта и «Редактировать профиль». */
.profile {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 26px;
  padding: 30px 32px;
  border-radius: 28px;
  background: var(--surface);
}
.profile__text { min-width: 0; }
.profile__name {
  font-size: 30px;
  font-weight: 650;
  letter-spacing: -.015em;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.profile__mail { margin: 4px 0 0; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.profile__edit { min-height: 44px; padding: 0 18px; font-size: 15px; }
.profile__edit .icon { width: 19px; height: 19px; }

/* Плитки под профилем (сейчас одна - приложение). */
.tiles { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; margin-top: 16px; }
/* Плитка - всё по центру: подпись, заголовок, текст и кнопка под ними. */
.tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 6px;
  min-height: 220px;
  padding: 26px 28px 28px;
  border-radius: 28px;
  background: var(--surface);
  /* Свечение ниже - внутри плитки, по её скруглённым краям. */
  overflow: hidden;
  isolation: isolate;
}
/* Под кнопкой «Скачать» - мягкое салатовое свечение: размытый овал вокруг
   кнопки, уходящий к нижнему краю плитки. Над подложкой, под текстом. */
.tile::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -70px;
  z-index: -1;
  width: min(460px, 100%);
  height: 190px;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(150, 240, 20, .42), rgba(150, 240, 20, .13) 62%, transparent);
  filter: blur(24px);
  pointer-events: none;
}
.tile__kicker { color: var(--ink-2); font-size: var(--t-small); }
.tile__title { font-size: 23px; font-weight: 650; letter-spacing: -.01em; line-height: 1.25; }
.tile__text { color: var(--ink-2); line-height: 1.5; max-width: 420px; text-wrap: balance; }
.tile__btn { margin-top: 16px; min-height: 44px; padding: 0 24px; font-size: 15px; }
/* Строка об условиях у кнопки: мелко, но читается; ссылка подчёркнута. */
.legalnote { margin: 0; color: var(--ink-3); font-size: 13.5px; line-height: 1.5; }
.legalnote a { color: var(--ink-2); text-decoration: underline; text-underline-offset: 3px; }
.form .legalnote { text-align: center; }

/* Окна поверх кабинета: «Редактировать профиль» и «Выйти из аккаунта?».
   Появляются и закрываются плавно (is-closing - на время ухода). */
.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(5, 7, 4, .62);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  animation: fade-in 200ms ease both;
}
.modal__box {
  position: relative;
  width: min(100%, 440px);
  padding: 30px 30px 28px;
  border-radius: 28px;
  background: var(--surface);
  animation: rise 320ms var(--ease-out) both;
}
/* Заголовок - строкой высотой 32px, крестик - в той же строке справа: оба
   по одной средней линии. Справа у заголовка место под крестик. */
.modal__title { font-size: 22px; font-weight: 650; line-height: 32px; padding-right: 44px; }
.modal__x {
  position: absolute;
  /* Заглавные Onest сидят в строке на пиксель выше середины - крестик
     поднят на столько же, чтобы стоять ровно по средней линии заголовка. */
  top: 29px;
  right: 24px;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-2);
}
.modal__x .icon { width: 22px; height: 22px; }
.modal .form { margin-top: 22px; }
.modal__text { margin: 10px 0 0; color: var(--ink-2); line-height: 1.5; text-wrap: balance; }
.modal__acts { display: flex; justify-content: flex-end; gap: 10px; margin-top: 4px; }
/* Кнопки без заливки в окне - на ступень светлее: фон окна почти того же
   цвета, край «Отмены» сливался с ним, и она казалась меньше «Сохранить»,
   хотя обе по 44 px. */
.modal__box .btn--quiet { background: var(--surface-3); }
/* Окно-вопрос (выйти из аккаунта) - как в приложении: знак сверху, текст
   и кнопки по центру, кнопки - две равные половины. */
.modal__icon { display: block; width: 64px; height: 64px; margin: 0 auto 10px; color: var(--ink-3); }
.modal__box--ask { width: min(100%, 480px); text-align: center; }
/* Текст - обычным переносом: при «ровном» делении короткая фраза рвалась
   на две половинки посередине. */
.modal__box--ask .modal__text { text-wrap: pretty; }
.modal__box--ask .modal__title { padding: 0 32px; }
.modal__box--ask .modal__acts { justify-content: center; }
.modal__box--ask .modal__acts .btn { flex: 1 1 0; }
.modal__text ~ .modal__acts { margin-top: 24px; }
.modal.is-closing { animation: fade-out 180ms ease both; pointer-events: none; }
.modal.is-closing .modal__box { animation: sink 180ms ease both; }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes sink { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(8px) scale(.98); } }

/* ── Уведомления - те же, что в приложении (app/src/renderer/style.css,
   .toasts) ────────────────────────────────────────────────────────────
   Все ошибки и сообщения страницы - плашкой сверху, поверх страницы:
   ничего под ней не сдвигается. Одно на экране, смена - на месте. */
.toasts {
  position: fixed;
  top: 16px;
  left: 0;
  right: 0;
  z-index: 70;
  display: grid;
  justify-items: center;
  width: min(100% - 32px, 440px);
  margin: 0 auto;
  pointer-events: none;
}
/* Уходящее и приходящее уведомления - в одной клетке, друг поверх друга:
   смена идёт на месте, без сдвига. */
.toast {
  grid-area: 1 / 1;
  padding: 10px 16px;
  border-radius: 20px;
  line-height: 20px;
  background: var(--surface-3);
  font-size: 14px;
  text-align: center;
  /* Длинный адрес без пробелов переносится, а не растягивает уведомление. */
  overflow-wrap: anywhere;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .35);
  animation: toast-in var(--d-l) var(--ease-out) both;
}
.toast--bad { color: var(--red); }
/* Открылось окно - верхнее уведомление никуда не едет, а уходит под
   затемнение (окно на 50) и гаснет вместе с фоном. Пришедшие при открытом
   окне - снизу, над затемнением (press.js, toast). */
body:has(.modal:not([hidden])) .toasts:not(.toasts--modal) { z-index: 49; }
.toasts--modal { top: auto; bottom: 24px; }
.toast.is-out { animation: toast-out 180ms var(--ease-in) both; }
@keyframes toast-in  { from { opacity: 0; transform: translateY(-6px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-4px) scale(.98); } }

/* Окно проверки «я не робот» (auth.js, captchaToken): виджет Яндекса во
   всю ширину окна, под ним - о SmartCaptcha. Место под виджет занято
   заранее: окно не вырастает, когда он дорисуется. */
.capbox { min-height: 100px; margin-top: 18px; }
.capmodal__note { margin: 14px 0 0; }

/* «Контакты» из подвала (press.js): почта и ВКонтакте - строками-плашками,
   как кнопки: та же кромка и то же нажатие. */
.contacts__list { display: grid; gap: 10px; margin-top: 20px; }
.contacts__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 54px;
  padding: 0 20px;
  border-radius: 999px;
  background: var(--surface-2);
  will-change: scale;
}
.contacts__label { color: var(--ink-2); font-size: 14px; }
.contacts__value { color: var(--ink); font-weight: 500; overflow-wrap: anywhere; text-align: right; }

/* Загрузка: зелёный кружок посередине, под ним всё размыто. Появляется и
   гаснет плавно; пока горит - страница под ним не нажимается. */
.loader {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  background: rgba(11, 13, 9, .55);
  -webkit-backdrop-filter: blur(10px);
          backdrop-filter: blur(10px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 240ms ease, visibility 0s linear 240ms;
}
.loader.is-on { opacity: 1; visibility: visible; transition: opacity 200ms ease, visibility 0s; }
/* Кружок - тот же круг загрузки, что в приложении (.spin), крупный. */

@media (max-width: 900px) {
  .cab { grid-template-columns: 1fr; gap: 20px; padding-top: 20px; }
  .cab__side { position: static; grid-template-columns: 1fr; }
  .nav { grid-auto-flow: column; grid-auto-columns: max-content; overflow-x: auto; }
  .profile { grid-template-columns: auto minmax(0, 1fr); }
  .profile__edit { grid-column: 1 / -1; justify-self: start; }
}

@media (prefers-reduced-motion: reduce) {
  .reveal, .card.is-in, .view.is-in > *, .cab .tab.is-in > *, .modal, .modal__box { animation: fade 300ms ease both; }
  .modal.is-closing, .modal.is-closing .modal__box { animation: fade-out 180ms ease both; }
  @keyframes fade { from { opacity: 0; } to { opacity: 1; } }
  /* Как в приложении: ровный медленный поворот, без разгона. */
  .spin { animation-duration: 2.4s; }
  .spin__arc { animation: none; }
  /* Уведомления - без сдвига, одним проявлением. */
  .toast { animation-name: fade-in; }
  .toast.is-out { animation-name: fade-out; }
  html { scroll-behavior: auto; }
}

/* ── Текст в кнопках - точно по центру ────────────────────────────────
   У шрифта Onest заглавные стоят в строке на 0,75-1 пикселя выше
   середины - надпись в кнопке выглядела приподнятой, а значок рядом с ней
   опущенным. Опускаем содержимое на пиксель (верхний отступ 2px сдвигает
   его на 1px) и поднимаем значок на столько же обратно: так середина
   заглавных и середина значка совпадают с серединой кнопки. Замерено по
   каждой кнопке сайта. !important - потому что у кнопок в разных местах
   свои отступы-сокращения (padding: 0 20px), и они иначе сбрасывали бы
   этот сдвиг. */
.btn, .nav__item, .seg__btn, .link { padding-top: 2px !important; }
:is(.btn, .nav__item) > .icon { margin-top: -2px; }
