/* app.bundle.css — автосборка релиза (scripts/bundle_js.py).
   Исходники — отдельные файлы в /css/ (порядок как в app.html). */

/* ===== /css/fonts.css ===== */
/* fonts.css — self-hosted Inter/Nunito (woff2, cyrillic+latin).
   Источник начертаний: Google Fonts (SIL OFL). Файлы в /public/fonts/ —
   без внешнего CDN: быстрее, стабильнее и данные не уходят третьей стороне.

   ⚠ Это ВАРИАТИВНЫЕ шрифты: в одном файле лежит вся ось насыщенности
   (Inter wght 100–900, Nunito wght 200–1000). Раньше здесь было 14
   @font-face на 4 физических файла — одни и те же байты качались по
   4 разным URL (Inter latin 48 КБ × 4, Inter cyrillic 19 КБ × 4 и т.д.),
   ~270 КБ лишнего трафика и 10 лишних запросов на КАЖДОМ первом заходе.
   Теперь — одно объявление на семейство и подмножество, с диапазоном
   font-weight: браузер сам ставит ось под нужный вес. Начертания
   выглядят ровно так же.

   Разбиение на cyrillic/latin оставлено намеренно: unicode-range даёт
   браузеру право не качать латиницу, пока она не встретилась в тексте. */

/* --- Inter (основной текст) ------------------------------------------ */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/public/fonts/inter-400-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/public/fonts/inter-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --- Nunito (заголовки) ---------------------------------------------- */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url(/public/fonts/nunito-700-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url(/public/fonts/nunito-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ===== /css/design-tokens.css ===== */
/* design-tokens.css — единственный источник истины по дизайн-токенам.
 * Значения — из SYSTEM_DESIGN.md §1. CSS Custom Properties + темы. */

:root {
  /* === ЦВЕТА (брендбук маскота ФокуснИИк) === */
  --clr-primary:        #6B5CFF;   /* Основной индиго бренда */
  --clr-primary-hover:  #5648E0;
  --clr-primary-light:  #EDEBFF;   /* Бледный тон для фонов (бейджи, активные состояния) */
  --clr-primary-soft:   #A78BFA;   /* Светло-фиолетовый бренда (градиенты, вторичные акценты) */
  --clr-accent:         #22D3EE;   /* Голубой «магии/ИИ». ДЕКОР-ОНЛИ: контраст с белым низкий, не для текста */
  --clr-accent-light:   #E2FBFF;

  /* Цвет содержимого НА заливке --clr-primary (текст кнопок, иконки, бейдж Pro).
     Отдельный токен, потому что в тёмной теме бренд светлеет и белым по нему
     писать нельзя: #FFF на #9C8FFF даёт 2.7:1 при норме 4.5:1. Каждая пара
     ниже проверена по WCAG 2.1 — светлая 4.57, тёмная 6.55, тихая 5.86,
     контрастная 11.22. Правило: ни один текст не ставится на --gradient-brand,
     он только декор (полоса прогресса, свечение). */
  --clr-on-primary:     #FFFFFF;

  --clr-text-1:         #2D2640;   /* Заголовки */
  --clr-text-2:         #6B6485;   /* Основной текст */
  --clr-text-3:         #736C8A;   /* Плейсхолдеры, подписи — затемнён до WCAG AA 4.5:1 на светлых поверхностях */

  --clr-success:        #3DB88A;
  --clr-warning:        #F0A030;
  --clr-error:          #E05555;
  --clr-info:           #4A9EE8;

  --clr-surface:        #FFFFFF;
  --clr-surface-2:      #F7F6FB;   /* Карточки, фоны */
  --clr-surface-3:      #EFECF8;   /* Hover состояния */
  --clr-border:         #E2DDEE;

  /* Фирменный градиент-подпись: строится из тем-токенов → сам адаптируется во
     всех 4 темах (значения ниже переопределяются per-theme). Повторяющийся мотив
     бренда: номера шагов, плашки иконок, eyebrow, прогресс квиза. */
  --gradient-brand: linear-gradient(135deg, var(--clr-primary) 0%, var(--clr-primary-soft) 55%, var(--clr-accent) 100%);

  /* === LIQUID GLASS ===
   * Слой «настоящего стекла»: полупрозрачная подложка + backdrop-filter с
   * повышенной насыщенностью (стекло не мутнит цвет за собой, а концентрирует
   * его) + внутреннее свечение по верхней кромке + тонкая световая граница.
   * Токены относительные (rgba белого/чёрного), поэтому работают на любой
   * поверхности — и на графите лендинга, и на фиолетовом фоне приложения.
   *
   * ⚠ Перф: backdrop-filter — дорогая композиция. Держите ≤10 одновременно
   * видимых стеклянных слоёв на экран и не вкладывайте стекло в стекло глубже
   * двух уровней. Радиусы blur на мобильном урезаны (см. медиазапрос ниже).
   *
   * Уровни: sm — мелкие плавающие элементы (чипы, пилюли);
   *         md — карточки и панели контента;
   *         lg — крупные «облака» (навигация, финальная CTA-панель). */
  --glass-blur-sm: 14px;
  --glass-blur-md: 24px;
  --glass-blur-lg: 36px;
  --glass-saturate: 180%;

  /* Заливка стекла и его световая оптика (светлая схема — frosted-белый). */
  --glass-fill:     rgba(255, 255, 255, 0.62);
  --glass-fill-2:   rgba(255, 255, 255, 0.44);
  --glass-edge:     rgba(255, 255, 255, 0.95);  /* верхняя световая кромка */
  --glass-edge-dim: rgba(255, 255, 255, 0.28);  /* нижняя, затухающая */
  --glass-hairline: rgba(12, 14, 20, 0.10);     /* контур на светлом фоне */
  --glass-specular: rgba(255, 255, 255, 0.55);  /* блик-рефракция */
  --glass-shadow:
    0 1px 2px rgba(12, 14, 20, 0.04),
    0 10px 30px rgba(12, 14, 20, 0.08),
    0 30px 60px rgba(12, 14, 20, 0.06);

  /* === ТИПОГРАФИКА === */
  --font-heading:       'Nunito', system-ui, sans-serif;
  --font-body:          'Inter', system-ui, sans-serif;

  /* Мелкие кегли подняты на 1px: 12px — ниже комфортного порога чтения при
     дислексии, а именно ими набраны подписи, даты и хинты полей. */
  --text-xs:    13px;
  --text-sm:    15px;
  --text-base:  16px;
  --text-lg:    18px;
  --text-xl:    20px;
  /* Крупные размеры — флюидные (clamp): плавно тянутся между мобильным минимумом
     и десктопным максимумом, без ступеней и без @media-переопределений. Значения
     подобраны так, что на десктопе = прежним px, а на телефоне мягко меньше. */
  --text-2xl:   clamp(1.25rem, 1.10rem + 0.75vw, 1.5rem);    /* 20 → 24 */
  --text-3xl:   clamp(1.5rem, 1.25rem + 1.25vw, 1.875rem);   /* 24 → 30 */
  --text-4xl:   clamp(1.75rem, 1.40rem + 1.75vw, 2.25rem);   /* 28 → 36 */
  --text-5xl:   clamp(2.125rem, 1.60rem + 2.40vw, 3rem);     /* 34 → 48 */
  /* Отдельный hero-размер: крупнее display, «уверенный» первый экран мирового
     SaaS. 40 → 64px. Только для маркетингового заголовка лендинга. */
  --text-hero:  clamp(2.5rem, 1.85rem + 3.0vw, 4rem);        /* 40 → 64 */

  --leading-tight:   1.25;
  --leading-normal:  1.5;
  --leading-relaxed: 1.65;  /* Основной для нейроотличных */

  --font-normal:  400;
  --font-medium:  500;
  --font-semi:    600;
  --font-bold:    700;

  /* === ОТСТУПЫ === */
  --space-1:   4px;
  --space-2:   8px;
  --space-3:   12px;
  --space-4:   16px;
  --space-5:   20px;
  --space-6:   24px;
  --space-8:   32px;
  --space-10:  40px;
  --space-12:  48px;
  --space-16:  64px;
  --space-20:  80px;

  /* === СКРУГЛЕНИЯ ===
   * Шкала поднята: 10px радиуса при высоте кнопки 44px — пропорция 2019-2021.
   * Правило вложенного радиуса: внутренний = внешний − отступ до края
   * (иначе углы визуально «косят»). Пример — .task-card__head в tasks.css. */
  --radius-sm:   8px;
  --radius-md:   12px;
  --radius-lg:   18px;
  --radius-xl:   26px;
  --radius-full: 9999px;

  /* === ТЕНИ === многослойные, низкая непрозрачность (премиальная мягкая глубина) */
  --shadow-xs:  0 1px 2px rgba(44, 38, 64, 0.05);
  --shadow-sm:  0 1px 2px rgba(44, 38, 64, 0.04), 0 2px 8px rgba(44, 38, 64, 0.05);
  --shadow-md:  0 2px 4px rgba(44, 38, 64, 0.05), 0 8px 20px rgba(44, 38, 64, 0.08);
  --shadow-lg:  0 4px 10px rgba(44, 38, 64, 0.06), 0 18px 44px rgba(44, 38, 64, 0.12);

  /* === АНИМАЦИИ ===
   * Кривые вместо браузерного `ease`: `ease` — дефолт, который читается как
   * «движение не настраивали». `linear()` (пружина) поддержана везде с 2024
   * и даёт настоящий отскок без JS.
   *   out-quart  — появление и hover: быстрый старт, мягкая остановка;
   *   in-out     — перемещение объекта из точки в точку;
   *   spring     — отклик на действие пользователя (нажатие, отметка);
   *   emphasis   — овершут для момента успеха.
   * Правило для нейроотличных: длительность ≤300мс, движение всегда следствие
   * действия пользователя, ничего бесконечного в периферии зрения. */
  --ease-out-quart:    cubic-bezier(0.25, 1, 0.5, 1);
  --ease-in-out-quart: cubic-bezier(0.76, 0, 0.24, 1);
  --ease-spring:       linear(0, 0.28 8%, 0.78 20%, 1.03 32%, 1.01 46%, 1);
  --ease-emphasis:     cubic-bezier(0.34, 1.56, 0.64, 1);

  --transition-fast:   150ms var(--ease-out-quart);
  --transition-normal: 250ms var(--ease-out-quart);
  --transition-slow:   400ms var(--ease-out-quart);

  /* === Z-INDEX === */
  --z-base:    1;
  --z-sticky:  100;
  --z-overlay: 200;
  --z-modal:   300;
  --z-toast:   400;
  --z-tooltip: 500;

  /* === МАКЕТ === */
  --container-max: 1140px;
  --sidebar-width: 240px;

  /* === КАРТОЧКИ-«ЗАМЕТКИ» (страница Задач) ===
   * Бумага блокнота + шапка-обложка цветом приоритета. Текст на шапку не
   * кладём (кроме ярлыка hero — для него парный ink-тон того же семейства). */
  --note-paper:       #FFFDF7;   /* тёплая бумага, теплее --clr-surface */
  --note-line:        #F0EBDC;   /* «линейки» тетради и кромка бумаги */
  --note-perf:        #D9D2BE;   /* точки перфорации под шапкой */
  --note-head-low:    #BFE3D4;   /* мятная — «лёгкое» */
  --note-ink-low:     #1F5C44;
  --note-head-medium: #F7CE46;   /* жёлтая — обычная (классический блокнот) */
  --note-ink-medium:  #63511A;
  --note-head-high:   #F0A08A;   /* коралловая — «важное» */
  --note-ink-high:    #5C2413;
}

/* Тёмная тема */
[data-theme="dark"] {
  --clr-primary:       #9C8FFF;
  --clr-primary-hover: #ADA2FF;
  --clr-primary-light: #2A2548;
  --clr-primary-soft:  #B9A6FF;
  /* Бренд в тёмной теме светлее фона, поэтому содержимое на нём — тёмное
     (тот же приём, что у капсулы лендинга). #1A1628 на #9C8FFF = 6.55:1. */
  --clr-on-primary:    #1A1628;
  --clr-accent:        #34DAF2;
  --clr-accent-light:  #16313A;
  --clr-text-1:        #F0EDF8;
  --clr-text-2:        #C4BEDE;
  --clr-text-3:        #887FA8;
  --clr-surface:       #1A1628;
  --clr-surface-2:     #221E33;
  --clr-surface-3:     #2D2845;
  --clr-border:        #352F50;

  /* Стекло на тёмном: заливка почти прозрачная (иначе получается «молоко»),
     а объём держится на световой кромке и глубокой внешней тени. */
  --glass-fill:     rgba(255, 255, 255, 0.055);
  --glass-fill-2:   rgba(255, 255, 255, 0.028);
  --glass-edge:     rgba(255, 255, 255, 0.20);
  --glass-edge-dim: rgba(255, 255, 255, 0.04);
  --glass-hairline: rgba(255, 255, 255, 0.10);
  --glass-specular: rgba(255, 255, 255, 0.12);
  --glass-shadow:
    0 1px 2px rgba(0, 0, 0, 0.30),
    0 12px 32px rgba(0, 0, 0, 0.38),
    0 34px 68px rgba(0, 0, 0, 0.30);

  /* Заметки: бумага чуть светлее фона страницы (surface-2), шапки приглушены */
  --note-paper:       #272242;
  --note-line:        #363052;
  --note-perf:        #4A4370;
  --note-head-low:    #2E5747;
  --note-ink-low:     #A9DFC8;
  --note-head-medium: #7A6B2E;
  --note-ink-medium:  #F0E3A8;
  --note-head-high:   #7A3A2E;
  --note-ink-high:    #F5C4B3;
}

/* Приглушённая тема (сенсорная чувствительность) */
[data-theme="muted"] {
  /* Бренд затемнён относительно прежнего #8E8BAA: тот был слишком средним по
     светлоте, чтобы нести хоть какой-то текст — белый давал 3.27:1, тёмный
     4.39:1, и заодно ссылки/активный пункт меню читались на 3.12:1.
     «Тихая» тема — это низкая насыщенность, а не низкий контраст. */
  --clr-primary:       #63608C;
  --clr-primary-hover: #524F78;
  --clr-primary-soft:  #A6A1BE;
  --clr-on-primary:    #FFFFFF;
  --clr-accent:        #7FB0B8;   /* Приглушённый акцент — без яркого голубого */
  --clr-accent-light:  #E9F1F2;
  --clr-success:       #6BA892;
  --clr-warning:       #B8955A;
  --clr-error:         #B07070;
  --clr-surface:       #FAF9FC;
  --clr-surface-2:     #F3F1F7;
  --clr-surface-3:     #EBE8F2;

  /* Заметки: без ярких обложек — приглушённые тона тех же семейств */
  --note-paper:       #FCFBF7;
  --note-line:        #E9E5DA;
  --note-perf:        #D8D3C4;
  --note-head-low:    #C9DDD3;
  --note-ink-low:     #3E5A4E;
  --note-head-medium: #E3D49A;
  --note-ink-medium:  #5C5024;
  --note-head-high:   #DDB4A8;
  --note-ink-high:    #5C332A;
}

/* Высокий контраст */
[data-theme="high-contrast"] {
  --clr-text-1:  #000000;
  --clr-text-2:  #111111;
  --clr-text-3:  #333333;
  --clr-border:  #000000;
  --clr-primary: #0000CC;
  --clr-primary-hover: #0000AA;
  --clr-primary-soft: #0000CC;
  --clr-on-primary: #FFFFFF;   /* 11.22:1 на #0000CC */
  --clr-accent: #006782;   /* Тёмный teal — достаточный контраст в режиме высокого контраста */
  --clr-accent-light: #FFFFFF;
  --clr-surface:   #FFFFFF;
  --clr-surface-2: #FFFFFF;
  --clr-surface-3: #F0F0F0;

  /* Заметки: цвет не носитель смысла — шапки чёрные, приоритет читается
   * словом «Важное» в мета-строке; бумага и линейки — максимальный контраст */
  --note-paper:       #FFFFFF;
  --note-line:        #000000;
  --note-perf:        #000000;
  --note-head-low:    #000000;
  --note-ink-low:     #FFFFFF;
  --note-head-medium: #000000;
  --note-ink-medium:  #FFFFFF;
  --note-head-high:   #000000;
  --note-ink-high:    #FFFFFF;
}

/* Стекло на мобильном: blur считается для каждого кадра прокрутки по площади
   слоя, поэтому радиусы урезаны почти вдвое. Визуально разница на 6" экране
   незаметна, а скролл остаётся 60 FPS на среднем Android. */
@media (max-width: 640px) {
  :root {
    --glass-blur-sm: 10px;
    --glass-blur-md: 16px;
    --glass-blur-lg: 22px;
  }
}

/* Уважение системной настройки уменьшенного движения. Явный выбор в Настройках
   главнее: при data-reduced-motion="false" длительности остаются живыми
   (см. animations.css и FN.motion в core/fn.js). */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-reduced-motion="false"]) {
    --transition-fast:   0ms;
    --transition-normal: 0ms;
    --transition-slow:   0ms;
  }
}

/* Явное отключение анимаций пользователем (атрибут на <html>) */
[data-reduced-motion="true"] {
  --transition-fast:   0ms;
  --transition-normal: 0ms;
  --transition-slow:   0ms;
}

/* ===== /css/reset.css ===== */
/* reset.css — современный CSS reset. */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Убираем серую вспышку при тапе на iOS/Android — фирменные :active важнее. */
  -webkit-tap-highlight-color: transparent;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  min-height: 100vh;
  min-height: 100dvh; /* iOS: без «прыжка» при сворачивании адресной строки */
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
  height: auto;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
  background: none;
  border: none;
}

a {
  color: inherit;
  text-decoration: none;
}

ul,
ol {
  list-style: none;
}

/* Видимый фокус для доступности (WCAG 2.2 — 2.4.7 + 2.4.11 Focus Appearance) */
:focus-visible {
  outline: 3px solid var(--clr-primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Скрытие визуально, но доступно скринридерам */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ===== /css/typography.css ===== */
/* typography.css — шрифты и текстовые стили.
 * line-height relaxed (1.65) — основной для нейроотличных пользователей. */

body {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--font-normal);
  line-height: var(--leading-relaxed);
  color: var(--clr-text-2);
  background: var(--clr-surface);
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: var(--font-bold);
  line-height: var(--leading-tight);
  /* Без отрицательного трекинга: аудитория с дислексией читает заголовки лучше
     при нормальных/чуть увеличенных интервалах, а не при сжатых. */
  letter-spacing: normal;
  color: var(--clr-text-1);
}

h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-2xl); }
h4 { font-size: var(--text-xl); }
h5 { font-size: var(--text-lg); }

p {
  max-width: 70ch; /* комфортная длина строки для чтения */
}

a {
  color: var(--clr-primary);
  transition: color var(--transition-fast);
}

a:hover {
  color: var(--clr-primary-hover);
}

strong { font-weight: var(--font-semi); }

.text-muted   { color: var(--clr-text-3); }
.text-lead    { font-size: var(--text-lg); color: var(--clr-text-2); }
.text-center  { text-align: center; }
.text-balance { text-wrap: balance; }

.display {
  font-family: var(--font-heading);
  font-size: var(--text-5xl);
  font-weight: var(--font-bold);
  line-height: 1.08;
  /* Лёгкий минус только у маркетингового display (крупный кегль это прощает). */
  letter-spacing: -0.01em;
  color: var(--clr-text-1);
}

/* @media-ступени убраны намеренно: размеры h1/h2/.display теперь флюидные
   (clamp в design-tokens.css) и уменьшаются на телефоне сами. */

/* ===== /css/utilities.css ===== */
/* utilities.css — хелперы layout/spacing. */

.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

/* Flex / grid */
.flex      { display: flex; }
.flex-col  { display: flex; flex-direction: column; }
.items-center   { align-items: center; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.flex-wrap { flex-wrap: wrap; }
.flex-1    { flex: 1; }

.grid { display: grid; }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }
.gap-6 { gap: var(--space-6); }
.gap-8 { gap: var(--space-8); }

/* Spacing */
.mt-2 { margin-top: var(--space-2); }
.mt-4 { margin-top: var(--space-4); }
.mt-6 { margin-top: var(--space-6); }
.mt-8 { margin-top: var(--space-8); }
.mb-2 { margin-bottom: var(--space-2); }
.mb-4 { margin-bottom: var(--space-4); }
.mb-6 { margin-bottom: var(--space-6); }
.mb-8 { margin-bottom: var(--space-8); }

/* Секции */
.section {
  padding-block: var(--space-20);
}

.section--tight {
  padding-block: var(--space-12);
}

/* Чередующийся фон секций (вместо инлайн-стилей в разметке). */
.section--alt {
  background: var(--clr-surface-2);
}

.section-title {
  text-align: center;
  margin-bottom: var(--space-3);
}

.section-subtitle {
  text-align: center;
  color: var(--clr-text-3);
  max-width: 56ch;
  margin-inline: auto;
  margin-bottom: var(--space-12);
}

.hidden { display: none !important; }

/* SVG-иконки: наследуют currentColor/состояние, единый размер через width/height. */
.ico { display: block; flex-shrink: 0; }

/* Иконка внутри строки текста (там, где раньше стоял эмодзи). svg в reset.css —
   display:block, поэтому в потоке текста его нужно вернуть в строку и опустить
   до оптической базовой линии глифов. */
.ico-inline {
  display: inline-flex;
  vertical-align: -0.18em;
  margin-inline-end: 0.15em;
}
/* Строка «иконка + текст» (там, где раньше эмодзи открывал строку). svg —
   display:block, поэтому контейнер должен сам собрать строку во flex. */
.ico-lead {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
}
.ico-lead .ico { flex-shrink: 0; }

/* Иконка-«чип» в баннерах: тон подложки задаёт сам баннер через currentColor. */
.ico-chip {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, currentColor 14%, transparent);
}

@media (max-width: 640px) {
  .section { padding-block: var(--space-12); }
}

/* ===== /css/animations.css ===== */
/* animations.css — keyframes (отключаются при reduced-motion). */

@keyframes fn-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes fn-rise {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes fn-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}

@keyframes fn-breathe {
  0%, 100% { transform: scale(1); opacity: 0.85; }
  50%      { transform: scale(1.15); opacity: 1; }
}

/* Прорисовка галочки штрихом — момент завершения задачи (см. checkbox.css). */
@keyframes fn-draw-check {
  from { stroke-dashoffset: 26; }
  to   { stroke-dashoffset: 0; }
}

.anim-rise   { animation: fn-rise var(--transition-slow) both; }
.anim-fade   { animation: fn-fade-in var(--transition-normal) both; }
.anim-pulse  { animation: fn-pulse 2s ease-in-out infinite; }

/* ── Переход между экранами (View Transitions, см. core/router.js) ─────────
   Кросс-фейд 180мс вместо резкой замены DOM. Роутер не запускает переход при
   отключённом движении, поэтому дополнительных гардов здесь не нужно. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 180ms;
  animation-timing-function: var(--ease-out-quart);
}
/* Новый экран слегка «подъезжает» — направление даёт ощущение перехода,
   а не мигания. Смещение маленькое: сильное движение утомляет при СДВГ. */
::view-transition-new(root) {
  animation-name: fn-fade-in, fn-vt-in;
}
@keyframes fn-vt-in {
  from { transform: translateY(6px); }
  to   { transform: none; }
}

/* Отключение анимаций по системной настройке. :not([data-reduced-motion="false"])
   — выбор в Настройках главнее системы: если человек явно ВЫКЛЮЧИЛ «Меньше
   движения», анимации играют даже с отключённой анимацией в самой ОС. Атрибута
   нет (ещё не выбирал) → решает система. Та же логика в JS — FN.motion. */
@media (prefers-reduced-motion: reduce) {
  html:not([data-reduced-motion="false"]) *,
  html:not([data-reduced-motion="false"]) *::before,
  html:not([data-reduced-motion="false"]) *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

[data-reduced-motion="true"] *,
[data-reduced-motion="true"] *::before,
[data-reduced-motion="true"] *::after {
  animation: none !important;
  transition: none !important;
}

/* ===== /css/components/buttons.css ===== */
/* buttons.css */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px; /* единый тач-таргет на всех устройствах (импульсивные движения) */
  padding: var(--space-3) var(--space-6);
  font-family: var(--font-heading);
  font-weight: var(--font-semi);
  font-size: var(--text-base);
  /* Капсула вместо 10px-радиуса: при высоте 44px скруглённый прямоугольник
     читается как интерфейс 2019-2021. */
  border-radius: var(--radius-full);
  border: 1.5px solid transparent;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    transform 220ms var(--ease-spring), box-shadow var(--transition-fast),
    color var(--transition-fast);
  text-align: center;
  white-space: nowrap;
}

/* Нажатие — материальное сжатие, а не сдвиг вниз (скевоморфизм 2013).
   Возврат идёт по пружине (--ease-spring): отклик ощущается физическим. */
.btn:active {
  transform: scale(0.97);
  transition-duration: 90ms;
}

.btn--primary {
  background: var(--clr-primary);
  color: var(--clr-on-primary);
  box-shadow: var(--shadow-xs);
}
.btn--primary:hover {
  background: var(--clr-primary-hover);
  color: var(--clr-on-primary);
  box-shadow: var(--shadow-md); /* мягкий подъём вместо сдвига — премиально и стабильно */
}

.btn--secondary {
  background: var(--clr-surface);
  color: var(--clr-primary);
  border-color: var(--clr-border);
}
.btn--secondary:hover {
  background: var(--clr-surface-3);
  box-shadow: var(--shadow-sm);
}

.btn--ghost {
  background: transparent;
  color: var(--clr-text-2);
}
.btn--ghost:hover {
  background: var(--clr-surface-3);
  color: var(--clr-text-1);
}

.btn--lg {
  padding: var(--space-4) var(--space-8);
  font-size: var(--text-lg);
}

.btn--block {
  width: 100%;
}

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
}

/* Иконочная кнопка — единый тач-таргет 44px и радиус для «✕»/иконок-действий.
   Глиф остаётся визуально небольшим по центру, а хит-зона всегда ≥44px
   (аудитория с импульсивной моторикой реже промахивается). Фон-подсветка —
   только на hover, поэтому в плотных шапках кнопка не «толстеет» визуально. */
.icon-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  /* Круг — как у кнопок композера (.composer-send/.composer-voice): все
     иконочные кнопки продукта выглядят одним компонентом. */
  border-radius: var(--radius-full);
  color: var(--clr-text-3);
  font-size: var(--text-lg);
  line-height: 1;
  transition: background var(--transition-fast), color var(--transition-fast),
    transform 220ms var(--ease-spring);
}
.icon-btn:active { transform: scale(0.92); transition-duration: 90ms; }
.icon-btn:hover {
  background: var(--clr-surface-3);
  color: var(--clr-text-1);
}
/* Компактный вариант: визуально 36px (плотные шапки), но хит-зона добирается
   до 44px прозрачным «вылетом» — тот же приём, что у кнопок композера. */
.icon-btn--sm {
  width: 36px;
  height: 36px;
  font-size: var(--text-base);
}
.icon-btn--sm::before {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: inherit;
}

/* ===== /css/components/cards.css ===== */
/* cards.css */

.card {
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}

.card--feature {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  transition: transform var(--transition-normal), box-shadow var(--transition-normal);
}
.card--feature:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
}
/* На тач-устройствах :hover «залипает» после тапа до следующего касания в
   другом месте — приподнятая карточка остаётся приподнятой и читается как
   выбранная. Гасим только движение, подсветку оставляем. */
@media (hover: none) {
  .card--feature:hover { transform: none; }
}

.card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-md);
  background: var(--clr-primary-light);
  color: var(--clr-primary);
  font-size: var(--text-2xl);
}

.card__title {
  font-size: var(--text-xl);
}

/* Тариф */
.pricing-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-xl);
  padding: var(--space-8);
}

.pricing-card--featured {
  border-color: var(--clr-primary);
  box-shadow: var(--shadow-lg);
  position: relative;
}

.pricing-card--platinum {
  position: relative;
  border-color: var(--clr-text-1);
  background: linear-gradient(
    165deg,
    color-mix(in srgb, var(--clr-text-1) 5%, var(--clr-surface)) 0%,
    var(--clr-surface) 55%
  );
}

.pricing-card__price {
  font-family: var(--font-heading);
  font-size: var(--text-4xl);
  font-weight: var(--font-bold);
  color: var(--clr-text-1);
}

.pricing-card__price span {
  font-size: var(--text-base);
  font-weight: var(--font-normal);
  color: var(--clr-text-3);
}

/* Годовой тариф под месячной ценой — ценовой якорь. */
.pricing-card__alt {
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--clr-primary);
  font-weight: var(--font-medium);
}

.pricing-features {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.pricing-features li {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
}
.pricing-features li::before {
  content: "✓";
  color: var(--clr-success);
  font-weight: var(--font-bold);
}

/* ===== /css/components/badges.css ===== */
/* badges.css */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  font-size: 13px; /* 12px мелковат для читаемости бейджей ЦА */
  font-weight: var(--font-semi);
  border-radius: var(--radius-full);
  background: var(--clr-surface-3);
  color: var(--clr-text-2);
}

.badge--pro {
  background: var(--clr-primary);
  color: var(--clr-on-primary);
}

.badge--accent {
  background: var(--clr-primary-light);
  /* primary-hover, а не primary: #6B5CFF на #EDEBFF давал 3.9:1 (ниже AA 4.5) */
  color: var(--clr-primary-hover);
}

.badge--success { background: rgba(61, 184, 138, 0.15); color: var(--clr-success); }
.badge--danger {
  background: color-mix(in srgb, var(--clr-error) 14%, transparent);
  color: var(--clr-error);
}
.badge--popular,
.badge--platinum {
  position: absolute;
  top: calc(-1 * var(--space-3));
  left: 50%;
  transform: translateX(-50%);
  background: var(--clr-primary);
  color: var(--clr-on-primary);
  box-shadow: var(--shadow-sm);
}
/* Platinum — премиальный «графитовый» акцент. */
.badge--platinum {
  background: var(--clr-text-1);
  letter-spacing: 0.04em;
}

/* ===== /css/components/forms.css ===== */
/* forms.css */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.field__label {
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--clr-text-1);
}

.input,
.textarea,
.select {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-base);
  color: var(--clr-text-1);
  background: var(--clr-surface);
  border: 1.5px solid var(--clr-border);
  border-radius: var(--radius-md);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.input::placeholder,
.textarea::placeholder {
  color: var(--clr-text-3);
}

.input:focus,
.textarea:focus,
.select:focus {
  outline: none;
  border-color: var(--clr-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--clr-primary) 18%, transparent);
}

.input[aria-invalid="true"] {
  border-color: var(--clr-error);
}

.field__hint  { font-size: var(--text-xs); color: var(--clr-text-3); }
.field__error { font-size: var(--text-xs); color: var(--clr-error); }

.textarea {
  min-height: 96px;
  resize: vertical;
}


/* Композер с кнопкой отправки ВНУТРИ поля (мессенджер-стиль): «Свалить мысль»,
   чат коуча, мини-чат. Кнопка прижата к правому нижнему углу — при росте
   textarea остаётся у последней строки. */
.composer-field {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
}
.composer-field .input {
  flex: 1;
  padding-right: 52px; /* место под круглую кнопку */
}
.composer-send {
  position: absolute;
  right: 6px;
  bottom: 6px;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background: var(--clr-primary);
  color: var(--clr-on-primary);
  transition: background var(--transition-fast), transform var(--transition-fast);
}
.composer-send:hover { background: var(--clr-primary-hover); }
.composer-send:active { transform: scale(0.94); }
.composer-send:disabled { opacity: 0.45; }

/* Зона касания ≥44px при визуальном круге 36px: прозрачный «вылет» вокруг
   кнопки. Аудитория с импульсивными движениями реже промахивается, а layout
   поля не сдвигается. Применяется к обеим круглым кнопкам композера. */
.composer-send::before,
.composer-voice::before {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: inherit;
}

/* --- Голосовая запись в капсуле композера (чат коуча, «Свалить мысль») ----- */
/* Две круглые кнопки внутри поля: микрофон + отправка. */
.composer-field--voice .input { padding-right: 96px; }
.composer-voice {
  position: absolute;
  right: 48px;
  bottom: 6px;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  color: var(--clr-text-2);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.composer-voice:hover { background: var(--clr-surface-3); color: var(--clr-primary); }
.composer-voice:disabled { opacity: 0.45; }

/* Режим записи: поле «уступает» таймеру и визуализатору, отправка прячется,
   кнопка микрофона становится стоп-кнопкой (красная, пульсирует). */
.composer-field--rec .input { visibility: hidden; }
.composer-field--rec .composer-send { opacity: 0; pointer-events: none; }
.composer-field--rec .composer-voice,
.composer-field--rec .composer-voice.voice-btn--on {
  background: var(--clr-error);
  color: #fff;
}
.composer-rec {
  position: absolute;
  inset: 2px 96px 2px 2px; /* не наезжаем на кнопки справа */
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0 var(--space-3);
  pointer-events: none;
}
/* display:flex выше перебил бы UA-правило [hidden] — возвращаем скрытие явно.
   Без этого оверлей записи виден постоянно, а не только во время записи. */
.composer-rec[hidden] { display: none; }
.composer-rec__dot {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--clr-error);
  animation: fn-pulse 1.2s ease-in-out infinite;
}
.composer-rec__time {
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
  color: var(--clr-text-2);
}
.composer-rec__bars {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 2px;
  height: 24px;
  overflow: hidden;
}
.composer-rec__bar {
  flex: 1;
  min-width: 2px;
  max-width: 4px;
  height: var(--h, 50%);
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--clr-primary) 55%, transparent);
  animation: fn-rec-bar 0.9s ease-in-out infinite alternate;
}
@keyframes fn-rec-bar {
  from { transform: scaleY(0.35); }
  to { transform: scaleY(1); }
}
.composer-rec__hint {
  flex-shrink: 0;
  font-size: var(--text-sm);
  color: var(--clr-text-3);
}
@media (max-width: 640px) {
  .composer-rec__hint { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .composer-rec__dot, .composer-rec__bar { animation: none; }
}

/* ===== /css/components/checkbox.css ===== */
/* checkbox.css — ЕДИНЫЙ чекбокс задачи: Главная, Задачи, шаги задачи.
 *
 * Раньше один и тот же объект выглядел на двух экранах по-разному: на Главной —
 * кастомный круг (.task-row__check), в карточке задачи — родной
 * <input type="checkbox"> с accent-color. Это читалось как «экраны делали в
 * разное время». Теперь оба используют этот компонент.
 *
 * Разметка (порядок важен — стили держатся на `input:checked + .check`):
 *   <label class="check-hit">
 *     <input type="checkbox" class="sr-only" …>
 *     <span class="check">…svg…</span>
 *     <span class="task-title">Название</span>
 *   </label>
 * Галочку рисует FN.checkMark() (core/icons.js не нужен — форма зашита здесь).
 */

.check {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-full);
  border: 2px solid color-mix(in srgb, var(--clr-primary) 55%, var(--clr-border));
  background: transparent;
  color: #fff;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    transform 240ms var(--ease-spring);
}
/* Уменьшенный вариант — для шагов внутри задачи (они подчинены заголовку). */
.check--sm { width: 20px; height: 20px; }

.check svg { display: block; width: 15px; height: 15px; }
.check--sm svg { width: 12px; height: 12px; }

/* Галочка прорисовывается штрихом, а не появляется мгновенно: это единственный
   момент награды в основном сценарии продукта. transition (а не animation) —
   чтобы уже выполненные задачи при первой отрисовке НЕ проигрывали анимацию. */
.check__mark {
  stroke-dasharray: 26;
  stroke-dashoffset: 26;
  transition: stroke-dashoffset 260ms var(--ease-out-quart);
}

.check-hit {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 44px;
  cursor: pointer;
}
/* Многострочный заголовок: кружок держится у первой строки, а не по центру. */
.check-hit--top { align-items: flex-start; }
.check-hit--top .check { margin-top: 1px; }

/* Отмечено. Состояние берётся прямо с родного input — JS не должен ничего
   дорисовывать: переключил чекбокс, остальное сделал CSS. */
.check-hit input:checked + .check {
  background: var(--clr-success);
  border-color: var(--clr-success);
}
.check-hit input:checked + .check .check__mark { stroke-dashoffset: 0; }

.check-hit:active input:not(:checked) + .check { transform: scale(0.88); }

.check-hit input:focus-visible + .check {
  outline: 3px solid var(--clr-primary);
  outline-offset: 2px;
}

/* Вычёркивание: анимируется цвет линии, а не её длина. Длину (background-size
   или ::after) нельзя анимировать корректно на заголовке в две строки —
   линия прошла бы через середину блока. text-decoration-color работает
   построчно и остаётся правильным при любом переносе. */
.task-title {
  line-height: var(--leading-normal);
  text-decoration-line: line-through;
  text-decoration-thickness: 1.5px;
  text-decoration-color: transparent;
  transition: text-decoration-color 260ms var(--ease-out-quart),
    color 260ms var(--ease-out-quart), opacity 260ms var(--ease-out-quart);
}
.check-hit input:checked ~ .task-title {
  text-decoration-color: currentColor;
  color: var(--clr-text-3);
}

/* Без движения — состояния переключаются мгновенно (глобальный сброс в
   animations.css гасит transition, здесь дублируем конечные значения). */
@media (prefers-reduced-motion: reduce) {
  .check-hit input:checked + .check .check__mark { stroke-dashoffset: 0; }
}

/* ===== /css/components/states.css ===== */
/* states.css — переходные состояния экранов: скелетоны загрузки,
 * пустые состояния и состояние ошибки загрузки.
 *
 * Цель (особенно для нейроотличных): убрать резкий «прыжок» layout при
 * появлении данных, отличать ошибку загрузки от реально пустого списка и
 * мягко подсказывать следующее действие. Анимация уважает reduced-motion. */

/* ============================================================
 * Скелетоны — заполняют место будущего контента, чтобы не было сдвига.
 * ============================================================ */
.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--clr-surface-3);
  border-radius: var(--radius-sm);
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(
    90deg,
    transparent 0%,
    color-mix(in srgb, var(--clr-surface) 55%, transparent) 50%,
    transparent 100%
  );
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
}

@keyframes skeleton-shimmer {
  100% { transform: translateX(100%); }
}

/* Типовые формы скелетона. */
.skeleton--line { height: 12px; }
.skeleton--text { height: 14px; border-radius: var(--radius-full); }
.skeleton--title { height: 22px; width: 40%; border-radius: var(--radius-full); }
.skeleton--pill { height: 28px; width: 120px; border-radius: var(--radius-full); }
.skeleton--btn { height: 44px; width: 140px; border-radius: var(--radius-md); }

.skeleton-w-90 { width: 90%; }
.skeleton-w-75 { width: 75%; }
.skeleton-w-60 { width: 60%; }
.skeleton-w-40 { width: 40%; }

/* Скелет карточки (задача, сессия, строка списка). */
.skeleton-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  background: var(--clr-surface);
}
.skeleton-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Скелет «крупной цифры» статистики. */
.skeleton-stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  background: var(--clr-surface);
}
.skeleton-stat .skeleton--num { height: 30px; width: 56px; border-radius: var(--radius-sm); }

/* Без движения — показываем спокойный статичный плейсхолдер. */
@media (prefers-reduced-motion: reduce) {
  .skeleton::after { animation: none; }
}
[data-reduced-motion="true"] .skeleton::after { animation: none; }

/* ============================================================
 * Пустое состояние и состояние ошибки — общий компонент.
 * ============================================================ */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-2);
  padding: var(--space-8) var(--space-4);
  max-width: 46ch;
  margin-inline: auto;
}
.empty-state__ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  margin-bottom: var(--space-2);
  border-radius: var(--radius-full);
  background: var(--clr-primary-light);
  color: var(--clr-primary);
}
/* Маскот в пустом состоянии — вместо круглой иконки (тёплый вид). */
.empty-state__mascot { margin-bottom: var(--space-2); }
.empty-state__title {
  font-family: var(--font-heading);
  font-weight: var(--font-bold);
  font-size: var(--text-lg);
  color: var(--clr-text-1);
}
.empty-state__text {
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
}
.empty-state__action { margin-top: var(--space-4); }

/* Вариант ошибки загрузки — тёплый, не тревожный: проблема в сети, а не в вас. */
.empty-state--error .empty-state__ico {
  background: color-mix(in srgb, var(--clr-error) 14%, transparent);
  color: var(--clr-error);
}

/* ===== /css/components/mascot.css ===== */
/* mascot.css — размеры и мягкая анимация маскота «Фокусик» (FN.mascot). */

.mascot { display: inline-block; flex-shrink: 0; line-height: 0; }
.mascot svg { display: block; width: 100%; height: 100%; }

.mascot--xs    { width: 30px;  height: 30px; }
.mascot--sm    { width: 40px;  height: 40px; }
.mascot--md    { width: 56px;  height: 56px; }
.mascot--greet { width: 64px;  height: 64px; }
.mascot--hero  { width: 104px; height: 104px; }

/* «Дыхание» маскота — едва заметное, 6s. Только при разрешённом движении. */
@media (prefers-reduced-motion: no-preference) {
  .mascot--float svg { animation: fn-mascot-float 6s ease-in-out infinite; }
  @keyframes fn-mascot-float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-5px); }
  }
}
/* Явное отключение анимаций пользователем. */
[data-reduced-motion="true"] .mascot--float svg { animation: none; }

/* ===== /css/components/cookie-consent.css ===== */
/* cookie-consent.css — ненавязчивое уведомление о файлах cookie (152-ФЗ).
 * Появляется один раз; выбор хранится в localStorage. */

.cookie-consent {
  position: fixed;
  left: max(var(--space-4), env(safe-area-inset-left, 0px));
  right: max(var(--space-4), env(safe-area-inset-right, 0px));
  bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
  z-index: var(--z-overlay); /* 200 — ниже тостов (400) и модалок (300) */
  max-width: 760px;
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  animation: fn-rise var(--transition-normal) ease both;
}

.cookie-consent__text {
  flex: 1;
  margin: 0;
  font-size: var(--text-sm);
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
}
.cookie-consent__text a {
  color: var(--clr-primary);
  text-decoration: underline;
}

.cookie-consent__actions {
  display: flex;
  gap: var(--space-2);
  flex-shrink: 0;
}
/* Компактнее стандартной кнопки — баннер не должен доминировать. */
.cookie-consent .btn {
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
}

@media (max-width: 600px) {
  .cookie-consent {
    flex-direction: column;
    align-items: stretch;
  }
  /* Кнопки в столбик: «Только необходимые» в строку из двух не помещается уже
     на 375px — .btn{white-space:nowrap} обрезал подпись, а на 320px баннер
     вылезал за правый край вьюпорта и давал горизонтальный скролл всей
     страницы. Столбик заодно даёт полноразмерные тач-таргеты. */
  .cookie-consent__actions {
    flex-direction: column;
    align-items: stretch;
  }
  .cookie-consent__actions .btn {
    flex: none;
    width: 100%;
    /* Подпись переносится, а не режется, если шрифт крупнее системного. */
    white-space: normal;
  }
}

/* В авторизованной зоне баннер не должен ложиться на нижний «остров»
   навигации (у него z-index ниже — бар был бы полностью перекрыт, пока
   человек не ответит на вопрос про cookie). body[data-route] ставит роутер —
   этого атрибута нет ни на лендинге, ни в Библиотеке. */
@media (max-width: 768px) {
  body[data-route] .cookie-consent {
    bottom: calc(var(--space-16) + var(--space-4) + env(safe-area-inset-bottom, 0px));
  }
}

/* На лендинге под баннером живёт плавающая капсула CTA — поднимаем баннер
   над ней ровно тогда, когда она показана. */
@media (max-width: 900px) {
  body:has(.lp-mobile-cta.is-visible) .cookie-consent {
    bottom: calc(var(--space-16) + var(--space-4) + env(safe-area-inset-bottom, 0px));
  }
}

/* ===== /css/components/quick-dock.css ===== */
/* quick-dock.css — плавающий док в углу (коуч + таймер) и мини-чат коуча. */

.quick-dock {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  z-index: var(--z-sticky, 900);
  display: flex;
  gap: var(--space-2);
}
.quick-dock__btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-full);
  background: var(--clr-surface);
  color: var(--clr-text-1);
  box-shadow: var(--shadow-lg);
  font-weight: var(--font-semi);
  font-size: var(--text-sm);
  transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}
.quick-dock__btn:hover { transform: translateY(-2px); }
@media (hover: none) {
  .quick-dock__btn:hover { transform: none; } /* залипший hover на тапе (планшеты >768px) */
}
.quick-dock__ico { display: inline-flex; color: var(--clr-primary); }
.quick-dock__btn--coach { background: var(--clr-primary); color: var(--clr-on-primary); }
.quick-dock__btn--coach .quick-dock__ico { color: var(--clr-on-primary); }

/* На самой странице ИИ-коуча капсула «Коуч» лишняя — вы уже в чате.
   Остаётся только «Таймер». */
body[data-route="/coach"] .quick-dock__btn--coach { display: none; }

/* Мини-чат коуча */
.coach-widget {
  position: fixed;
  right: var(--space-5);
  bottom: calc(var(--space-5) + 56px); /* над доком */
  z-index: var(--z-overlay, 200);
  width: 320px;
  max-width: calc(100vw - var(--space-8));
  max-height: 60vh;
  max-height: 60dvh;
  display: flex;
  flex-direction: column;
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  animation: fn-rise var(--transition-fast) ease both;
  overflow: hidden;
}
.cw-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--clr-border);
}
.cw-title { font-family: var(--font-heading); font-weight: var(--font-bold); color: var(--clr-text-1); }
.cw-head__actions { display: flex; align-items: center; gap: var(--space-2); }
.cw-soft {
  font-size: var(--text-xs);
  color: var(--clr-text-2);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
}
.cw-soft:hover { background: var(--clr-surface-3); color: var(--clr-primary); }
/* .cw-close — целиком на .icon-btn icon-btn--sm (без своих размеров). */

.cw-thread {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 96px;
}
.cw-empty {
  color: var(--clr-text-3);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  text-align: center;
  padding: var(--space-4) 0;
}
.cw-msg {
  max-width: 85%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  line-height: var(--leading-relaxed);
  font-size: var(--text-sm);
  white-space: pre-wrap;
  word-break: break-word;
}
.cw-msg--me { align-self: flex-end; background: var(--clr-primary); color: var(--clr-on-primary); }
.cw-msg--coach { align-self: flex-start; background: var(--clr-surface-3); color: var(--clr-text-1); }

.cw-composer {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4) var(--space-3);
  border-top: 1px solid var(--clr-border);
}
.cw-composer .input { flex: 1; }
.cw-full {
  display: block;
  text-align: center;
  padding: var(--space-2);
  font-size: var(--text-sm);
  color: var(--clr-primary);
  border-top: 1px solid var(--clr-border);
}

@media (max-width: 768px) {
  /* Плавающий док (Коуч + Таймер) на мобильном убран: навигация — в нижнем баре,
     коуч открывается полноэкранно из таб-бара, таймер сам показывается в сессии. */
  .quick-dock { display: none; }

  /* Мини-чат коуча → лист почти на весь экран, НО нижний бар остаётся видимым:
     оверлей заканчивается над баром (его высота ≈ 60px). Навигация по бару
     закрывает коуча (coach-widget.js). */
  .coach-widget {
    top: 0;
    right: 0;
    bottom: calc(var(--space-16) + var(--space-3) + env(safe-area-inset-bottom, 0px)); /* над «островом» */
    left: 0;
    width: auto;
    max-width: none;
    max-height: none;
    height: auto;
    border: none;
    border-radius: 0;
    z-index: var(--z-modal, 300);
  }
  /* Полноэкранный чат — это уже полный вид: ссылка «Открыть полный чат» лишняя. */
  .coach-widget .cw-full { display: none; }
}
@media (max-width: 560px) {
  .quick-dock__label { display: none; }
  .quick-dock__btn { padding: var(--space-3); }
}
@media (prefers-reduced-motion: reduce) {
  .quick-dock__btn:hover { transform: none; }
  .coach-widget { animation: none; }
}

/* Компактные карточки действий коуча в мини-чате */
.cw-action {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-self: stretch;
  padding: var(--space-3);
  border: 1.5px solid color-mix(in srgb, var(--clr-primary) 35%, var(--clr-border));
  border-radius: var(--radius-md);
  background: var(--clr-primary-light);
  font-size: var(--text-sm);
  color: var(--clr-text-1);
}
.cw-action__btns { display: flex; gap: var(--space-2); }
.cw-action__btns .btn { flex: 1; padding: var(--space-1) var(--space-3); font-size: var(--text-sm); }
.cw-action--done {
  border-color: color-mix(in srgb, var(--clr-success) 45%, var(--clr-border));
  background: color-mix(in srgb, var(--clr-success) 8%, var(--clr-surface));
  color: var(--clr-text-2);
}

/* ===== /css/components/toasts.css ===== */
/* toasts.css */

.toasts {
  position: fixed;
  bottom: var(--space-6);
  right: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  z-index: var(--z-toast);
  max-width: 360px;
}

.toast {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  box-shadow: var(--shadow-md);
  color: var(--clr-text-1);
  font-size: var(--text-sm);
  border-left: 4px solid var(--clr-info);
  animation: fn-rise var(--transition-normal) ease both;
}

.toast--success { border-left-color: var(--clr-success); }
.toast--error   { border-left-color: var(--clr-error); }
.toast--warning { border-left-color: var(--clr-warning); }
.toast--out     { opacity: 0; transition: opacity var(--transition-normal); }

/* Кнопка действия в тосте («Отменить», «Открыть»). Тап-таргет ≥44px по высоте
   не нужен: тост временный, но кнопку делаем заметной и с запасом по паддингу. */
.toast {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.toast__btn {
  flex-shrink: 0;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--clr-primary);
  border-radius: var(--radius-full);
  color: var(--clr-primary);
  font-weight: var(--font-semi);
  font-size: var(--text-sm);
  background: transparent;
}
.toast__btn:hover { background: var(--clr-primary-light); }

@media (max-width: 560px) {
  .toasts {
    left: max(var(--space-4), env(safe-area-inset-left, 0px));
    right: max(var(--space-4), env(safe-area-inset-right, 0px));
    max-width: none;
  }
}

/* В авторизованной зоне тост вставал ровно поверх нижнего «острова» навигации
   (z-index тоста 400 против 100 у бара) — на всё время показа разделы были
   недоступны для нажатия. Поднимаем ленту тостов над баром. */
@media (max-width: 768px) {
  body[data-route] .toasts {
    bottom: calc(var(--space-16) + var(--space-4) + env(safe-area-inset-bottom, 0px));
  }
}

/* ===== /css/components/modals.css ===== */
/* modals.css */

/* Блокировка скролла фона при открытой модалке. position:fixed фиксирует body
   (top задаёт JS = -scrollY), overflow:hidden гасит инерцию — надёжно на iOS. */
.fn-scroll-lock {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
}

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  /* Вырезы экрана: модалка занимает весь вьюпорт, отступы больше никто не
     даёт — на iPhone нижняя кнопка иначе уезжает под индикатор Home. */
  padding:
    calc(var(--space-4) + env(safe-area-inset-top, 0px))
    calc(var(--space-4) + env(safe-area-inset-right, 0px))
    calc(var(--space-4) + env(safe-area-inset-bottom, 0px))
    calc(var(--space-4) + env(safe-area-inset-left, 0px));
  background: rgba(44, 38, 64, 0.45);
  animation: fn-fade-in var(--transition-fast) ease both;
}
.modal-overlay.modal--out { opacity: 0; transition: opacity var(--transition-fast); }

.modal {
  width: 100%;
  max-width: 460px;
  background: var(--clr-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  max-height: 90vh;
  max-height: 90dvh; /* iOS: не выше видимой области, учитывает клавиатуру/адрес-бар */
  overflow-y: auto;
  overscroll-behavior: contain;
  animation: fn-rise var(--transition-normal) ease both;
}

.modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-5) var(--space-6) 0;
}
.modal__title { font-size: var(--text-xl); }
/* .btn даёт min-height:44px, но собственный padding сжимал крестик до 35.6px
   по ширине — тач-таргет должен быть квадратным 44×44. */
.modal__close {
  font-size: var(--text-lg);
  padding: var(--space-2);
  min-width: 44px;
  flex-shrink: 0;
}
.modal__body { padding: var(--space-4) var(--space-6) var(--space-6); }

/* Вертикальный блок действий (одна основная CTA + второстепенная). */
.modal__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-5);
}

/* Приветственное окно */
.welcome__text {
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
  white-space: pre-wrap;
  margin-bottom: var(--space-5);
}
.welcome__dont {
  margin-bottom: var(--space-4);
  color: var(--clr-text-3);
  font-size: var(--text-sm);
}

.voice-btn--on {
  background: var(--clr-primary);
  color: var(--clr-on-primary);
  animation: fn-pulse 1.2s ease-in-out infinite;
}

/* ===== /css/components/panic.css ===== */
/* panic.css — плавающая кнопка помощи и дыхательный оверлей. */

.panic-fab {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  z-index: var(--z-sticky, 900);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: none;
  border-radius: var(--radius-full);
  background: var(--clr-surface);
  color: var(--clr-text-1);
  box-shadow: var(--shadow-lg);
  font-weight: var(--font-semi);
  cursor: pointer;
  transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}
.panic-fab:hover { transform: translateY(-2px); }
@media (hover: none) {
  .panic-fab:hover { transform: none; } /* залипший hover на тапе */
}
.panic-fab__ico { display: inline-flex; color: var(--clr-primary); }
.panic-fab__text { font-size: var(--text-sm); }

/* Оверлей */
.panic {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal, 1000);
  display: flex;
  /* Центрируем, но НЕ обрезаем. При раскрытом «5-4-3-2-1», в ландшафте и на
     экранах ~568px содержимое выше вьюпорта: `align-items:center` уводил верх
     в минус, а кнопку «Мне лучше» — за нижний край, и доскроллить было нельзя
     (фон в этот момент заблокирован). Центрирование через `margin:auto` у
     .panic__inner: пока помещается — по центру, как только нет — обычная
     прокрутка от верхнего края. Работает во всех браузерах, в отличие от
     `align-items: safe center`. */
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  /* Спокойный приглушённый фон, минимум сенсорной нагрузки. */
  background: var(--clr-primary-light);
  /* Вырезы экрана: сверху место под чёлку/Dynamic Island, снизу — под
     индикатор Home (оверлей полноэкранный, отступы никто больше не даёт). */
  padding:
    calc(var(--space-6) + env(safe-area-inset-top, 0px))
    calc(var(--space-6) + env(safe-area-inset-right, 0px))
    calc(var(--space-6) + env(safe-area-inset-bottom, 0px))
    calc(var(--space-6) + env(safe-area-inset-left, 0px));
}
.panic__close {
  position: fixed;
  top: calc(var(--space-4) + env(safe-area-inset-top, 0px));
  right: calc(var(--space-4) + env(safe-area-inset-right, 0px));
  z-index: 1; /* поверх прокручиваемого содержимого */
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background: var(--clr-surface);
  color: var(--clr-text-2);
  font-size: var(--text-lg);
  cursor: pointer;
}
.panic__inner {
  /* margin:auto — вертикальное и горизонтальное центрирование, которое не
     обрезает содержимое выше экрана (см. комментарий у .panic). */
  margin: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
  max-width: 420px;
  text-align: center;
}
.panic__lead {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  color: var(--clr-text-1);
  line-height: var(--leading-relaxed);
}

/* Дышащий круг */
.panic__circle {
  width: 180px;
  height: 180px;
  border-radius: 50%;
  background: var(--clr-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--clr-on-primary);
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  font-weight: var(--font-bold);
  transition: transform 4s ease-in-out, background 4s ease-in-out;
}
.panic__circle[data-phase="in"] { transform: scale(1.25); }
.panic__circle[data-phase="out"] { transform: scale(0.8); }
.panic__circle[data-phase="hold"] { transform: scale(1.05); }
/* При reduced-motion круг не масштабируется — ведём только текстом фаз. */
.panic__circle--static { transition: none; }
.panic__circle--static[data-phase] { transform: none; }

.panic__count { color: var(--clr-text-2); }
.panic__ground { color: var(--clr-text-2); width: 100%; }
/* summary — интерактивный элемент: тач-таргет 44px, как у кнопок. */
.panic__ground summary {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  cursor: pointer;
  font-weight: var(--font-medium);
}
.panic__ground ul { text-align: left; margin: var(--space-2) 0 0; padding-left: var(--space-5); line-height: var(--leading-relaxed); }

body.panic-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .panic-fab { transition: none; }
  .panic__circle { transition: background 0.01s; }
  .panic__circle[data-phase] { transform: none; }
}

/* На мобильных навигация — плавающий «остров» внизу; поднимаем FAB над ним,
   чтобы кнопка помощи и крайняя иконка навигации не перекрывали друг друга. */
@media (max-width: 768px) {
  .panic-fab {
    bottom: calc(var(--space-16) + var(--space-4) + env(safe-area-inset-bottom, 0px));
  }
}

@media (max-width: 640px) {
  .panic-fab__text { display: none; }
  .panic-fab { padding: var(--space-3); }
}

/* ===== /css/components/coach-tour.css ===== */
/* coach-tour.css — спотлайт-тур по интерфейсу (мини-гайд). */

/* Прозрачный слой поверх страницы: ловит клики, чтобы во время тура нельзя
   было случайно взаимодействовать с приложением (кроме карточки-подсказки). */
.tour-catch {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal, 1000);
}

/* «Дырка» подсветки: сама прозрачная, а огромная тень затемняет всё вокруг. */
.tour-hole {
  position: fixed;
  z-index: calc(var(--z-modal, 1000) + 1);
  border-radius: 12px;
  box-shadow: 0 0 0 9999px rgba(20, 16, 45, 0.55);
  pointer-events: none;
  transition: top 0.25s ease, left 0.25s ease, width 0.25s ease, height 0.25s ease;
}

/* Карточка-подсказка. */
.tour-tip {
  position: fixed;
  z-index: calc(var(--z-modal, 1000) + 2);
  width: min(320px, calc(100vw - 24px));
  padding: var(--space-4);
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  border-radius: 14px;
  box-shadow: var(--shadow-lg);
  transition: top 0.25s ease, left 0.25s ease;
}
.tour-tip__count {
  font-size: var(--text-xs);
  font-weight: var(--font-semi);
  color: var(--clr-primary);
  margin-bottom: var(--space-1);
}
.tour-tip__title {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  margin: 0 0 var(--space-2);
}
.tour-tip__body {
  font-size: var(--text-sm);
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
  margin: 0 0 var(--space-4);
}
.tour-tip__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.tour-tip__right {
  display: flex;
  gap: var(--space-2);
}

@media (prefers-reduced-motion: reduce) {
  .tour-hole,
  .tour-tip {
    transition: none;
  }
}

/* ===== /css/layouts/app-shell.css ===== */
/* app-shell.css — оболочка авторизованной зоны: фон-сцена, плавающая
 * стеклянная навигация, поповер профиля, командная палитра.
 *
 * Навигация — одна разметка на две формы: на десктопе «облако» сверху
 * (капсула поверх контента), на мобильном — «остров» снизу. Переключение
 * целиком на CSS: второй DOM пришлось бы синхронизировать вручную, а
 * рассинхрон в навигации — самый заметный класс багов.
 *
 * ⚠ Перф: backdrop-filter — самая дорогая часть композиции. На экране
 * одновременно живут 1 капсула навигации + 4–6 карточек контента; список
 * строк и мелкие чипы стекла НЕ получают (они внутри стеклянной карточки —
 * второй слой размытия там всё равно не виден). См. также урезанные радиусы
 * blur на мобильном в design-tokens.css.
 */

/* ═══════════════════════════════════════════════════════════════════════════
   1. КАРКАС И ФОН-СЦЕНА
   ═══════════════════════════════════════════════════════════════════════════ */

.app-shell {
  /* Геометрия плавающей навигации — одним набором переменных: от них зависит
     и отступ контента сверху, и высота капсулы в двух состояниях. */
  --nav-top: clamp(18px, 1.4vw, 28px);
  --nav-h: 62px;
  --nav-h-stuck: 54px;
  --nav-gap: var(--space-8);

  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  isolation: isolate; /* стеклянные слои шелла не смешиваются с фоном страницы */
}

/* Фон-сцена: мягкие световые орбы + едва различимое зерно. Орбы — радиальные
   градиенты на одном фиксированном слое, а не размытые div-ы: тот же эффект
   без единого пикселя blur (размытие фона стоило бы дороже всего стекла
   страницы вместе взятого). Слой фиксированный — при прокрутке не
   перерисовывается, только композитится. */
.app-scene {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(42rem 32rem at 12% -8%,
      color-mix(in srgb, var(--clr-primary) 22%, transparent) 0%, transparent 60%),
    radial-gradient(36rem 28rem at 94% 2%,
      color-mix(in srgb, var(--clr-accent) 14%, transparent) 0%, transparent 58%),
    radial-gradient(48rem 40rem at 50% 108%,
      color-mix(in srgb, var(--clr-primary-soft) 18%, transparent) 0%, transparent 62%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--clr-surface-2) 70%, var(--clr-surface)) 0%,
      var(--clr-surface-2) 100%);
}
[data-theme="dark"] .app-scene {
  background:
    radial-gradient(42rem 32rem at 12% -8%,
      color-mix(in srgb, var(--clr-primary) 18%, transparent) 0%, transparent 58%),
    radial-gradient(36rem 28rem at 94% 2%,
      color-mix(in srgb, var(--clr-accent) 10%, transparent) 0%, transparent 56%),
    radial-gradient(48rem 40rem at 50% 108%,
      color-mix(in srgb, var(--clr-primary) 14%, transparent) 0%, transparent 60%),
    linear-gradient(180deg, var(--clr-surface) 0%, #0F0D1A 100%);
}
/* Зерно убирает пластиковую гладкость градиентов и полосы (banding) на больших
   плоскостях. Один SVG-шум в data-URI — без сетевого запроса. */
.app-scene::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.03;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* Высокий контраст: никакой сцены — ровный фон, максимальная читаемость. */
[data-theme="high-contrast"] .app-scene {
  background: var(--clr-surface);
}
[data-theme="high-contrast"] .app-scene::after { display: none; }
/* «Тихая» тема — сенсорная чувствительность: орбы почти гасим. */
[data-theme="muted"] .app-scene { opacity: 0.55; }

/* Ссылка «пропустить навигацию»: первый Tab на странице. Раньше клавиатурному
   пользователю приходилось прощёлкивать всё меню на каждом экране. */
.skip-link {
  position: fixed;
  top: calc(var(--space-3) + env(safe-area-inset-top, 0px));
  left: 50%;
  z-index: calc(var(--z-sticky) + 10);
  transform: translate(-50%, -160%);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-full);
  background: var(--clr-primary);
  color: var(--clr-on-primary);
  font-weight: var(--font-semi);
  box-shadow: var(--shadow-lg);
  transition: transform var(--transition-normal);
}
.skip-link:focus-visible {
  transform: translate(-50%, 0);
  color: var(--clr-on-primary);
}

.app-main {
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
  /* Боковые вырезы (ландшафт на iPhone) — иначе первая колонка уходит под
     скруглённый угол экрана. Сверху инсет не нужен: там висит капсула,
     которая уже отодвинута от выреза (см. .topnav ниже). */
  padding: calc(var(--nav-top) + var(--nav-h) + var(--nav-gap))
    max(var(--space-8), env(safe-area-inset-right, 0px))
    var(--space-20)
    max(var(--space-8), env(safe-area-inset-left, 0px));
}
.app-main:focus { outline: none; } /* цель skip-link — рамка не нужна */

/* ═══════════════════════════════════════════════════════════════════════════
   2. ПЛАВАЮЩЕЕ СТЕКЛЯННОЕ ОБЛАКО (десктоп)
   ═══════════════════════════════════════════════════════════════════════════ */

.topnav {
  position: fixed;
  /* apple-mobile-web-app-status-bar-style=black-translucent: в установленной
     PWA контент начинается от самого верха экрана, и капсула наезжала бы на
     статус-бар / Dynamic Island. В браузере инсет = 0 и ничего не меняется. */
  inset-block-start: calc(var(--nav-top) + env(safe-area-inset-top, 0px));
  inset-inline: 0;
  z-index: var(--z-sticky);
  display: flex;
  justify-content: center;
  padding-inline: max(var(--space-6), env(safe-area-inset-left, 0px))
    max(var(--space-6), env(safe-area-inset-right, 0px));
  /* Мимо капсулы клики уходят на контент под ней. */
  pointer-events: none;
}

.topnav__cloud {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--nav-h);
  padding: 0 var(--space-2) 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--glass-hairline);
  background: var(--glass-fill);
  -webkit-backdrop-filter: blur(var(--glass-blur-lg)) saturate(200%);
  backdrop-filter: blur(var(--glass-blur-lg)) saturate(200%);
  /* Объём стекла: световая кромка сверху, затухающая снизу, мягкая тень. */
  box-shadow:
    inset 0 1px 0 var(--glass-edge),
    inset 0 -1px 0 var(--glass-edge-dim),
    var(--glass-shadow);
  transition:
    height var(--transition-normal),
    background var(--transition-normal),
    box-shadow var(--transition-normal),
    transform 320ms var(--ease-spring);
  will-change: height, transform;
}

/* «Магнитное прилипание» при прокрутке: капсула садится ниже, чуть сжимается
   и становится плотнее — контент под ней перестаёт просвечивать текстом. */
.topnav--stuck .topnav__cloud {
  height: var(--nav-h-stuck);
  transform: translate3d(0, -4px, 0);
  background: color-mix(in srgb, var(--glass-fill) 100%, var(--clr-surface) 22%);
  box-shadow:
    inset 0 1px 0 var(--glass-edge),
    inset 0 -1px 0 var(--glass-edge-dim),
    0 1px 2px rgba(12, 14, 20, 0.05),
    0 14px 34px rgba(12, 14, 20, 0.10),
    0 34px 64px rgba(12, 14, 20, 0.08);
}
[data-theme="dark"] .topnav--stuck .topnav__cloud {
  background: color-mix(in srgb, var(--glass-fill) 100%, #000 26%);
}

/* Логотип в капсуле: знак-градиент + словесная марка. */
.topnav__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding-right: var(--space-2);
  font-family: var(--font-heading);
  font-weight: var(--font-bold);
  font-size: var(--text-base);
  color: var(--clr-text-1);
  white-space: nowrap;
}
.topnav__brand:hover { color: var(--clr-text-1); }
.topnav__brand span span { color: var(--clr-primary); }
/* Знак приложения. Скругление и градиент — внутри самой картинки, от CSS нужна
   только тень, которая сажает знак на капсулу. */
.topnav__mark {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  box-shadow: 0 3px 10px color-mix(in srgb, var(--clr-primary) 35%, transparent);
}

/* Разделы. Капсула-индикатор физически переезжает между пунктами: позицию и
   ширину задаёт JS (--pill-x/--pill-w), движение — transform, поэтому layout
   не пересчитывается. */
.topnav__nav {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
  margin-inline: var(--space-2);
}
.topnav__pill {
  position: absolute;
  inset-block: 6px;
  inset-inline-start: 0;
  width: var(--pill-w, 0);
  opacity: var(--pill-o, 0);
  transform: translate3d(var(--pill-x, 0), 0, 0);
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--clr-primary) 13%, transparent);
  box-shadow:
    inset 0 1px 0 var(--glass-edge),
    0 2px 10px color-mix(in srgb, var(--clr-primary) 18%, transparent);
  pointer-events: none;
}
/* Класс ставится через кадр после монтирования: первая установка индикатора
   не должна выглядеть как «прилёт» капсулы слева. */
.topnav__nav--ready .topnav__pill {
  transition:
    transform 420ms var(--ease-spring),
    width 420ms var(--ease-spring),
    opacity var(--transition-fast);
}

.topnav__link {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 40px;
  padding-inline: var(--space-4);
  border-radius: var(--radius-full);
  color: var(--clr-text-2);
  font-weight: var(--font-medium);
  font-size: var(--text-sm);
  white-space: nowrap;
  transition: color var(--transition-fast), transform 220ms var(--ease-spring);
}
.topnav__link:hover { color: var(--clr-text-1); transform: translateY(-1px); }
/* Тач: после тапа по разделу :hover остаётся до следующего касания, и пункт
   нижнего бара «зависал» приподнятым. Гасим только сдвиг; блок стоит ДО
   :active, чтобы сжатие при нажатии продолжало перебивать его. */
@media (hover: none) {
  .topnav__link:hover { transform: none; }
}
.topnav__link:active { transform: scale(0.97); }
.topnav__link--active { color: var(--clr-primary); font-weight: var(--font-semi); }
.topnav__ico { display: inline-flex; }
/* Иконка активного пункта чуть плотнее — тонкая подсказка без цветового шума. */
.topnav__link--active .ico { stroke-width: 2.2; }

/* Правая группа: поиск, уведомления, тема, профиль. */
.topnav__tools {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-inline-start: auto;
}
.topnav__act {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-full);
  color: var(--clr-text-2);
  transition:
    background var(--transition-fast),
    color var(--transition-fast),
    transform 220ms var(--ease-spring);
}
.topnav__act:hover {
  background: color-mix(in srgb, var(--clr-text-1) 7%, transparent);
  color: var(--clr-text-1);
  transform: translateY(-1px);
}
@media (hover: none) {
  .topnav__act:hover { transform: none; }
}
.topnav__act:active { transform: scale(0.92); }
/* Точка непрочитанных уведомлений. */
.topnav__act--unread::after {
  content: "";
  position: absolute;
  top: 8px;
  right: 8px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--clr-error);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--clr-surface) 80%, transparent);
}

.topnav__user {
  display: inline-flex;
  align-items: center;
  padding: 4px;
  margin-inline-start: var(--space-1);
  border-radius: var(--radius-full);
  transition: background var(--transition-fast), transform 220ms var(--ease-spring);
}
.topnav__user:hover { background: color-mix(in srgb, var(--clr-text-1) 7%, transparent); }
.topnav__user:active { transform: scale(0.94); }
.topnav__user[aria-expanded="true"] {
  background: color-mix(in srgb, var(--clr-primary) 14%, transparent);
}

/* Кнопка «Ещё» — только в мобильном баре. */
.topnav__more { display: none; }

/* Без поддержки backdrop-filter и в контрастной теме — плотный фон:
   читаемость важнее эффекта. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .topnav__cloud { background: var(--clr-surface); }
}
[data-theme="high-contrast"] .topnav__cloud {
  background: var(--clr-surface);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: 2px solid var(--clr-border);
  box-shadow: var(--shadow-lg);
}
[data-theme="high-contrast"] .topnav__pill {
  background: var(--clr-primary-light);
  border: 2px solid var(--clr-primary);
}

/* ═══════════════════════════════════════════════════════════════════════════
   3. ПОПОВЕР ПРОФИЛЯ / «ЕЩЁ»
   ═══════════════════════════════════════════════════════════════════════════ */

.app-menu {
  position: fixed;
  z-index: calc(var(--z-sticky) + 1);
  inset-block-start: calc(var(--nav-top) + var(--nav-h) + var(--space-2) + env(safe-area-inset-top, 0px));
  inset-inline-end: max(var(--space-6), env(safe-area-inset-right, 0px), calc((100vw - 1240px) / 2));
  width: min(264px, calc(100vw - 2 * var(--space-4)));
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3);
  border-radius: var(--radius-xl);
  border: 1px solid var(--glass-hairline);
  background: var(--glass-fill);
  -webkit-backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  box-shadow:
    inset 0 1px 0 var(--glass-edge),
    var(--glass-shadow);
  /* Появление: лёгкий подъём + проявление, без «выпрыгивания». */
  opacity: 0;
  transform: translateY(-6px) scale(0.98);
  transform-origin: top right;
  transition:
    opacity var(--transition-fast),
    transform 260ms var(--ease-spring);
}
.app-menu--open { opacity: 1; transform: none; }
.app-menu[hidden] { display: none; }

.app-menu__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--glass-hairline);
  margin-bottom: var(--space-1);
}
.app-menu__who { display: flex; flex-direction: column; min-width: 0; }
.app-menu__who strong {
  font-family: var(--font-heading);
  color: var(--clr-text-1);
  font-size: var(--text-base);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-menu__who span { font-size: var(--text-xs); }

.app-menu__group { display: flex; flex-direction: column; gap: 1px; }
.app-menu__group + .app-menu__group {
  padding-top: var(--space-1);
  margin-top: var(--space-1);
  border-top: 1px solid var(--glass-hairline);
}
/* Пункты, которые нужны только в мобильном баре (десктоп их держит в капсуле). */
.app-menu__group--mobile { display: none; }

.app-menu__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 44px; /* тач-таргет для импульсивной моторики */
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  color: var(--clr-text-2);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  text-align: left;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.app-menu__item:hover,
.app-menu__item:focus-visible {
  background: color-mix(in srgb, var(--clr-text-1) 7%, transparent);
  color: var(--clr-text-1);
}
.app-menu__item--active { color: var(--clr-primary); }
.app-menu__item--quiet { color: var(--clr-text-3); }
.app-menu__ico { display: inline-flex; opacity: 0.85; }
.app-menu__item--unread::after {
  content: "";
  position: absolute;
  right: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--clr-error);
}

/* Быстрый выбор темы: четыре точки вместо ухода в Настройки. */
.app-menu__themes {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-1);
  padding: var(--space-2) var(--space-1) var(--space-1);
  margin-top: var(--space-1);
  border-top: 1px solid var(--glass-hairline);
}
.theme-dot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  min-height: 44px; /* тач-таргет */
  padding: var(--space-2) 2px;
  border-radius: var(--radius-md);
  color: var(--clr-text-3);
  font-size: var(--text-xs);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.theme-dot:hover { background: color-mix(in srgb, var(--clr-text-1) 7%, transparent); }
.theme-dot[aria-checked="true"] {
  background: color-mix(in srgb, var(--clr-primary) 14%, transparent);
  color: var(--clr-primary);
}
.theme-dot__label { line-height: 1.1; }

/* ═══════════════════════════════════════════════════════════════════════════
   4. КОМАНДНАЯ ПАЛИТРА (Ctrl/Cmd+K)
   ═══════════════════════════════════════════════════════════════════════════ */

.cmdk-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: clamp(var(--space-8), 12vh, 140px) var(--space-4) var(--space-4);
  background: color-mix(in srgb, var(--clr-text-1) 32%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 180ms var(--ease-out-quart);
}
.cmdk-overlay--in { opacity: 1; }

.cmdk {
  width: min(560px, 100%);
  max-height: min(60vh, 520px);
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-xl);
  border: 1px solid var(--glass-hairline);
  background: color-mix(in srgb, var(--clr-surface) 82%, transparent);
  -webkit-backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  box-shadow:
    inset 0 1px 0 var(--glass-edge),
    var(--glass-shadow);
  overflow: hidden;
  transform: translateY(-8px) scale(0.985);
  transition: transform 260ms var(--ease-spring);
}
.cmdk-overlay--in .cmdk { transform: none; }

.cmdk__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--glass-hairline);
}
.cmdk__head-ico { display: inline-flex; color: var(--clr-text-3); }
.cmdk__input {
  flex: 1;
  min-width: 0;
  border: none;
  background: none;
  font-size: var(--text-lg);
  font-family: var(--font-body);
  color: var(--clr-text-1);
}
.cmdk__input:focus { outline: none; }
.cmdk__input::placeholder { color: var(--clr-text-3); opacity: 0.75; }
.cmdk__esc,
.cmdk__foot kbd {
  padding: 2px 7px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--glass-hairline);
  background: color-mix(in srgb, var(--clr-text-1) 5%, transparent);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--clr-text-3);
}

.cmdk__list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  list-style: none;
  margin: 0;
  padding: var(--space-2);
}
.cmdk__group {
  padding: var(--space-3) var(--space-3) var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--font-semi);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--clr-text-3);
}
.cmdk__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  cursor: pointer;
  color: var(--clr-text-2);
}
.cmdk__item[aria-selected="true"] {
  background: color-mix(in srgb, var(--clr-primary) 12%, transparent);
  color: var(--clr-text-1);
}
.cmdk__item-ico { display: inline-flex; color: var(--clr-text-3); }
.cmdk__item[aria-selected="true"] .cmdk__item-ico { color: var(--clr-primary); }
.cmdk__item-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.cmdk__item-title {
  font-weight: var(--font-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cmdk__item-hint { font-size: var(--text-xs); color: var(--clr-text-3); }
.cmdk__item-key { display: none; color: var(--clr-primary); }
.cmdk__item[aria-selected="true"] .cmdk__item-key { display: inline-flex; }
.cmdk__empty {
  padding: var(--space-8) var(--space-5);
  text-align: center;
  color: var(--clr-text-3);
}
.cmdk__foot {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--glass-hairline);
  font-size: var(--text-xs);
  color: var(--clr-text-3);
}
.cmdk__foot span { display: inline-flex; align-items: center; gap: 4px; }
@media (max-width: 560px) {
  .cmdk__foot { display: none; } /* на телефоне подсказки клавиш бессмысленны */
  .cmdk-overlay { padding-top: var(--space-6); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   5. ПОПОВЕР УВЕДОМЛЕНИЙ
   ═══════════════════════════════════════════════════════════════════════════ */

.notif-panel {
  position: fixed;
  z-index: var(--z-overlay, 200);
  width: 280px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-hairline);
  background: color-mix(in srgb, var(--clr-surface) 88%, transparent);
  -webkit-backdrop-filter: blur(var(--glass-blur-md)) saturate(180%);
  backdrop-filter: blur(var(--glass-blur-md)) saturate(180%);
  box-shadow: inset 0 1px 0 var(--glass-edge), var(--glass-shadow);
  animation: fn-rise var(--transition-fast) ease both;
}
.notif__head {
  font-family: var(--font-heading);
  font-weight: var(--font-bold);
  font-size: var(--text-base);
  color: var(--clr-text-1);
}
.notif__hint { font-size: var(--text-sm); color: var(--clr-text-3); line-height: var(--leading-relaxed); }
.notif__status { font-size: var(--text-sm); font-weight: var(--font-medium); }
.notif__status--on { color: var(--clr-success); }
.notif__feed {
  margin-top: var(--space-1);
  padding-top: var(--space-3);
  border-top: 1px solid var(--glass-hairline);
  font-size: var(--text-sm);
  color: var(--clr-text-3);
  text-align: center;
}
.notif__list {
  margin-top: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  max-height: 320px;
  overflow-y: auto;
  overscroll-behavior: contain; /* прокрутка ленты не «протекает» на body */
}
.notif__item {
  padding: var(--space-3);
  border: 1px solid var(--glass-hairline);
  border-radius: var(--radius-md);
}
.notif__item-title { font-weight: var(--font-semi); color: var(--clr-text-1); }
.notif__item-body {
  margin-top: 2px;
  font-size: var(--text-sm);
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
}
.notif__item-date { margin-top: var(--space-1); font-size: var(--text-xs); color: var(--clr-text-3); }

/* ═══════════════════════════════════════════════════════════════════════════
   6. МОБИЛЬНЫЙ «ОСТРОВ» (≤768px)
   Та же разметка: капсула переезжает вниз, подписи гаснут, вторичное уходит
   в поповер «Ещё». Порядок в баре: Главная, Задачи, [КОУЧ], Pomodoro, Ещё —
   акцентная кнопка коуча ровно по центру.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {
  .topnav {
    inset-block-start: auto;
    inset-block-end: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
    padding-inline: max(var(--space-3), env(safe-area-inset-left, 0px))
      max(var(--space-3), env(safe-area-inset-right, 0px));
  }
  .topnav__cloud {
    width: 100%;
    height: auto;
    justify-content: space-around;
    gap: 0;
    padding: var(--space-2) var(--space-2);
    border-radius: var(--radius-xl);
  }
  /* Прилипание вниз не сжимает остров — на телефоне это мельтешение. */
  .topnav--stuck .topnav__cloud { height: auto; transform: none; }

  .topnav__brand,
  .topnav__tools,
  .topnav__pill { display: none; }
  .topnav__nav { display: contents; }
  .topnav__label { display: none; }

  .topnav__link,
  .topnav__more {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    height: auto;
    padding: var(--space-2);
  }
  /* Body Double уезжает в «Ещё», а не мозолит глаза в баре. Селектор с
     родителем — чтобы перебить .topnav__link выше (та же специфичность, но
     объявлен раньше). */
  .topnav__nav .topnav__link--mobile-more { display: none; }

  .topnav__more { color: var(--clr-text-2); }
  .topnav__more[aria-expanded="true"] { color: var(--clr-primary); }
  .topnav__more--unread::after {
    content: "";
    position: absolute;
    top: 6px;
    right: 6px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--clr-error);
  }
  .topnav__more { position: relative; }

  .topnav a[href="#/dashboard"] { order: 1; }
  .topnav a[href="#/tasks"] { order: 2; }
  .topnav a[href="#/coach"] { order: 3; }
  .topnav a[href="#/pomodoro"] { order: 4; }
  .topnav__more { order: 5; }

  /* Акцентная кнопка ИИ-коуча: круглая, фирменного цвета, в габаритах капсулы.
     Заливка сплошная: на градиенте белая иконка теряла контраст к правому краю
     (циановый стоп давал 1.7:1 при норме 3:1 для графики). */
  .topnav a[href="#/coach"] {
    width: 48px;
    height: 48px;
    min-width: 48px;
    border-radius: var(--radius-full);
    background: var(--clr-primary);
    color: var(--clr-on-primary);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.3),
      0 4px 14px color-mix(in srgb, var(--clr-primary) 45%, transparent);
  }
  .topnav a[href="#/coach"].topnav__link--active {
    outline: 3px solid color-mix(in srgb, var(--clr-primary) 30%, transparent);
    outline-offset: 2px;
  }

  /* Поповер встаёт над островом, справа. */
  .app-menu {
    inset-block-start: auto;
    inset-block-end: calc(var(--space-16) + var(--space-4) + env(safe-area-inset-bottom, 0px));
    inset-inline-end: var(--space-3);
    width: min(280px, calc(100vw - 2 * var(--space-3)));
    transform-origin: bottom right;
    transform: translateY(6px) scale(0.98);
  }
  .app-menu--open { transform: none; }
  .app-menu__group--mobile { display: flex; }
  /* Док делит угол с поповером — прячем его, пока меню открыто. */
  body.fn-menu-open .quick-dock { display: none; }

  .app-main {
    /* Сверху навигации нет (она внизу), поэтому именно здесь нужен верхний
       инсет: в установленной PWA заголовок экрана иначе оказывается под
       чёлкой / Dynamic Island. */
    padding:
      calc(var(--space-5) + env(safe-area-inset-top, 0px))
      max(var(--space-4), env(safe-area-inset-right, 0px))
      calc(var(--space-16) + var(--space-8) + env(safe-area-inset-bottom, 0px))
      max(var(--space-4), env(safe-area-inset-left, 0px));
  }
}

/* Очень узкие экраны: ужимаем иконки бара сильнее. */
@media (max-width: 380px) {
  .topnav__link,
  .topnav__more { padding: var(--space-1); }
}

/* Планшеты: подписи разделов гаснут раньше, чем ломается капсула. */
@media (min-width: 769px) and (max-width: 1080px) {
  .topnav__label { display: none; }
  .topnav__link { padding-inline: var(--space-3); }
  .topnav__wordmark { display: none; }
}

/* Уважение к «меньше движения»: капсула не ездит, поповеры просто появляются. */
@media (prefers-reduced-motion: reduce) {
  .topnav__cloud,
  .topnav__pill,
  .app-menu,
  .cmdk { transition: none; }
  .topnav--stuck .topnav__cloud { transform: none; }
}
[data-reduced-motion="true"] .topnav__cloud,
[data-reduced-motion="true"] .topnav__pill,
[data-reduced-motion="true"] .app-menu,
[data-reduced-motion="true"] .cmdk { transition: none; }
[data-reduced-motion="true"] .topnav--stuck .topnav__cloud { transform: none; }

/* ===== /css/layouts/app-glass.css ===== */
/* app-glass.css — Liquid Glass для авторизованной зоны: поверхности, кнопки,
 * поля, чипы. Слой примитивов; композиция экранов — в css/pages/*.
 *
 * ВСЁ заскоплено на `.app-shell` (корень приложения). Лендинг и Библиотека
 * этот файл не подключают, а базовые компоненты (.btn, .panel, .input) внутри
 * них остаются прежними — так редизайн приложения не может «протечь» в
 * маркетинговые страницы.
 *
 * Рецепт стекла один на всё приложение:
 *   слой заливки (полупрозрачный градиент сверху вниз)
 * + backdrop-filter (blur + saturate: стекло концентрирует цвет за собой)
 * + световая кромка сверху и затухающая снизу (внутренние тени)
 * + мягкая многослойная внешняя тень
 * + блик-рефракция в левом верхнем углу (::before)
 *
 * ⚠ Перф: backdrop-filter получают только КРУПНЫЕ поверхности (карточки,
 * панели, поповеры). Мелкие элементы внутри стекла (строки списков, чипы,
 * кнопки) размытия не получают: второго слоя за ними всё равно нет, а каждый
 * такой слой — отдельная композиция на каждый кадр прокрутки.
 */

/* ═══════════════════════════════════════════════════════════════════════════
   1. ПОВЕРХНОСТИ
   ═══════════════════════════════════════════════════════════════════════════ */

/* Блик-рефракция (первый слой фона) — то, что отличает настоящее стекло от
 * «полупрозрачного прямоугольника»: мягкое пятно света в левом верхнем углу.
 *
 * Именно СЛОЙ ФОНА, а не ::before: абсолютно спозиционированный потомок
 * рисуется ПОВЕРХ не спозиционированного контента, то есть блик ложился бы на
 * заголовок карточки и съедал его контраст. */
.app-shell .glass,
.app-shell .panel,
.app-shell .card {
  position: relative;
  border-radius: var(--radius-xl);
  border: 1px solid var(--glass-hairline);
  background:
    radial-gradient(120% 80% at 0% 0%,
      color-mix(in srgb, var(--glass-specular) 55%, transparent) 0%, transparent 46%),
    linear-gradient(180deg, var(--glass-fill) 0%, var(--glass-fill-2) 100%);
  -webkit-backdrop-filter: blur(var(--glass-blur-md)) saturate(var(--glass-saturate));
  backdrop-filter: blur(var(--glass-blur-md)) saturate(var(--glass-saturate));
  box-shadow:
    inset 0 1px 0 var(--glass-edge),
    inset 0 -1px 0 var(--glass-edge-dim),
    var(--glass-shadow);
}

/* Панель контента: базовая геометрия (стекло — выше). */
.panel {
  padding: var(--space-6);
}
.panel + .panel,
.stats-row + .panel { margin-top: var(--space-6); }
.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.panel__head h2 { font-size: var(--text-xl); }

/* Интерактивная карточка: подъём, усиление свечения и плотности стекла.
   Двигаем только transform/opacity — repaint не задевает layout. */
.app-shell .glass--hover {
  transition:
    transform 320ms var(--ease-spring),
    box-shadow var(--transition-normal),
    background var(--transition-normal),
    border-color var(--transition-normal);
}
.app-shell .glass--hover:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--clr-primary) 22%, var(--glass-hairline));
  background:
    radial-gradient(120% 80% at 0% 0%,
      color-mix(in srgb, var(--glass-specular) 70%, transparent) 0%, transparent 46%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--glass-fill) 100%, var(--clr-surface) 14%) 0%,
      var(--glass-fill) 100%);
  box-shadow:
    inset 0 1px 0 var(--glass-edge),
    inset 0 -1px 0 var(--glass-edge-dim),
    0 4px 12px rgba(12, 14, 20, 0.06),
    0 22px 48px rgba(12, 14, 20, 0.12),
    0 0 0 1px color-mix(in srgb, var(--clr-primary) 8%, transparent);
}

/* Вложенная поверхность внутри стекла: второй backdrop-filter здесь был бы
   лишней композицией — берём плотную заливку без размытия. */
.app-shell .glass-inset {
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-hairline);
  background: color-mix(in srgb, var(--clr-surface) 46%, transparent);
}

/* Мобильный: вторичные поверхности теряют backdrop-filter. На среднем Android
   6–8 слоёв размытия на прокрутке — это уже не 60 FPS, а визуальная разница
   на 6" экране практически нулевая. */
@media (max-width: 640px) {
  .app-shell .card,
  .app-shell .glass-secondary {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: color-mix(in srgb, var(--clr-surface) 72%, transparent);
  }
}

/* Без поддержки backdrop-filter — плотные поверхности (Firefox со старыми
   флагами, встроенные webview). */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .app-shell .glass,
  .app-shell .panel,
  .app-shell .card {
    background: color-mix(in srgb, var(--clr-surface) 92%, transparent);
  }
}

/* Контрастная тема: стекло выключено целиком — рамки и плотный фон. */
[data-theme="high-contrast"] .app-shell .glass,
[data-theme="high-contrast"] .app-shell .panel,
[data-theme="high-contrast"] .app-shell .card {
  background: var(--clr-surface);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: 2px solid var(--clr-border);
  box-shadow: none;
}
[data-theme="high-contrast"] .app-shell .glass--hover:hover {
  background: var(--clr-surface);
  transform: none;
  box-shadow: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   2. КНОПКИ
   Капсулы со стеклянной оптикой. Главная CTA — единственная заливка бренда на
   экране: если «важных» кнопок больше одной, важной не выглядит ни одна.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Заливка сплошная, а не --gradient-brand. Градиент шёл индиго → сирень →
   циан, и белая подпись съезжала по нему с 4.57:1 до 1.81:1 (в тёмной теме —
   с 2.70 до 1.69). Текст на градиенте нечитаем в принципе: контраст зависит от
   того, под какой буквой оказался стоп. Фирменность держат свечение бренда в
   тени и световая кромка — они остались; градиент живёт там, где текста нет
   (полоса прогресса дня). Цвет подписи — --clr-on-primary (см. design-tokens). */
.app-shell .btn--primary {
  background: var(--clr-primary);
  color: var(--clr-on-primary);
  border-color: transparent;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.30),
    inset 0 -1px 0 rgba(0, 0, 0, 0.12),
    0 4px 14px color-mix(in srgb, var(--clr-primary) 32%, transparent);
}
.app-shell .btn--primary:hover {
  background: var(--clr-primary-hover);
  color: var(--clr-on-primary);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.38),
    0 8px 26px color-mix(in srgb, var(--clr-primary) 42%, transparent);
}

/* Вторичная — стеклянная капсула: полупрозрачная заливка + световая кромка.
   БЕЗ backdrop-filter намеренно: почти все такие кнопки лежат внутри
   стеклянных карточек, где размывать уже нечего (фон за ними — размытая
   поверхность карточки), а каждый вложенный слой стоит отдельной композиции
   на каждый кадр прокрутки. Визуально разницы нет, кадровый бюджет — есть. */
.app-shell .btn--secondary {
  background: color-mix(in srgb, var(--clr-surface) 62%, transparent);
  color: var(--clr-text-1);
  border-color: var(--glass-hairline);
  box-shadow:
    inset 0 1px 0 var(--glass-edge),
    0 2px 8px rgba(12, 14, 20, 0.05);
}
.app-shell .btn--secondary:hover {
  background: color-mix(in srgb, var(--clr-surface) 88%, transparent);
  border-color: color-mix(in srgb, var(--clr-primary) 28%, var(--glass-hairline));
  color: var(--clr-primary);
  box-shadow:
    inset 0 1px 0 var(--glass-edge),
    0 6px 18px rgba(12, 14, 20, 0.09);
}

.app-shell .btn--ghost {
  color: var(--clr-text-2);
}
.app-shell .btn--ghost:hover {
  background: color-mix(in srgb, var(--clr-text-1) 7%, transparent);
  color: var(--clr-text-1);
}

.app-shell .icon-btn:hover {
  background: color-mix(in srgb, var(--clr-text-1) 8%, transparent);
}

[data-theme="high-contrast"] .app-shell .btn--primary {
  background: var(--clr-primary);
  box-shadow: none;   /* без свечения и кромки — только плотный цвет */
}
[data-theme="high-contrast"] .app-shell .btn--secondary {
  background: var(--clr-surface);
  border-color: var(--clr-border);
}

/* ═══════════════════════════════════════════════════════════════════════════
   3. ПОЛЯ ВВОДА
   ═══════════════════════════════════════════════════════════════════════════ */

.app-shell .input,
.app-shell .textarea,
.app-shell .select {
  background: color-mix(in srgb, var(--clr-surface) 55%, transparent);
  border: 1px solid var(--glass-hairline);
  border-radius: var(--radius-lg);
  box-shadow: inset 0 1px 2px rgba(12, 14, 20, 0.04);
  transition:
    border-color var(--transition-fast),
    box-shadow var(--transition-fast),
    background var(--transition-fast);
}
/* Плейсхолдер тише основного текста, но не ниже порога читаемости: это
   подсказка, а не украшение (важно при дислексии). */
.app-shell .input::placeholder,
.app-shell .textarea::placeholder {
  color: var(--clr-text-3);
  opacity: 0.8;
}
.app-shell .input:hover,
.app-shell .textarea:hover {
  border-color: color-mix(in srgb, var(--clr-primary) 22%, var(--glass-hairline));
}
.app-shell .input:focus,
.app-shell .textarea:focus,
.app-shell .select:focus {
  background: color-mix(in srgb, var(--clr-surface) 82%, transparent);
  border-color: var(--clr-primary);
  box-shadow:
    0 0 0 4px color-mix(in srgb, var(--clr-primary) 16%, transparent),
    inset 0 1px 2px rgba(12, 14, 20, 0.03);
}
/* Стрелка отправки — иконка на заливке бренда: те же правила, что у кнопки
   (градиент уронил бы контраст глифа до 1.8:1 при норме 3:1 для графики). */
.app-shell .composer-send {
  background: var(--clr-primary);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.28),
    0 3px 10px color-mix(in srgb, var(--clr-primary) 35%, transparent);
}

/* ═══════════════════════════════════════════════════════════════════════════
   4. МЕЛОЧИ: чипы, скелетоны, пустые состояния, аватар
   ═══════════════════════════════════════════════════════════════════════════ */

.app-shell .badge {
  border: 1px solid var(--glass-hairline);
  box-shadow: inset 0 1px 0 var(--glass-edge);
}

.app-shell .skeleton-card,
.app-shell .skeleton-stat {
  border-color: var(--glass-hairline);
  background: color-mix(in srgb, var(--clr-surface) 45%, transparent);
}
.app-shell .skeleton { background: color-mix(in srgb, var(--clr-text-1) 8%, transparent); }

.app-shell .empty-state__ico {
  background: color-mix(in srgb, var(--clr-primary) 12%, transparent);
  border: 1px solid var(--glass-hairline);
  box-shadow: inset 0 1px 0 var(--glass-edge);
}

/* Аватар — общий для шапки, поповера и Настроек. */
.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--clr-primary-light);
  color: var(--clr-primary);
  font-family: var(--font-heading);
  font-weight: var(--font-bold);
  line-height: 1;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.avatar--sm { width: 32px; height: 32px; font-size: var(--text-sm); }
.avatar--md { width: 52px; height: 52px; font-size: var(--text-xl); }
.avatar--lg { width: 76px; height: 76px; font-size: var(--text-2xl); }
.app-shell .avatar {
  border: 1px solid var(--glass-hairline);
  box-shadow: inset 0 1px 0 var(--glass-edge);
}

/* ═══════════════════════════════════════════════════════════════════════════
   5. ФОКУС
   Видимая рамка одинаковой формы по всему приложению: две обводки (светлая +
   брендовая) читаются и на стекле, и на плотной поверхности.
   ═══════════════════════════════════════════════════════════════════════════ */

.app-shell a:focus-visible,
.app-shell button:focus-visible,
.app-shell [tabindex]:focus-visible,
.app-menu button:focus-visible,
.app-menu a:focus-visible,
.cmdk button:focus-visible {
  outline: 2px solid var(--clr-primary);
  outline-offset: 2px;
  border-radius: var(--radius-md);
}
.app-shell .input:focus-visible,
.app-shell .textarea:focus-visible { outline: none; } /* своё кольцо выше */

/* ===== /css/pages/auth.css ===== */
/* auth.css — экран входа/регистрации. */

.auth {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background: linear-gradient(180deg, var(--clr-primary-light) 0%, var(--clr-surface) 60%);
}
[data-theme="dark"] .auth {
  background: linear-gradient(180deg, var(--clr-surface-2) 0%, var(--clr-surface) 60%);
}

.auth__card {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  box-shadow: var(--shadow-lg);
}

.auth__logo {
  font-size: var(--text-2xl);
  text-align: center;
}

.auth__title {
  font-size: var(--text-2xl);
  text-align: center;
}

.auth__subtitle {
  text-align: center;
  margin-top: calc(-1 * var(--space-2));
}

.auth__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.auth__legal {
  font-size: var(--text-xs);
  text-align: center;
}

/* Разделитель «или» между OTP и соц-входом. */
.auth__divider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--clr-text-3);
  font-size: var(--text-sm);
}
.auth__divider::before,
.auth__divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--clr-border);
}

/* Кнопки входа через VK ID / Yandex ID. */
.oauth-btns {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.oauth-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  font-weight: var(--font-semi);
}
.oauth-btn__ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  font-size: 11px;
  font-weight: var(--font-bold);
  line-height: 1;
}
.oauth-btn--vk {
  background: #0077ff;
  color: #fff;
  border: 1px solid #0077ff;
}
.oauth-btn--vk:hover { background: #006ae6; }
.oauth-btn--vk .oauth-btn__ico { background: #fff; color: #0077ff; }
.oauth-btn--yandex {
  background: var(--clr-surface);
  color: var(--clr-text-1);
  border: 1px solid var(--clr-border);
}
.oauth-btn--yandex:hover { border-color: var(--clr-text-3); }
.oauth-btn--yandex .oauth-btn__ico { background: #fc3f1d; color: #fff; }

/* ===== /css/pages/onboarding.css ===== */
/* onboarding.css — визард онбординга. */

.onboarding {
  width: 100%;
  max-width: 520px;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  box-shadow: var(--shadow-lg);
}

/* Маскот-проводник — по центру над прогрессом. */
.ob-mascot {
  align-self: center;
  margin-bottom: var(--space-1);
}

.onboarding__progress {
  height: 6px;
  background: var(--clr-surface-3);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.onboarding__progress span {
  display: block;
  height: 100%;
  background: var(--clr-primary);
  border-radius: var(--radius-full);
  transition: width var(--transition-normal);
}

.onboarding__title {
  font-size: var(--text-2xl);
}

.choices {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.choices--grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}

.choice {
  padding: var(--space-3) var(--space-4);
  border: 1.5px solid var(--clr-border);
  border-radius: var(--radius-md);
  background: var(--clr-surface);
  color: var(--clr-text-1);
  font-weight: var(--font-medium);
  text-align: left;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
.choice:hover { border-color: var(--clr-primary); }
.choice--on {
  border-color: var(--clr-primary);
  background: var(--clr-primary-light);
  color: var(--clr-primary);
}

.onboarding__nav {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-2);
}

/* Финальный «ага-момент»: разбивка задачи. */
.ob-try { display: flex; gap: var(--space-2); }
.ob-try .input { flex: 1; }

.ob-steps {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
}
.ob-step {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--clr-surface-2);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-md);
  animation: fn-rise var(--transition-normal) ease both;
}
.ob-step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  background: var(--clr-primary);
  color: var(--clr-on-primary);
  font-size: var(--text-xs);
  font-weight: var(--font-bold);
}
.ob-step__time {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--clr-text-3);
  white-space: nowrap;
}

@media (max-width: 480px) {
  .choices--grid { grid-template-columns: 1fr; }
}

/* ===== /css/pages/dashboard.css ===== */
/* dashboard.css — Главная: сетка экрана, герой «следующий шаг», задачи дня,
 * правый рельс. Стеклянные поверхности приходят из layouts/app-glass.css
 * (.glass / .panel) — здесь только композиция и то, что специфично Главной.
 *
 * Иерархия экрана намеренно жёсткая:
 *   1. Приветствие          — кто я и как у меня дела (тихо, мелко)
 *   2. Герой                — ОДНО действие + прогресс дня (громко, крупно)
 *   3. Захват мысли         — не потерять то, что всплыло
 *   4. Задачи на сегодня    — список, где можно отметить
 *   5. Рельс справа         — всё остальное (на телефоне складывается)
 * Ровно один градиентный акцент на экране (герой): если «важного» больше
 * одного, важным не выглядит ничего.
 */

/* ═══════════════════════════════════════════════════════════════════════════
   1. ШАПКА ЭКРАНА (общая для всех разделов приложения)
   ═══════════════════════════════════════════════════════════════════════════ */

.app-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-8);
}
.app-header h1 {
  font-size: var(--text-3xl);
  letter-spacing: -0.02em; /* крупные заголовки набираются плотнее — «дорогой» тон */
}

.dash-head { margin-bottom: var(--space-6); }
.dash-greet { display: flex; align-items: center; gap: var(--space-4); }
.dash-greet__text { min-width: 0; }
/* Однократный приветственный «взмах» руки. Только при разрешённом движении.
   Внутри — SVG-иконка (display:block из reset), поэтому inline-flex + сдвиг
   до оптической базовой линии заголовка. */
.dash-greet__wave {
  display: inline-flex;
  vertical-align: -0.1em;
  color: var(--clr-primary);
}
@media (prefers-reduced-motion: no-preference) {
  .dash-greet__wave { animation: dash-wave 2.6s ease-in-out 1; transform-origin: 70% 80%; }
  @keyframes dash-wave {
    0%, 60%, 100% { transform: rotate(0); }
    10%, 30% { transform: rotate(14deg); }
    20%, 40% { transform: rotate(-8deg); }
  }
}
[data-reduced-motion="true"] .dash-greet__wave { animation: none; }

/* Чипы в шапке: лимит, мягкая цепочка, настроение. */
.dash-badges {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.streak-chip { background: color-mix(in srgb, var(--clr-success) 14%, transparent); }
.streak-chip--frozen { opacity: 0.85; }
.dash-mood-chip {
  cursor: pointer;
  background: color-mix(in srgb, var(--clr-accent) 14%, transparent);
  transition: background var(--transition-fast), transform 220ms var(--ease-spring);
}
.dash-mood-chip:hover {
  background: color-mix(in srgb, var(--clr-accent) 24%, transparent);
  transform: translateY(-1px);
}
@media (hover: none) {
  .dash-mood-chip:hover { transform: none; } /* залипший hover на тапе */
}
.dash-mood-chip .ico-inline { margin-right: 2px; }
/* Тач: «Настроение» — единственный кликабельный чип в этом ряду, и он был
   31px в высоту. Поднимаем только на тач-устройствах: на десктопе ряд бейджей
   должен остаться визуально однородным (лимит и цепочка — не кнопки). */
@media (pointer: coarse) {
  .dash-mood-chip {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* Блок настроения раскрывается над сеткой — отделяем его от неё. */
#mood-host > * { margin-bottom: var(--space-6); }

/* ═══════════════════════════════════════════════════════════════════════════
   2. СЕТКА ЭКРАНА
   ═══════════════════════════════════════════════════════════════════════════ */

.dash-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-6);
  align-items: start;
}
.dash-flow {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  min-width: 0;
  /* Контейнер запросов: герой перестраивается по ширине СВОЕЙ колонки, а не
     окна. С рельсом справа колонка заметно уже вьюпорта — медиазапрос по
     вьюпорту здесь врал бы. */
  container-type: inline-size;
  container-name: dashflow;
}

/* Правый рельс: второстепенные виджеты. Липкий — при длинном списке задач
   «Ещё сегодня» остаётся на виду, а не уезжает в никуда. */
.dash-rail {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}
.dash-rail__title {
  font-size: var(--text-sm);
  font-weight: var(--font-semi);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--clr-text-3);
  padding-inline: var(--space-1);
}
.dash-rail__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
/* Кнопка-гармошка нужна только на узких экранах (см. медиазапрос ниже). */
.dash-rail__toggle { display: none; }

@media (min-width: 1100px) {
  .dash-grid { grid-template-columns: minmax(0, 1fr) 328px; gap: var(--space-8); }
  .dash-rail {
    position: sticky;
    top: calc(var(--nav-top) + var(--nav-h) + var(--space-6));
  }
  /* На десктопе рельс всегда раскрыт: сворачивать нечего — он не отнимает
     место у основного потока. Перебиваем .hidden (тоже !important) более
     высокой специфичностью. */
  .dash-rail__body.hidden { display: flex !important; }
}

/* Узкие экраны: рельс уезжает под контент и складывается в «Ещё сегодня» —
   над сгибом остаются приветствие и герой. */
@media (max-width: 1099px) {
  .dash-rail__title { display: none; }
  .dash-rail__toggle {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    min-height: 48px;
    padding: var(--space-3) var(--space-5);
    border-radius: var(--radius-lg);
    border: 1px solid var(--glass-hairline);
    background: color-mix(in srgb, var(--clr-surface) 45%, transparent);
    color: var(--clr-text-2);
    font-family: var(--font-heading);
    font-weight: var(--font-semi);
    transition: background var(--transition-fast), color var(--transition-fast);
  }
  .dash-rail__toggle:hover {
    background: color-mix(in srgb, var(--clr-surface) 70%, transparent);
    color: var(--clr-text-1);
  }
  .dash-rail__label { flex: 1; text-align: left; }
  .dash-rail__chev {
    display: inline-flex;
    color: var(--clr-text-3);
    transition: transform var(--transition-fast);
  }
  .dash-rail__toggle[aria-expanded="true"] .dash-rail__chev { transform: rotate(180deg); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   3. ГЕРОЙ «СЛЕДУЮЩИЙ ШАГ»
   Единственный акцентный объект экрана: стекло + брендовое свечение внутри.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Свечение бренда живёт ВНУТРИ стекла — дополнительными слоями фона поверх
   стеклянной заливки (не псевдоэлементом: он рисовался бы поверх текста).
   Заливка остаётся полупрозрачной, поэтому герой не превращается в плотный
   градиентный прямоугольник. */
.next-step {
  position: relative;
  overflow: hidden;
  padding: var(--space-8);
  border-radius: var(--radius-xl);
}
/* Селектор с .app-shell — чтобы перебить общий рецепт стекла из
   layouts/app-glass.css (та же специфичность, но этот файл грузится позже). */
.app-shell .next-step {
  background:
    radial-gradient(120% 80% at 0% 0%,
      color-mix(in srgb, var(--glass-specular) 55%, transparent) 0%, transparent 46%),
    radial-gradient(70% 120% at 100% 0%,
      color-mix(in srgb, var(--clr-accent) 16%, transparent) 0%, transparent 60%),
    radial-gradient(80% 130% at 0% 100%,
      color-mix(in srgb, var(--clr-primary) 14%, transparent) 0%, transparent 62%),
    linear-gradient(180deg, var(--glass-fill) 0%, var(--glass-fill-2) 100%);
}
[data-theme="high-contrast"] .app-shell .next-step { background: var(--clr-surface); }

.next-step__main {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}
.next-step__body { flex: 1; min-width: 0; }
.next-step__mascot { flex-shrink: 0; }
.next-step__label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  padding: 4px 12px 4px 8px;
  border-radius: var(--radius-full);
  border: 1px solid color-mix(in srgb, var(--clr-primary) 20%, transparent);
  background: color-mix(in srgb, var(--clr-primary) 10%, transparent);
  font-size: var(--text-xs);
  font-weight: var(--font-semi);
  letter-spacing: 0.03em;
  color: var(--clr-primary);
}
.next-step__label::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: var(--radius-full);
  background: var(--clr-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--clr-primary) 20%, transparent);
}
.next-step__title {
  font-family: var(--font-heading);
  font-size: var(--text-3xl);
  font-weight: var(--font-bold);
  color: var(--clr-text-1);
  line-height: var(--leading-tight);
  letter-spacing: -0.02em;
  text-wrap: balance; /* заголовок не оставляет одинокое слово на строке */
}
.next-step__sub {
  margin-top: var(--space-2);
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
}
.next-step__actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-6);
}
.next-step--done .next-step__title { color: var(--clr-success); }

/* Прогресс дня — подвал героя: та же карточка, отделён световой линией. */
.dash-progress {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--glass-hairline);
}
.dash-progress__cells { display: flex; gap: 5px; }
.dash-progress__cell {
  flex: 1 1 0;
  height: 8px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--clr-text-1) 10%, transparent);
  box-shadow: inset 0 1px 1px rgba(12, 14, 20, 0.06);
  transition: background var(--transition-normal), box-shadow var(--transition-normal);
}
.dash-progress__cell.is-done {
  background: var(--gradient-brand);
  box-shadow: 0 1px 6px color-mix(in srgb, var(--clr-primary) 40%, transparent);
}
.dash-progress__track {
  height: 8px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--clr-text-1) 10%, transparent);
  box-shadow: inset 0 1px 1px rgba(12, 14, 20, 0.06);
  overflow: hidden;
}
.dash-progress__fill {
  display: block;
  height: 100%;
  border-radius: var(--radius-full);
  background: var(--gradient-brand);
  transition: width var(--transition-slow);
}
.dash-progress__caption {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--clr-text-2);
  font-variant-numeric: tabular-nums;
}
.dash-progress--done .dash-progress__cell.is-done,
.dash-progress--done .dash-progress__fill {
  background: var(--clr-success);
  box-shadow: 0 1px 6px color-mix(in srgb, var(--clr-success) 40%, transparent);
}
.dash-progress--done .dash-progress__caption {
  color: var(--clr-success);
  font-weight: var(--font-medium);
}

/* Узкая колонка: маскот уходит, приоритет — тексту и кнопкам. */
@container dashflow (max-width: 560px) {
  .next-step { padding: var(--space-6) var(--space-5); }
  .next-step__mascot { display: none; }
  .next-step__title { font-size: var(--text-2xl); }
  .next-step__actions .btn { flex: 1 1 auto; }
}
/* Фолбэк для браузеров без container queries. */
@supports not (container-type: inline-size) {
  @media (max-width: 560px) {
    .next-step { padding: var(--space-6) var(--space-5); }
    .next-step__mascot { display: none; }
    .next-step__title { font-size: var(--text-2xl); }
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   4. ЗАХВАТ МЫСЛИ И ЗАДАЧИ ДНЯ
   ═══════════════════════════════════════════════════════════════════════════ */

.dash-capture__hint {
  margin-top: calc(-1 * var(--space-2));
  margin-bottom: var(--space-4);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

.dash-tasks__tools {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
/* Счётчик «сделано / всего» — тихий, табличными цифрами: не прыгает по ширине
   при отметке задачи. */
.dash-tasks__count {
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--clr-text-3);
}

.dash-tasks__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Строка задачи — не карточка в карточке: тонкий разделитель и подсветка при
   наведении. Список из десяти «карточек» внутри панели читается как свалка. */
.dash-task {
  border-radius: var(--radius-md);
  padding-inline: var(--space-3);
  transition: background var(--transition-fast);
}
.dash-task + .dash-task {
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--clr-text-1) 7%, transparent);
}
.dash-task:hover {
  background: color-mix(in srgb, var(--clr-primary) 7%, transparent);
  box-shadow: none;
}
.dash-task:hover + .dash-task { box-shadow: none; }
.dash-task__hit { padding-block: var(--space-2); }
.dash-task__title { line-height: var(--leading-relaxed); }
.dash-task--done { opacity: 0.66; }

/* ─── Задачи дня как лист из блокнота ──────────────────────────────────────
   Жёлтая шапка-обложка сверху, ниже — бумага в клетку. Токены --note-* общие
   с карточками на странице Задач (design-tokens.css) и переопределены во всех
   четырёх темах, поэтому блок подстраивается сам.
   Селектор с .app-shell нужен, чтобы перебить стекло из layouts/app-glass.css:
   бумага и стекло — взаимоисключающие поверхности, а не слои. */
.app-shell .panel.dash-tasks {
  /* Клетка 22px — ровно половина строки задачи (44px, минимальный тап-таргет),
     поэтому строка занимает две клетки и список не «плывёт» по сетке. */
  --note-cell: 22px;
  padding: 0; /* свои отступы у обложки и листа: обложка идёт до кромки */
  overflow: hidden; /* обложка обрезается по скруглению листа */
  border-radius: var(--radius-lg);
  border: 1px solid var(--note-line);
  background: var(--note-paper);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: var(--shadow-md);
}

/* Обложка — единственное цветное поле блока. Текст на ней парным ink-тоном
   того же семейства (в контрастной теме это белое на чёрном), под ней —
   «перфорация» точечным пунктиром, как у карточек-заметок. */
.dash-tasks__head {
  margin: 0;
  padding: var(--space-4) var(--space-5);
  background: var(--note-head-medium);
  color: var(--note-ink-medium);
  border-bottom: 3px dotted var(--note-perf);
}
.dash-tasks__head h2 { color: inherit; }
.dash-tasks__head .dash-tasks__count { color: inherit; opacity: 0.72; }
/* Кнопка на обложке: полупрозрачная бумага в обводке ink-тоном. Белая плашка
   btn--secondary на жёлтом читалась бы как заплатка. */
.dash-tasks__head .btn--secondary {
  background: color-mix(in srgb, var(--note-paper) 58%, transparent);
  border-color: color-mix(in srgb, var(--note-ink-medium) 26%, transparent);
  color: var(--note-ink-medium);
}
.dash-tasks__head .btn--secondary:hover {
  background: color-mix(in srgb, var(--note-paper) 88%, transparent);
}

/* Лист в клетку. background-origin: content-box привязывает сетку к началу
   контента — первая строка ложится ровно в клетку. Сдвиг на пол-клетки уводит
   горизонтальные линии из-под текста: они проходят выше и ниже строки. */
.dash-tasks__sheet {
  padding: var(--space-4) var(--space-5) var(--space-5);
  background-image:
    repeating-linear-gradient(to right,
      var(--note-line) 0 1px, transparent 1px var(--note-cell)),
    repeating-linear-gradient(to bottom,
      var(--note-line) 0 1px, transparent 1px var(--note-cell));
  background-origin: content-box;
  background-position: 0 calc(var(--note-cell) / -2);
}
/* На клетчатом листе разделители строк лишние — их роль играет сама сетка. */
.dash-tasks__sheet .dash-tasks__list { gap: 0; }
.dash-tasks__sheet .dash-task + .dash-task { box-shadow: none; }

/* Контрастная тема: бумага и клетка выключены — сетка линий под текстом при
   максимальном контрасте становится шумом. Остаётся плоская панель. */
[data-theme="high-contrast"] .app-shell .panel.dash-tasks {
  background: var(--clr-surface);
  border: 2px solid var(--clr-border);
  box-shadow: none;
}
[data-theme="high-contrast"] .dash-tasks__head {
  background: var(--clr-surface);
  color: var(--clr-text-1);
  border-bottom: 2px solid var(--clr-border);
}
[data-theme="high-contrast"] .dash-tasks__head .btn--secondary {
  background: var(--clr-surface);
  border-color: var(--clr-border);
  color: var(--clr-primary);
}
[data-theme="high-contrast"] .dash-tasks__sheet { background-image: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   5. КАРТОЧКИ РЕЛЬСА
   Разная высота и «вес» намеренно: одинаковые карточки в столбик — это не
   дашборд, а таблица. Цифры дня плотные, совет — просторный, действия — с CTA.
   ═══════════════════════════════════════════════════════════════════════════ */

.dash-card {
  padding: var(--space-5);
  border-radius: var(--radius-lg);
}
.dash-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.dash-card__title {
  flex: 1;
  min-width: 0;
  font-family: var(--font-heading);
  font-size: var(--text-base);
  font-weight: var(--font-bold);
  color: var(--clr-text-1);
}
.dash-card__title--sub {
  font-size: var(--text-xs);
  font-weight: var(--font-semi);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--clr-text-3);
  margin-bottom: var(--space-3);
}
.dash-card__meta {
  color: var(--clr-text-2);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}
.dash-card .btn { margin-top: var(--space-4); }
/* Размер/форма чипа-иконки — из .ico-chip (utilities.css), здесь только тон. */
.dash-card__ico { color: var(--clr-primary); }

/* Цифры дня. */
.dash-metrics__row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2);
  margin: 0;
}
.dash-metric {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--space-2) var(--space-1);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--clr-surface) 40%, transparent);
}
.dash-metric__ico { display: inline-flex; color: var(--clr-primary); opacity: 0.8; }
.dash-metric__value {
  order: -1; /* число выше подписи, но в DOM <dt> обязан идти первым */
  margin: 0;
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  font-weight: var(--font-bold);
  color: var(--clr-text-1);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
/* Кегль подписи — не ниже --text-xs (13px): всё, что мельче, при дислексии
   читается хуже, а это подпись к числу, а не декор. */
.dash-metric__label {
  font-size: var(--text-xs);
  color: var(--clr-text-3);
  text-align: center;
  line-height: 1.2;
  text-wrap: balance;
}

/* Совет дня — тёплый янтарный тон вместо брендового: это другой голос. */
.dash-tip .dash-card__ico { color: var(--clr-warning); }
.dash-tip__body {
  color: var(--clr-text-1);
  line-height: var(--leading-relaxed);
  font-size: var(--text-sm);
}
.dash-tip__close { margin-inline-start: auto; }

/* Body Double. */
.dash-bd__topic {
  font-weight: var(--font-semi);
  color: var(--clr-text-1);
  line-height: var(--leading-normal);
  margin-bottom: 2px;
}

/* Вечернее закрытие дня. */
.dash-close--done { border-style: dashed; }
.dash-close__streak {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--clr-text-2);
}

/* ═══════════════════════════════════════════════════════════════════════════
   6. «ПЕРЕНОС БЕЗ ВИНЫ»
   Живёт в основном потоке, а не в рельсе: просрочку нельзя прятать за сгибом,
   но и пугать ею нельзя — отсюда мягкий тон и кнопка «отпустить».
   ═══════════════════════════════════════════════════════════════════════════ */

.dash-carry {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
}
.dash-carry__head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}
.dash-carry__ico { color: var(--clr-warning); }
.dash-carry__text {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: var(--leading-relaxed);
}
.dash-carry__text strong { color: var(--clr-text-1); }
/* .dash-carry__close — целиком на .icon-btn icon-btn--sm (без своих размеров). */
.dash-carry__actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.dash-carry__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: var(--space-3) 0 0;
  border-top: 1px solid var(--glass-hairline);
}
.dash-carry__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.dash-carry__title { flex: 1; min-width: 160px; }
.dash-carry__btns { display: flex; gap: var(--space-1); flex-wrap: wrap; }
.dash-carry__btns .btn {
  min-height: 36px;
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
}

/* ═══════════════════════════════════════════════════════════════════════════
   7. МЕТРИКИ ДРУГИХ РАЗДЕЛОВ (Статистика, Партнёрам, Админ)
   ═══════════════════════════════════════════════════════════════════════════ */

.stats-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4);
  margin-bottom: var(--space-8);
}
.stat {
  position: relative;
  overflow: hidden;
  padding: var(--space-5);
  text-align: center;
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-hairline);
  background: linear-gradient(180deg, var(--glass-fill) 0%, var(--glass-fill-2) 100%);
  box-shadow: inset 0 1px 0 var(--glass-edge), var(--shadow-sm);
  transition: transform 320ms var(--ease-spring), box-shadow var(--transition-normal);
}
/* Цветовая маркировка метрик тонкой полосой сверху. */
.stats-row .stat::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--clr-primary);
  opacity: 0.9;
}
.stats-row .stat:nth-child(1)::before { background: var(--clr-success); }
.stats-row .stat:nth-child(2)::before { background: var(--clr-primary); }
.stats-row .stat:nth-child(3)::before { background: var(--clr-accent); }
.stats-row .stat:hover {
  transform: translateY(-3px);
  box-shadow: inset 0 1px 0 var(--glass-edge), var(--shadow-md);
}
@media (hover: none) {
  .stats-row .stat:hover { transform: none; } /* залипший hover на тапе */
}
.stat__value {
  font-family: var(--font-heading);
  font-size: var(--text-3xl);
  font-weight: var(--font-bold);
  color: var(--clr-primary);
  font-variant-numeric: tabular-nums;
}
.stat__label { font-size: var(--text-sm); color: var(--clr-text-3); }

/* ═══════════════════════════════════════════════════════════════════════════
   8. МОБИЛЬНАЯ ПЛОТНОСТЬ (общая для всех разделов)
   Правило в этом файле определено позже базовых — побеждает по каскаду.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {
  .panel { padding: var(--space-5); }
  .panel__head { gap: var(--space-2); }
  .app-header h1 { font-size: var(--text-2xl); }
  .dash-head { margin-bottom: var(--space-5); }
  .next-step { padding: var(--space-6) var(--space-5); }
  .dash-greet { gap: var(--space-3); }
  .dash-tasks__count { display: none; } /* прогресс уже виден в герое */
  /* Лист задач: у .panel padding обнулён, поэтому плотность задаём обложке и
     самому листу отдельно. */
  .dash-tasks__head { padding: var(--space-4); }
  .dash-tasks__sheet { padding: var(--space-3) var(--space-4) var(--space-4); }
}

@media (max-width: 560px) {
  .stats-row { gap: var(--space-2); }
  .stat { padding: var(--space-3) var(--space-2); }
  .stat__value { font-size: var(--text-2xl); }
  .stat__label { font-size: var(--text-xs); }
  .next-step__actions .btn { width: 100%; }
  .dash-carry__btns .btn { flex: 1 1 auto; }
}

/* ===== /css/pages/tasks.css ===== */
/* tasks.css */

/* Догрузка следующей страницы («Все»/«Когда-нибудь»): центрируем под списком. */
.tasks-more {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-6);
}
.tasks-more__hint {
  font-size: var(--text-sm);
  text-align: center;
  margin: 0;
}

/* Панель выбора дня (пресеты + календарь). .segmented/.seg — из stats.css. */
.tasks-datebar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.tasks-date-input {
  width: auto;
  padding: var(--space-2) var(--space-3);
  color: var(--clr-text-2);
}
@media (max-width: 560px) {
  .tasks-datebar { gap: var(--space-2); }
  .tasks-datebar .seg { padding: var(--space-2) var(--space-3); }
}

/* Быстрый ввод задачи — капсула (.composer-* из forms.css), как «Свалить мысль». */
.tasks-quickadd {
  max-width: 640px;
  margin-bottom: var(--space-5);
}

/* Поиск в панели дня (клиентский фильтр по загруженному списку). */
.tasks-search {
  width: 170px;
  padding: var(--space-2) var(--space-3);
}
@media (max-width: 560px) {
  .tasks-search { flex: 1 1 100%; width: auto; }
}

/* Чипы фильтра по тегам — только когда теги есть. */
.tasks-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  max-width: 640px;
}
.tasks-filters:empty { display: none; }
.tag-chip {
  padding: 4px var(--space-3);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-full);
  background: var(--clr-surface);
  color: var(--clr-text-2);
  font-size: var(--text-sm);
  transition: border-color var(--transition-fast), color var(--transition-fast);
}
.tag-chip:hover { border-color: var(--clr-primary); color: var(--clr-primary); }
.tag-chip--on {
  background: var(--clr-primary-light);
  border-color: var(--clr-primary);
  color: var(--clr-primary);
  font-weight: var(--font-medium);
}
/* Тач: фильтры по ярлыкам были 34px — ниже нормы 44px. Порог по типу
   указателя, десктопная плотность не меняется. */
@media (pointer: coarse) {
  .tag-chip {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* Один спокойный столбец: порядок чтения сверху вниз, первая строка —
   следующее действие. Сетка из нескольких колонок разбрасывает внимание.
   position: relative — якорь для подложки свайпа (.swipe-under). */
.tasks-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  align-items: start;
  max-width: 640px;
  position: relative;
}

/* Группа по дню в режиме «Все задачи» */
.tasks-group + .tasks-group { margin-top: var(--space-6); }
.tasks-group__head {
  font-family: var(--font-heading);
  font-size: var(--text-base);
  font-weight: var(--font-semi);
  color: var(--clr-text-3);
  margin-bottom: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--clr-border);
}

/* Карточка-«заметка»: тёплая бумага блокнота, сверху шапка-обложка цветом
   приоритета (--nh/--ni задаются модификаторами --prio-*), внутренние блоки
   разделены «линейками» тетради. */
.task-card {
  --card-py: var(--space-4);
  --card-px: var(--space-5);
  --nh: var(--note-head-medium);
  --ni: var(--note-ink-medium);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--note-paper);
  border: 1px solid var(--note-line);
  border-radius: var(--radius-lg);
  padding: var(--card-py) var(--card-px);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-fast), transform var(--transition-fast);
}

/* Шапка-обложка на всю ширину (компенсирует паддинг карточки), под ней —
   «перфорация» точечным пунктиром. */
.task-card__head {
  flex-shrink: 0;
  height: 12px;
  margin: calc(-1 * var(--card-py)) calc(-1 * var(--card-px)) 0;
  background: var(--nh);
  /* Вложенный радиус: шапка прижата к кромке карточки, значит её радиус =
     радиус карточки − толщина её рамки (1px). Иначе углы визуально «косят». */
  border-radius: calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px) 0 0;
  border-bottom: 3px dotted var(--note-perf);
}
.task-card { position: relative; } /* поверх .swipe-under при свайпе */
.task-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
/* Тач: после тапа по карточке :hover залипает до следующего касания — задача
   оставалась приподнятой и читалась как выбранная. Тень оставляем. */
@media (hover: none) {
  .task-card:hover { transform: none; }
}
.task-card--done { opacity: 0.6; }

/* Карточки вне вьюпорта браузер не рендерит: в режиме «Все задачи» их до сотни
   на странице, и каждая — сложное дерево (шаги, меню, мета). contain-intrinsic-size
   с ключевым словом auto запоминает реальную высоту, поэтому скроллбар не
   «прыгает». Порог 168px — типичная высота карточки без раскрытых шагов. */
.task-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 168px;
}
/* Меню «⋯» абсолютно позиционировано внутри карточки и выходит за её нижнюю
   границу, а content-visibility даёт paint-containment — поповер обрезало бы.
   Пока меню открыто, контейнмент снимаем. */
.task-card:has(.card-menu) { content-visibility: visible; }

/* Уход выполненной карточки: короткое «растворение» перед перестановкой в
   «Готово» (см. schedulePaintList 500мс) — момент завершения виден, не телепорт. */
.task-card--leaving {
  opacity: 0.3;
  transform: translateX(14px) scale(0.985);
  transition: opacity 0.45s ease, transform 0.45s ease;
}

/* Hero — первая невыполненная задача дня: «с этого начать». Крупнее и с тенью;
   ярлык-подсказка вынесен наружу карточки (см. .tasks-hero-cue). */
.task-card--hero {
  --card-py: var(--space-5);
  --card-px: var(--space-6);
  box-shadow: var(--shadow-md);
}
.task-card--hero .task-card__title {
  font-size: var(--text-lg);
  font-weight: var(--font-semi);
}
/* Подпись над hero-карточкой — не внутри неё: caption для «начни с этого». */
.tasks-hero-cue {
  margin: 0 0 calc(-1 * var(--space-1));
  padding-left: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--font-semi);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--clr-primary);
}
.task-card__hero-hint {
  margin: 0;
  color: var(--clr-text-2);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

/* Баннер «Что сейчас?» — выбранная ИИ задача + причина. */
.whatnow-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  max-width: 640px;
  margin-bottom: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border: 1px solid color-mix(in srgb, var(--clr-primary) 40%, var(--clr-border));
  border-radius: var(--radius-lg);
  background: var(--clr-primary-light);
}
.whatnow-banner__label {
  font-size: var(--text-xs);
  font-weight: var(--font-semi);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--clr-primary);
}
.whatnow-banner__reason {
  margin: var(--space-1) 0 0;
  color: var(--clr-text-1);
  line-height: var(--leading-relaxed);
}
.whatnow-banner__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}
/* Подсвеченная «Что сейчас?» карточка. */
.task-card--spotlight {
  border-color: var(--clr-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--clr-primary) 20%, transparent);
}

/* Баннер разгрузки дня (перегруз/вечерний перенос). */
.relief-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  max-width: 640px;
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px dashed var(--clr-border);
  border-radius: var(--radius-lg);
  background: var(--clr-surface);
}
.relief-banner__text {
  margin: 0;
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
}
.relief-banner__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* Просрочка в «Сегодня»: незакрытое за прошлые дни — видно, но без упрёка. */
.overdue-banner {
  max-width: 640px;
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px dashed var(--clr-border);
  border-radius: var(--radius-lg);
  background: var(--clr-surface);
}
.overdue-banner__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.overdue-banner__text {
  margin: 0;
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
}
.overdue-banner__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  /* flex-shrink:0 + .btn{white-space:nowrap} распирали баннер на 320px:
     ряд кнопок выходил за правый край и тянул за собой скролл всей страницы.
     Перенос вместо распирания. */
  flex-wrap: wrap;
}
.overdue-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px dashed var(--clr-border);
  list-style: none;
  padding-left: 0;
}
.overdue-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.overdue-item__title { line-height: var(--leading-normal); }
.overdue-item__btns {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}
.overdue-item__btns .btn { padding: var(--space-2) var(--space-3); font-size: var(--text-sm); }

/* Баннер застрявшей задачи (postpone_count ≥ 3): бережное предложение
   разбить или отпустить. Показывается вместо баннера разгрузки. */
.stuck-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  max-width: 640px;
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px dashed var(--clr-border);
  border-radius: var(--radius-lg);
  background: var(--clr-surface);
}
.stuck-banner__text {
  margin: 0;
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
}
.stuck-banner__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
  flex-wrap: wrap;
}

/* Одноразовая подсказка про свайпы (только тач, только «Сегодня»). */
.swipe-hint {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  max-width: 640px;
  margin-bottom: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--clr-surface-2);
  color: var(--clr-text-2);
  font-size: var(--text-sm);
}
.swipe-hint__text { margin: 0; flex: 1; line-height: var(--leading-relaxed); }
.swipe-hint__close {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  color: var(--clr-text-3);
}
.swipe-hint__close:hover { background: var(--clr-surface-3); color: var(--clr-text-2); }

/* Секция «Вечером» в списке дня. */
.tasks-evening-head {
  font-family: var(--font-heading);
  font-size: var(--text-base);
  font-weight: var(--font-semi);
  color: var(--clr-text-3);
  margin: var(--space-5) 0 var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--clr-border);
  max-width: 640px;
}

/* «✂ мельче» на шаге: ИИ дробит залипший шаг. На курсоре — по наведению. */
.step-row__right {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}
.step-split {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  color: var(--clr-text-3);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.step-split:hover {
  background: var(--clr-surface-3);
  color: var(--clr-primary);
}
@media (hover: hover) and (pointer: fine) {
  .step-split { opacity: 0; transition: opacity var(--transition-fast); }
  .step-row:hover .step-split,
  .step-split:focus-visible { opacity: 1; }
}

/* Подложка свайпа: цвет и подпись действия под уезжающей карточкой. */
.swipe-under {
  position: absolute;
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--space-4);
  color: var(--clr-on-primary);
  font-weight: var(--font-semi);
}
.swipe-under__done,
.swipe-under__later { opacity: 0; }
.swipe-under--done { background: var(--clr-success); }
.swipe-under--done .swipe-under__done { opacity: 1; }
.swipe-under--later { background: var(--clr-primary); }
.swipe-under--later .swipe-under__later { opacity: 1; }

/* Приоритет — цвет шапки-обложки: жёлтая — обычная (дефолт), мятная — лёгкая,
   коралловая — важная. Дублируется словом «Важное» в мета-строке (дальтонизм). */
.task-card--prio-low { --nh: var(--note-head-low); --ni: var(--note-ink-low); }
.task-card--prio-high { --nh: var(--note-head-high); --ni: var(--note-ink-high); }

.task-card__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
}
/* Чекбокс задачи и шага — общий компонент components/checkbox.css
   (.check-hit / .check / .task-title). Раньше здесь был родной
   <input type="checkbox"> с accent-color, а на Главной — кастомный круг:
   один и тот же объект выглядел на двух экранах по-разному. Ниже — только
   то, что специфично для карточки. */
.task-check { flex: 1; min-width: 0; }
/* Шаг подчинён задаче: строка ниже по высоте и без «кнопочного» тап-таргета. */
.step-check { min-height: 32px; }
.task-card__title {
  font-weight: var(--font-medium);
  color: var(--clr-text-1);
}

/* «⋯» — единственная служебная кнопка карточки (диета: остальное в меню). */
.task-card__more {
  flex-shrink: 0;
  display: inline-flex;
  width: 32px;
  height: 32px;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  color: var(--clr-text-3);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.task-card__more:hover,
.task-card__more[aria-expanded="true"] {
  background: var(--clr-surface-3);
  color: var(--clr-primary);
}

/* Выпадающее меню действий карточки. */
.card-menu {
  position: absolute;
  z-index: 30;
  min-width: 190px;
  display: flex;
  flex-direction: column;
  padding: var(--space-1);
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
}
.card-menu__item {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--clr-text-1);
  font-size: var(--text-sm);
  transition: background var(--transition-fast);
}
.card-menu__item:hover,
.card-menu__item:focus-visible { background: var(--clr-surface-2); }
.card-menu__item--danger { color: var(--clr-error); }
.card-menu__item--danger:hover {
  background: color-mix(in srgb, var(--clr-error) 10%, transparent);
}

/* Тихая метастрока: тег, прогресс шагов, оценка минут — приглушённым текстом,
   над ней — «линейка» тетради. */
.task-card__meta {
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  border-top: 1px solid var(--note-line);
  padding-top: var(--space-2);
}

/* Чип «Важное» — единственный громкий элемент, только для high-приоритета
   (цвет кромки не считывается при дальтонизме). */
.task-prio {
  padding: 2px var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: var(--font-semi);
}
.task-prio--high { background: color-mix(in srgb, var(--clr-error) 16%, transparent); color: var(--clr-error); }

.task-card__steps {
  padding-top: var(--space-3);
  border-top: 1px solid var(--note-line);
}
.steps {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.step-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.step-empty { margin-bottom: var(--space-3); }
.step-add { display: flex; gap: var(--space-2); }

/* Ряд действий карточки: 1–3 контекстные кнопки, видимы всегда (скрытые за
   hover действия для СДВГ «не существуют»; остальное — в «⋯»-меню). */
.task-card__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  border-top: 1px solid var(--note-line);
  padding-top: var(--space-3);
}
.task-action { padding: var(--space-2) var(--space-3); font-size: var(--text-sm); }

/* Свёрнутая группа выполненных: прогресс виден, но не тянет взгляд. */
.tasks-done-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-5);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  color: var(--clr-text-3);
  font-weight: var(--font-medium);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.tasks-done-toggle:hover {
  background: var(--clr-surface-3);
  color: var(--clr-text-2);
}
@media (pointer: coarse) {
  .tasks-done-toggle { min-height: 44px; } /* было 42.4px */
}
.tasks-done { margin-top: var(--space-3); }

.voice-btn { flex-shrink: 0; }

/* Повторение по выбранным датам (модалка настройки задачи) */
.repeat-dates__row { display: flex; gap: var(--space-2); }
.repeat-dates__row .input { flex: 1; }
.repeat-dates {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.repeat-date-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background: var(--clr-primary-light);
  color: var(--clr-primary-hover);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
}
.repeat-date-chip button {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  color: inherit;
  line-height: 1;
}
.repeat-date-chip button:hover { background: color-mix(in srgb, var(--clr-primary) 18%, transparent); }
.repeat-dates__hint { margin-top: var(--space-2); font-size: var(--text-sm); }


/* Мобильный: тап-таргеты ≥44px и отступ снизу, чтобы плавающий док
   (Коуч/Таймер) не перекрывал кнопки последней карточки. */
@media (max-width: 768px) {
  .task-card__more {
    width: 44px;
    height: 44px;
  }
  .card-menu__item {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  .tasks-body {
    padding-bottom: 110px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tasks-done-toggle {
    transition: none;
  }
  .task-card--leaving {
    transition: none;
    transform: none;
  }
}

/* ===== /css/pages/inbox.css ===== */
/* inbox.css — быстрый инбокс «Свалить мысль»: захват и лента заметок. */

/* Форма быстрого захвата (на странице инбокса и на Главной). */
.inbox-capture {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}
.inbox-capture__input { flex: 1; min-width: 0; }
/* Микрофон и отправка — внутри капсулы (.composer-voice/.composer-send из forms.css). */

.dash-capture__hint { margin-bottom: var(--space-3); }

/* Лента заметок. */
.inbox-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  list-style: none;
  margin: 0;
  padding: 0;
}
.inbox-item {
  padding: var(--space-4);
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.inbox-item__text {
  color: var(--clr-text-1);
  line-height: var(--leading-relaxed);
  word-break: break-word;
  margin-bottom: var(--space-3);
}
.inbox-item__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.inbox-item__actions { display: flex; gap: var(--space-2); }

.inbox-body { margin-top: var(--space-6); }

/* Мобильный: кнопка отправки теперь внутри поля — капчер помещается в одну
   строку (поле + микрофон), перенос не нужен. */
@media (max-width: 560px) {
  .inbox-item__actions { width: 100%; }
  .inbox-item__actions .btn { flex: 1; }
}

/* ===== /css/pages/focus-now.css ===== */
/* focus-now.css — режим «Сейчас / Потом»: максимум внимания на одном деле. */

.focus-now {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  max-width: 640px;
  margin: 0 auto;
  padding: var(--space-6) 0;
}

/* Карточка текущего дела — крупная, тёплая, в центре внимания. */
.focus-now__card {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-4);
  padding: var(--space-8) var(--space-6);
  border-radius: var(--radius-xl);
  border: 1px solid color-mix(in srgb, var(--clr-primary) 18%, transparent);
  background:
    radial-gradient(120% 140% at 100% 0%,
      color-mix(in srgb, var(--clr-accent) 12%, transparent) 0%, transparent 55%),
    linear-gradient(135deg,
      var(--clr-primary-light) 0%,
      color-mix(in srgb, var(--clr-surface) 82%, var(--clr-primary-light)) 100%);
  box-shadow: var(--shadow-md);
}
.focus-now__label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--font-semi);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--clr-primary);
}
.focus-now__title {
  font-family: var(--font-heading);
  font-size: var(--text-3xl);
  font-weight: var(--font-bold);
  color: var(--clr-text-1);
  line-height: var(--leading-tight);
  word-break: break-word;
}
.focus-now__steps { font-size: var(--text-sm); color: var(--clr-text-3); }
.focus-now__actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  justify-content: center;
  margin-top: var(--space-2);
}

/* Следующее дело — намеренно бледное: оно «на потом», не отвлекает. */
.focus-now__next {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px dashed var(--clr-border);
  opacity: 0.65;
}
.focus-now__next-label {
  font-size: var(--text-xs);
  font-weight: var(--font-semi);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--clr-text-3);
  flex-shrink: 0;
}
.focus-now__next-title {
  color: var(--clr-text-2);
  word-break: break-word;
}
.focus-now__next--empty {
  text-align: center;
  justify-content: center;
  color: var(--clr-text-3);
}

@media (max-width: 560px) {
  .focus-now__card { padding: var(--space-6) var(--space-4); }
  .focus-now__title { font-size: var(--text-2xl); }
  .focus-now__actions .btn { flex: 1 1 100%; }
}

/* ===== /css/pages/pomodoro.css ===== */
/* pomodoro.css */

.pomodoro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-xl);
  padding: var(--space-8);
  box-shadow: var(--shadow-sm);
}
.pomodoro:fullscreen {
  justify-content: center;
  background: var(--clr-surface);
}

/* Баннер задачи, к которой привязан фокус («Фокус над: …»). */
.pomo-task {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 100%;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full);
  background: var(--clr-primary-light);
  color: var(--clr-text-1);
}
.pomo-task.hidden { display: none; }
.pomo-task__ico { display: inline-flex; color: var(--clr-primary); }
.pomo-task__label {
  font-size: var(--text-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.presets {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  justify-content: center;
}
.preset {
  padding: var(--space-2) var(--space-5);
  border: 1.5px solid var(--clr-border);
  border-radius: var(--radius-full);
  background: var(--clr-surface);
  color: var(--clr-text-2);
  font-weight: var(--font-semi);
  font-family: var(--font-heading);
  transition: border-color var(--transition-fast), background var(--transition-fast),
    box-shadow var(--transition-fast);
}
.preset:hover:not(:disabled) { border-color: var(--clr-primary); box-shadow: var(--shadow-xs); }
.preset--on {
  border-color: var(--clr-primary);
  background: var(--clr-primary-light);
  color: var(--clr-primary);
  box-shadow: var(--shadow-sm);
}
.preset:disabled { opacity: 0.5; cursor: default; }
.preset__lock { display: inline-flex; vertical-align: -2px; margin-left: 4px; opacity: 0.65; }

/* Персональные пресеты */
.preset--add { border-style: dashed; font-size: var(--text-lg); line-height: 1; }
.preset-chip { position: relative; display: inline-flex; }
.preset-chip__del {
  position: absolute;
  top: -7px;
  right: -7px;
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background: var(--clr-error);
  color: #fff;
  font-size: var(--text-sm);
  line-height: 1;
  box-shadow: var(--shadow-sm);
}
.preset-chip__del:hover { background: color-mix(in srgb, var(--clr-error) 85%, #000); }

.preset-form {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  justify-content: center;
}
.preset-form.hidden { display: none; } /* специфичнее общего .hidden — перебивает display:flex */
.preset-form__sep { color: var(--clr-text-3); }
.preset-input { width: 130px; }

/* Тумблеры сигналов таймера. Живут прямо над пресетами, а не в свёрнутом
   «Фоновом шуме»: звук и уведомления решают, заметит ли человек конец
   помидора, — прятать их за раскрывашку значит прятать сам смысл таймера. */
.pomo-signals {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: center;
}
.pomo-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--clr-text-2);
  cursor: pointer;
}
.pomo-toggle input {
  width: 18px;
  height: 18px;
  accent-color: var(--clr-primary);
  cursor: pointer;
}

/* Фоновый шум для СДВГ-сессий. Прогрессивное раскрытие держится на одной
   галочке: пока шум не нужен, на экране только строка заголовка и таймер не
   тонет в настройках. Выбор и громкость появляются, когда галочка стоит. */
.pomo-noise {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  max-width: 520px;
  padding: var(--space-4);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  background: var(--clr-surface-2);
}
.pomo-noise__head {
  font-family: var(--font-heading);
  font-weight: var(--font-semi);
  color: var(--clr-text-2);
}
.pomo-noise__hint { font-weight: var(--font-normal); }
.pomo-noise__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
}
.pomo-noise__body.hidden { display: none; }
.pomo-noise__select-wrap { display: block; width: 100%; max-width: 260px; }
/* Стрелка вниз рисуется фоном — список раскрывается вниз (нативный <select>). */
.pomo-noise__select {
  width: 100%;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--space-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
}
.pomo-noise__vol {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-sm);
}
.pomo-noise__vol input[type="range"] {
  width: 180px;
  accent-color: var(--clr-primary);
}

/* Тач-таргеты страницы таймера. Здесь были самые мелкие цели во всём
   приложении: галочки «звук/уведомления/шум» жили в строке 24.8px с нативным
   чекбоксом 18px, ползунок громкости — 16px по высоте, крестик удаления
   пресета — 20px. Порог по типу указателя: десктопная плотность не меняется. */
@media (pointer: coarse) {
  .preset { min-height: 44px; display: inline-flex; align-items: center; }
  .pomo-toggle { min-height: 44px; }
  .pomo-toggle input { width: 22px; height: 22px; }
  /* Дорожка визуально та же — вырастает только зона касания. */
  .pomo-noise__vol input[type="range"] { height: 44px; }
  /* Крестик пресета остаётся маленьким кружком, но получает прозрачный
     «вылет» до 44px — тот же приём, что у .icon-btn--sm и кнопок композера. */
  .preset-chip__del::before {
    content: "";
    position: absolute;
    inset: -12px;
    border-radius: inherit;
  }
}

@media (max-width: 640px) {
  .pomo-noise__hint { display: none; }
}

/* Кольцо */
.ring-wrap {
  position: relative;
  width: 280px;
  height: 280px;
}
.ring { width: 280px; height: 280px; }
.ring__bg {
  fill: none;
  stroke: var(--clr-surface-3);
  stroke-width: 14;
}
.ring__progress {
  fill: none;
  /* Градиент индиго → голубой бренда (магия фокуса + технологии ИИ). */
  stroke: url(#ring-grad);
  stroke-width: 14;
  stroke-linecap: round;
  transform: rotate(-90deg);
  transform-origin: 140px 140px;
  transition: stroke-dashoffset 1s linear;
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--clr-accent) 40%, transparent));
}
/* Перерыв — спокойный сплошной зелёный, без «магического» свечения. */
.ring__progress[data-variant="break"] { stroke: var(--clr-success); filter: none; }
.ring-grad__a { stop-color: var(--clr-primary); }
.ring-grad__b { stop-color: var(--clr-accent); }

.ring__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
}
.ring__time {
  font-family: var(--font-heading);
  font-size: var(--text-5xl);
  font-weight: var(--font-bold);
  color: var(--clr-text-1);
  font-variant-numeric: tabular-nums;
}
.ring__phase { color: var(--clr-text-3); }

.pomo-controls {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
}

.long-break {
  max-width: 46ch;
  text-align: center;
  color: var(--clr-text-2);
  background: var(--clr-primary-light);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
}

@media (prefers-reduced-motion: reduce) {
  .ring__progress { transition: stroke-dashoffset 0s; }
}

/* ============================================================
 * Плавающий виджет Pomodoro (виден на всех экранах во время сессии)
 * ============================================================ */
.pomo-widget {
  position: fixed;
  left: var(--space-5);
  bottom: var(--space-5);
  z-index: var(--z-sticky, 900);
  width: 220px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  animation: fn-rise var(--transition-normal) ease both;
}
.pomo-widget[hidden] { display: none; }

/* Перетаскивание виджета (десктоп): курсор-подсказка на «ручках». */
@media (min-width: 769px) {
  .pomo-widget__head,
  .pomo-widget__pill { cursor: grab; }
}
.pomo-widget--dragging,
.pomo-widget--dragging * { cursor: grabbing !important; }
.pomo-widget--dragging { user-select: none; }

.pomo-widget__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.pomo-widget__phase {
  font-size: var(--text-sm);
  font-weight: var(--font-semi);
  color: var(--clr-text-2);
}
/* Привязанная задача в виджете — одна строка, длинное имя обрезаем. */
.pomo-widget__task {
  font-size: var(--text-sm);
  color: var(--clr-text-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pomo-widget__min {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  color: var(--clr-text-3);
  font-size: var(--text-lg);
  line-height: 1;
}
.pomo-widget__min:hover { background: var(--clr-surface-3); color: var(--clr-text-1); }

.pomo-widget__time {
  font-family: var(--font-heading);
  font-variant-numeric: tabular-nums;
  color: var(--clr-text-1);
}
.pomo-widget__time--lg {
  font-size: var(--text-3xl);
  font-weight: var(--font-bold);
  text-align: left;
  width: 100%;
}

.pomo-widget__bar {
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--clr-surface-3);
  overflow: hidden;
}
.pomo-widget__bar > span {
  display: block;
  height: 100%;
  border-radius: var(--radius-full);
  background: var(--clr-primary);
  transition: width 1s linear;
}
.pomo-widget[data-variant="break"] .pomo-widget__bar > span { background: var(--clr-success); }

.pomo-widget__head-btns { display: flex; align-items: center; gap: var(--space-1); }
.pomo-widget__controls { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.pomo-widget__controls .btn {
  flex: 1 1 auto;
  min-width: 84px;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
}

/* Свёрнутая «пилюля» */
.pomo-widget--collapsed {
  width: auto;
  padding: 0;
  border: none;
  background: transparent;
  box-shadow: none;
}
.pomo-widget__pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full);
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  box-shadow: var(--shadow-lg);
  font-family: var(--font-heading);
  font-weight: var(--font-bold);
  font-variant-numeric: tabular-nums;
  color: var(--clr-text-1);
}
.pomo-widget__dot { width: 10px; height: 10px; border-radius: 50%; background: var(--clr-primary); }
.pomo-widget[data-variant="break"] .pomo-widget__dot { background: var(--clr-success); }

/* Над нижней навигацией на мобильных. */
@media (max-width: 768px) {
  .pomo-widget {
    bottom: calc(var(--space-16) + var(--space-4) + env(safe-area-inset-bottom, 0px));
  }
}
@media (prefers-reduced-motion: reduce) {
  .pomo-widget { animation: none; }
  .pomo-widget__bar > span { transition: none; }
}

/* ===== /css/pages/coach.css ===== */
/* coach.css — ИИ-коуч: тред, быстрые подсказки, композер. */

.chat {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-xl);
  padding: var(--space-4);
  min-height: 48vh;
}

.chat__thread-wrap {
  flex: 1;
  overflow-y: auto;
  max-height: 46vh;
  padding-right: var(--space-2);
}

/* Полновысотный layout страницы коуча (класс ставит coach.js):
   страница не скроллится — скроллится только тред, композер прижат к низу.
   Убирает «окно в окне» с двойным скроллом. */
.app-main--chat {
  display: flex;
  flex-direction: column;
  height: 100vh; /* фолбэк */
  height: 100dvh;
  overflow: hidden;
  max-width: 820px;
}
/* На десктопе чат занимает всю рабочую ширину (как остальные разделы) — длинные
   ответы коуча и списки шагов читаются без узкой колонки. Плавающий док в углу
   больше не наезжает за счёт отступов снизу и справа, а не сужения всей колонки. */
@media (min-width: 769px) {
  .app-main--chat {
    max-width: 1200px;
    padding-bottom: calc(var(--space-8) + 52px);
    padding-right: calc(var(--space-8) + 64px);
  }
}
.app-main--chat .app-header { flex-shrink: 0; }
.app-main--chat .chat {
  flex: 1;
  min-height: 0;
}
.app-main--chat .chat__thread-wrap {
  max-height: none;
  min-height: 0;
}

.chat-thread {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.chat-bubble {
  /* Пузырь тянется вместе с колонкой, но строка не становится бесконечной:
     предел по ch держит читаемую длину строки (важно для дислексии), иначе на
     широком экране текст шёл бы одной длинной лентой. */
  max-width: min(78%, 72ch);
  display: flex;
  flex-direction: column;
  gap: 2px;
  animation: bubble-in 0.18s ease-out;
}
@keyframes bubble-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

/* Мигающий курсор стримящегося ответа */
.chat-bubble--streaming .chat-bubble__body::after {
  content: "▍";
  margin-left: 1px;
  color: var(--clr-text-3);
  animation: stream-cursor 1s steps(1) infinite;
}
@keyframes stream-cursor {
  50% { opacity: 0; }
}
.chat-bubble--user { align-self: flex-end; align-items: flex-end; }
.chat-bubble--coach { align-self: flex-start; align-items: flex-start; }

.chat-bubble__body {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-lg);
  line-height: var(--leading-relaxed);
  white-space: pre-wrap;
  word-break: break-word;
}
.chat-bubble--user .chat-bubble__body {
  background: var(--clr-primary);
  color: var(--clr-on-primary);
  border-bottom-right-radius: var(--radius-xs);
}
.chat-bubble--coach .chat-bubble__body {
  background: var(--clr-surface-3);
  color: var(--clr-text-1);
  border-bottom-left-radius: var(--radius-xs);
}

.chat-bubble__meta {
  display: flex;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--clr-text-3);
}
.chat-bubble__note { font-style: italic; }

/* Разделитель дней в истории: «Сегодня / Вчера / 12 июля» */
.chat-day {
  align-self: center;
  list-style: none;
  margin: var(--space-2) 0;
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
  color: var(--clr-text-3);
  background: var(--clr-surface-2);
  border-radius: var(--radius-full);
}

/* Заголовок коуча: маскот «Фокусик» рядом с названием — присутствие коуча. */
.coach-title { display: flex; align-items: center; gap: var(--space-3); }

.chat-empty {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-6) var(--space-4);
}
.chat-empty__title {
  font-family: var(--font-heading);
  font-weight: var(--font-bold);
  font-size: var(--text-lg);
}

/* Индикатор набора */
.chat-bubble--typing .chat-bubble__body {
  display: flex;
  gap: 5px;
  align-items: center;
}
.chat-bubble--typing .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--clr-text-3);
  animation: chat-typing 1.2s infinite ease-in-out;
}
.chat-bubble--typing .dot:nth-child(2) { animation-delay: 0.2s; }
.chat-bubble--typing .dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes chat-typing {
  0%, 60%, 100% { opacity: 0.3; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}

/* Выбор настроения — коуч подстраивает тон ответа */
.coach-mood {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.coach-mood__label {
  font-size: var(--text-sm);
  color: var(--clr-text-3);
  margin-right: var(--space-1);
}
.coach-mood__opt {
  width: 44px; /* тап-таргет ≥44px (правило продукта) */
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xl);
  line-height: 1;
  border: 1.5px solid var(--clr-border);
  border-radius: var(--radius-full);
  background: var(--clr-surface);
  filter: grayscale(0.35);
  opacity: 0.7;
  transition: border-color var(--transition-fast), background var(--transition-fast),
    filter var(--transition-fast), opacity var(--transition-fast);
}
.coach-mood__opt:hover {
  border-color: var(--clr-primary);
  filter: none;
  opacity: 1;
}
.coach-mood__opt--on {
  border-color: var(--clr-primary);
  background: var(--clr-primary-light);
  filter: none;
  opacity: 1;
}

/* Быстрые подсказки */
.chat__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.chip {
  padding: var(--space-2) var(--space-4);
  border: 1.5px solid var(--clr-border);
  border-radius: var(--radius-full);
  background: var(--clr-surface);
  color: var(--clr-text-2);
  font-weight: var(--font-medium);
  transition: border-color var(--transition-fast), color var(--transition-fast);
}
/* В чате подсказки компактнее — не отбирают место у переписки. */
.chat__chips { gap: var(--space-1); }
.chat__chips .chip {
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
  border-width: 1px;
}
.chip:hover {
  border-color: var(--clr-primary);
  color: var(--clr-primary);
}
/* Тач-устройства: подсказки-чипы были 34px в высоту — ниже нормы проекта 44px.
   Правило по типу указателя, а не по ширине экрана: на десктопе с мышью
   компактный вид сохраняется без изменений. */
@media (pointer: coarse) {
  .chip {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* Композер */
.chat__composer {
  display: flex;
  gap: var(--space-2);
  align-items: flex-end;
}
.chat__input {
  flex: 1;
  resize: none;
  line-height: var(--leading-relaxed);
  max-height: 160px;
}
.chat__limit-note {
  font-size: var(--text-sm);
  color: var(--clr-text-3);
  text-align: center;
}

.breakdown-result { margin-top: var(--space-2); }
.breakdown-steps {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding-left: var(--space-5);
}
.breakdown-steps li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  line-height: var(--leading-relaxed);
}

@media (prefers-reduced-motion: reduce) {
  .chat-bubble--typing .dot { animation: none; }
  .chat-bubble { animation: none; }
  .coach-action--done { animation: none; }
  .chat-bubble--streaming .chat-bubble__body::after { animation: none; }
}

@media (max-width: 640px) {
  .chat-bubble { max-width: 90%; }
}

/* --- Действия коуча: карточка-предложение с подтверждением одной кнопкой --- */
.coach-action {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: 1.5px solid color-mix(in srgb, var(--clr-primary) 35%, var(--clr-border));
  border-radius: var(--radius-md);
  background: var(--clr-primary-light);
}
.coach-action__label { color: var(--clr-text-1); font-weight: var(--font-medium); }
.coach-action__btns { display: flex; gap: var(--space-2); }
.coach-action__btns .btn { padding: var(--space-1) var(--space-4); font-size: var(--text-sm); }
.coach-action--done {
  border-color: color-mix(in srgb, var(--clr-success) 45%, var(--clr-border));
  background: color-mix(in srgb, var(--clr-success) 8%, var(--clr-surface));
  color: var(--clr-text-2);
  animation: action-done 0.35s ease-out;
}
@keyframes action-done {
  0% { transform: scale(0.97); }
  55% { transform: scale(1.015); }
  100% { transform: scale(1); }
}

/* Отклонённое предложение: короткая реакция вместо пустоты */
.coach-action--dismissed {
  border-color: var(--clr-border);
  background: var(--clr-surface-2);
  color: var(--clr-text-3);
}

/* Чипы-ответы от коуча: тап вместо набора текста (suggest_replies) */
.coach-replies {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.coach-replies .chip {
  border-color: color-mix(in srgb, var(--clr-primary) 35%, var(--clr-border));
  color: var(--clr-primary);
  background: var(--clr-surface);
}
.coach-replies .chip:hover {
  background: var(--clr-primary-light);
}

/* Итог выполненного действия в истории */
.chat-bubble--action .chat-bubble__body { color: var(--clr-success); font-weight: var(--font-medium); }

/* «Запомнил: …» с мгновенной отменой */
.coach-remember {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background: var(--clr-surface-2);
  border: 1px solid var(--clr-border);
  color: var(--clr-text-2);
  font-size: var(--text-sm);
}
.coach-remember__del {
  position: relative;
  color: var(--clr-text-3);
  width: 22px; height: 22px;
  border-radius: var(--radius-full);
  line-height: 1;
}
/* Невидимое расширение зоны нажатия до 44px (правило продукта) */
.coach-remember__del::after { content: ""; position: absolute; inset: -11px; }
.coach-remember__del:hover { background: var(--clr-surface-3); color: var(--clr-error); }

/* Память коуча (модалка) */
.memory-list { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-4); }
.memory-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-md);
  color: var(--clr-text-1);
  line-height: var(--leading-relaxed);
}
.memory-item__del {
  position: relative;
  flex-shrink: 0;
  color: var(--clr-text-3);
  width: 26px; height: 26px;
  border-radius: var(--radius-sm);
}
/* Невидимое расширение зоны нажатия до 44px (правило продукта) */
.memory-item__del::after { content: ""; position: absolute; inset: -9px; }
.memory-item__del:hover { background: var(--clr-surface-3); color: var(--clr-error); }
.memory-empty { margin-top: var(--space-4); }

/* Кнопки подтверждающей модалки (очистка истории) */
.modal-confirm__btns {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

/* ===== /css/pages/body-double.css ===== */
/* body-double.css — лобби (список/фильтры/создание) и комната. */

/* --- Лобби --- */
.bd-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.chip--on {
  border-color: var(--clr-primary);
  background: var(--clr-primary-light);
  color: var(--clr-primary);
}

/* Чип с выбором даты (календарь) в фильтре Body Double. */
.bd-datechip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  cursor: pointer;
}
.bd-datechip input[type="date"] {
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  padding: 0;
  cursor: pointer;
  width: 8.5rem;
}
.bd-datechip input[type="date"]::-webkit-calendar-picker-indicator { cursor: pointer; }
/* Тач: чип-обёртка получает 44px от .chip, но календарь открывается только по
   самому полю (28px по высоте) — растягиваем поле на всю высоту чипа. */
@media (pointer: coarse) {
  .bd-datechip input[type="date"] { align-self: stretch; min-height: 44px; }
}

.bd-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}
.bd-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  background: var(--clr-surface);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-fast), transform var(--transition-fast),
    border-color var(--transition-fast);
}
.bd-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--clr-primary) 30%, var(--clr-border));
}
.bd-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.bd-card__host { font-weight: var(--font-semi); font-family: var(--font-heading); }
/* Счётчик завершённых сессий рядом с именем хоста. */
.bd-card__exp {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--text-sm);
  white-space: nowrap;
}
.bd-card__topic { line-height: var(--leading-relaxed); }
.bd-card__meta {
  display: flex;
  justify-content: space-between;
  font-size: var(--text-sm);
}

/* Запланированная сессия — метка времени старта. */
.bd-card__when { margin-top: calc(-1 * var(--space-1)); }
.bd-card__sched {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--clr-primary-light);
  color: var(--clr-primary);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
}
/* Своя сессия (создал или записался) — мягкая подсветка рамкой. */
.bd-card--mine { border-color: color-mix(in srgb, var(--clr-primary) 45%, var(--clr-border)); }

/* «Отменить сессию» / «Отписаться» — тихая кнопка под основной. */
.bd-card__cancel {
  margin-top: calc(-1 * var(--space-2));
  font-size: var(--text-sm);
  color: var(--clr-text-3);
}
.bd-card__cancel:hover { color: var(--clr-danger, #c0392b); }

.bd-empty {
  /* Flex-центрирование, а не только text-align: глобальное p{max-width:70ch}
     делает абзацы блоками уже панели, и при margin-left:0 их центрированный
     текст «уезжал» влево от маскота. align-items центрирует сами блоки. */
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-8) var(--space-4);
}
.bd-empty__mascot { margin-bottom: var(--space-3); }
.bd-empty__title {
  font-family: var(--font-heading);
  font-weight: var(--font-bold);
  font-size: var(--text-lg);
  margin-bottom: var(--space-2);
}

.check-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  line-height: var(--leading-relaxed);
  cursor: pointer;
}

/* --- Комната (полноэкранный оверлей) --- */
.bd-room {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal, 1000);
  display: flex;
  flex-direction: column;
  /* Токена --clr-bg нет — прозрачный фон просвечивал страницу под оверлеем. */
  background: var(--clr-surface-2);
  padding: var(--space-4);
  gap: var(--space-3);
}
/* display:flex у блоков комнаты сильнее UA-правила для [hidden] — возвращаем
   атрибуту силу (скрытие чата, контролов, плейсхолдеров под видео). */
.bd-room [hidden] { display: none !important; }

.bd-room__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.bd-room__topic { display: flex; align-items: baseline; gap: var(--space-2); }
.bd-room__partner-info {
  flex: 1;
  text-align: center;
  color: var(--clr-text-2);
  font-weight: var(--font-medium);
}

/* Баннер потери соединения (WS переподключается с backoff). */
.bd-room__reconnect {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--clr-warning-light, #fdf3e0);
  color: var(--clr-warning, #a2681c);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  text-align: center;
}

/* Прогресс сессии: тонкая полоса под шапкой — «сколько прошло» без цифр. */
.bd-progress {
  height: 4px;
  border-radius: var(--radius-full);
  background: var(--clr-surface-3);
  overflow: hidden;
}
.bd-progress__fill {
  display: block;
  height: 100%;
  width: 0;
  background: var(--clr-primary);
  transition: width 1s linear;
}

/* Видео — крупный ряд сверху; под ним кнопки и всегда открытый чат.
   Высота ощутимая (не сплющенные плитки), но с потолком, чтобы чат помещался. */
.bd-room__stage {
  flex: 0 0 auto;
  height: clamp(240px, 46vh, 480px);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
  min-height: 0;
}
.bd-tile {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--clr-surface-3);
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Видео показываем, только когда в нём реально есть кадр: пустой <video>
   лежит поверх заглушки и превращает плитку в немой чёрный прямоугольник. */
.bd-tile video {
  display: none;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
}
.bd-tile video.is-live { display: block; }
/* Себя показываем зеркально — как во всех видеозвонках. */
#bd-video-self { transform: scaleX(-1); }
.bd-tile__placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  color: var(--clr-text-3);
}
/* Аватар-кружок в плейсхолдере плитки (пока нет видео). */
.bd-tile__ava {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--clr-primary-light);
  color: var(--clr-primary);
  font-size: var(--text-xl);
  font-weight: var(--font-bold);
}
.bd-tile__ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bd-tile__hint {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--clr-text-3);
  text-align: center;
  line-height: var(--leading-relaxed);
  padding: 0 var(--space-4);
}
.bd-tile__name {
  position: absolute;
  left: var(--space-3);
  bottom: var(--space-3);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: var(--text-sm);
}
.bd-tile--empty { border: 1.5px dashed var(--clr-border); }

/* --- Проверка камеры перед входом --- */
/* Увидеть себя раньше, чем тебя увидит напарник: снимает тревогу и сразу
   показывает, если камера не отдаёт картинку. */
.bd-precheck {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background: var(--clr-surface-2);
  overflow-y: auto;
}
.bd-precheck__card {
  width: 100%;
  max-width: 520px;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  text-align: center;
}
.bd-precheck__title { font-family: var(--font-heading); font-size: var(--text-xl); }
.bd-precheck__sub { font-size: var(--text-sm); line-height: var(--leading-relaxed); }
.bd-precheck__view {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--clr-surface-3);
}
.bd-precheck__view video {
  display: none;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
  transform: scaleX(-1);
}
.bd-precheck__view video.is-live { display: block; }
.bd-precheck__ph {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--space-4);
  color: var(--clr-text-3);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  text-align: center;
}
.bd-precheck__toggles {
  display: flex;
  justify-content: center;
  gap: var(--space-3);
}

/* Чат */
.bd-room__chat {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  /* Всегда открыт и занимает всё место под видео. */
  flex: 1;
  min-height: 0;
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
  background: var(--clr-surface);
}
.bd-chat__list {
  flex: 1;
  overflow-y: auto;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.bd-chat__msg {
  max-width: 80%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  line-height: var(--leading-relaxed);
}
.bd-chat__msg--me { align-self: flex-end; background: var(--clr-primary); color: var(--clr-on-primary); }
.bd-chat__msg--them { align-self: flex-start; background: var(--clr-surface-3); }
.bd-chat__form { display: flex; gap: var(--space-2); }
.bd-chat__form .input { flex: 1; }

/* Кнопка «Свернуть» в шапке комнаты. */
.bd-room__mini-btn {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-md);
  color: var(--clr-text-2);
  font-size: var(--text-lg);
  line-height: 1;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.bd-room__mini-btn:hover { background: var(--clr-surface-3); color: var(--clr-primary); }

/* Контролы */
.bd-room__controls {
  display: flex;
  justify-content: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.bd-ctrl {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 72px;
  padding: var(--space-2) var(--space-3);
  border: 1.5px solid var(--clr-border);
  border-radius: var(--radius-md);
  background: var(--clr-surface);
  color: var(--clr-text-2);
  font-size: var(--text-xs);
  font-weight: var(--font-medium);
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
.bd-ctrl:hover { border-color: var(--clr-primary); }
.bd-ctrl--off { background: var(--clr-danger-light, #fde8e8); color: var(--clr-danger, #c0392b); border-color: transparent; }
.bd-ctrl--on { background: var(--clr-primary-light); color: var(--clr-primary); border-color: var(--clr-primary); }
.bd-ctrl--alert { border-color: var(--clr-primary); animation: bd-pulse 1s infinite; }
.bd-ctrl--leave:hover { border-color: var(--clr-danger, #c0392b); color: var(--clr-danger, #c0392b); }

/* Счётчик непрочитанных сообщений на кнопке чата. */
.bd-ctrl__badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: var(--radius-full);
  background: var(--clr-error);
  color: #fff;
  font-size: 11px;
  font-weight: var(--font-bold);
  font-style: normal;
  line-height: 18px;
  text-align: center;
}

/* Финальный экран сессии (вместо мёртвой комнаты после выхода напарника). */
.bd-end {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  text-align: center;
}
.bd-end__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--clr-success-light, var(--clr-primary-light));
  color: var(--clr-success, var(--clr-primary));
  font-size: var(--text-2xl);
  font-weight: var(--font-bold);
}
.bd-end__title {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  margin: 0;
}

/* Кнопки подтверждения выхода. */
.bd-confirm__actions {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.bd-confirm__actions .btn { flex: 1; }

.bd-room__note {
  text-align: center;
  color: var(--clr-text-3);
  font-size: var(--text-sm);
}

/* ── Свёрнутый режим: плавающий виджет в углу ─────────────────────────────
   Тот же DOM-узел (WS/LiveKit продолжают жить), меняется только раскладка.
   Оверлей перестаёт быть полноэкранным → страница под ним кликабельна. */
.bd-room--mini {
  inset: auto;
  bottom: var(--space-4);
  right: var(--space-4);
  width: min(340px, calc(100vw - 2 * var(--space-4)));
  height: auto;
  max-height: min(80vh, 620px);
  padding: var(--space-2);
  gap: var(--space-2);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
/* Что прячем в компактном виде. */
.bd-room--mini .bd-room__partner-info,
.bd-room--mini #bd-report,
.bd-room--mini #bd-minimize,
.bd-room--mini #bd-tile-self,
.bd-room--mini .bd-progress,
.bd-room--mini #bd-video-note { display: none !important; }
.bd-room--mini .bd-room__bar { margin-bottom: 0; }
.bd-room--mini .bd-room__topic strong { font-size: var(--text-sm); }
.bd-room--mini #bd-elapsed { font-size: var(--text-sm); }
/* Видео напарника — небольшой кадр; своё скрыто. */
.bd-room--mini .bd-room__stage {
  height: 128px;
  grid-template-columns: 1fr;
  gap: 0;
}
.bd-room--mini .bd-tile__ava { width: 48px; height: 48px; font-size: var(--text-base); }
/* Чат — компактный список + строка ввода. */
.bd-room--mini .bd-chat__list { max-height: 160px; }
.bd-room--mini .bd-room__chat { padding: var(--space-2); }
/* Контролы — иконки без подписей, в одну строку. */
.bd-room--mini .bd-room__controls { gap: var(--space-1); }
.bd-room--mini .bd-ctrl {
  min-width: 0;
  flex: 1;
  padding: var(--space-2);
  font-size: var(--text-lg);
}
.bd-room--mini .bd-ctrl span { display: none; }

@keyframes bd-pulse { 50% { opacity: 0.5; } }

@media (prefers-reduced-motion: reduce) {
  .bd-ctrl--alert { animation: none; }
}

@media (max-width: 640px) {
  .bd-room__stage { grid-template-columns: 1fr; }
  /* Свёрнутый виджет — во всю ширину над нижней навигацией. */
  .bd-room--mini {
    left: max(var(--space-3), env(safe-area-inset-left, 0px));
    right: max(var(--space-3), env(safe-area-inset-right, 0px));
    /* Без нижнего инсета виджет наезжал на «остров» навигации на iPhone. */
    bottom: calc(var(--space-16) + var(--space-2) + env(safe-area-inset-bottom, 0px));
    width: auto;
  }
}

/* Аватар хоста в карточке сессии */
.bd-avatar {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--clr-primary-light);
  color: var(--clr-primary);
  font-weight: var(--font-bold);
  font-size: var(--text-sm);
}
.bd-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ===== /css/pages/mood.css ===== */
/* mood.css — трекер настроения: пикер, динамика (спарклайн), история. */

.panel__title {
  font-family: var(--font-heading);
  font-weight: var(--font-bold);
  font-size: var(--text-lg);
  margin-bottom: var(--space-4);
}

/* Пикер настроения */
.mood-picker {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.mood-opt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  min-width: 84px;
  padding: var(--space-3);
  border: 1.5px solid var(--clr-border);
  border-radius: var(--radius-lg);
  background: var(--clr-surface);
  color: var(--clr-text-2);
  transition: border-color var(--transition-fast), background var(--transition-fast),
    transform var(--transition-fast);
}
.mood-opt:hover { border-color: var(--clr-primary); transform: translateY(-2px); }
/* Тач: выбор настроения — один тап, и залипший :hover оставлял «чужую»
   кнопку приподнятой рядом с реально выбранной. */
@media (hover: none) {
  .mood-opt:hover { transform: none; }
}
.mood-opt--on {
  border-color: var(--clr-primary);
  background: var(--clr-primary-light);
  color: var(--clr-primary);
}
.mood-opt__emoji { font-size: var(--text-3xl); line-height: 1; }
.mood-opt__label { font-size: var(--text-sm); font-weight: var(--font-medium); }

.mood-comment-field { margin-bottom: var(--space-4); }
.mood-comment-save { margin-top: var(--space-2); }
.mood-hint { margin-bottom: var(--space-3); }

/* Компактное состояние после чек-ина: «Сейчас: 🙂 Хорошо» + реакция. */
.mood-now {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}
.mood-now__emoji { font-size: var(--text-3xl); line-height: 1.15; }
.mood-now__body { flex: 1; min-width: 0; }
.mood-now__state { font-weight: var(--font-medium); }
.mood-now__reaction {
  margin-top: var(--space-1);
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
}
.mood-now__comment {
  margin-top: var(--space-2);
  color: var(--clr-text-2);
  font-style: italic;
  line-height: var(--leading-relaxed);
}
.mood-now__actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-top: var(--space-3);
}
.mood-now__link {
  align-self: flex-start;
  padding: var(--space-1) 0;
  font-size: var(--text-sm);
  color: var(--clr-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.mood-now__link:hover { text-decoration: none; }
.mood-now__change { flex-shrink: 0; }

/* Спарклайн динамики (Статистика) */
.mood-spark {
  width: 100%;
  max-width: 560px;
  height: auto;
}
.mood-spark__base { stroke: var(--clr-border); stroke-width: 1; }
.mood-spark__line {
  fill: none;
  stroke: var(--clr-primary);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mood-spark__dots circle { fill: var(--clr-primary); }

/* История */
.mood-history {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  list-style: none;
  margin: 0;
  padding: 0;
}
.mood-row {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
}
.mood-row__emoji { font-size: var(--text-2xl); line-height: 1.2; }
.mood-row__body { flex: 1; }
.mood-row__top {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  font-weight: var(--font-medium);
}
.mood-row__comment {
  margin-top: var(--space-1);
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
}

@media (prefers-reduced-motion: reduce) {
  .mood-opt:hover { transform: none; }
}

@media (max-width: 640px) {
  .mood-opt { min-width: 64px; padding: var(--space-2); }
}

/* ===== /css/pages/stats.css ===== */
/* stats.css — статистика: сегментер периода, метрики, график фокуса, тепловая карта. */

/* Сегментированный переключатель периода.
   max-width + прокрутка: на 320px четыре сегмента («Сегодня/Завтра/Неделя/
   Когда-нибудь» в Задачах) в строку не помещались и распирали страницу —
   появлялся горизонтальный скролл всего документа. Теперь лишнее прокручивается
   внутри самого переключателя. */
.segmented {
  display: inline-flex;
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-full);
  padding: 3px;
  background: var(--clr-surface-2);
}
.segmented::-webkit-scrollbar { display: none; }
.seg {
  flex-shrink: 0;
  /* Тач-таргет 44px: было 42.4px — ниже правила проекта. */
  min-height: 44px;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--clr-text-2);
  font-weight: var(--font-medium);
  white-space: nowrap;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.seg:hover:not(.seg--on) { color: var(--clr-text-1); }
.seg--on {
  background: var(--clr-surface);
  color: var(--clr-primary);
  font-weight: var(--font-semi);
  box-shadow: var(--shadow-sm);
}

/* Метрики */
.stats-row--wide {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
/* Иконизированная метрика: чип-иконка + значение (как на дашборд-эталоне). */
.metric {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--clr-surface);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}
.metric:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
/* Тач: :hover залипает после тапа — карточка метрики оставалась приподнятой. */
@media (hover: none) {
  .metric:hover { transform: none; }
}
.metric__chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  border-radius: var(--radius-md);
  color: var(--clr-primary);
  background: var(--clr-primary-light);
}
/* Цветовая маркировка отдельных метрик — согласована с дашбордом. */
.metric:nth-child(1) .metric__chip {
  color: var(--clr-success);
  background: color-mix(in srgb, var(--clr-success) 14%, transparent);
}
.metric:nth-child(4) .metric__chip {
  color: var(--clr-info);
  background: color-mix(in srgb, var(--clr-info) 14%, transparent);
}
.metric__value {
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  font-weight: var(--font-bold);
  color: var(--clr-text-1);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.metric__label { font-size: var(--text-sm); color: var(--clr-text-3); margin-top: 3px; }
.metric__hint { margin-top: 2px; font-size: var(--text-xs); color: var(--clr-text-3); }

/* График фокуса */
.focus-chart { width: 100%; max-width: 600px; height: auto; }
.focus-chart .axis { stroke: var(--clr-border); stroke-width: 1; }
.focus-chart .bar { fill: var(--clr-primary); rx: 3px; transition: fill var(--transition-fast); }
.focus-chart .bar:hover { fill: var(--clr-primary-hover, var(--clr-primary)); }
.focus-chart .bar-val { fill: var(--clr-text-3); font-size: 10px; }
.focus-chart .bar-label { fill: var(--clr-text-3); font-size: 10px; }

/* Тепловая карта */
.heatmap-wrap { overflow-x: auto; }
.heatmap {
  border-collapse: separate;
  border-spacing: 2px;
}
.heat-row-label {
  font-size: var(--text-xs);
  color: var(--clr-text-3);
  text-align: right;
  padding-right: var(--space-2);
  font-weight: var(--font-medium);
  white-space: nowrap;
}
.heat-cell {
  width: 14px;
  height: 14px;
  border-radius: 3px;
  background: var(--clr-surface-3);
}
.heat-hours {
  display: flex;
  justify-content: space-between;
  max-width: 380px;
  margin: var(--space-2) 0 0 36px;
  font-size: var(--text-xs);
  color: var(--clr-text-3);
}

@media (prefers-reduced-motion: reduce) {
  .focus-chart .bar, .seg, .metric { transition: none; }
}

/* «Мы заметили» — наблюдения по данным пользователя. */
.stats-insight {
  display: flex;
  gap: var(--space-2);
  line-height: var(--leading-relaxed);
  color: var(--clr-text-2);
}
.stats-insight + .stats-insight { margin-top: var(--space-2); }

/* Личные рекорды. */
.stats-records__hint { margin-bottom: var(--space-3); font-size: var(--text-sm); }

/* ===== /css/pages/settings.css ===== */
/* settings.css — профиль, темы, переключатели доступности, подписка, удаление. */

.set-form { display: flex; flex-direction: column; gap: var(--space-4); max-width: 420px; }

/* Пояснение и кнопка под ним раньше слипались (у p нет нижнего margin, а кнопка
   — inline-flex). Единое правило для всех блоков Настроек: «Telegram-бот»,
   «Мои данные», «Аккаунт», «Удаление аккаунта» — везде одинаковый отступ. */
.panel > p + .btn,
#tg-host > p + .btn,
#tg-host > .toggle-row + .btn,
.panel > .toggle-row + .btn { margin-top: var(--space-4); }
/* Абзац-пояснение перед второй кнопкой в блоке (например «Выйти на других
   устройствах») отделяем и сверху — иначе он прилипает к предыдущей кнопке. */
.set-hr { margin-top: var(--space-5); }

/* Telegram-раздел */
.tg-times { display: flex; gap: var(--space-4); margin: var(--space-3) 0; }
.tg-times .field { flex: 1; max-width: 160px; }
.tg-code-card {
  margin-top: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  background: var(--clr-surface-2);
}
.tg-code {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  letter-spacing: 0.12em;
  color: var(--clr-primary);
}
.tg-code-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }

/* Загрузка аватара профиля */
.avatar-edit { display: flex; align-items: center; gap: var(--space-4); margin-bottom: var(--space-5); }
.avatar-edit__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.avatar-edit__hint { flex-basis: 100%; margin: 0; font-size: var(--text-sm); }
.set-readonly {
  padding: var(--space-2) var(--space-3);
  background: var(--clr-surface-2);
  border-radius: var(--radius-md);
  color: var(--clr-text-2);
}

/* Темы */
.theme-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--space-3);
  max-width: 560px;
}
.theme-opt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 2px solid var(--clr-border);
  border-radius: var(--radius-lg);
  background: var(--clr-surface);
  color: var(--clr-text-2);
  font-weight: var(--font-medium);
  transition: border-color var(--transition-fast);
}
.theme-opt:hover { border-color: var(--clr-primary); }
.theme-opt--on { border-color: var(--clr-primary); background: var(--clr-primary-light); }
/* Мини-превью палитры темы: фон = surface, полоса = акцент, линии = текст. */
.theme-opt__swatch {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 5px;
  width: 100%;
  height: 48px;
  padding: 0 10px;
  border-radius: var(--radius-md);
  border: 1px solid var(--clr-border);
  overflow: hidden;
}
.swatch-prev__bar { width: 34%; height: 9px; border-radius: 4px; }
.swatch-prev__line { width: 80%; height: 4px; border-radius: 2px; opacity: 0.85; }
.swatch-prev__line--short { width: 55%; opacity: 0.5; }

/* Переключатели */
.toggle-list { display: flex; flex-direction: column; gap: var(--space-1); max-width: 560px; }
.toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3);
  margin-inline: calc(-1 * var(--space-3));
  border-bottom: 1px solid var(--clr-border);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--transition-fast);
}
.toggle-row:hover { background: var(--clr-surface-2); }
.toggle-row:last-child { border-bottom: none; }
.toggle-row__text { display: flex; flex-direction: column; gap: 2px; }
.toggle-row__label { font-weight: var(--font-medium); }
.toggle-row__hint { font-size: var(--text-sm); color: var(--clr-text-3); }

/* Switch */
.switch {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 44px;
  height: 24px;
  border-radius: var(--radius-full);
  background: var(--clr-surface-3);
  cursor: pointer;
  flex-shrink: 0;
  transition: background var(--transition-fast);
}
.switch::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition-fast);
}
.switch:checked { background: var(--clr-primary); }
.switch:checked::after { transform: translateX(20px); }
.switch:focus-visible { outline: 2px solid var(--clr-primary); outline-offset: 2px; }
/* Тач: сам тумблер 44×24 — по высоте вдвое ниже нормы. Дорожка и «шайба»
   остаются прежними, растёт только зона касания (прозрачный вылет ±10px).
   position:relative уже задан выше — ::after используется под шайбу,
   поэтому вылет вешаем на ::before. */
@media (pointer: coarse) {
  .switch::before {
    content: "";
    position: absolute;
    inset: -10px 0;
    border-radius: inherit;
  }
}

/* Подписка */
.sub-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-start;
  padding: var(--space-4);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  max-width: 420px;
}
.sub-card--pro { border-color: var(--clr-primary); background: var(--clr-primary-light); }

/* Опасная зона */
.panel--danger { border: 1px solid var(--clr-error); }
.btn--danger { color: var(--clr-error); }
.btn--danger:hover { background: var(--clr-error); color: #fff; }

@media (prefers-reduced-motion: reduce) {
  .switch, .switch::after, .theme-opt { transition: none; }
}

/* --- Мобильная полировка --------------------------------------------------
   Одиночные кнопки-действия в панелях настроек — на всю ширину (крупный тап,
   ровная колонка). Множественные кнопки в ряду (аватар) не трогаем этим
   правилом. Ограничители ширины форм/карточек на телефоне не нужны. */
@media (max-width: 640px) {
  .panel > .btn,
  #tg-host > .btn,
  .sub-card .btn,
  .set-form .btn { width: 100%; }

  .set-form,
  .sub-card { max-width: none; }
}

/* Очень узкий экран: аватар и его кнопки — столбиком, кнопки поровну в ряд. */
@media (max-width: 480px) {
  .avatar-edit { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
  .avatar-edit__actions { width: 100%; }
  .avatar-edit__actions .btn { flex: 1; }
}

/* ===== /css/pages/help.css ===== */
/* help.css — раздел «Помощь»: гид, контакты + FAQ. */

/* Карточка «Гид по ФокуснИИку» — запуск спотлайт-тура (сам тур идёт на Главной). */
.help-guide__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.help-guide__row .btn {
  flex-shrink: 0;
}
.help-guide__text {
  margin: 0;
  line-height: var(--leading-relaxed);
}

.help-ok {
  margin-top: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--clr-success) 14%, transparent);
  color: var(--clr-text-1);
}

/* Вложения формы обращения (фото/видео). */
.help-attach__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.help-attach__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-2);
  list-style: none;
  padding: 0;
}
.help-attach__list:empty {
  display: none;
}
.help-attach__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-md);
  background: var(--clr-surface);
}
.help-attach__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.help-attach__size {
  flex-shrink: 0;
  font-size: var(--text-sm);
}
.help-attach__rm {
  margin-left: auto;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-md);
  color: var(--clr-text-3);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.help-attach__rm:hover {
  background: var(--clr-surface-3);
  color: var(--clr-error);
}

/* Способы связи — карточки-ссылки. */
.help-contacts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-3);
}
.help-contact {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-lg);
  background: var(--clr-surface);
  color: var(--clr-text-1);
  transition: border-color var(--transition-fast), transform var(--transition-fast);
}
.help-contact:hover {
  border-color: var(--clr-primary);
  transform: translateY(-1px);
}
.help-contact__ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--clr-primary-light);
  color: var(--clr-primary);
}
.help-contact .text-muted {
  font-size: var(--text-sm);
  word-break: break-word;
}

/* Блок «Контакты и о сервисе»: описание, правовые ссылки и версия. */
.help-info__note { margin: 0; }
.help-info__about { margin-top: var(--space-3); line-height: var(--leading-relaxed); }
.help-info__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin-top: var(--space-4);
}
.help-info__link {
  color: var(--clr-primary);
  font-size: var(--text-sm);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.help-info__link:hover { color: var(--clr-primary-hover, var(--clr-primary)); }
/* Тач: правовые ссылки шли одна под другой строками по 24.8px — промахнуться
   между «Офертой» и «Политикой» было легко. На тач-устройствах ссылка
   становится полноценной строкой-таргетом 44px, вертикальный зазор — 8px. */
@media (pointer: coarse) {
  .help-info__links { gap: var(--space-2) var(--space-4); }
  .help-info__link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}
.help-info__ver {
  margin-top: var(--space-4);
  font-size: var(--text-xs);
  letter-spacing: 0.02em;
}

/* FAQ-аккордеон (нативный details/summary). */
.faq-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.faq-item {
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-md);
  background: var(--clr-surface);
  overflow: hidden;
}
.faq-item__q {
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  font-weight: var(--font-semi);
  color: var(--clr-text-1);
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.faq-item__q::-webkit-details-marker {
  display: none;
}
.faq-item__q::after {
  content: "+";
  font-size: var(--text-xl);
  color: var(--clr-text-3);
  line-height: 1;
  transition: transform var(--transition-fast);
}
.faq-item[open] .faq-item__q::after {
  transform: rotate(45deg);
}
.faq-item__a {
  padding: 0 var(--space-4) var(--space-4);
  color: var(--clr-text-2);
  line-height: var(--leading-relaxed);
}

/* Редактор FAQ в админке. */
.help-faq-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-2);
}
.help-faq-row__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.help-faq-row__head .input {
  flex: 1;
}

@media (prefers-reduced-motion: reduce) {
  .help-contact,
  .faq-item__q::after {
    transition: none;
  }
}

/* ===== /css/pages/upgrade.css ===== */
/* upgrade.css — тарифы Pro, промокод, история платежей. */

.benefits {
  display: grid;
  gap: var(--space-2);
  list-style: none;
  margin: 0 0 var(--space-5);
  padding: 0;
}
.benefits li { color: var(--clr-text-1); line-height: var(--leading-relaxed); }

.plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}
.plan-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-5);
  border: 2px solid var(--clr-border);
  border-radius: var(--radius-xl);
  background: var(--clr-surface);
  text-align: left;
  transition: border-color var(--transition-fast), transform var(--transition-fast);
}
.plan-card:hover { border-color: var(--clr-primary); transform: translateY(-2px); }
/* Тач: залипший :hover оставлял карточку тарифа приподнятой — это читается
   как «выбрано», хотя выбор ещё не сделан. */
@media (hover: none) {
  .plan-card:hover { transform: none; }
}
.plan-card--on { border-color: var(--clr-primary); background: var(--clr-primary-light); }
.plan-card--best { box-shadow: var(--shadow-md); }
/* Platinum — премиальный тариф: тёмный «графитовый» акцент. */
.plan-card--premium {
  border-color: var(--clr-text-1);
  background: linear-gradient(
    160deg,
    color-mix(in srgb, var(--clr-text-1) 4%, var(--clr-surface)) 0%,
    var(--clr-surface) 60%
  );
}
.plan-card--premium.plan-card--on {
  border-color: var(--clr-text-1);
  background: linear-gradient(
    160deg,
    color-mix(in srgb, var(--clr-text-1) 9%, var(--clr-surface)) 0%,
    color-mix(in srgb, var(--clr-text-1) 3%, var(--clr-surface)) 100%
  );
}
.plan-card--premium:hover { border-color: var(--clr-text-1); }
.plan-card__badge--premium { background: var(--clr-text-1); }
.plan-card__badge {
  position: absolute;
  top: calc(-1 * var(--space-3));
  right: var(--space-4);
  padding: 2px var(--space-3);
  border-radius: var(--radius-full);
  background: var(--clr-primary);
  color: var(--clr-on-primary);
  font-size: var(--text-xs);
  font-weight: var(--font-bold);
}
.plan-card__title { font-weight: var(--font-semi); color: var(--clr-text-2); }
.plan-card__price {
  font-family: var(--font-heading);
  font-size: var(--text-3xl);
  font-weight: var(--font-bold);
  color: var(--clr-text-1);
}
/* --clr-text-3 рассчитан на светлые нейтральные поверхности. На заливке
   --clr-primary-light (её носят карточки тарифов) он даёт 4.23:1 в светлой и
   «тихой» темах и 3.88:1 в тёмной — ниже AA 4.5 для основного кегля. Поэтому
   вторичные подписи здесь идут на --clr-text-2 (4.74 / 8.06 / 4.74). */
.plan-card__period { font-size: var(--text-base); font-weight: var(--font-regular); color: var(--clr-text-2); }
.plan-card__note { font-size: var(--text-sm); color: var(--clr-text-2); }

.promo-field { max-width: 320px; margin-bottom: var(--space-4); }
.pay-note { font-size: var(--text-sm); text-align: center; margin-top: var(--space-3); }

.pay-history {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}
.pay-row {
  display: grid;
  grid-template-columns: 1fr 1fr auto auto;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--clr-border);
}
.pay-row:last-child { border-bottom: none; }

@media (max-width: 560px) {
  /* Дата+тариф в первой строке, сумма+статус — во второй. */
  .pay-row { grid-template-columns: 1fr auto; }
}

@media (prefers-reduced-motion: reduce) {
  .plan-card:hover { transform: none; }
}

/* ===== /css/pages/cabinets.css ===== */
/* cabinets.css — партнёрский кабинет и админ-панель. */

/* Реферальная ссылка */
.ref-link { display: flex; gap: var(--space-2); max-width: 560px; }
.ref-link .input { flex: 1; }
.ref-conv { margin-top: var(--space-3); }

/* Фильтры */
.admin-filters {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.admin-filters .input { flex: 1; min-width: 200px; }
.select--sm { padding: var(--space-1) var(--space-2); font-size: var(--text-sm); }

/* Списки админки/рефералов */
.admin-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}
.admin-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-3);
  border: 1px solid var(--clr-border);
  border-radius: var(--radius-md);
  background: var(--clr-surface);
}
.admin-row--blocked { border-color: var(--clr-error); background: color-mix(in srgb, var(--clr-error) 8%, transparent); }
.admin-row__main {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 180px;
}
.admin-row__main .text-muted { font-size: var(--text-sm); }
.admin-row__actions { display: flex; gap: var(--space-2); }

/* Раскрывающиеся детали строки пользователя («Подробнее»). */
.admin-row__details {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  padding-top: var(--space-2);
  border-top: 1px dashed var(--clr-border);
  font-size: var(--text-sm);
  color: var(--clr-text-2);
}
.admin-row__details[hidden] { display: none; } /* display:flex сильнее UA-правила [hidden] */
.admin-row__id { font-size: var(--text-xs); color: var(--clr-text-3); word-break: break-all; }

.admin-count { margin-bottom: var(--space-3); font-size: var(--text-sm); }
.admin-more { margin-top: var(--space-3); }

/* Кнопки в модалках подтверждения админ-действий. */
.admin-confirm {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.admin-confirm .btn { flex: 1; }

/* Под-вкладки статусов (жалобы). */
.admin-subtabs { margin-bottom: var(--space-4); }

/* Отключённый/истёкший промокод — приглушённая строка. */
.admin-row--off { opacity: 0.65; }

/* Вкладки шапки (7 штук в админке) на мобильном не влезают — скролл. */
.app-header .segmented { max-width: 100%; overflow-x: auto; }
.app-header .seg { white-space: nowrap; flex-shrink: 0; }

.promo-ok {
  margin-top: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--clr-success) 14%, transparent);
  color: var(--clr-text-1);
}

@media (max-width: 640px) {
  .admin-row { align-items: flex-start; }
}

/* Вложения обращений в поддержку (фото/видео из формы «Помощь»). */
.admin-att-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin: 2px 0;
}
.admin-att {
  cursor: pointer;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.admin-att:hover { border-color: var(--clr-primary); color: var(--clr-primary); }
.admin-att:disabled { opacity: 0.6; cursor: wait; }

/* Мини-графики «Обзора» (14 дней). */
.adm-charts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-4);
}
.adm-chart__bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 72px;
}
.adm-bar {
  flex: 1;
  min-width: 4px;
  border-radius: 3px 3px 0 0;
  background: var(--clr-primary);
  opacity: 0.75;
}
.adm-bar:hover { opacity: 1; }
.adm-chart__label {
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--clr-text-2);
}

/* Карточка пользователя (раскрытие «Подробнее»). */
.admin-udet { flex-basis: 100%; margin-top: var(--space-2); }
.admin-udet__grid {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--text-sm);
}
.admin-udet__warn { color: var(--clr-error); }
.admin-udet__pays {
  margin: 0;
  padding-left: var(--space-4);
  font-size: var(--text-sm);
  color: var(--clr-text-2);
}
.admin-udet__actions {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
  flex-wrap: wrap;
}

/* Фильтры платежей. */
.admin-filters__search { display: flex; gap: var(--space-2); flex: 1; min-width: 240px; }

/* Вкладка «Система». */
.sys-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.sys-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.sys-row { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.sys-subtitle { font-size: var(--text-base); margin-bottom: var(--space-2); }
.sys-offline { margin-top: var(--space-2); font-size: var(--text-sm); line-height: var(--leading-relaxed); }
