/* Оболочка, навигация, экраны */

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

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
}

body {
  font-family: var(--font);
  font-weight: 600;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;
}

button, input, select { font: inherit; color: inherit; }
button { cursor: pointer; border: 0; background: none; }
a { color: var(--turquoise-dark); }

h1, h2, h3, p { margin: 0; }

/* ---------- Загрузочный экран --------------------------------------------- */
.boot {
  min-height: 100vh;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 24px;
}
.boot__logo { font-size: 28px; font-weight: 900; letter-spacing: -0.5px; }
.boot__logo span { color: var(--turquoise); }
.boot__spinner {
  width: 36px; height: 36px;
  border: 4px solid var(--ink-15);
  border-top-color: var(--turquoise);
  border-radius: 50%;
  animation: spin 700ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Каркас -------------------------------------------------------- */
.app { min-height: 100vh; }

.shell {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: 32px;
  max-width: 1100px;
  margin: 0 auto;
  padding: 28px 24px 40px;
  align-items: start;
}

.side { position: sticky; top: 28px; display: grid; gap: 8px; }
.side__logo {
  font-size: 22px; font-weight: 900; letter-spacing: -0.5px;
  padding: 4px 14px 18px;
}
.side__logo span { color: var(--turquoise); }

.navlink {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px;
  border-radius: var(--r-md);
  font-weight: 800;
  color: var(--ink-60);
  transition: background var(--dur), color var(--dur);
  text-align: left;
  width: 100%;
}
.navlink:hover { background: var(--ink-08); color: var(--ink); }
.navlink--active { background: var(--turquoise-soft); color: var(--turquoise-dark); }
.navlink__icon { font-size: 20px; line-height: 1; }
.navlink__badge {
  margin-left: auto;
  min-width: 24px; padding: 2px 7px;
  border-radius: var(--r-pill);
  background: var(--lipstick); color: var(--white);
  font-size: 12px; font-weight: 900; text-align: center;
}

.main { min-width: 0; }

.page { position: relative; display: grid; gap: 20px; animation: fade var(--dur) ease-out; }
@keyframes fade { from { opacity: 0; transform: translateY(6px); } }

.page__head { display: grid; gap: 6px; }
.page__title { font-size: 30px; font-weight: 900; letter-spacing: -0.6px; }
.page__sub { color: var(--ink-60); font-weight: 600; }

/* ---------- Кнопки -------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 52px;
  padding: 0 24px;
  border-radius: var(--r-md);
  font-weight: 900;
  font-size: 16px;
  letter-spacing: 0.2px;
  background: var(--turquoise);
  color: var(--white);
  /* «Подложка» снизу: кнопка вдавливается при нажатии */
  box-shadow: 0 var(--lift) 0 var(--turquoise-dark);
  transform: translateY(0);
  transition: transform 90ms var(--ease), box-shadow 90ms var(--ease),
              background var(--dur), opacity var(--dur);
}
/* Наведение поднимает кнопку: без него не понять, что курсор попал по ней —
   особенно у тихих кнопок вроде «выйти из аккаунта». */
.btn:hover:not(:disabled) { transform: translateY(-2px); filter: brightness(1.05); }
.btn:active:not(:disabled) {
  transform: translateY(var(--lift));
  box-shadow: 0 0 0 var(--turquoise-dark);
  filter: none;
}
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn--wide { width: 100%; }
.btn--ghost {
  background: var(--white);
  color: var(--ink);
  box-shadow: 0 var(--lift) 0 var(--ink-15);
}
/* У светлой кнопки яркость ничего не даёт — подсвечиваем её фоном и рамкой. */
.btn--ghost:hover:not(:disabled) {
  filter: none;
  background: var(--paper);
  box-shadow: 0 var(--lift) 0 var(--ink-40);
}
.btn--danger { background: var(--lipstick); box-shadow: 0 var(--lift) 0 var(--lipstick-dark); }
.btn--danger:hover:not(:disabled) { background: var(--lipstick-dark); filter: none; }
.btn--gold { background: var(--gold); box-shadow: 0 var(--lift) 0 #b97f24; }
.btn--next { background: var(--green); box-shadow: 0 var(--lift) 0 var(--green-dark); }
.btn--sm { min-height: 42px; padding: 0 18px; font-size: 14px; --lift: 3px; }
.btn--link {
  background: none; box-shadow: none; color: var(--turquoise-dark);
  min-height: auto; padding: 4px 2px; font-size: 15px; text-decoration: underline;
}
.btn--link:active { transform: none; }

/* ---------- Карточки ------------------------------------------------------ */
/* Сетка с зазором, а не просто блок: иначе кнопка внутри карточки
   прижимается к тексту над ней. */
.card {
  background: var(--white);
  border-radius: var(--r-lg);
  padding: 20px;
  box-shadow: var(--shadow-sm);
  display: grid;
  gap: 12px;
}

/* ---------- Вход и регистрация -------------------------------------------- */
.auth {
  min-height: 100vh;
  display: grid;
  /* minmax(0, 1fr), а не auto: колонка по умолчанию растёт под max-content
     содержимого, и карточка с шестью квадратами кода вылезала за край окна
     вместе с горизонтальной прокруткой. Здесь ширину задаёт окно, а карточка
     ужимается в неё. */
  grid-template-columns: minmax(0, 1fr);
  place-items: center;
  padding: 24px;
}
.auth__box {
  width: 100%; max-width: 420px;
  background: var(--white);
  border-radius: var(--r-lg);
  padding: 32px 28px;
  box-shadow: var(--shadow-lg);
  /* Колонка ограничена по той же причине, что и у .auth: иначе её ширину
     диктует самое широкое содержимое, и ряд квадратов кода вылезает за
     края карточки, вместо того чтобы ужаться внутри неё. */
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px;
}
.auth__logo { font-size: 30px; font-weight: 900; text-align: center; letter-spacing: -0.7px; }
.auth__logo span { color: var(--turquoise); }
.auth__tagline { text-align: center; color: var(--ink-60); margin-top: -8px; }

.tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
        background: var(--paper); padding: 6px; border-radius: var(--r-md); }
.tabs__btn {
  padding: 11px; border-radius: var(--r-sm); font-weight: 800; color: var(--ink-60);
  transition: background var(--dur), color var(--dur);
}
.tabs__btn--active { background: var(--white); color: var(--ink); box-shadow: var(--shadow-sm); }

.field { display: grid; gap: 6px; }
.field__label { font-size: 13px; font-weight: 800; color: var(--ink-60); padding-left: 4px; }
.field__input {
  min-height: 52px;
  padding: 0 18px;
  border-radius: var(--r-md);
  border: 2px solid var(--ink-15);
  background: var(--white);
  font-weight: 700;
  transition: border-color var(--dur), box-shadow var(--dur);
}
.field__input:focus {
  outline: none;
  border-color: var(--turquoise);
  box-shadow: 0 0 0 4px var(--turquoise-soft);
}
.field__input--error { border-color: var(--lipstick); }

.divider {
  display: flex; align-items: center; gap: 12px;
  color: var(--ink-40); font-size: 13px; font-weight: 700;
}
.divider::before, .divider::after {
  content: ''; flex: 1; height: 2px; background: var(--ink-08); border-radius: 2px;
}

.error-note {
  background: var(--lipstick-soft);
  color: var(--lipstick);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  font-size: 14px; font-weight: 700;
}

/* «Забыли пароль» — тихой строкой под полем, а не кнопкой в ряд с «Войти»:
   это выход из тупика, а не второй равноправный способ входа. */
.auth__forgot { justify-self: end; font-size: 13px; margin-top: -6px; }

/* ---------- Подтверждение почты кодом ------------------------------------- */

/* Карточка со стрелкой назад. Стрелка absolute, поэтому ей нужен свой
   относительный столбец: без него она считает координаты от окна и улетает
   в угол экрана, а не встаёт над карточкой. Отступ сверху — место под неё. */
.auth__stack {
  position: relative;
  width: 100%; max-width: 420px;
  padding-top: 56px;
}

.auth__box--verify { gap: 14px; }
.verify__title { font-size: 24px; font-weight: 900; text-align: center; line-height: 1.2; }
.verify__lead {
  text-align: center; color: var(--ink-60);
  font-size: 14px; line-height: 1.6;
}
/* Сам адрес выделен: на него смотрят, чтобы проверить, туда ли ушло письмо.
   overflow-wrap, а не word-break: тот рвал адрес посреди слова даже когда
   целиком он помещался на следующей строке. Здесь браузер сначала переносит
   адрес целиком и режет, только если он длиннее строки. */
.verify__mail { font-weight: 900; color: var(--ink); overflow-wrap: anywhere; }
.verify__note {
  background: var(--paper); border-radius: var(--r-sm);
  padding: 10px 14px; font-size: 13px; line-height: 1.5; color: var(--ink-60);
}

/* Шесть квадратов. Ширину делят поровну и ужимаются под карточку: считать её
   от ширины окна нельзя — на телефоне отступы окна и карточки съедают сотню
   пикселей, шесть квадратов переставали влезать и вылезали за край страницы.
   min-width: 0 обязателен: у input своя минимальная ширина, и без него
   flex-basis его не ужмёт. */
.code { display: flex; gap: 8px; justify-content: center; }
.code__box {
  flex: 1 1 0; min-width: 0; max-width: 52px;
  height: clamp(48px, 15vw, 62px);
  padding: 0; text-align: center;
  font-size: clamp(22px, 6vw, 27px); font-weight: 900;
  font-variant-numeric: tabular-nums;
  border-radius: var(--r-md);
  border: 2px solid var(--ink-15);
  background: var(--white); color: var(--ink);
  transition: border-color var(--dur), box-shadow var(--dur), background var(--dur);
}
.code__box:focus {
  outline: none; border-color: var(--turquoise);
  box-shadow: 0 0 0 4px var(--turquoise-soft);
}

/* Неверный код: квадраты краснеют и тряхаются, но цифры остаются на месте —
   поправить одну проще, чем набрать всё заново. */
.code--bad .code__box {
  border-color: var(--lipstick); background: var(--lipstick-soft); color: var(--lipstick);
  animation: shake 380ms var(--ease);
}

/* Верный код: волна по квадратам слева направо. Задержка на каждый следующий
   даёт ту самую волну — иначе все шесть подпрыгнули бы разом. */
.code--ok .code__box {
  border-color: var(--turquoise); background: var(--turquoise-soft);
  color: var(--turquoise-dark);
  animation: codeHop 520ms var(--ease) both;
}
.code--ok .code__box:nth-child(1) { animation-delay: 0ms; }
.code--ok .code__box:nth-child(2) { animation-delay: 70ms; }
.code--ok .code__box:nth-child(3) { animation-delay: 140ms; }
.code--ok .code__box:nth-child(4) { animation-delay: 210ms; }
.code--ok .code__box:nth-child(5) { animation-delay: 280ms; }
.code--ok .code__box:nth-child(6) { animation-delay: 350ms; }
@keyframes codeHop {
  0%, 100% { transform: translateY(0); }
  40% { transform: translateY(-14px) scale(1.06); }
}

.verify__again { display: grid; justify-items: center; }

/* ---------- Вход через сторонние сервисы ---------------------------------- */
.providers { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

.provider {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 50px;
  padding: 0 14px;
  border-radius: var(--r-md);
  border: 2px solid var(--ink-15);
  background: var(--white);
  font-weight: 800; font-size: 15px;
  transition: border-color var(--dur), background var(--dur), transform 90ms var(--ease);
}
.provider:hover { border-color: var(--ink-40); }
.provider:active { transform: scale(0.98); }

/* Значок буквой: логотипы сервисов — товарные знаки, их картинки
   в проект не кладём. */
.provider__mark {
  width: 26px; height: 26px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--white);
  font-size: 13px; font-weight: 900; line-height: 1;
}
.provider__mark--google { background: #4285f4; }
.provider__mark--vk { background: #0077ff; font-size: 11px; }
.provider__mark--yandex { background: #fc3f1d; }
.provider__mark--apple { background: var(--ink); font-size: 15px; }

.tg-slot { display: grid; justify-items: center; gap: 10px; min-height: 8px; }
.hint { font-size: 13px; color: var(--ink-40); text-align: center; line-height: 1.5; }

/* ---------- Вход через бота Telegram -------------------------------------- */
/* Сейчас не используется: на экране входа стоит официальный виджет. Стили
   оставлены вместе с рабочими эндпоинтами (api/auth/telegram/start/ и poll/)
   на случай возврата к этому входу — виджет не грузится у российских
   провайдеров, и тогда вернуться придётся. Включается одной строкой в
   js/screens/auth.js. */
.tg-login { display: grid; gap: 10px; justify-items: stretch; }

.btn--tg { background: #29a1d4; }
.btn--tg:hover { background: #2490bf; }

.tg-login__wait {
  font-size: 14px; font-weight: 700; color: var(--ink-60);
  text-align: center; line-height: 1.5;
}
.tg-login__note {
  font-size: 13px; font-weight: 700; color: var(--lipstick);
  text-align: center; line-height: 1.5;
}
.tg-login__link {
  font-size: 14px; font-weight: 700; color: var(--turquoise-dark);
  text-align: center; text-decoration: underline;
}
.tg-login__manual {
  font-size: 13px; color: var(--ink-40); text-align: center; line-height: 1.6;
}
/* Код иногда вводят руками с другого устройства — он должен читаться посимвольно. */
.tg-login__code {
  display: inline-block;
  font-family: ui-monospace, "Cascadia Mono", Menlo, Consolas, monospace;
  font-size: 15px; font-weight: 900; letter-spacing: 2px;
  color: var(--ink);
  background: var(--ink-08);
  border-radius: var(--r-sm);
  padding: 2px 8px;
  user-select: all;
}

/* ---------- Полоски и статистика ------------------------------------------ */
.statrow { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; }
.stat {
  background: var(--white); border-radius: var(--r-md); padding: 16px 18px;
  box-shadow: var(--shadow-sm); display: grid; gap: 2px;
}
.stat__value { font-size: 26px; font-weight: 900; letter-spacing: -0.5px; }
.stat__label { font-size: 13px; color: var(--ink-60); font-weight: 700; }
/* Доля от каталога — подпись помельче: это пояснение к числу, а не число. */
.stat__share { font-size: 12px; color: var(--ink-40); font-weight: 700; margin-top: 2px; }

/* Карточка с необратимым действием: отделена цветом, чтобы её не пролистали
   как обычную настройку. */
.card--danger { border: 2px solid var(--lipstick-soft); }
.card--danger .topic__title { color: var(--lipstick); }
.stat--gold .stat__value { color: var(--gold); }

/* ---------- Список тем ---------------------------------------------------- */
.level-head {
  display: flex; align-items: center; gap: 10px;
  font-size: 14px; font-weight: 900; color: var(--ink-40);
  text-transform: uppercase; letter-spacing: 1px;
  margin-top: 8px;
}
.level-head::after { content: ''; flex: 1; height: 2px; background: var(--ink-08); border-radius: 2px; }

.topics { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px; }

.topic {
  position: relative;
  background: var(--white);
  border-radius: var(--r-lg);
  padding: 18px;
  box-shadow: var(--shadow-sm);
  display: grid; gap: 12px;
  text-align: left;
  border: 2px solid transparent;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur), border-color var(--dur);
}
.topic:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.topic--mastered { border-color: var(--gold); background: var(--gold-soft); }
.topic--ready { border-color: var(--turquoise); }
/* Легендарная — золотая рамка потолще и мягкое свечение. */
.topic--legendary {
  border-color: var(--gold);
  border-width: 3px;
  background: var(--gold-soft);
  box-shadow: var(--shadow-sm), 0 0 0 4px rgba(226, 161, 60, 0.18);
}

.topic__top { display: flex; align-items: center; gap: 12px; }
.topic__emoji {
  width: 46px; height: 46px; flex: none;
  display: grid; place-items: center;
  font-size: 24px;
  background: var(--paper); border-radius: var(--r-sm);
}
.topic--mastered .topic__emoji { background: rgba(255, 255, 255, 0.75); }
.topic__title { font-weight: 900; font-size: 17px; line-height: 1.25; }
.topic__desc { font-size: 13px; color: var(--ink-60); font-weight: 600; line-height: 1.4; }

.bar { height: 10px; border-radius: var(--r-pill); background: var(--ink-08); overflow: hidden; }
.bar__fill {
  height: 100%; border-radius: var(--r-pill);
  background: var(--turquoise);
  transition: width 350ms var(--ease);
}
.bar__fill--gold { background: var(--gold); }

.topic__foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.topic__count { font-size: 13px; font-weight: 800; color: var(--ink-60); }

/* Рекорд — в две строки. Одной строкой «рекорд 1 мин 20 с» не влезает
   рядом с плашкой статуса и переносится в произвольном месте. */
.topic__count--record { display: grid; gap: 1px; line-height: 1.25; }
.topic__count-label { color: var(--ink-40); font-weight: 700; }
.topic__count-value { white-space: nowrap; font-variant-numeric: tabular-nums; }

.chip {
  font-size: 12px; font-weight: 900; padding: 4px 10px; border-radius: var(--r-pill);
  background: var(--ink-08); color: var(--ink-60);
}
.chip--ready { background: var(--turquoise-soft); color: var(--turquoise-dark); }
.chip--mastered { background: var(--gold); color: var(--white); }
/* Внутри плашки медаль и слово: flex держит их на одной линии, тогда как
   у строчного span картинка тянет базовую линию и текст съезжает вниз. */
.chip--legendary {
  background: var(--ink); color: var(--gold);
  display: inline-flex; align-items: center; gap: 5px;
}

/* ---------- Рекорд прохождения на время ----------------------------------- */
.record {
  display: inline-flex; align-items: baseline; gap: 8px;
  padding: 8px 16px;
  border-radius: var(--r-pill);
  background: var(--gold-soft);
  border: 2px solid var(--gold);
}
.record__label { font-size: 12px; font-weight: 800; color: var(--ink-60); }
.record__value { font-size: 18px; font-weight: 900; color: var(--gold); }

/* ---------- Эмодзи -------------------------------------------------------- */
/* Картинки статичные (Fluent Emoji 3D), движение целиком на CSS: сначала
   выпрыгивают, потом тихо покачиваются. Живее, чем зацикленная анимация,
   и не требует анимированных файлов. */
.emoji {
  display: block;
  width: 64px; height: 64px;
  object-fit: contain;
  user-select: none;
  animation: emojiPop 520ms var(--ease) both,
             emojiFloat 3.4s ease-in-out 520ms infinite;
}
.emoji--lg { width: 88px; height: 88px; }
.emoji--xl { width: 112px; height: 112px; }
.emoji--sm { width: 34px; height: 34px; animation: none; }
/* Анимированным качание не нужно — они и так в движении. */
.emoji--animated { animation: emojiPop 520ms var(--ease) both; }

@keyframes emojiPop {
  0%   { opacity: 0; transform: scale(0.4) rotate(-12deg); }
  55%  { opacity: 1; transform: scale(1.12) rotate(4deg); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}
@keyframes emojiFloat {
  50% { transform: translateY(-7px) rotate(-2deg); }
}

/* ---------- Уроки внутри темы --------------------------------------------- */
.lessons { display: grid; gap: 12px; }

.lesson-card {
  background: var(--white);
  border-radius: var(--r-lg);
  padding: 16px 18px;
  box-shadow: var(--shadow-sm);
  display: grid; gap: 10px;
  text-align: left;
  border: 2px solid transparent;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur), border-color var(--dur);
}
.lesson-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.lesson-card--done { border-color: var(--gold); background: var(--gold-soft); }

.lesson-card__top { display: flex; align-items: center; gap: 12px; }
.lesson-card__num {
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-sm);
  background: var(--paper);
  font-weight: 900; font-size: 17px;
}
.lesson-card--done .lesson-card__num { background: rgba(255, 255, 255, 0.6); }
.lesson-card__title { font-weight: 900; font-size: 16px; }
.lesson-card__preview {
  font-size: 13px; color: var(--ink-60); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 46vw;
}
.lesson-card__top .chip { margin-left: auto; flex: none; }

/* ---------- Трудные слова -------------------------------------------------- */
.hard-list { display: grid; gap: 10px; }
.hard {
  background: var(--white);
  border-radius: var(--r-md);
  padding: 14px 16px;
  box-shadow: var(--shadow-sm);
  border-left: 4px solid var(--lipstick);
  display: flex; align-items: center; gap: 14px;
}
.hard__head { display: flex; align-items: center; gap: 8px; }
.hard__en { font-weight: 900; font-size: 17px; }
.hard__ru { font-size: 14px; color: var(--ink-60); font-weight: 700; }
.hard__example { font-size: 13px; color: var(--ink-40); font-weight: 600; margin-top: 2px; }
.hard__side { margin-left: auto; text-align: center; flex: none; }
.hard__count { font-size: 22px; font-weight: 900; color: var(--lipstick); }
.hard__label { font-size: 11px; color: var(--ink-40); font-weight: 700; }

.speaker--sm { width: 32px; height: 32px; font-size: 15px; }

/* ---------- Разбивка повторения по темам ---------------------------------- */
/* Строка читается слева направо одной фразой: «🎨 Цвета — 5». Числа
   моноширинные, иначе столбик справа пляшет от ширины цифр.
   По стрелке тема раскрывается и показывает сами слова. */
.due-list { display: grid; gap: 8px; }
.due {
  background: var(--white);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  border-left: 4px solid var(--turquoise);
  overflow: hidden;
}
.due__head {
  width: 100%; text-align: left;
  padding: 12px 16px;
  display: flex; align-items: center; gap: 12px;
}
.due__head:hover { background: var(--paper); }
.due__emoji { font-size: 20px; flex: none; }
.due__title { font-weight: 800; font-size: 15px; }
.due__count {
  margin-left: auto; flex: none;
  font-size: 18px; font-weight: 900; color: var(--turquoise-dark);
  font-variant-numeric: tabular-nums;
}
.due__arrow {
  flex: none; width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--paper); color: var(--turquoise-dark);
  transition: transform var(--dur) var(--ease), background var(--dur);
}
/* Галочка нарисована в SVG: текстовый «⌄» в разных шрифтах висит на разной
   высоте и читается как опечатка, а не как стрелка. */
.due__arrow svg { display: block; width: 15px; height: 15px; }
.due--open .due__arrow { transform: rotate(180deg); background: var(--turquoise); color: var(--white); }

/* Раскрытие высотой через строку грида: 0fr → 1fr анимируется, в отличие
   от height: auto, и не требует замера содержимого скриптом. */
.due__body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 260ms ease; }
.due--open .due__body { grid-template-rows: 1fr; }
.due__inner { overflow: hidden; }
/* Отступ сверху обязателен: без него первое слово прилипает к строке темы
   и читается как её продолжение, а не как начало списка. */
.due__words { display: grid; gap: 4px; padding: 4px 16px 14px; }
.due__word {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-radius: var(--r-sm);
  background: var(--paper);
}
.due__en { font-weight: 900; font-size: 15px; }
.due__ru { font-size: 13px; color: var(--ink-60); font-weight: 700; }
.due__more { font-size: 12px; color: var(--ink-40); font-weight: 700; padding: 6px 10px; }

/* ---------- Выбор темы оформления ----------------------------------------- */
.themes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.theme-btn {
  display: grid; justify-items: center; gap: 8px;
  padding: 14px 8px;
  border-radius: var(--r-md);
  border: 2px solid var(--ink-15);
  font-size: 13px; font-weight: 800;
  transition: border-color var(--dur), background var(--dur);
}
.theme-btn:hover { background: var(--ink-08); }
.theme-btn--active { border-color: var(--turquoise); background: var(--turquoise-soft); }
.theme-btn__swatch {
  width: 34px; height: 34px; border-radius: 50%;
  border: 2px solid var(--ink-15);
}
.theme-btn__swatch--light { background: #f0effe; }
.theme-btn__swatch--dark { background: #161614; }
.theme-btn__swatch--auto { background: linear-gradient(135deg, #f0effe 50%, #161614 50%); }

/* ---------- Пустые состояния ---------------------------------------------- */
.empty {
  display: grid; gap: 10px; justify-items: center; text-align: center;
  padding: 48px 24px;
  background: var(--white); border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
}
.empty__emoji { font-size: 44px; }
/* Кнопка «Попробовать снова» на экране ошибки: отступ, чтобы не липла к тексту. */
.empty .btn { margin-top: 6px; }
.empty__title { font-size: 19px; font-weight: 900; }
.empty__text { color: var(--ink-60); max-width: 340px; line-height: 1.5; }

/* ---------- Профиль ------------------------------------------------------- */
/* ---------- Кнопка «назад» ------------------------------------------------- */
/* Одна на все внутренние экраны, закреплена в правом верхнем углу: раньше
   возврат назывался по-разному и лежал в разных местах — внизу списка,
   посередине результата, ссылкой сверху. */
.backbtn {
  /* Прижата к левому краю самого содержимого, а не окна: на широком экране
     колонка узкая, и кнопка у края монитора висела бы в пустоте сама по себе. */
  position: absolute;
  top: 0;
  left: 0;
  z-index: 25;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--white);
  color: var(--ink);
  font-size: 20px; font-weight: 900; line-height: 1;
  box-shadow: var(--shadow-md);
  transition: transform var(--dur) var(--ease), background var(--dur);
}
.backbtn:hover { transform: translateX(-2px); background: var(--paper); }
.backbtn:active { transform: translateX(0); }

/* Кнопка лежит поверх страницы, поэтому заголовку нужно уступить ей место —
   иначе он оказывается под ней. Отступ только там, где кнопка есть. */
.page:has(> .backbtn) .page__head { padding-left: 56px; }
.result:has(> .backbtn) .result__title { padding-inline: 56px; }

.profile-head { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
/* Имя занимает всё свободное место, серия и шестерёнка прижимаются вправо. */
/* Базовая ширина маленькая намеренно: при переносе строк flex сначала
   сравнивает базовые размеры и только потом ужимает. С крупной базой
   группа справа срывалась на вторую строку, хотя место в строке было. */
.profile-head__who { flex: 1 1 120px; min-width: 0; }
.profile-head__who .page__title { overflow-wrap: anywhere; }
.profile-head__side { display: flex; align-items: center; gap: 12px; margin-left: auto; flex: none; }
/* На телефоне имя в 30px вместе с аватаркой, серией и шестерёнкой в строку
   не помещается, и группа справа съезжает под него. Уменьшаем заголовок. */
@media (max-width: 520px) {
  .profile-head { gap: 12px; }
  .profile-head__who .page__title { font-size: 23px; }
  .streak__flame { width: 34px; height: 34px; }
  .streak__value { font-size: 26px; }
}

/* Серия дней рядом с именем. Огонёк анимированный, число — градиентом
   от оранжевого к красному: это то, на что смотрят первым делом. */
.streak { display: flex; align-items: center; gap: 6px; flex: none; }
.streak__flame { width: 40px; height: 40px; }
.streak__value {
  font-size: 30px; font-weight: 900; letter-spacing: -1px; line-height: 1;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(180deg, #ffa41b 0%, #f0592a 55%, #d61f1f 100%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
/* Шестерёнка рядом с именем: настройки — не отдельный пункт списка,
   а действие над своим профилем. */
.profile-head__gear {
  flex: none;
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--white); box-shadow: var(--shadow-sm);
  font-size: 19px;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur);
}
.profile-head__gear:hover { transform: rotate(35deg); box-shadow: var(--shadow-md); }

/* Пара плашек в одну линию: по отдельности каждая занимала всю ширину и
   гнала профиль вниз, хотя внутри — одна строка и кнопка. */
.duo { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.duo .card { gap: 10px; align-content: start; justify-items: start; }

/* ---------- Разделы настроек ------------------------------------------------ */
.setlist { display: grid; gap: 10px; }
.setrow {
  display: flex; align-items: center; gap: 14px;
  width: 100%; text-align: left;
  padding: 16px 18px;
  background: var(--white); border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur);
}
.setrow:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.setrow__icon {
  width: 44px; height: 44px; flex: none;
  display: grid; place-items: center;
  background: var(--paper); border-radius: var(--r-sm);
  font-size: 20px;
}
.setrow__title { font-weight: 900; font-size: 16px; }
.setrow__hint { font-size: 13px; color: var(--ink-60); font-weight: 600; margin-top: 2px; }
.setrow__arrow { margin-left: auto; flex: none; color: var(--ink-40); font-size: 18px;
                 font-weight: 900; }
.setrow--danger .setrow__icon { background: var(--lipstick-soft); }
.setrow--danger .setrow__title { color: var(--lipstick); }

/* Раздел, закрытый для гостя. Приглушён, но не выключен: нажатие ведёт на
   регистрацию — человек нажал именно потому, что раздел ему понадобился,
   и мёртвая строка тут была бы хуже подсказки. */
.setrow--locked .setrow__title,
.setrow--locked .setrow__arrow { opacity: 0.55; }
.setrow--locked .setrow__hint { color: var(--turquoise); opacity: 1; }

/* Сноска пробного урока и её строка в гриде живут в css/exercises.css —
   рядом с самим .lesson. Здесь их держать нельзя: styles.css подключается
   раньше exercises.css, специфичность у .lesson и .lesson--trial одинаковая,
   и правило отсюда молча проигрывало бы тому, что ниже по списку. */

/* ---------- Требования к паролю -------------------------------------------- */
/* Раскрываются по касанию поля: под пустым полем это просто четыре строки
   мелкого текста, которые никто не читает. */
.pwrules {
  display: none;
  gap: 6px;
  margin-top: -4px;
  padding: 12px 14px;
  background: var(--paper); border-radius: var(--r-sm);
  animation: riseIn 200ms var(--ease);
}
.pwrules--on { display: grid; }
.pwrules__row {
  display: flex; align-items: center; gap: 9px;
  font-size: 13px; font-weight: 700; color: var(--ink-60);
  transition: color var(--dur);
}
.pwrules__mark {
  width: 20px; height: 20px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--lipstick-soft); color: var(--lipstick);
  font-size: 11px; font-weight: 900;
  transition: background var(--dur), color var(--dur);
}
.pwrules__row--done { color: var(--turquoise-dark); }
.pwrules__row--done .pwrules__mark { background: var(--turquoise); color: var(--white); }

/* Адрес поддержки — крупно и нажимаемо: его чаще копируют, чем читают. */
.support__mail {
  display: block;
  font-size: 20px; font-weight: 900; letter-spacing: -0.3px;
  color: var(--turquoise-dark);
  padding: 14px 16px;
  background: var(--paper); border-radius: var(--r-md);
  text-align: center; text-decoration: none;
  word-break: break-all;
}
.support__mail:hover { background: var(--turquoise-soft); }
.avatar {
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--turquoise); color: var(--white);
  display: grid; place-items: center; font-size: 26px; font-weight: 900;
  object-fit: cover; flex: none;
}
/* Календарь активности. Раньше это была полоска одинаковых квадратиков без
   подписей — не понять ни какой день где, ни что означает цвет. Теперь семь
   столбцов по дням недели, число в каждой клетке и расшифровка снизу. */
.cal {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px;
  max-width: 380px;
}
.cal__weekday {
  text-align: center; font-size: 11px; font-weight: 800;
  color: var(--ink-40); text-transform: uppercase; letter-spacing: 0.4px;
  padding-bottom: 2px;
}
.cal__day {
  aspect-ratio: 1;
  display: grid; place-items: center;
  border-radius: var(--r-sm);
  background: var(--ink-08);
  font-size: 13px; font-weight: 800; color: var(--ink-60);
  font-variant-numeric: tabular-nums;
}
/* Дни, которые ещё не наступили: сетка всегда пять полных недель, и хвост
   текущей недели показываем бледно — это будущее, а не «не занимались». */
.cal__day--off { background: transparent; color: var(--ink-15); }
.cal__day--on { background: var(--turquoise); color: var(--white); }
.cal__day--goal { background: var(--gold); color: var(--white); }
.cal__day--today { box-shadow: 0 0 0 2px var(--ink-40); }

/* Сетка узкая, карточка широкая. Ставим расшифровку сбоку, чтобы правая
   половина карточки не пустовала, а на телефоне возвращаем её под сетку. */
.cal-wrap { display: flex; flex-wrap: wrap; gap: 14px 32px; align-items: flex-start; }
.cal-wrap .cal { flex: 0 1 380px; }
.cal-wrap .cal__legend { flex: 1 1 200px; }
@media (min-width: 720px) {
  .cal-wrap .cal__legend { flex-direction: column; gap: 10px; margin-top: 24px; }
}

.cal__legend { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 14px; }
.cal__key { display: flex; align-items: center; gap: 7px;
            font-size: 12px; font-weight: 700; color: var(--ink-60); }
.cal__chip { width: 14px; height: 14px; border-radius: 5px; background: var(--ink-08); flex: none; }
.cal__chip--on { background: var(--turquoise); }
.cal__chip--goal { background: var(--gold); }

/* ---------- Пояснительная плашка ------------------------------------------ */
.note {
  background: var(--paper);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  display: grid; gap: 4px;
}
.note__title { font-weight: 800; font-size: 14px; }

/* ---------- Переключатель ------------------------------------------------- */
.switch {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 0;
  cursor: pointer;
  border-top: 2px solid var(--ink-08);
}
.switch:first-of-type { border-top: 0; }
.switch__title { font-weight: 800; }
.switch__hint { font-size: 13px; color: var(--ink-60); font-weight: 600; line-height: 1.4; }

/* Настоящий чекбокс прячем, но оставляем в потоке — он держит фокус и клавиатуру. */
.switch__input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch__track {
  margin-left: auto; flex: none;
  width: 52px; height: 30px;
  border-radius: var(--r-pill);
  background: var(--ink-15);
  transition: background var(--dur);
  position: relative;
}
.switch__knob {
  position: absolute; top: 3px; left: 3px;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--white);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease);
}
.switch__input:checked ~ .switch__track { background: var(--turquoise); }
.switch__input:checked ~ .switch__track .switch__knob { transform: translateX(22px); }
.switch__input:focus-visible ~ .switch__track { box-shadow: 0 0 0 4px var(--turquoise-soft); }

/* ---------- Окно подтверждения -------------------------------------------- */
.modal {
  position: fixed; inset: 0;
  z-index: 80;
  display: grid; place-items: center;
  padding: 24px;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 180ms;
}
.modal--show { opacity: 1; }

.modal__card {
  width: 100%; max-width: 380px;
  display: grid; justify-items: center; gap: 12px;
  padding: 28px 24px 22px;
  border-radius: var(--r-lg);
  background: var(--white);
  box-shadow: var(--shadow-lg);
  text-align: center;
  transform: scale(0.92);
  transition: transform 200ms var(--ease);
}
.modal--show .modal__card { transform: scale(1); }

.modal__title { font-size: 22px; font-weight: 900; letter-spacing: -0.4px; }
.modal__text { color: var(--ink-60); font-weight: 600; line-height: 1.5; }

/* «Остаться» — крупной кнопкой сверху, «Уйти» — тихой ссылкой снизу:
   быстрый случайный тап должен оставлять человека в уроке, а не выкидывать. */
/* Между кнопками намеренно большой зазор: «Уйти» не должно оказаться
   под пальцем сразу после промаха мимо «Остаться». */
.modal__actions { width: 100%; display: grid; gap: 22px; margin-top: 8px; }
.modal__leave { color: var(--ink-40); font-weight: 700; text-decoration: none; }
.modal__leave:hover { color: var(--lipstick); text-decoration: underline; }

/* ---------- Окно-уведомление ---------------------------------------------- */
/* Пока оно открыто, страница под ним замирает: без этого человек продолжает
   листать урок и не замечает, что его о чём-то спросили. */
body.frozen { overflow: hidden; }

.notice {
  position: fixed; inset: 0;
  z-index: 90;
  display: grid; place-items: center;
  padding: 20px;
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 200ms;
  overflow-y: auto;
}
.notice--show { opacity: 1; }

.notice__card {
  position: relative;
  width: 100%; max-width: 380px;
  display: grid; gap: 12px;
  padding: 26px 22px 22px;
  border-radius: var(--r-lg);
  background: var(--white);
  box-shadow: var(--shadow-lg);
  transform: translateY(14px) scale(0.96);
  transition: transform 220ms var(--ease);
}
.notice__card--wide { max-width: 460px; padding: 0 0 18px; overflow: hidden; }
.notice--show .notice__card { transform: translateY(0) scale(1); }

.notice__close {
  position: absolute; top: 10px; right: 10px;
  z-index: 2;
  width: 34px; height: 34px; min-height: 34px;
  padding: 0;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--white);
  color: var(--ink-60);
  font-size: 15px; font-weight: 900; line-height: 1;
  box-shadow: var(--shadow-sm);
}
.notice__close:hover { color: var(--ink); }

/* Блок с эмодзи и текстом по центру карточки — сама карточка тянет
   содержимое по ширине, а такому сообщению нужна ось симметрии. */
.notice__center { display: grid; justify-items: center; gap: 10px; text-align: center; }

.notice__title { font-size: 21px; font-weight: 900; letter-spacing: -0.4px; }
.notice__text { color: var(--ink-60); font-weight: 600; line-height: 1.55; }
.notice__actions { display: grid; gap: 10px; margin-top: 6px; }

/* ---------- Пост об обновлении -------------------------------------------- */
.update__cover { display: block; width: 100%; height: auto; }
.update__body { display: grid; gap: 12px; padding: 18px 22px 0; }

/* Свёрнутый текст не обрезаем по высоте жёстко: строк мало, и «смотреть
   далее» должно открывать содержимое, а не доскроллить обрезанное. */
.update__full {
  display: grid; gap: 14px;
  max-height: min(46vh, 340px);
  overflow-y: auto;
  padding-right: 6px;
  -webkit-overflow-scrolling: touch;
}
.update__item { display: grid; gap: 3px; }
.update__item-title { font-weight: 900; font-size: 15px; }
.update__item-text { color: var(--ink-60); font-weight: 600; line-height: 1.5; font-size: 14px; }

/* ---------- Аватарки на выбор --------------------------------------------- */
.avatars {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
  gap: 10px;
}
.avatar-btn {
  padding: 6px; min-height: auto;
  border-radius: var(--r-md);
  border: 2px solid transparent;
  background: var(--paper);
  display: grid; place-items: center;
  transition: border-color var(--dur), transform 90ms var(--ease);
}
.avatar-btn:hover { border-color: var(--ink-15); }
.avatar-btn:active { transform: scale(0.95); }
.avatar-btn--active { border-color: var(--turquoise); background: var(--turquoise-soft); }
.avatar-btn img { width: 46px; height: 46px; display: block; }

/* ---------- Медали за тест на время --------------------------------------- */
.medal-row { display: grid; gap: 8px; }
.medal-line {
  display: flex; align-items: center; gap: 10px;
  font-size: 14px; font-weight: 700; color: var(--ink-60);
}
.medal-line img { width: 28px; height: 28px; flex: none; }
.medal-line--earned { color: var(--ink); }
.medal-line__time { margin-left: auto; font-variant-numeric: tabular-nums; }

/* Медаль рядом с названием темы в списке. */
.topic__medal { width: 20px; height: 20px; flex: none; }

/* ---------- Слово с подсказкой -------------------------------------------- */
/* Пунктир говорит: у слова есть перевод, по нему можно нажать. */
.hintword {
  border-bottom: 2px dotted var(--ink-40);
  cursor: help;
  transition: border-color var(--dur), background var(--dur);
  border-radius: 3px;
}
.hintword:hover { border-bottom-color: var(--turquoise); }
.hintword--open {
  background: var(--turquoise-soft);
  border-bottom-color: var(--turquoise);
}

.hintbubble {
  position: fixed;
  z-index: 70;
  max-width: min(280px, calc(100vw - 24px));
  padding: 9px 14px;
  border-radius: var(--r-sm);
  background: var(--ink);
  color: var(--paper);
  font-size: 14px; font-weight: 700; line-height: 1.35;
  text-align: center;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 140ms, transform 140ms var(--ease);
  pointer-events: none;
}
.hintbubble--show { opacity: 1; transform: translateY(0); }

/* Вторая строка подсказки — перевод всего выражения, в которое входит слово.
   «me» — это «мне», но «excuse me» целиком — «извините», и без этой строки
   перевод собирался из «простите» и «меня», хотя «меня» там нет. */
.hintbubble__rule {
  height: 1px; margin: 7px 0;
  background: currentColor; opacity: 0.25;
}
.hintbubble__phrase { font-size: 13px; font-weight: 600; }
.hintbubble__src { font-weight: 900; }

/* ---------- Полоса «нет интернета» ---------------------------------------- */
/* Внизу, а не сверху: сверху в уроке живут полоса прогресса и крестик выхода,
   и накрывать их сообщением, которое висит долго, нельзя. Над нижней
   навигацией — она перекрыла бы полосу собой. */
.offbar {
  position: fixed;
  left: 0; right: 0;
  bottom: calc(var(--nav-h) + env(safe-area-inset-bottom));
  z-index: 50;
  padding: 10px 16px;
  background: var(--lipstick); color: #fff;
  font-size: 13px; font-weight: 800; text-align: center;
  /* Спрятанное положение обязано перекрыть не только собственную высоту
     (130%), но и отступ от низа (bottom): на телефоне тот больше высоты
     самой плашки (нижняя навигация + вырез экрана), и без этой добавки
     «спрятанная» плашка всё равно торчала из-под края экрана — независимо
     от того, есть связь или нет. Один человек так видел баннер постоянно,
     хотя сеть была ни при чём. */
  transform: translateY(calc(130% + var(--nav-h) + env(safe-area-inset-bottom)));
  transition: transform var(--dur) var(--ease);
}
.offbar--show { transform: translateY(0); }
/* На широком экране нижней навигации нет — полоса встаёт к самому краю,
   и обычных 130% хватает, чтобы спрятать её целиком. */
@media (min-width: 501px) {
  .offbar {
    bottom: 0;
    transform: translateY(130%);
  }
  .offbar--show { transform: translateY(0); }
}

/* ---------- Всплывающее сообщение ----------------------------------------- */
/* Выезжает сверху: снизу его перекрывала бы нижняя навигация на телефоне.
   Центрируем через left/right + margin, а не через left: 50%, — иначе плашке
   достаётся только правая половина экрана и текст ломается на узком телефоне. */
.toast {
  position: fixed;
  /* Ниже выреза экрана и ниже полосы прогресса в уроке: у самого верха
     плашка наезжала на неё и выглядела приклеенной криво. env() отдаёт 0
     в обычной вкладке, поэтому свой минимум обязателен. */
  top: max(18px, calc(env(safe-area-inset-top) + 16px));
  left: 16px; right: 16px;
  /* Во всю ширину экрана плашка расползается на три строки и перестаёт
     читаться как короткое сообщение. */
  width: fit-content;
  max-width: min(420px, calc(100% - 32px));
  margin-inline: auto;
  transform: translateY(-140%);
  background: var(--ink); color: var(--white);
  padding: 13px 20px; border-radius: var(--r-pill);
  font-weight: 800; font-size: 14px;
  line-height: 1.35;
  text-align: center;
  box-shadow: var(--shadow-lg);
  opacity: 0; pointer-events: none;
  transition: opacity var(--dur), transform var(--dur) var(--ease);
  z-index: 60;
}
.toast--show { opacity: 1; transform: translateY(0); }
.toast--error { background: var(--lipstick); }

/* ---------- Нижняя навигация (мобильная) ---------------------------------- */
.tabbar { display: none; }

/* ---------- Мобильная раскладка ------------------------------------------- */
@media (max-width: 860px) {
  .shell {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    /* Сверху с запасом под чёлку и строку состояния: без него содержимое
       начинается прямо под вырезом экрана. env() отдаёт 0, когда сайт открыт
       обычной вкладкой, поэтому подстраховываемся своим минимумом.
       Снизу запас должен перекрывать всю нижнюю панель, иначе последняя
       карточка и кнопка выхода прячутся под ней и до них не дотянуться. */
    padding: max(16px, calc(env(safe-area-inset-top) + 10px)) 16px
             calc(var(--nav-h) + env(safe-area-inset-bottom) + 32px);
  }
  .side { display: none; }

  /* Экраны-заставки («Проверка темы», «Упражнения пройдены») ставим по центру
     свободной высоты. Прижатые к верху, они попадают под чёлку, а снизу
     остаётся пустое поле в пол-экрана. */
  .page--center {
    min-height: calc(100dvh - var(--nav-h) - env(safe-area-inset-bottom)
                     - env(safe-area-inset-top) - 96px);
    align-content: center;
  }

  .page__title { font-size: 24px; }

  .topics { grid-template-columns: minmax(0, 1fr); }

  .tabbar {
    position: fixed; left: 0; right: 0; bottom: 0;
    /* Колонки считаются от числа вкладок: с жёстким repeat(3) четвёртая
       переносилась на вторую строку и панель становилась вдвое выше. */
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    background: var(--white);
    border-top: 2px solid var(--ink-08);
    padding-bottom: env(safe-area-inset-bottom);
    z-index: 40;
  }
  .tabbar__btn {
    display: grid; justify-items: center; gap: 2px;
    padding: 10px 4px 12px;
    font-size: 11px; font-weight: 800; color: var(--ink-40);
    position: relative;
  }
  .tabbar__btn--active { color: var(--turquoise-dark); }
  .tabbar__icon { font-size: 21px; line-height: 1; }
  .tabbar__badge {
    position: absolute; top: 6px; left: 50%; margin-left: 6px;
    min-width: 18px; padding: 1px 5px;
    background: var(--lipstick); color: var(--white);
    border-radius: var(--r-pill); font-size: 10px; font-weight: 900;
  }
}

/* Мобильный заголовок отображаем компактнее */
@media (max-width: 500px) {
  .auth__box { padding: 26px 20px; }
}
