/* Раскладка и адаптив.
 *
 * Ровно одна точка перелома — 900px:
 *
 *   уже  → телефон:    разделы в нижнем баре, слои 4 и 5 сменяют друг друга
 *   шире → компьютер:  разделы в боковом меню слева, слои 4 и 5 видны разом
 *
 * Разметка при этом одна и та же. Меняется только то, где стоит навигация
 * и сколько колонок в рабочей области — никаких отдельных мобильной и
 * десктопной версий, которые пришлось бы чинить дважды.
 */

.app {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;

  /* Атмосфера на слоях 2 и 3, где направление ещё не выбрано и --surface
     пустой. Внутри направления рабочая область накрывает это своим
     градиентом — он непрозрачный, так что слои не просвечивают друг
     через друга.
     Пятна берутся из переменных: в светлой прихожей они погашены, и
     жёстко вписанный сюда фиолет проступал бы сквозь белое поле. */
  background:
    radial-gradient(135% 80% at 58% -18%, var(--air-1) 0%, transparent 68%),
    radial-gradient(90% 55% at 2% 34%, var(--air-2) 0%, transparent 62%);
}

/* ---------- Слой 1: заставка ---------- */

.splash {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  /* Свет из центра — там, где знак. Переменной, а не значением: на
     светлой заставке это белое поле с еле заметным тёплым ядром. */
  background: var(--splash-bg);
  transition: opacity .6s var(--ease), visibility .6s;
}

.splash.is-hidden { opacity: 0; visibility: hidden; }

.splash__mark {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gap);
}

/* Кольцо набрано двумя цветами семьи: баклажан и розовый. Раньше тут
   спорили фиолетовый и синий — два цвета из разных направлений. */
.splash__ring {
  width: 92px;
  height: 92px;
  border-radius: 50%;
  border: 2px solid transparent;
  border-top-color: var(--ring-1);
  border-right-color: var(--ring-2);
  animation: spin 1.15s var(--ease) infinite;
}

/* Надпись на заставке — рисунок, а не текст, поэтому задаётся ширина,
   а высота считается сама по пропорции. */
.splash__word {
  display: block;
  width: 212px;
  height: auto;
  /* Буквы берут цвет чернил: на тёмной заставке кремовые, на светлой —
     баклажановые. Две средние остаются цветными — они и есть знак. */
  color: var(--text);
  opacity: 0;
  animation: rise .9s var(--ease) .25s forwards;
}

@media (max-width: 380px) {
  .splash__word { width: 176px; }
}

.splash__sub {
  font-size: 13px;
  color: var(--text-faint);
  opacity: 0;
  animation: rise .9s var(--ease) .5s forwards;
}

.splash__ver {
  margin-top: 10px;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-faint);
  opacity: 0;
  animation: rise .9s var(--ease) .62s forwards;
}

/* Номер сборки на главном экране: тем, кто в бете, надо уметь назвать
   версию, когда пишут об ошибке. Держим тихо, под плитками. */
.app-ver {
  margin-top: var(--gap-lg, 24px);
  text-align: center;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-faint);
}

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---------- Экраны ---------- */

.screen { display: none; flex: 1; min-height: 0; }

/* Экран не подменяется, а входит: проявляется и чуть поднимается.
 *
 * Двадцать пикселей и треть секунды — этого хватает, чтобы глаз успел
 * заметить смену, и мало, чтобы начать ждать. Раньше экраны сменялись
 * мгновенно, и переход между разделами читался как перерисовка
 * страницы, а не как движение внутри приложения. */
.screen.is-active { display: flex; flex-direction: column; }

/* Анимируется содержимое экрана, а не сам экран.
 *
 * Внутри экрана лежит нижний бар с position: fixed, а трансформ на
 * предке отбирает у fixed точку отсчёта: бар начинает считать «низ» от
 * низа экрана, а не окна, и уезжает под содержимое — вниз страницы, где
 * его надо искать прокруткой. Поэтому трансформ висит на детях, а бар
 * остаётся в окне. */
.screen.is-active > .screen__inner,
.screen.is-active > .workspace {
  animation: screen-in .34s var(--ease-soft) both;
}

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

/* Кому анимации мешают — тому их нет. Это не украшение поверх
   содержимого, а подсказка о движении; человеку, который её отключил,
   подсказка не нужна. */
@media (prefers-reduced-motion: reduce) {
  .screen.is-active > .screen__inner,
  .screen.is-active > .workspace { animation: none; }
  .tabbar__pill { transition: none; }
  .tabbar__pill.is-moving { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .16); }
  .aura__layer { transition: none; }
}

.screen__inner {
  width: 100%;
  max-width: 1320px;
  margin: 0 auto;
  /* Сверху добавляем безопасную зону: на iPhone там вырез и часы, и без
   * этого отступа заголовок уезжает под них. На остальных устройствах
   * зона нулевая, и ничего не меняется. */
  padding: calc(var(--gap-lg) + env(safe-area-inset-top, 0px))
           var(--gap) var(--gap-lg);
  flex: 1;
}

/* ---------- Слой 3: колода направлений ---------- */

/* Атмосфера за колодой.
 *
 * По слою на направление, все лежат друг на друге, видно тот, у которого
 * is-on. Переключение — сменой прозрачности, а не сменой градиента:
 * градиенты между собой не перетекают, и без слоёв фон менялся бы
 * рывком посреди жеста. */
.aura {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Свет за колодой. Прозрачность ставит прокрутка — тем же числом, что
   и масштаб карточки, — поэтому переход здесь короткий: он сглаживает
   шаг между кадрами, а не ведёт анимацию сам. Раньше слой перетекал
   семь десятых секунды и всегда опаздывал за картой. */
.aura__layer {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .18s linear;
}

.aura__layer.is-on { opacity: 1; }

/* Экран становится точкой отсчёта для слоёв, а содержимое поднимается
   над ними. */
#screen-domains { position: relative; }
#screen-domains > .screen__inner { position: relative; z-index: 1; }

.domains {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

/* Главный экран — колонка на всю высоту: заголовок и колода сверху,
   подвал прижат к низу. Между ними воздух, а не текст, — ссылки на
   условия не должны стоять вплотную к карточкам, будто продолжают их. */
#screen-domains > .screen__inner {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  padding-bottom: calc(var(--gap-lg) + env(safe-area-inset-bottom, 0px)
                       + var(--tg-safe-bottom, 0px));
}

#screen-domains .app-foot { margin-top: auto; }

/* Колоду можно тянуть мышью (см. drag() в domains.js); курсор об этом
   говорит. */
.domains__viewport { cursor: grab; }
.domains__viewport.is-grabbing { cursor: grabbing; user-select: none; }
.domains__viewport.is-grabbing > .domain-tile { transition: none; }

/* Лента карточек. Одна карточка — один экран: направление показывает
   себя целиком, а не строкой меню. */
.domains__viewport {
  display: flex;
  gap: var(--gap);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  /* Отступы под тень и приподнятую при наведении карточку: без них
     верхний край срезается собственным overflow ленты. */
  padding: 6px 0;
  margin: -6px 0;
}

.domains__viewport::-webkit-scrollbar { display: none; }

/* Карточка уже экрана: соседняя выглядывает краем с обеих сторон.
   Это единственное, что честно сообщает о свайпе до того, как человек
   его сделал, — точки говорят «их несколько», край говорит «вон она». */
.domains__viewport > .domain-tile {
  flex: 0 0 88%;
  scroll-snap-align: center;
  min-height: 230px;
  /* Поля уже, чем у карточки во весь экран: сама карточка стала уже, и
     прежние отступы съедали строку с разделами. */
  padding: var(--gap) 20px;
  /* Соседи приглушены и чуть отодвинуты вглубь: в фокусе одна карточка,
     остальные — фон для неё.
     
     Насколько карточка «в фокусе», решает не класс, а число --near от
     нуля до единицы: его ставит прокрутка на каждом кадре (см.
     layers/domains.js). Пока это был класс, карточка щёлкала из
     уменьшенной в полную ровно на середине пути — палец вёл плавно, а
     колода прыгала. Теперь она растёт вместе с движением руки.
     
     Переход короткий и нужен только чтобы сгладить шаг между кадрами;
     длинный здесь работал бы против пальца — карточка догоняла бы его
     с опозданием. */
  --near: 0;
  transform: scale(calc(.94 + .06 * var(--near)));
  opacity: calc(.5 + .5 * var(--near));
  transition: transform .12s linear, opacity .12s linear,
              border-color .28s var(--ease);
}

/* Класс остаётся: по нему работают наведение и нажатие, и он же
   страхует на случай, если прокрутка ещё не успела ничего посчитать. */
.domains__viewport > .domain-tile.is-on { --near: 1; }

/* В колоде карточка не приподнимается под курсором: она и так двигается
   при листании, и два разных движения по одному поводу сбивают. */
.domains__viewport > .domain-tile:hover {
  transform: scale(calc(.94 + .06 * var(--near)));
}

.domains__viewport > .domain-tile:active {
  transform: scale(calc(.93 + .055 * var(--near)));
}

/* Первая и последняя всё равно встают по центру: без этих отступов
   крайние карточки прилипали бы к краю экрана. */
.domains__viewport::before,
.domains__viewport::after {
  content: '';
  flex: 0 0 calc(6% - var(--gap) / 2);
}

.domains__nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-sm);
}

.domains__dots { display: flex; gap: 7px; }

.domains__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--line);
  transition: background .25s var(--ease), width .25s var(--ease);
}

.domains__dot.is-on { background: var(--text); width: 20px; border-radius: 4px; }

.domains__dot:disabled { cursor: default; }

/* На компьютере карточка не должна растягиваться на всю ширину окна:
   плитка в полтора метра шириной перестаёт быть карточкой. */
@media (min-width: 900px) {
  .domains__viewport > .domain-tile { min-height: 280px; }
  /* Колонка уже всего экрана — и вместе с заголовком, а не отдельно от
     него: центрированная колода под прижатым влево заголовком читается
     как два несвязанных блока. */
  #screen-domains > .screen__inner { max-width: 760px; }
}

/* ---------- Слои 4 и 5 ---------- */

/* Рабочая область.
 *
 * Дерево навигации отдаёт --surface одним плоским цветом — так и должно
 * быть: сервер присылает данные, а не оформление, и знать про радиальные
 * градиенты ему незачем. Атмосферу направления рисует уже CSS, кладя
 * свет поверх этого цвета. Меняется раздел — меняется цвет под светом,
 * и весь экран переодевается сам. */
.workspace {
  display: flex;
  flex: 1;
  min-height: 0;
  background:
    radial-gradient(135% 74% at 58% -16%, var(--air-1) 0%, transparent 68%),
    radial-gradient(90% 50% at 2% 36%, var(--air-2) 0%, transparent 62%),
    /* Затемнение поверх подложки. Подложка — из данных навигации, и она
       же красит плитку на главном; внутри же нужно темнее, чем на
       плитке: там поверх лежат карточки и цифры. Слой даёт это, не
       трогая цвет в данных. */
    linear-gradient(var(--surface-shade), var(--surface-shade)),
    var(--surface);
  transition: background .5s var(--ease-soft);
}

/* Боковое меню: скрыто на телефоне, показано на компьютере */
.sidebar { display: none; }

.workspace__main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding-bottom: calc(var(--tabbar-h)
                       + max(env(safe-area-inset-bottom, 0px), var(--tg-safe-bottom, 0px))
                       + 32px);
}

/* Нижний бар: только телефон.
 *
 * Плавающая стеклянная капсула, а не полоса во всю ширину. Полоса делит
 * экран надвое и отрезает нижний край содержимого; капсула лежит поверх
 * него, и видно, что страница продолжается под ней.
 *
 * Стекло тут не украшение: под баром проезжает содержимое, и размытие
 * оставляет от него цветное пятно вместо читаемого текста. Без размытия
 * пришлось бы делать панель непрозрачной, а это снова полоса.
 */
.tabbar {
  position: fixed;
  left: 12px;
  right: 12px;
  /* От большей из двух безопасных зон: браузерной (env) и той, что
     сообщает сам Telegram (--tg-safe-bottom, см. app.js). Внутри
     Telegram env() — ноль, и без второй бар ложился на полосу жестов.
     Плюс шестнадцать пикселей воздуха — столько же держит сам Telegram
     между своей панелью и краем. */
  bottom: calc(max(env(safe-area-inset-bottom, 0px), var(--tg-safe-bottom, 0px)) + 16px);
  z-index: 30;
  height: var(--tabbar-h);
  display: flex;
  align-items: stretch;
  gap: 8px;
}

/* Капсула разделов. */
.tabbar__deck {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: stretch;
  gap: 2px;
  padding: 5px;
  border-radius: 100px;

  background: var(--bar);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-shadow), inset 0 1px 0 var(--glass-light);
  backdrop-filter: blur(22px) saturate(150%);
  -webkit-backdrop-filter: blur(22px) saturate(150%);

  /* Бар листается вбок: разделов бывает и четыре, и восемь, а прятать
   * лишние под кнопку «Ещё» — значит уводить половину направления в
   * окно поверх экрана. Полосу прокрутки убираем: она съела бы место
   * подписей, а что список продолжается, видно по обрезанной краем
   * вкладке. */
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.tabbar__deck::-webkit-scrollbar { display: none; }

.tabbar__item {
  /* Ширина по подписи, а не поровну на всех: подложка активной вкладки
   * должна охватывать и значок, и слово целиком. При равных долях
   * длинные подписи вылезали за свою капсулу и висели по бокам от неё.
   * Разделы, которые не поместились, уезжают за край — капсула
   * листается. */
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 0 13px;
  border-radius: 100px;
  color: var(--text-faint);
  font-size: 10.5px;
  font-weight: 550;
  white-space: nowrap;
  transition: color .2s var(--ease), background .2s var(--ease);
}

.tabbar__item svg { width: 21px; height: 21px; }

/* Активная вкладка — капсула внутри капсулы, как у Telegram.
 * Одним цветом текста тут не обойтись: на стекле подсвеченная подпись
 * читается слабее, чем на плотном фоне, и подложка возвращает ей вес. */
.tabbar__item.is-active { color: var(--accent); }

/* Та самая подложка. Одна на всю капсулу: переезжает под новую вкладку,
   а не вспыхивает на ней. Плавность здесь не для красоты — она
   показывает, откуда и куда перешёл человек, и это единственное, что
   отличает переход от подмены экрана. */
.tabbar__pill {
  position: absolute;
  top: 5px;
  bottom: 5px;
  left: 0;
  width: 0;
  border-radius: 100px;
  opacity: 0;
  pointer-events: none;
  transform-origin: center;

  /* Линза, а не плашка.
   *
   * Настоящее стекло на экране выдают три вещи: оно светлее того, что
   * под ним (свет проходит и собирается), у него есть ребро (тонкая
   * светлая кромка, где преломление сильнее всего) и блик сверху. Всё
   * это здесь есть, и ничего сверх: заливка почти прозрачная, форму
   * держит кромка. */
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .10) 0%, rgba(255, 255, 255, .03) 100%),
    var(--glass-pill);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .16),
    inset 0 1.5px 0 rgba(255, 255, 255, .22),
    inset 0 -1px 0 rgba(255, 255, 255, .05);
  backdrop-filter: brightness(1.14) saturate(1.25);
  -webkit-backdrop-filter: brightness(1.14) saturate(1.25);

  /* Переезд ведёт скрипт (см. movePill в nav.js): капля растягивается
     в полёте, а такое CSS-переходом не описать. Здесь только
     проявление. */
  transition: opacity .3s var(--ease);
}

/* В полёте ребро ярче, и по краям проступает радуга: у настоящей линзы
   на кромке цвета расходятся, и Telegram это показывает ровно в
   движении. Оттенки — из семьи акцента, а не произвольные, чтобы в
   монохромном направлении радуга не стала мультфильмом. */
.tabbar__pill.is-moving {
  box-shadow:
    inset 0 0 0 1.5px rgba(255, 255, 255, .34),
    inset 0 2px 0 rgba(255, 255, 255, .28),
    inset 2px 0 0 color-mix(in oklab, var(--accent) 55%, transparent),
    inset -2px 0 0 color-mix(in oklab, var(--accent) 35%, #7cc4ff);
  backdrop-filter: brightness(1.28) saturate(1.5);
  -webkit-backdrop-filter: brightness(1.28) saturate(1.5);
}

/* Значок стоит на своей оси: прыжок при посадке масштабирует его из
   центра, а не из угла. */
.tabbar__item > span:first-child {
  display: grid;
  place-items: center;
  transform-origin: center;
}

/* Появляется, только когда встала на место: иначе первый кадр показывал
   бы её в левом углу капсулы, откуда она потом уезжала бы к вкладке. */
.tabbar__pill.is-ready { opacity: 1; }

/* Курсор на вкладке, где уже стоишь, не обещает перехода. */
.tabbar__item:disabled,
.sidebar__item:disabled { cursor: default; }

/* Выход к выбору направления.
 *
 * Отдельной круглой кнопкой сбоку, а не пунктом в ряду: это шаг наружу,
 * а не раздел. Раньше он стоял последним в общем ряду и ловил промахи
 * пальцем при листании — а промах здесь стоит выхода из раздела.
 */
.tabbar__exit {
  flex: 0 0 auto;
  width: var(--tabbar-h);
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--text-dim);

  background: var(--bar);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-shadow), inset 0 1px 0 var(--glass-light);
  backdrop-filter: blur(22px) saturate(150%);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  transition: color .2s var(--ease);
}

.tabbar__exit:hover { color: var(--text); }
.tabbar__exit svg { width: 22px; height: 22px; }

/* ---------- Компьютер ---------- */

@media (min-width: 900px) {
  .workspace__main {
    padding-bottom: 0;
    overflow-y: auto;
  }

  .tabbar { display: none; }

  /* Боковое меню прижато к окну, а не к содержимому.
   *
   * Без этого оно растягивалось по высоте рабочей области: на экране
   * финансов та почти вдвое выше окна, и «Сменить направление», прижатое
   * к низу меню, оказывалось далеко за нижним краем экрана. Человек видел
   * меню без последнего пункта и не догадывался, что тот есть.
   *
   * align-self убирает растягивание, sticky держит меню на месте, пока
   * рабочая область прокручивается. Длинный список разделов прокрутится
   * внутри самого меню. */
  .sidebar {
    display: flex;
    flex-direction: column;
    width: var(--sidebar-w);
    flex-shrink: 0;
    align-self: flex-start;
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
    border-right: 1px solid var(--line-soft);
    background: rgba(0, 0, 0, .24);
    padding: var(--gap) var(--gap-sm);
    gap: var(--gap-xs);
    overflow-y: auto;
  }

  .sidebar__brand {
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
    padding: var(--gap-sm) var(--gap-sm) var(--gap);
    font-weight: 700;
    letter-spacing: -.01em;
  }

  .sidebar__logo {
    width: 30px;
    height: 30px;
    border-radius: 9px;
    background: var(--accent);
    display: grid;
    place-items: center;
    color: var(--on-accent);
    flex-shrink: 0;
  }

  .sidebar__group { margin-top: var(--gap); }

  .sidebar__item {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 10px 12px;
    border-radius: var(--r-sm);
    color: var(--text-dim);
    font-size: 14px;
    font-weight: 550;
    width: 100%;
    text-align: left;
    transition: background .18s var(--ease), color .18s var(--ease);
  }

  .sidebar__item svg { width: 18px; height: 18px; flex-shrink: 0; }
  .sidebar__item:hover { background: var(--card); color: var(--text); }

  .sidebar__item.is-active {
    background: var(--accent-soft);
    color: var(--text);
  }

  .sidebar__foot {
    margin-top: auto;
    padding-top: var(--gap-sm);
    border-top: 1px solid var(--line-soft);
  }

  /* На широком экране рабочая область — сетка карточек, как на
   * референсных дашбордах. Слои 4 и 5 живут одновременно. */
  .finance-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: var(--gap-lg);
    align-items: start;
  }

  .screen__inner { padding: var(--gap-lg) var(--gap-lg); }
}

@media (min-width: 1240px) {
  .finance-grid { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); }
}

/* ---------- Общие блоки страницы ---------- */

.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
  padding: var(--gap) 0 var(--gap-lg);
}

.page-head__title { display: flex; flex-direction: column; gap: 3px; }

/* Шестерёнка цвета — слева от названия (components/stylegear.js).
 *
 * Шапка растаскивает детей по краям; с третьим ребёнком название
 * оказалось бы посередине. Поэтому оно само отталкивает всё правое
 * — а шестерёнка остаётся первой слева, как и задумано. */
.page-head--gear .page-head__title { margin-right: auto; }

.stylegear { flex-shrink: 0; color: var(--text-dim); }
.stylegear:hover { color: var(--accent); }
.stylegear svg { transition: transform .5s var(--ease-soft); }
.stylegear:hover svg { transform: rotate(60deg); }

.stylegear__hint {
  font-size: 12.5px;
  color: var(--text-dim);
  line-height: 1.45;
  margin-bottom: 6px;
}

/* Сетка наборов: три в ряд. Кружок крупный — выбирают его, а не
   подпись; подпись только называет то, что уже видно. */
.stylegear__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-top: 4px;
}

.stylegear__cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  padding: 12px 4px 10px;
  border-radius: 14px;
  border: 1px solid transparent;
}

.stylegear__cell:hover { background: var(--card-hover); }
.stylegear__cell.is-on { cursor: default; border-color: var(--line); }

.stylegear__swatch {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  flex-shrink: 0;
  background: linear-gradient(145deg, var(--swatch-accent), var(--swatch-surface) 78%);
  border: 1px solid rgba(255, 255, 255, .18);
}

/* Выбранный обведён кольцом цвета чернил — с зазором в цвет окна, чтобы
   кольцо читалось как кольцо, а не как толстая рамка кружка. */
.stylegear__cell.is-on .stylegear__swatch {
  box-shadow: 0 0 0 2px var(--bg-raised), 0 0 0 3.5px var(--text);
}

.stylegear__name {
  font-size: 11.5px;
  color: var(--text-dim);
  text-align: center;
  line-height: 1.3;
}

.stylegear__cell.is-on .stylegear__name { color: var(--text); font-weight: 600; }

/* Язык — тем же окном, ниже цвета (components/stylegear.js, js/i18n.js).
   Три кнопки в ряд: языков всегда три, и выпадающий список ради трёх
   строк — лишний жест и лишний экран. */
.stylegear__title {
  margin: 16px 0 6px;
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.stylegear__langs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-bottom: 8px;
}

.stylegear__lang { padding: 10px 4px; font-size: 13px; }

.stylegear__lang.is-on {
  cursor: default;
  color: var(--text);
  font-weight: 600;
  border-color: var(--text);
}

/* Рабочая область раздела: столбик блоков на телефоне, две колонки на
 * компьютере (правило для широкого экрана — выше, в медиазапросе).
 *
 * Зазор нужен именно здесь: на телефоне колонки складываются в один
 * столбик, и без него нижняя карточка первой колонки сходилась вплотную
 * с верхней карточкой второй — «Что съедено» ложилось на «Воду». */
.finance-grid {
  display: flex;
  flex-direction: column;
  gap: var(--gap-lg);
}

.stack { display: flex; flex-direction: column; gap: var(--gap); }

/* Между соседними карточками воздуха больше, чем между строками внутри
 * них. Шестнадцати пикселей не хватало: карточки одного тона, с тонкой
 * границей, и на телефоне читались как одна длинная — «Что съедено»
 * зрительно ложилось на «Воду». */
.stack > .card + .card { margin-top: 8px; }

.row { display: flex; align-items: center; gap: var(--gap-sm); }
.row--between { justify-content: space-between; }
.spacer { flex: 1; }

/* ---------- Перелистывание разделов ---------- */

/* Раздел не подменяется, а проезжает.
 *
 * Сторона зависит от того, куда человек пошёл по ленте разделов: дальше
 * по списку — содержимое уезжает влево, назад — вправо. Это то же
 * движение, что делает палец при свайпе, и оно отвечает на вопрос «где
 * я теперь» без единой подписи.
 *
 * Анимация висит на .workspace__main, а не на самом #feature-root:
 * трансформ отбирает точку отсчёта у вложенных элементов с
 * position: fixed, и плавающая панель питания уехала бы вниз страницы.
 */
.workspace__main.is-sliding-left { animation: slide-left .26s var(--ease-soft) both; }
.workspace__main.is-sliding-right { animation: slide-right .26s var(--ease-soft) both; }

@keyframes slide-left {
  from { opacity: 0; transform: translateX(26px); }
  to   { opacity: 1; transform: none; }
}

@keyframes slide-right {
  from { opacity: 0; transform: translateX(-26px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .workspace__main.is-sliding-left,
  .workspace__main.is-sliding-right { animation: none; }
}

