/* ============================================================
   base.css — токены темы, сброс, типографика, каркас приложения

   ГАЙД ДИЗАЙН-СИСТЕМЫ (коротко; подробности — у каждого блока ниже)
   • Брейкпоинты, mobile-first (в @media переменные не работают — пишите числа):
       телефон  < 600px  — базовые стили, без медиазапроса
       планшет  ≥ 600px  — @media (min-width: 600px)
       десктоп  ≥ 1024px — @media (min-width: 1024px): навигация — боковая панель слева (--rail-w),
                           шторки — модальные окна по центру, тосты — по центру контента.
     Для «мышь/тачпад» (hover) — @media (hover: hover) and (pointer: fine).
   • Ширина контента: --page-max (каталоги, 1200px) и --page-narrow (списки, формы, чтение, 760px).
     Экран меняет ширину ОДНОЙ строкой: .screen[data-screen="x"] { --page-max: var(--page-narrow); }
     — по ней центрируются .page / .container и выравнивается содержимое .topbar.
   • Контейнеры: .page (поля + нижний отступ), .container (центр + поля), .full-bleed (на всю ширину внутри .page).
     Сетки: .grid-auto (--grid-min задаёт минимальную ширину колонки), .stack (колонка с --stack-gap).
   • Отступы: --sp-1…--sp-8 (4, 8, 12, 16, 20, 24, 32, 48). Поля экрана: --gutter (16 → 24 → 32 px).
   • Шрифт: --fs-xs…--fs-3xl (11…34 px), --lh-tight/--lh-snug/--lh-base, --fw-*; классы .h1 .h2 .h3 .text-*.
   • Поверхности: --card/--card-2/--card-3; стекло --glass-bg(-strong/-media), --glass-border, --blur,
     --glass-filter (класс .glass); подъёмы --elev-1…--elev-3; блик --inner-hi; свечение --glow/--glow-violet.
   • Движение: --ease (базовая), --ease-out (появление), --ease-spring (пружина), --t-fast/--t/--t-slow.
     prefers-reduced-motion гасит анимации глобально (правило ниже).
   • Слои (z-index): .dock 4, топбар 5, навигация 20, своя кнопка «Назад» 25, шторки 50, просмотрщик 55, тосты 60,
     заставка 100.
   • Классы корня: html.has-nav — видна нижняя «пилюля» (телефон/планшет, корневые экраны),
     html.has-rail — видна боковая панель (десктоп), html.is-tg — открыто в Telegram.

   КАРКАС «КАК НА НАСТОЯЩЕМ ТЕЛЕФОНЕ» (core/tg.js, core/viewport.js, core/router.js)
   • Верх: --sat = --sat-sys (статус-бар) + --sat-tg (кнопки Telegram в fullscreen). html.is-fullscreen —
     Mini App на весь экран; --tg-band-l/-r — поля полосы Telegram (116/96, иначе 0). Своя шапка экрана в
     fullscreen кладёт заголовок В полосу Telegram: padding-top: var(--sat-sys), высота var(--sat-tg), поля
     max(--tg-band-l, --tg-band-r) — как .topbar (chrome.css). В полосу — только то, что не страшно на
     секунду закрыть кнопкой Telegram: заголовок или имя. topbar({right}) в fullscreen right не рисует.
   • Высота: раскладку по высоте считаем от --app-usable-h (= --app-h − --sat − --sab) и классов
     html.h-short (доступно < 560 px: Android маленький) и html.h-compact (560–659: iPhone SE, узкий
     Telegram Desktop), а не от vh и @media (max-height): в fullscreen вебвью «высокий», но его верх занят.
     Размеры внутри колонок — container-type: size и cq*.
   • Клавиатура: html.kb-open (core/viewport.js: onKeyboardChange, isKeyboardOpen). Нижняя навигация и .fab
     прячутся, .topbar и .dock перестают быть липкими; поле в фокусе прокручивается в видимую часть
     (ensureFocusVisible) с учётом scroll-padding.
   • Липкие края: у .screen scroll-padding-top/-bottom = --screen-sticky-top / --screen-sticky-bottom —
     каркас сам меряет .screen > .topbar и [data-sticky-top] (другие липкие шапки экрана), навигацию и .dock.
   • Низ: нижняя панель действий — .dock (chrome.css) + watchDock(el): сплошной фон, отступ под «домой»,
     тосты над ней (--toast-space считается сам). Свои липкие подвалы и ручной --toast-space не заводим.
   • «Назад»: router.setBackInterceptor(fn) — шаги внутри экрана (мастер); порядок: шторка → экран → история.
   • Цели касания ≥ 44 px: .btn--xs и button.chip--xs расширены невидимым ::before, .btn--icon не сжимается.
   • Имена: .text-name (перенос по слогам, не посреди слова), .name-age (имя с многоточием + возраст).
   • Ленты: .hscroll + attachHScroll(el) (core/hscroll.js: колесо мыши, гаснущие края). На телефоне в ленте —
     только то, что видно без прокрутки; остальное — «Фильтры» со шторкой.
   • Ошибка и «пусто» внутри экрана — .empty--compact (emptyState({compact: true})): у сетевой ошибки всегда
     «Повторить», у «не найдено» — «Назад».
   • Скелетон собирается из тех же блоков и классов, что готовый экран (шапка, вкладки, композер, кнопки
     на своих местах), а уже известные данные (имя, аватар из списка) рисуются сразу: ключевой элемент
     не должен сдвигаться больше чем на 4 px, когда данные пришли.
   • Кнопки действий — только свои (.btn, .dock), нативные MainButton/SecondaryButton Telegram не используем.
   ============================================================ */

:root {
  /* Палитра «ночной неон» */
  --bg: #0b0a14;
  --bg-2: #12101f;
  --card: #171526;
  --card-2: #1f1c33;
  --card-3: #2a2643;
  --line: rgba(255, 255, 255, 0.08);
  --line-2: rgba(255, 255, 255, 0.14);
  --text: #f2f0ff;
  --text-2: rgba(242, 240, 255, 0.8); /* основной текст второго плана (описания на карточках) */
  --muted: #9a95b8;
  --muted-2: #8a85a8; /* вторичный текст: ≥4.5:1 на карточках (WCAG AA) */
  --pink: #ff2d78;
  --violet: #8b5cf6;
  --violet-2: #b429f9;
  --green: #2dd4a0;
  --red: #ff4d5e;
  --amber: #ffb547;
  --focus: #c4b5fd; /* кольцо фокуса с клавиатуры */
  --grad: linear-gradient(90deg, #ff2d78, #b429f9);
  --grad-diag: linear-gradient(135deg, #ff2d78, #8b5cf6);
  --grad-soft: linear-gradient(135deg, rgba(255, 45, 120, 0.22), rgba(139, 92, 246, 0.22));
  --grad-amber: linear-gradient(135deg, #ffd27a, #ffb547 45%, #ff8a3d); /* ⚡ энергия */
  --glow: 0 8px 28px rgba(255, 45, 120, 0.35);
  /* Активный пункт сегмента-переключателя (.seg в components.css; вкладки со своей разметкой берут те же токены) */
  --seg-active-bg: linear-gradient(135deg, rgba(255, 45, 120, 0.28), rgba(139, 92, 246, 0.34));
  --seg-active-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16), 0 6px 18px -8px rgba(255, 45, 120, 0.6);
  --glow-strong: 0 10px 34px rgba(255, 45, 120, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.08) inset;
  --glow-violet: 0 0 0 4px rgba(139, 92, 246, 0.18);
  --glow-amber: 0 0 18px rgba(255, 181, 71, 0.45);
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.45);

  /* Подъёмы (тени) и блик сверху у приподнятых поверхностей */
  --elev-1: 0 1px 2px rgba(0, 0, 0, 0.35), 0 4px 14px rgba(0, 0, 0, 0.22);
  --elev-2: 0 10px 30px rgba(0, 0, 0, 0.45);
  --elev-3: 0 24px 64px rgba(0, 0, 0, 0.6);
  --inner-hi: inset 0 1px 0 rgba(255, 255, 255, 0.07);

  /* Стекло (backdrop-filter): обычное, плотное (панели), поверх медиа */
  --glass-bg: rgba(22, 19, 38, 0.72);
  --glass-bg-strong: rgba(13, 11, 24, 0.86);
  --glass-bg-media: rgba(10, 8, 20, 0.46);
  --glass-border: rgba(255, 255, 255, 0.1);
  --blur: 18px;
  --glass-filter: blur(var(--blur)) saturate(1.4);

  /* Радиусы, размеры */
  --r-xs: 8px;
  --r-sm: 10px;
  --r: 16px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-pill: 999px;
  --tap: 44px; /* минимальная зона касания */
  /* Высота кнопок .btn: обычная, крупный CTA (.btn--lg), мелкая (.btn--sm). Экран размер кнопки не задаёт —
     выбирает модификатор; скелетон кнопки берёт ту же переменную */
  --btn-h: 48px;
  --btn-h-lg: 56px;
  --btn-h-sm: 40px;
  --nav-h: 62px;
  --nav-gap: 10px; /* отступ плавающей навигации от нижнего края */
  --rail-w: 96px; /* ширина боковой панели навигации на десктопе */
  --topbar-h: 56px;
  --gutter: 16px;
  --page-max: 1200px;
  --page-narrow: 760px;
  --sheet-max: 560px;

  /* Типографика: шкала размеров, межстрочные, насыщенность */
  --fs-xs: 11px;
  --fs-sm: 13px;
  --fs-base: 15px;
  --fs-md: 17px;
  --fs-lg: 20px;
  --fs-xl: 24px;
  --fs-2xl: 28px;
  --fs-3xl: 34px;
  --lh-tight: 1.15;
  --lh-snug: 1.3;
  --lh-base: 1.45;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-heavy: 800;
  --fw-black: 900;
  --tracking-tight: -0.02em;
  --tracking-caps: 0.12em;

  /* Отступы: шаг 4px */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-7: 32px;
  --sp-8: 48px;

  /* Безопасные зоны: JS переопределяет из Telegram.WebApp.safeAreaInset (core/tg.js).
     --sat — весь небезопасный верх = --sat-sys (статус-бар, вырез) + --sat-tg (полоса кнопок Telegram
     «✕ Закрыть … ⌄ ⋯» в fullscreen, 46px; в обычном режиме 0) */
  --sat: env(safe-area-inset-top, 0px);
  --sat-sys: env(safe-area-inset-top, 0px);
  --sat-tg: 0px;
  --sab: env(safe-area-inset-bottom, 0px);
  --sal: env(safe-area-inset-left, 0px);
  --sar: env(safe-area-inset-right, 0px);
  /* Поля полосы Telegram в fullscreen: слева «✕ Закрыть»/«‹ Назад» (ширина плавает — берём с запасом),
     справа «⌄ ⋯». Вне fullscreen — 0 (html.is-fullscreen ниже) */
  --tg-band-l: 0px;
  --tg-band-r: 0px;
  /* Высота приложения: 100dvh если поддерживается, в Telegram — viewportStableHeight из JS */
  --app-h: 100vh;
  /* Доступная высота: без статус-бара, кнопок Telegram и полосы «домой». Раскладку по высоте считаем
     от неё (и классов html.h-short / html.h-compact), а не от vh и @media (max-height) */
  --app-usable-h: calc(var(--app-h) - var(--sat) - var(--sab));
  /* Липкие края текущего экрана (меряет core/viewport.js): шапка сверху, навигация или .dock снизу */
  --screen-sticky-top: 0px;
  --screen-sticky-bottom: 0px;

  /* Системный стек: CSP (font-src 'self' data:) не пускает Google Fonts, свой файл шрифта не нужен —
     SF Pro на iOS/macOS, Roboto на Android, Segoe UI Variable на Windows 11 */
  --font: -apple-system, BlinkMacSystemFont, "Inter", "Roboto", "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-spring: cubic-bezier(0.34, 1.45, 0.64, 1);
  --t-fast: 140ms;
  --t: 220ms;
  --t-slow: 360ms;
}

@supports (height: 100dvh) {
  :root { --app-h: 100dvh; }
}
.is-fullscreen { --tg-band-l: 116px; --tg-band-r: 96px; }

/* Поля экрана растут вместе с экраном */
@media (min-width: 600px) { :root { --gutter: 24px; } }
@media (min-width: 1024px) { :root { --gutter: 32px; } }

*, *::before, *::after { box-sizing: border-box; }

/* Атрибут hidden должен побеждать любые display из компонентов
   (иначе .btn/.chip/.composer__row с display:flex остаются видимыми) */
[hidden] { display: none !important; }

html {
  height: 100%;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--bg);
}

body {
  margin: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-base);
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  user-select: none;
  -webkit-user-select: none;
  overscroll-behavior: none;
  overflow: hidden;
}

/* Мягкое фиолетовое свечение фона */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(60% 40% at 50% -10%, rgba(139, 92, 246, 0.35), transparent 70%),
    radial-gradient(45% 30% at 100% 105%, rgba(255, 45, 120, 0.14), transparent 70%);
}

#app {
  position: relative;
  z-index: 1;
  height: var(--app-h);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.screen {
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding-left: var(--sal);
  padding-right: var(--sar);
  /* Прокрутка к полю или плашке (scrollIntoView, фокус) не прячет их под липкой шапкой и нижней панелью */
  scroll-padding-top: max(var(--screen-sticky-top, 0px), var(--sat, 0px));
  scroll-padding-bottom: var(--screen-sticky-bottom, 0px);
}

/* Экраны с собственной прокруткой (чат, звонок, лента) */
.screen[data-screen="chat"],
.screen[data-screen="call"],
.screen[data-screen="feed"] { overflow: hidden; }

/* Ширина по умолчанию: списки, формы и чтение — узкой колонкой (экран может переопределить у себя) */
.screen[data-screen="chats"],
.screen[data-screen="profile"],
.screen[data-screen="partner"],
.screen[data-screen="create"],
.screen[data-screen="chat"] { --page-max: var(--page-narrow); }

/* Корневые экраны: запас под плавающую навигацию, чтобы контент не прятался под ней */
.has-nav .screen { padding-bottom: calc(var(--nav-h) + var(--nav-gap) + var(--sab) + 14px); }
.has-nav .screen[data-screen="feed"] { padding-bottom: 0; }

/* Клавиатура открыта (html.kb-open, core/viewport.js): места над ней мало — нижняя навигация и «Создать»
   прячутся, шапка и нижняя панель .dock перестают быть липкими и не закрывают поле, в которое печатают.
   Десктопную боковую панель не трогаем: она не над контентом, а рядом */
@media (max-width: 1023.98px) {
  .kb-open .bottom-nav { display: none; }
}
.kb-open .fab { display: none; }
.kb-open .topbar { position: relative; }
.kb-open .dock { position: static; }

/* Десктоп: навигация — колонка слева, экран — справа (см. .bottom-nav в chrome.css) */
@media (min-width: 1024px) {
  #app { flex-direction: row; }
}

input, textarea, select, button {
  font: inherit;
  color: inherit;
}
input, textarea, select { user-select: text; -webkit-user-select: text; }
button { cursor: pointer; border: 0; background: none; padding: 0; margin: 0; }
button:disabled { cursor: default; opacity: 0.55; }
a { color: var(--violet); text-decoration: none; }
img, video { display: block; max-width: 100%; }
img { -webkit-user-drag: none; }
h1, h2, h3, h4, p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
::selection { background: rgba(255, 45, 120, 0.35); color: #fff; }

::-webkit-scrollbar { width: 0; height: 0; }
/* Мышь: тонкая вертикальная полоса прокрутки (горизонтальные ленты остаются без неё) */
@media (hover: hover) and (pointer: fine) {
  .screen::-webkit-scrollbar,
  .sheet__body::-webkit-scrollbar { width: 10px; }
  .screen::-webkit-scrollbar-thumb,
  .sheet__body::-webkit-scrollbar-thumb {
    border: 3px solid transparent;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.14) padding-box;
  }
  .screen::-webkit-scrollbar-thumb:hover,
  .sheet__body::-webkit-scrollbar-thumb:hover { background-color: rgba(255, 255, 255, 0.24); }
}

/* Фокус с клавиатуры: единое заметное кольцо (мышь и тач его не показывают).
   У полей ввода своя подсветка рамкой — кольцо им не нужно. */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.input:focus-visible, .textarea:focus-visible, .select:focus-visible { outline: none; }

/* ---------- Типографика ---------- */
.h1 { font-size: var(--fs-2xl); font-weight: var(--fw-heavy); letter-spacing: var(--tracking-tight); line-height: var(--lh-tight); }
.h2 { font-size: var(--fs-lg); font-weight: var(--fw-bold); letter-spacing: -0.01em; line-height: 1.2; }
.h3 { font-size: 16px; font-weight: var(--fw-bold); line-height: var(--lh-snug); }
.display { font-size: var(--fs-3xl); font-weight: var(--fw-black); letter-spacing: -0.03em; line-height: 1.05; }
.text-xs { font-size: var(--fs-xs); }
.text-sm { font-size: var(--fs-sm); }
.text-base { font-size: var(--fs-base); }
.text-md { font-size: var(--fs-md); }
.text-lg { font-size: var(--fs-lg); }
.text-2 { color: var(--text-2); }
.muted { color: var(--muted); }
.small { font-size: var(--fs-sm); }
.tiny { font-size: var(--fs-xs); }
.bold { font-weight: var(--fw-bold); }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.tabular { font-variant-numeric: tabular-nums; }
.clamp-2, .clamp-3 { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.clamp-2 { -webkit-line-clamp: 2; line-clamp: 2; }
.clamp-3 { -webkit-line-clamp: 3; line-clamp: 3; }
.grad-text {
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* Ровные переносы: заголовки — сбалансированно, абзацы — без «висячих» слов */
.h1, .h2, .h3, .display { text-wrap: balance; }
.section-title {
  font-size: 12px;
  font-weight: var(--fw-bold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--muted);
  margin: 22px 0 10px;
}
/* Доступный скрытый текст (для экранных читалок) */
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Каркас и утилиты раскладки ---------- */
.page {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding: 0 var(--gutter) calc(24px + var(--sab));
}
.page--nav { padding-bottom: 8px; } /* остальной запас даёт .has-nav .screen */
.page--narrow { max-width: var(--page-narrow); }
.page--wide { max-width: none; }
.container {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
/* Внутри .page/.container: блок на всю ширину экрана (горизонтальные ленты, баннеры) */
.full-bleed { margin-inline: calc(var(--gutter) * -1); }
.grid-auto {
  display: grid;
  gap: var(--grid-gap, var(--sp-3));
  grid-template-columns: repeat(auto-fill, minmax(min(var(--grid-min, 160px), 100%), 1fr));
}
.stack { display: flex; flex-direction: column; gap: var(--stack-gap, var(--sp-3)); }
.row { display: flex; align-items: center; gap: 10px; }
.row--between { justify-content: space-between; }
.col { display: flex; flex-direction: column; gap: 10px; }
.grow { flex: 1; min-width: 0; }
.wrap { flex-wrap: wrap; }
.mt-8 { margin-top: 8px; } .mt-12 { margin-top: 12px; } .mt-16 { margin-top: 16px; } .mt-24 { margin-top: 24px; }
.mb-8 { margin-bottom: 8px; } .mb-12 { margin-bottom: 12px; } .mb-16 { margin-bottom: 16px; }
.ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hidden { display: none !important; }
.selectable { user-select: text; -webkit-user-select: text; }
/* Показ по брейкпоинтам */
@media (max-width: 1023.98px) { .only-desktop { display: none !important; } }
@media (min-width: 1024px) {
  .hide-desktop { display: none !important; }
  .page--nav { padding-bottom: calc(var(--sp-7) + var(--sab)); }
}
@media (max-width: 599.98px) { .hide-phone { display: none !important; } }

/* Стекло: полупрозрачная панель с размытием того, что под ней */
.glass {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
}

/* ---------- Анимации ---------- */
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes rise-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes pop-in { from { opacity: 0; transform: scale(0.94); } to { opacity: 1; transform: none; } }
@keyframes shimmer { from { background-position: -200% 0; } to { background-position: 200% 0; } }
/* Единый блик скелетонов (.skeleton): мягкая полоса слева направо */
@keyframes sheen { from { background-position: 180% 0; } to { background-position: -80% 0; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse-ring { 0% { transform: scale(1); opacity: 0.8; } 100% { transform: scale(1.35); opacity: 0; } }
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@keyframes bounce-dot { 0%, 80%, 100% { transform: translateY(0); opacity: 0.4; } 40% { transform: translateY(-4px); opacity: 1; } }
@keyframes glow-pulse { 0%, 100% { box-shadow: var(--glow); } 50% { box-shadow: var(--glow-strong); } }

.fade-in { animation: fade-in var(--t) var(--ease) both; }
.rise-in { animation: rise-in 260ms var(--ease) both; }
.pop-in { animation: pop-in 260ms var(--ease-out) both; }
/* Каскад появления: style="--i: 3" у элемента списка → задержка 3 × 40 мс */
.stagger > * { animation: rise-in 320ms var(--ease-out) both; animation-delay: calc(min(var(--i, 0), 10) * 40ms); }

/* Переход между экранами: router.js ставит .is-entering + data-nav-dir на время появления.
   Вкладки (replace) — растворение; вперёд/назад — лёгкий сдвиг содержимого, шапка только проявляется.
   Сам .screen не сдвигаем: transform на нём сломал бы position: fixed у детей (.fab) */
@keyframes screen-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes screen-in-fwd { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }
@keyframes screen-in-back { from { opacity: 0; transform: translateX(-16px); } to { opacity: 1; transform: none; } }
.screen.is-entering[data-nav-dir="replace"] { animation: screen-in 200ms var(--ease-out) both; }
.screen.is-entering[data-nav-dir="forward"] > :not(.topbar):not(.fab) { animation: screen-in-fwd 280ms var(--ease-out) both; }
.screen.is-entering[data-nav-dir="back"] > :not(.topbar):not(.fab) { animation: screen-in-back 280ms var(--ease-out) both; }
.screen.is-entering[data-nav-dir="forward"] > .topbar,
.screen.is-entering[data-nav-dir="back"] > .topbar { animation: screen-in 200ms var(--ease-out) both; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Пустое состояние или ошибка вместо всего экрана — по центру, а не прижато к верху */
.screen > .empty { min-height: 100%; justify-content: center; padding-bottom: calc(48px + var(--sab)); }
.screen > .empty--compact { padding-bottom: calc(20px + var(--sab)); }
