/*
 * Стили веб-клиента EGO: каркас, типографика, компоненты экранов.
 *
 * Написан по дизайн-системе «Электро-спектр» (Р-107): docs/design.md — формы,
 * сетка и компоненты, docs/design-colors.md — цвет, docs/design-preview.html —
 * живой образец. Ни одного HEX здесь нет и быть не может: всё через токены
 * `tokens.css`, иначе тема перестанет переключаться.
 *
 * Каркас (docs/design.md §4.1): на ПК и планшете — верхняя панель и широкий
 * контент, на телефоне — нижняя панель вкладок. Прежняя колонка телефона
 * 480 px, растянутая на любой экран, отменена вместе со старой системой.
 *
 * Стили витрины (E-01) живут отдельно — `landing.css`: страница верстается
 * как документ и подключает свой файл только на себе.
 *
 * Связано: docs/egoweb/architecture.md §3, docs/screens.md §1
 */

/* ═══ 1. База и каркас ════════════════════════════════════════════════════ */

* { box-sizing: border-box; }

html {
    /* Ни один экран не уводит страницу вбок (docs/design.md §3.4, п. 1).
       Именно `clip`, а не `hidden`: `hidden` сделал бы элемент контейнером
       прокрутки, и липкие панели перестали бы липнуть */
    overflow-x: clip;
    /* Прокрутка к якорю не должна прятать заголовок под липкой панелью */
    scroll-padding-top: calc(var(--h-topbar) + var(--space-4));
}

body {
    margin: 0;
    min-height: 100dvh;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-family);
    font-size: var(--text-body);
    line-height: var(--lh-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: clip;
}

/* Оболочка: колонка во всю ширину. Подсветка лежит поверх фона и прибита к
   области просмотра — при прокрутке пятна остаются на месте, иначе они
   «едут» вместе с содержимым и мешают читать (docs/design-colors.md §6) */
.app {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
    position: relative;
    background: var(--ambient), var(--bg);
    background-attachment: fixed;
}

/* Чат — единственный экран с внутренней прокруткой: лента перевёрнута, а поле
   ввода прижато к низу. Остальные экраны прокручиваются документом, как
   обычные страницы. Признак берётся из `data-screen`, который сервер и так
   проставляет каждой странице (app/pages.py) */
html[data-screen="E-10"], html[data-screen="E-10"] body { height: 100%; overflow: hidden; }
html[data-screen="E-10"] .app { height: 100%; min-height: 0; overflow: hidden; }

/* Контентная область экрана.

   Ширина у всех экранов одна и та же — та, что у ленты чата (`--reading`).
   Решение оператора от 2026-08-17: разная ширина у разделов читалась как
   разные приложения, а растянутый на 27" список карточек — как недоделка.
   Полноширинными остаются только фон, липкие панели и их границы; само
   содержимое всегда стоит в одной колонке. */
.screen {
    flex: 1;
    width: 100%;
    max-width: calc(var(--reading) + var(--page-padding) * 2);
    margin: 0 auto;
    padding: var(--space-3) var(--page-padding) var(--space-10);
}
@media (min-width: 768px) {
    .screen { padding-top: var(--space-5); }
}

.screen--reading { max-width: calc(var(--reading) + var(--page-padding) * 2); }
/* Экраны-формы: ширину ограничивает только сама форма, а карточки, списки и
   заголовки живут во всю колонку. Ограничение на всех детей сжимало раздел
   ровно вдвое — так и выглядело: половина экрана пустая */
.screen--form form, .screen--form .form-column { max-width: var(--form); }

/* Телефон: под нижней панелью вкладок должно оставаться место, иначе она
   закрывает последнюю карточку списка */
@media (max-width: 767.98px) {
    .app { padding-bottom: calc(var(--h-tabbar) + env(safe-area-inset-bottom, 0)); }
    html[data-screen="E-10"] .app { padding-bottom: 0; }
}

.safe-bottom { padding-bottom: env(safe-area-inset-bottom, 0); }

/* Фокус виден всегда и одинаково (docs/design.md §12). Снимать `outline` без
   замены запрещено — этим правилом заменяем его один раз на всё приложение */
:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
    border-radius: var(--radius-sm);
}

::selection { background: var(--violet-soft); color: var(--text); }

/* Полоса прокрутки в наших контейнерах: видимая, но неброская. Прятать нельзя —
   мышью прокрутить ряд без неё невозможно (docs/design.md §9.4) */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
    background: var(--border-strong);
    border-radius: var(--radius-pill);
}
*::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

/* Пользовательский текст, адрес партнёра, имя модуля — рвутся, а не уезжают
   за край (docs/design.md §3.4, п. 7) */
.text-break, .bubble, .menu-row, .card-ego { overflow-wrap: anywhere; }

img, video { max-width: 100%; height: auto; }

a { color: var(--violet-text); text-decoration: none; }
a:hover { text-decoration: underline; }
/* Ссылка внутри текста цветом не выделяется (Р-128: ссылки — цветом текста),
   поэтому её держит подчёркивание */
p a:not([class]) { text-decoration: underline; text-underline-offset: 3px; }

.skip-link {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    padding: var(--space-3) var(--space-4);
    background: var(--surface); border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
}
.skip-link:focus { left: var(--space-4); top: var(--space-4); }

/* Обёртка содержимого — только якорь для ссылки «К содержимому»: своего блока
   она не создаёт, поэтому колонка экрана остаётся прямым потомком оболочки и
   раскладка не меняется */
.layout-anchor { display: contents; }


/* ═══ 2. Навигация ════════════════════════════════════════════════════════ */

/* Верхняя панель приложения. На телефоне её заменяет нижняя панель вкладок,
   поэтому здесь она скрыта (docs/design.md §4.1) */
.appnav {
    display: none;
    position: sticky;
    top: 0;
    z-index: 30;
    align-items: center;
    gap: var(--space-4);
    height: var(--h-topbar);
    /* Панель тянется во всю ширину — фон и нижняя граница должны доходить до
       краёв окна, — а её содержимое стоит в той же колонке, что и контент.
       Отсюда отступ по краям, а не `max-width`: он держит колонку, не разрезая
       саму полосу */
    padding-inline: max(var(--page-padding),
                        calc((100% - var(--reading)) / 2));
    /* Сплошная (2026-10-15): сквозь полупрозрачную полосу проступал текст */
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}

/* Без размытия слой обязан стать сплошным: сквозь полупрозрачную панель
   читался бы текст под ней (docs/design.md §5.4) */
@supports not (backdrop-filter: blur(2px)) {
    .appnav { background: var(--surface); }
}

/* Под панелью — тонкая линия, а не цветная полоса раздела: акцент на экране
   один, и он у главного действия (брендбук, docs/design-colors.md §7) */
.appnav::after {
    content: "";
    position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
    background: var(--border);
}

@media (min-width: 768px) {
    .appnav { display: flex; }
}

.appnav-brand {
    display: inline-flex; align-items: center; gap: var(--space-2);
    color: var(--text); text-decoration: none;
}
.appnav-brand:hover { text-decoration: none; }

/* Старое слово «EGO» набором. Шапки перешли на вордмарк-картинку
   (`wordmark()` в components/logo.html); класс оставлен на случай старых
   шаблонов */
.wordmark {
    font-weight: 800;
    font-size: var(--text-body);
    letter-spacing: var(--tracking-word);
}

/* Кнопка темы на экранах без шапки: форма входа, документы, гейт */
.theme-floating {
    position: fixed; z-index: 35;
    top: calc(var(--space-3) + env(safe-area-inset-top, 0));
    right: var(--space-3);
    background: color-mix(in srgb, var(--surface) 80%, transparent);
    backdrop-filter: blur(12px);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

.appnav-links { display: flex; align-items: center; gap: var(--space-1); }

.appnav-link {
    display: inline-flex; align-items: center; gap: var(--space-2);
    height: var(--h-button); padding: 0 var(--space-4);
    border-radius: var(--radius-pill);
    color: var(--text-secondary);
    font-size: var(--text-small); font-weight: 700;
    text-decoration: none;
    transition: background var(--motion-fast) var(--ease-out),
                color var(--motion-fast) var(--ease-out);
}
.appnav-link:hover { background: var(--fill); color: var(--text); text-decoration: none; }
/* Текущий пункт — как активная вкладка телефона: залитая плашка цветом
   действия и содержимое чернилами (оператор 2026-10-16: «везде как на
   телефоне»). Раньше на ПК была приглушённая плашка `accent-soft` с белым
   текстом, и одно и то же место выглядело по-разному на двух экранах */
.appnav-link.is-current { background: var(--violet); color: var(--on-violet); }
.appnav-link svg { width: 20px; height: 20px; }

.appnav-side { margin-left: auto; display: flex; align-items: center; gap: var(--space-2); }

.appnav-balance {
    display: inline-flex; align-items: center; gap: var(--space-1);
    height: var(--h-button-sm); padding: 0 var(--space-3);
    border: 1px solid var(--border); border-radius: var(--radius-pill);
    color: var(--text-secondary); font-size: var(--text-small); font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Шапка экрана: заголовок и действия. На телефоне липкая и с кнопкой «назад»,
   на ПК — обычная строка внутри контента (там навигация в верхней панели) */
.topbar {
    position: sticky; top: 0; z-index: 30;
    display: flex; align-items: center; gap: var(--space-3);
    min-height: var(--h-topbar-mobile);
    padding: var(--space-2) var(--page-padding);
    padding-top: calc(var(--space-2) + env(safe-area-inset-top, 0px));
    /* Сплошной фон (2026-10-15): полупрозрачное «стекло» показывало текст,
       уехавший под шапку при прокрутке, — строки лезли друг на друга */
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}

/* Заголовок в шапке экрана переносится на вторую строку, а не обрезается
   многоточием (запрос оператора 2026-10-15: «Политика обработки п…» на
   телефоне). Unbounded широкий, поэтому на телефоне кегль 18, на самых узких
   (до 360 px) — 16; дальше третьей строки срезаем, чтобы шапка не съела экран */
.topbar h1.t-screen-title {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    white-space: normal;
    overflow-wrap: anywhere;
    hyphens: auto;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    overflow: hidden;
}
@media (max-width: 767.98px) {
    .topbar h1.t-screen-title { font-size: 18px; line-height: 1.25; }
}
@media (max-width: 359.98px) {
    .topbar h1.t-screen-title { font-size: 16px; }
}


@media (min-width: 768px) {
    .topbar {
        top: var(--h-topbar);
        max-width: calc(var(--reading) + var(--page-padding) * 2);
        margin: 0 auto;
        width: 100%;
        min-height: var(--h-topbar);
        /* На ПК шапка экрана тоже липкая, и прозрачной быть не может: под ней
           при прокрутке проезжал текст документа (/privacy и др., 2026-10-15).
           Фон — цвет страницы во всю ширину окна: сама шапка узкая (колонка
           чтения), а тень без размытия и обрезка по вертикали растягивают
           заливку влево и вправо, не трогая раскладку */
        background: var(--bg);
        box-shadow: 0 0 0 100vmax var(--bg);
        clip-path: inset(0 -100vmax);
        backdrop-filter: none;
        border-bottom: none;
        padding-top: var(--space-4);
    }
    /* Отступ сверху нужен только под панелью приложения. На публичных
       страницах (FAQ, «О сервисе») панели нет, а липкий заголовок со сдвигом
       64 px наезжал на первый блок даже без прокрутки */
    body:not(:has(.appnav)) .topbar { top: 0; }
    /* Знак в шапке экрана — только на телефоне: на ПК он уже есть в панели,
       и второй читается как ошибка вёрстки */
    .topbar .appnav-brand { display: none; }
    /* Меню и знак на ПК — в верхней панели приложения; в шапке экрана их нет */
    .topbar .topbar-menu, .topbar span.topbar-logo { display: none; }
}

/* Нижняя панель вкладок — телефон (docs/design.md §9.4) */
.tabbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    display: flex;
    height: calc(var(--h-tabbar) + env(safe-area-inset-bottom, 0));
    padding-bottom: env(safe-area-inset-bottom, 0);
    /* Сплошная (2026-10-15): сквозь полупрозрачную полосу проступал текст */
    background: var(--surface);
    border-top: 1px solid var(--border);
}
@supports not (backdrop-filter: blur(2px)) { .tabbar { background: var(--surface); } }

@media (min-width: 768px) { .tabbar { display: none; } }

.tab {
    flex: 1;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px;
    color: var(--text-muted);
    font-size: var(--text-micro); font-weight: 700;
    text-decoration: none;
    position: relative;
}
.tab:hover { text-decoration: none; }
.tab svg { width: 22px; height: 22px; }

/* Текущая вкладка — залитая плашка под иконкой цветом действия (чернила в
   светлой теме, сигнал в тёмной) и жирная подпись цветом текста. Прежняя
   точка над иконкой была слишком мелкой: на телефоне не было понятно, где ты
   (запрос оператора 2026-10-14). Цвет не единственный признак — у плашки
   есть форма, у подписи вес (docs/design.md §12) */
.tab-pill {
    display: inline-flex; align-items: center; justify-content: center;
    width: 56px; height: 30px;
    border-radius: var(--radius-pill);
    transition: background var(--motion-fast) var(--ease-out),
                color var(--motion-fast) var(--ease-out);
}
.tab-label { font-weight: 600; }
.tab[aria-current="page"] { color: var(--text); }
.tab[aria-current="page"] .tab-pill { background: var(--violet); color: var(--on-violet); }
.tab[aria-current="page"] .tab-label { font-weight: 800; }


/* ═══ 3. Типографика ══════════════════════════════════════════════════════ */

h1, h2, h3, p { margin: 0; }
h1, h2, h3 { text-wrap: balance; }

.t-hero, .t-display {
    font-family: var(--font-display);
    font-size: var(--text-display); line-height: var(--lh-display);
    font-weight: 700; letter-spacing: var(--tracking-display);
}
/* Шкала помощников подобрана под то, как они стоят в разметке, а не по
   порядку уровней документа: `t-title` в клиенте — это заголовок шторки и
   крупное число (имя в профиле, баланс токенов, счётчик приглашений), а не
   герой страницы. Поставленный сюда `h1` (32–48) ломал профиль: имя не
   помещалось в строку и переезжало на вторую */
.t-title {
    font-size: var(--text-h2); line-height: var(--lh-h2);
    font-weight: 800; letter-spacing: var(--tracking-heading);
}
/* Заголовок экрана — Unbounded, как заголовки разделов лендинга: по нему
   узнаётся бренд (брендбук: display-шрифт — только для заголовков) */
.t-screen-title {
    font-family: var(--font-display);
    font-size: var(--text-h3); line-height: var(--lh-h3);
    font-weight: 600; letter-spacing: var(--tracking-heading);
}
/* Подзаголовок внутри экрана: месяц в календаре, состояние live-режима,
   заголовок пустого состояния. Крупнее текста, мельче заголовка экрана */
.t-section {
    font-size: var(--text-body-lg); line-height: 1.3;
    font-weight: 700; letter-spacing: var(--tracking-heading);
}
.t-body-strong { font-size: var(--text-body); line-height: var(--lh-body); font-weight: 700; }
.t-body { font-size: var(--text-body); line-height: var(--lh-body); }
.t-caption { font-size: var(--text-small); line-height: var(--lh-small); }
.t-micro { font-size: var(--text-micro); line-height: 1.4; font-weight: 500; }
.t-mono { font-family: var(--font-mono); font-size: var(--text-small); }

.t-secondary { color: var(--text-secondary); }
.t-tertiary { color: var(--text-muted); }
.t-error { color: var(--danger-text); }
.t-accent { color: var(--accent-text); }
.t-success { color: var(--success-text); }

.t-label {
    font-size: var(--text-micro); line-height: 1.2; font-weight: 700;
    letter-spacing: var(--tracking-label); text-transform: uppercase;
    color: var(--text-muted);
}

/* Крупный заголовок заливкой спектра. Запасной `color` обязателен: без
   `background-clip: text` заголовок исчез бы целиком (docs/design.md §2.2) */
.t-gradient {
    color: var(--violet-text);
    background: var(--gradient-spectrum);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

/* Числа, стоящие столбцом или меняющиеся на месте, — табличными цифрами */
.t-num, .appnav-balance, .metric-value { font-variant-numeric: tabular-nums; }

/* Длинная строка нечитаема: 68 знаков — предел (docs/design.md §2.2) */
.t-measure { max-width: var(--measure); }


/* ═══ 4. Кнопки ═══════════════════════════════════════════════════════════ */

.btn-ego, .btn-ego-secondary, .btn-ego-text, .btn-ego-danger {
    display: inline-flex; align-items: center; justify-content: center;
    gap: var(--space-2);
    height: var(--h-button-lg);
    padding: 0 var(--space-6);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-family: inherit; font-size: var(--text-button); font-weight: 700;
    letter-spacing: 0.01em;
    cursor: pointer;
    text-decoration: none;
    transition: transform var(--motion-fast) var(--ease-out),
                box-shadow var(--motion-fast) var(--ease-out),
                background var(--motion-fast) var(--ease-out),
                border-color var(--motion-fast) var(--ease-out);
}
.btn-ego:hover, .btn-ego-secondary:hover, .btn-ego-text:hover, .btn-ego-danger:hover {
    text-decoration: none;
}
.btn-ego:active, .btn-ego-secondary:active, .btn-ego-danger:active { transform: translateY(1px); }

/* Главная кнопка — заливка бренд-градиентом и свечение под ней. На экране
   такая одна: две градиентные рядом — ошибка ревью (docs/design.md §9.1) */
.btn-ego {
    background: var(--gradient-brand);
    color: var(--on-violet);
    box-shadow: var(--glow-primary);
}
.btn-ego:hover {
    box-shadow: var(--glow-primary),
                0 0 0 4px color-mix(in srgb, var(--violet) 18%, transparent);
}

/* Вторая по важности — контур, а не цвет: иначе на экране два «главных» */
.btn-ego-secondary {
    background: transparent;
    color: var(--text);
    border-color: var(--border-strong);
}
.btn-ego-secondary:hover { background: var(--fill); border-color: var(--text-muted); }

/* Текстовая кнопка — действие, а не навигация, поэтому фиолет, а не акцент
   раздела: иначе «Скопировать» в профиле становится янтарным и читается как
   предупреждение (docs/design-colors.md §7) */
.btn-ego-text {
    height: auto; padding: var(--space-2) var(--space-3);
    background: transparent; color: var(--violet-text);
    border-radius: var(--radius-sm);
}
.btn-ego-text:hover { background: var(--fill); }

.btn-ego-danger { background: var(--danger); color: var(--on-danger); }
.btn-ego-danger:hover { background: var(--danger-hover); }

.btn-ego[disabled], .btn-ego-secondary[disabled], .btn-ego-danger[disabled] {
    background: var(--fill); color: var(--text-muted);
    border-color: transparent; box-shadow: none; cursor: not-allowed;
}

.btn-sm {
    height: var(--h-button-sm); padding: 0 var(--space-4);
    font-size: var(--text-small); border-radius: var(--radius-sm);
}
.btn-md { height: var(--h-button); padding: 0 var(--space-5); }

/* Иконочная кнопка. Цель нажатия 44 независимо от размера иконки
   (docs/design.md §3.4, п. 2) */
.btn-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: var(--h-button); height: var(--h-button);
    flex: none;
    padding: 0;
    background: transparent; color: var(--text);
    border: none; border-radius: var(--radius-md);
    cursor: pointer;
    transition: background var(--motion-fast) var(--ease-out),
                color var(--motion-fast) var(--ease-out);
}
.btn-icon:hover { background: var(--fill); }
.btn-icon.is-accent { color: var(--accent-text); }
.btn-icon.is-accent-soft { color: var(--violet); opacity: 0.75; }
.btn-icon.is-accent-soft:hover { opacity: 1; }

/* Переключатель темы показывает результат нажатия, а не текущее состояние:
   в светлой теме — луна, в тёмной — солнце. Обе иконки лежат в разметке,
   лишнюю прячет CSS — подмена скриптом ждала бы его загрузки
   (docs/design-themes.md §4) */
.theme-toggle-sun { display: none; }
.theme-toggle-moon { display: inline-flex; }

:root[data-theme="dark"] .theme-toggle-sun { display: inline-flex; }
:root[data-theme="dark"] .theme-toggle-moon { display: none; }

@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] .theme-toggle-sun { display: inline-flex; }
    :root[data-theme="auto"] .theme-toggle-moon { display: none; }
}

.d-grid > .btn-ego, .d-grid > .btn-ego-secondary, .d-grid > .btn-ego-danger { width: 100%; }


/* ═══ 5. Поля и формы ═════════════════════════════════════════════════════ */

/* `.field` — это САМО поле, а не обёртка вокруг него: так класс стоит в
   разметке всех форм (`<input class="field">`). Обёрткой его сделать нельзя —
   тогда поля остаются без стилей, и на экране появляются серые прямоугольники
   браузера по умолчанию. Проверено живой поломкой на E-41 */
.field-label {
    display: block;
    margin-bottom: 6px;
    font-size: var(--text-small); color: var(--text-secondary);
}

/* Плотность формы. Раньше расстояние между полями складывалось из отступа
   обёртки (16) и всегда занятого места под ошибку (18) — форма растягивалась
   вдвое против нужного. Теперь место под ошибку резервируется только тогда,
   когда ошибка есть, а ритм задаёт один отступ */
form .mb-3 { margin-bottom: var(--space-3) !important; }
.field-error:empty { display: none; }

.field,
input[type="text"], input[type="email"], input[type="password"],
input[type="tel"], input[type="search"], input[type="date"], input[type="time"],
input[type="number"], input[type="url"], input[type="datetime-local"], textarea, select {
    width: 100%;
    height: var(--h-input);
    padding: 0 var(--space-4);
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    font-family: inherit;
    /* 16 px — не про красоту: мельче iOS зумит страницу при фокусе и обратно
       не отпускает (docs/design.md §3.4, п. 4) */
    font-size: var(--text-body);
    transition: border-color var(--motion-fast) var(--ease-out),
                box-shadow var(--motion-fast) var(--ease-out);
}

textarea, textarea.field {
    height: auto; min-height: 96px;
    padding: var(--space-3) var(--space-4);
    resize: vertical;
}

/* Родная стрелка `select` съедает текст, если не оставить ей места */
select, select.field { padding-right: var(--space-8); }

input::placeholder, textarea::placeholder, .field::placeholder { color: var(--text-muted); }

.field:focus, input:focus, textarea:focus, select:focus {
    outline: none;
    border-color: var(--violet);
    box-shadow: var(--focus-ring);
}

.field:disabled, input:disabled, select:disabled, textarea:disabled {
    background: var(--fill);
    color: var(--text-muted);
    cursor: not-allowed;
}

.field-error {
    display: block;
    margin-top: var(--space-1);
    font-size: var(--text-micro); font-weight: 500;
    color: var(--danger-text);
}

.is-invalid, .field.is-invalid { border-color: var(--danger); }
.field.is-invalid:focus {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 40%, transparent);
}

/* Чекбокс и переключатель */
input[type="checkbox"], input[type="radio"] {
    width: var(--size-checkbox); height: var(--size-checkbox);
    accent-color: var(--violet);
    cursor: pointer;
}

.switch {
    position: relative;
    width: 44px; height: 26px;
    flex: none;
    background: var(--fill-strong);
    border-radius: var(--radius-pill);
    border: none;
    cursor: pointer;
    transition: background var(--motion-fast) var(--ease-out);
}
.switch::after {
    content: "";
    position: absolute; top: 3px; left: 3px;
    width: 20px; height: 20px; border-radius: 50%;
    background: var(--surface);
    box-shadow: var(--shadow-1);
    transition: transform var(--motion-fast) var(--ease-out);
}
.switch[aria-checked="true"] { background: var(--gradient-brand); }
.switch[aria-checked="true"]::after { transform: translateX(18px); }


/* ═══ 6. Карточки, списки, чипы ═══════════════════════════════════════════ */

.card-ego {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
}

@media (min-width: 768px) { .card-ego { padding: var(--space-5); } }

/* Кликабельная карточка: поднимается и подсвечивает границу. На касании
   наведения нет, поэтому оно только усиливает то, что и так видно */
.card-link {
    display: block; color: inherit; text-decoration: none;
    transition: transform var(--motion-fast) var(--ease-out),
                border-color var(--motion-fast) var(--ease-out),
                background var(--motion-fast) var(--ease-out);
}
.card-link:hover {
    text-decoration: none;
    transform: translateY(-2px);
    border-color: var(--border-strong);
    background: var(--surface-raised);
}

/* Акцентная карточка — градиентная рамка двойным фоном. Одна на экран
   (docs/design.md §5.2) */
.card-accent {
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    background:
        linear-gradient(var(--surface), var(--surface)) padding-box,
        var(--accent-gradient) border-box;
}

/* Плашка под иконкой: подсвеченный квадрат вместо голой иконки на пустом */
.icon-plate {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; flex: none;
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
    border: 1px solid color-mix(in srgb, var(--accent) 24%, transparent);
    color: var(--accent-text);
}
.icon-plate svg { width: 22px; height: 22px; }
.icon-plate-lg { width: 56px; height: 56px; border-radius: var(--radius-md); }
.icon-plate-lg svg { width: 28px; height: 28px; }

/* Строка меню: иконка, подпись, стрелка. Из них собран профиль */
.menu-row {
    display: flex; align-items: center; gap: var(--space-3);
    min-height: 56px;
    padding: var(--space-3) var(--space-4);
    color: inherit; text-decoration: none;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    transition: background var(--motion-fast) var(--ease-out),
                border-color var(--motion-fast) var(--ease-out);
}
.menu-row:hover { text-decoration: none; background: var(--fill); border-color: var(--border-strong); }
.menu-row svg { flex: none; }
/* Подпись занимает всю свободную ширину и прижимает стрелку вправо. Растягивать
   первый элемент нельзя — первый здесь иконка, и подпись уезжала в центр */
.menu-row > span.flex-grow-1 { flex: 1; min-width: 0; }
.menu-row > span:first-child { display: inline-flex; color: var(--text-secondary); }

/* Список строк одной карточкой: разделители вместо отступов между ними.
   Карточка теряет внутренний отступ — его дают сами строки, иначе у списка
   появляется двойная рамка и лишний воздух по краям */
.card-ego.divide-rows { padding: 0; overflow: hidden; }
.card-ego.divide-rows > * {
    border: none;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    background: transparent;
}
.card-ego.divide-rows > *:last-child { border-bottom: none; }

/* Тот же список без карточки — например, внутри шторки */
.divide-rows:not(.card-ego) { display: grid; }
.divide-rows:not(.card-ego) > * { border-radius: 0; border-bottom-width: 0; }
.divide-rows:not(.card-ego) > *:first-child { border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
.divide-rows:not(.card-ego) > *:last-child {
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    border-bottom-width: 1px;
}

/* Чип выбора */
.chip {
    display: inline-flex; align-items: center; gap: var(--space-2);
    height: var(--h-button-sm);
    padding: 0 var(--space-4);
    background: var(--fill);
    color: var(--text-secondary);
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    font-size: var(--text-small); font-weight: 700;
    cursor: pointer;
    transition: background var(--motion-fast) var(--ease-out),
                color var(--motion-fast) var(--ease-out);
}
.chip:hover { background: var(--fill-strong); }

/* Выбор чипа скрипты помечают `aria-pressed`, а не классом: чип — кнопка со
   состоянием, и атрибут тут не украшение, а то, что читает screen reader.
   Класс поддержан рядом — им пользуется календарь (`tasks.js`) */
/* Акцент разделов теперь один — цвет действия (Р-128), и текст на нём
   берётся парой к нему: бумага на чернилах, чернила на сигнале */
.chip[aria-pressed="true"], .chip.is-selected {
    background: var(--accent);
    color: var(--on-violet);
    border-color: transparent;
}
.chip-sm { height: 28px; padding: 0 var(--space-3); font-size: var(--text-micro); }

/* Плашка статуса: подложка смысла, текст смыслом, точка слева */
.status-pill {
    display: inline-flex; align-items: center; gap: var(--space-2);
    padding: 5px var(--space-3);
    border-radius: var(--radius-pill);
    font-size: var(--text-micro); font-weight: 700;
    background: var(--fill); color: var(--text-secondary);
}
.status-dot, .dot {
    width: 7px; height: 7px; flex: none;
    border-radius: 50%;
    background: currentColor;
}

/* Точка состояния сервиса (каталог и окно модуля): «работает» — лайм во
   всех темах (оператор 2026-10-16). На светлом фоне лайм почти не виден
   (1.04 : 1), поэтому там у точки чернильный ободок — тот же приём, что у
   лаймовой точки уведомления на лендинге */
.status-dot.is-up { background: var(--lime); }
.status-dot.is-warn { background: var(--amber); }
.status-dot.is-down { background: var(--danger); }
[data-bs-theme="light"] .status-dot.is-up { box-shadow: 0 0 0 1.5px var(--on-bright); }

.status-pill.is-success { background: var(--success-soft); color: var(--success-text); }
.status-pill.is-warning { background: var(--warning-soft); color: var(--warning-text); }
.status-pill.is-error { background: var(--danger-soft); color: var(--danger-text); }
.status-pill.is-info { background: var(--info-soft); color: var(--info-text); }

/* Точки приоритетов задач (docs/design-colors.md §8) */
.dot-urgent { background: var(--priority-urgent); }
.dot-high { background: var(--priority-high); }
.dot-medium { background: var(--priority-medium); }
.dot-low { background: var(--priority-low); }

/* Бейдж «новое» — единственное место лайма в клиенте */
.badge-new {
    display: inline-flex; align-items: center;
    padding: 3px var(--space-2);
    background: var(--lime); color: var(--ink);
    border-radius: var(--radius-xs);
    font-size: var(--text-micro); font-weight: 700;
}

.alert-soft {
    display: flex; gap: var(--space-3);
    padding: var(--space-4);
    background: var(--info-soft);
    border: 1px solid color-mix(in srgb, var(--info) 40%, transparent);
    border-radius: var(--radius-lg);
    font-size: var(--text-small);
}
.alert-soft.is-warning {
    background: var(--warning-soft);
    border-color: color-mix(in srgb, var(--warning) 40%, transparent);
}
.alert-soft.is-error {
    background: var(--danger-soft);
    border-color: color-mix(in srgb, var(--danger) 40%, transparent);
}

.progress-ego {
    height: 8px;
    background: var(--fill);
    border-radius: var(--radius-pill);
    overflow: hidden;
}
.progress-ego > * {
    display: block; height: 100%;
    background: var(--gradient-brand);
    border-radius: inherit;
    transition: width var(--motion) var(--ease-out);
}

/* Метрика: число крупно, подпись капслоком */
.metric-value {
    font-size: var(--text-metric); font-weight: 800; line-height: 1;
    letter-spacing: var(--tracking-heading);
}


/* ═══ 7. Чат (E-10) ═══════════════════════════════════════════════════════ */

.chat-feed {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    /* Перевёрнутая колонка: диалог открывается на последнем сообщении, а
       подгрузка истории сверху не сдвигает прочитанное */
    display: flex;
    flex-direction: column-reverse;
    justify-content: flex-start;  /* column-reverse: start = bottom, keeps messages at bottom */
    padding: var(--space-4) var(--page-padding);
    /* Отступ снизу = composer sticky (мобайл: +tabbar) */
    padding-bottom: 150px;
}

/* Перевёрнута и лента, и список внутри неё — это не дублирование, а пара.
   `chat.js` вставляет новое сообщение ПЕРВЫМ узлом (`insertBefore`), а историю
   дописывает в конец: при `column-reverse` новое оказывается внизу, а
   подгруженная история — сверху, не сдвигая прочитанное. Поставить здесь
   обычный `column` — значит перевернуть диалог: новые реплики уезжают наверх */

@media (min-width: 768px) {
    /* На десктопе нет tabbar — уменьшаем отступ */
    .chat-feed { padding-bottom: 80px; }
}
.chat-messages {
    width: 100%;
    max-width: var(--reading);
    margin: 0 auto;
    display: flex;
    flex-direction: column-reverse;
    gap: var(--space-3);
}

.bubble {
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-body);
    line-height: var(--lh-body);
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
}

/* Длинные ответы ассистента (текст песни, статья) — ограничиваем высоту с прокруткой внутри */
/* Своё сообщение — единственное место в ленте, где появляется бренд-градиент:
   он отмечает «сказал человек» (docs/design.md §9.8) */
.bubble-user {
    align-self: flex-end;
    max-width: 78%;
    background: var(--gradient-brand);
    color: var(--on-violet);
    border-radius: var(--radius-lg) var(--radius-lg) 6px var(--radius-lg);
}

/* Ответ ассистента — своя карточка, зеркальная сообщению человека
   (запрос оператора 2026-10-15): раньше текст висел прямо на фоне ленты, и
   в тёмной теме было непонятно, где реплика начинается и кончается. Карточка
   — поверхность с линией, без заливки цветом: цвет остаётся за человеком,
   поэтому «кто говорит» видно с одного взгляда. Острый угол снизу слева —
   «хвостик» к стороне ассистента, у человека он справа */
.bubble-assistant {
    align-self: flex-start;
    max-width: min(92%, 680px);
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg) var(--radius-lg) var(--radius-lg) 6px;
}
/* Ответ из одних карточек сервиса — без своей рамки: карточки уже карточки,
   рамка вокруг них дала бы «коробку в коробке» и съела ширину на телефоне */
.bubble-assistant:has(> .chat-cards) {
    background: transparent;
    border: none;
    padding-left: 0;
    padding-right: 0;
    max-width: 100%;
}

/* Иконки действий под ответом ИИ (Gemini-style) */
.bubble-actions {
    display: flex;
    gap: var(--space-2);
    margin-top: var(--space-2);
    opacity: 0.5;
    transition: opacity 0.2s;
}
.bubble-actions:hover { opacity: 1; }
.bubble-action-btn {
    background: none;
    border: none;
    padding: 4px;
    cursor: pointer;
    color: var(--text-muted);
    border-radius: var(--radius-sm);
    font-size: 16px;
    line-height: 1;
    transition: color 0.15s, background 0.15s;
}
.bubble-action-btn:hover {
    color: var(--text);
    background: var(--fill);
}
.bubble-action-btn.is-active { color: var(--accent-text); }

/* Каретка стриминга: мигает, пока модель дописывает ответ. Текст при этом
   дописывается без анимации — анимировать каждое слово значит мешать читать */
.bubble-streaming::after {
    content: "";
    display: inline-block;
    width: 2px; height: 1em;
    margin-left: 2px;
    background: var(--accent-text);
    vertical-align: text-bottom;
    animation: ego-caret 1s steps(2) infinite;
}
@keyframes ego-caret { 50% { opacity: 0; } }

.typing-dots {
    display: inline-flex; gap: 4px; align-items: center;
    min-height: 20px;
}
.typing-dots::before, .typing-dots::after, .typing-dots > i {
    content: "";
    width: 6px; height: 6px; border-radius: 50%;
    background: var(--text-muted);
    animation: ego-typing 1.2s ease-in-out infinite;
}
.typing-dots::after { animation-delay: 0.4s; }
/* Подпись под точками: что ассистент сейчас делает («Рисую картинку · 12 с»).
   Своей строкой под точками — порядок задаёт flex, а не разметка, потому что
   третья точка — псевдоэлемент ::after (оператор 2026-10-20) */
.typing-dots.has-status { flex-wrap: wrap; row-gap: var(--space-1); }
.typing-status {
    order: 10; flex-basis: 100%;
    font-size: var(--text-micro); color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.typing-dots > i { animation-delay: 0.2s; }
/* Пузырь человека, пока распознаётся его речь в live-режиме: точки цвета
   текста пузыря, иначе на градиенте их не видно */
.bubble-user.typing-dots::before,
.bubble-user.typing-dots::after,
.bubble-user.typing-dots > i { background: currentColor; }
@keyframes ego-typing {
    0%, 60%, 100% { opacity: .35; transform: translateY(0); }
    30% { opacity: 1; transform: translateY(-3px); }
}

.bubble-photo {
    display: block;
    max-height: 240px; max-width: 300px;
    border-radius: var(--radius-md);
    object-fit: cover;
    cursor: zoom-in;
}

/* Мозаика фотографий одного сообщения: квадраты, кроме одиночного снимка */
.bubble-mosaic {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-1);
    max-width: 300px;
}
.bubble-mosaic .bubble-photo { width: 100%; aspect-ratio: 1; max-width: none; }
.bubble-mosaic > :only-child { grid-column: span 2; aspect-ratio: auto; }
/* Нечётное число: первый снимок занимает оба столбца — иначе внизу дыра */
.bubble-mosaic > :first-child:nth-last-child(odd) { grid-column: span 2; }

.bubble-audio { width: 100%; max-width: 280px; }
.bubble-time {
    display: block;
    font-size: 10px;
    opacity: 0.45;
    margin-top: 4px;
    text-align: right;
    user-select: none;
    letter-spacing: 0.01em;
}

/* Строка действия: «спрашиваю у сервиса…». Без неё пауза на вызов чужого
   сервиса выглядит зависанием (docs/screens.md §1.3) */
.tool-line {
    display: flex; align-items: center; gap: var(--space-2);
    align-self: flex-start;
    font-size: var(--text-micro); font-weight: 700;
    color: var(--text-muted);
}
.tool-line svg { width: 14px; height: 14px; }

/* Панель ввода */
.composer {
    position: sticky; bottom: 0;
    padding: var(--space-3) var(--page-padding)
             calc(var(--space-3) + env(safe-area-inset-bottom, 0));
    /* Сплошная (2026-10-15): сквозь полупрозрачную полосу проступал текст */
    background: var(--surface);
    border-top: 1px solid var(--border);
}
@supports not (backdrop-filter: blur(2px)) { .composer { background: var(--surface); } }

@media (max-width: 767.98px) {
    .composer { margin-bottom: calc(var(--h-tabbar) + env(safe-area-inset-bottom, 0)); }
}
/* На экране чата (E-10) padding-bottom уже 0, composer не двигаем */

/* Tabbar: на чате composer sticky — padding не нужен */


.composer-row {
    display: flex; align-items: flex-end; gap: var(--space-2);
    width: 100%; max-width: var(--reading); margin: 0 auto;
}

.composer-input {
    flex: 1;
    min-height: var(--h-button); max-height: 140px;
    padding: var(--space-3) var(--space-4);
    background: var(--fill);
    color: var(--text);
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
    font-family: inherit; font-size: var(--text-body); line-height: 1.4;
    resize: none;
    overflow: hidden;
}
.composer-input:focus {
    outline: none;
    background: var(--surface);
    border-color: var(--violet);
    box-shadow: var(--focus-ring);
}

.composer-send {
    display: inline-flex; align-items: center; justify-content: center;
    width: var(--h-button); height: var(--h-button); flex: none;
    background: var(--gradient-brand); color: var(--on-violet);
    border: none; border-radius: var(--radius-md);
    box-shadow: var(--glow-primary);
    cursor: pointer;
}

/* Полоса выбранных фотографий над полем: пока они здесь, сообщение не ушло */
.attach-strip {
    display: flex; gap: var(--space-2);
    max-width: var(--reading); margin: 0 auto var(--space-2);
    overflow-x: auto;
    padding-bottom: var(--space-1);
}
.attach-item {
    position: relative;
    width: 64px; height: 64px; flex: none;
    border-radius: var(--radius-sm);
    overflow: hidden;
    border: 1px solid var(--border);
}
.attach-item img { width: 100%; height: 100%; object-fit: cover; }
/* Крестик поверх угла: палец попадает по нему, не задевая саму карточку */
.attach-remove {
    position: absolute; top: 2px; right: 2px;
    width: 22px; height: 22px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--overlay); color: #FFFFFF;
    border: none; border-radius: 50%;
    cursor: pointer;
}
.attach-remove svg { width: 14px; height: 14px; }

/* Запись голосового: панель встаёт на место строки ввода (2026-10-13).
   Строка прячется классом на панели ввода, а не скриптом по элементам —
   так поле, скрепка и кнопки возвращаются разом */
.composer.is-recording .composer-row,
.composer.is-recording .attach-strip { display: none; }
.composer-recording[hidden] { display: none; }
.composer-recording {
    display: flex; align-items: center; gap: var(--space-2);
    width: 100%; max-width: var(--reading); margin: 0 auto;
    animation: rec-enter var(--motion) var(--ease-emphasized);
}
@keyframes rec-enter { from { opacity: 0; transform: translateY(4px); } }

.rec-cancel { color: var(--text-muted); }
.rec-cancel:hover { color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); }

/* Капсула той же высоты и формы, что поле ввода: глаз видит, что строка
   ввода «превратилась» в запись, а не что появилось что-то новое */
.rec-pill {
    flex: 1; min-width: 0;
    display: flex; align-items: center; gap: var(--space-2);
    min-height: var(--h-button);
    padding: 0 var(--space-4);
    background: var(--fill);
    border-radius: var(--radius-lg);
}
.rec-dot {
    width: 9px; height: 9px; border-radius: 50%; flex: none;
    background: var(--danger);
    animation: ego-pulse 1.2s ease-in-out infinite;
}
.rec-time {
    flex: none; min-width: 34px;
    font-size: var(--text-body); font-variant-numeric: tabular-nums;
    color: var(--text);
}
.rec-hint {
    flex: none;
    font-size: var(--text-small); color: var(--text-muted);
    white-space: nowrap;
}
/* Столбики громкости: новые справа, старые уходят влево — запись «течёт».
   Цвет — градиент бренда, как у кнопки отправки рядом */
.rec-wave {
    flex: 1; min-width: 0; height: 26px;
    display: flex; align-items: center; justify-content: flex-end; gap: 2px;
    overflow: hidden;
}
.rec-wave i {
    flex: none; width: 3px; height: 12%;
    border-radius: var(--radius-pill);
    background: var(--gradient-brand);
    transition: height 80ms linear;
}
/* На узком экране подсказка уступает место столбикам */
@media (max-width: 420px) { .rec-hint { display: none; } }

@keyframes ego-pulse { 50% { opacity: .3; transform: scale(.8); } }

/* Живой разговор (2026-10-28): полоса на месте строки ввода, как запись.
   Волна во всю ширину — столбики в такт голосу (voice.js, scaleY); акцент
   один: сигнал в тёмной теме, чернила в светлой (на бумаге у лайма нет
   контраста, Р-132). «Завершить» — явная кнопка с подписью, инверсией темы */
.composer.is-live .composer-row,
.composer.is-live .attach-strip,
.composer.is-live .composer-recording { display: none; }
.composer-live[hidden] { display: none; }
.composer-live {
    --live-accent: var(--text);
    display: flex; align-items: center; gap: var(--space-2);
    width: 100%; max-width: var(--reading); margin: 0 auto;
    animation: rec-enter var(--motion) var(--ease-emphasized);
}
:root[data-theme="dark"] .composer-live { --live-accent: var(--lime); }
@media (prefers-color-scheme: dark) { :root[data-theme="auto"] .composer-live { --live-accent: var(--lime); } }
.live-pill {
    flex: 1; min-width: 0;
    display: flex; align-items: center; gap: var(--space-3);
    min-height: var(--h-button);
    padding: 0 var(--space-4);
    background: var(--fill);
    border-radius: var(--radius-lg);
}
.live-dot {
    width: 10px; height: 10px; border-radius: 50%; flex: none;
    background: var(--live-accent);
    animation: ego-pulse 1.6s ease-in-out infinite;
}
.live-status {
    flex: none; min-width: 92px;
    font-size: var(--text-small); font-weight: 600; color: var(--text);
    white-space: nowrap;
}
.live-wave {
    flex: 1; min-width: 0; height: 28px;
    display: flex; align-items: center; justify-content: space-between; gap: 2px;
    overflow: hidden;
}
@media (min-width: 768px) { .live-wave i { width: 4px; } }
.live-wave i {
    flex: 0 0 auto; width: 3px; height: 100%;
    border-radius: var(--radius-pill);
    background: var(--live-accent);
    transform: scaleY(.15); transform-origin: center;
    transition: transform 90ms linear;
}
/* Пока соединяемся или ассистент думает, волна приглушена — «живая» она,
   когда звучит голос человека или ответ */
.composer-live[data-state="connecting"] .live-wave i,
.composer-live[data-state="thinking"] .live-wave i { opacity: .35; }
.composer-live[data-state="listening"] .live-wave i { opacity: .7; }
.live-stop {
    flex: none;
    display: inline-flex; align-items: center; gap: var(--space-2);
    min-height: var(--h-button);
    padding: 0 var(--space-4);
    background: var(--text); color: var(--bg);
    border: none; border-radius: var(--radius-lg);
    font: inherit; font-size: var(--text-small); font-weight: 600;
    cursor: pointer;
    transition: opacity var(--motion-fast) var(--ease-out), transform var(--motion-fast) var(--ease-out);
}
.live-stop:hover { opacity: .88; }
.live-stop:active { transform: scale(.97); }
.live-stop:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.live-stop svg { width: 18px; height: 18px; flex: none; fill: currentColor; }
/* На узком экране подпись состояния уступает место волне; «Завершить»
   остаётся словом — кнопка должна читаться без догадок */
@media (max-width: 479.98px) {
    .live-status { display: none; }
    .live-pill { gap: var(--space-2); padding: 0 var(--space-3); }
    .live-wave { gap: 3px; }
    .live-wave i:nth-child(2n) { display: none; }
    .live-wave i { max-width: 3px; }
}
@media (prefers-reduced-motion: reduce) { .live-dot { animation: none; } }


/* ═══ 8. Live-режим (E-11) и просмотр фото (E-12) ═════════════════════════ */

/* Ссылки из описания задачи — кнопками под текстом (tasks.js) */
/* Строки описания (место, время) — каждая своей строкой, как записаны */
#card-description { white-space: pre-line; }
.task-links { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0 0 var(--space-3); }
.task-links[hidden] { display: none; }
.task-link { text-decoration: none; }

/* Действия на карточке модуля в чате (Р-118): «Пойду», «Напомнить»,
   «Маршрут» — ровный ряд из трёх кнопок одной ширины, под ним «Подробнее»
   ссылкой. Включённое состояние («Иду ✓», «За 1 час») — заливка акцентом */
.card-actions {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
    gap: var(--space-2);
    margin: var(--space-2) 0 var(--space-2);
}
.card-act {
    /* Иконка над подписью: три кнопки умещаются целиком даже в карточке
       шириной 260 px, «Напомнить» не режется до «Напо…» */
    display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; min-width: 0;
    min-height: 50px; padding: 6px 4px;
    /* Нейтральная кнопка: залитый акцент на экране один (Р-128), а у карточек
       в ленте их десятки */
    background: var(--fill); color: var(--text);
    border: 1px solid transparent; border-radius: var(--radius-md);
    font: inherit; font-size: 13px; font-weight: 600; line-height: 1.1;
    cursor: pointer;
    transition: background var(--motion-fast) var(--ease-out),
                color var(--motion-fast) var(--ease-out);
}
.card-act svg { flex: none; }
.card-act span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-act:hover { background: var(--fill-strong); }
.card-act.is-on { background: var(--gradient-brand); color: var(--on-violet); }
.card-act.is-busy { opacity: .6; cursor: progress; }
/* Напоминание стоит — свой, «уведомительный» цвет (янтарь палитры), а не
   тот же, что у «Иду»: по кнопке сразу видно, что колокольчик включён и за
   сколько он прозвенит («За 1 час»). При включении колокольчик раз качнётся */
.card-act[data-act="remind"].is-on {
    background: color-mix(in srgb, var(--amber) 22%, transparent);
    color: var(--amber-text);
    border-color: color-mix(in srgb, var(--amber) 55%, transparent);
}
.card-act[data-act="remind"].is-on svg { animation: bell-ring 700ms var(--ease-out) 1; transform-origin: 50% 10%; }
@keyframes bell-ring {
    20% { transform: rotate(14deg); } 40% { transform: rotate(-12deg); }
    60% { transform: rotate(8deg); } 80% { transform: rotate(-4deg); }
}
.card-remind {
    display: flex; flex-wrap: wrap; gap: 6px;
    margin-bottom: var(--space-2);
}
.card-remind .chip { font-size: 13px; padding: 6px 12px; min-height: 0; }
.card-remind[hidden] { display: none; }
/* «Когда пойдёте?» у карточки места без даты: подпись, готовые варианты и
   «Другое время» — поле даты и времени с кнопкой «Готово» */
.card-when { flex-direction: column; flex-wrap: nowrap; }
.card-when__title { margin: 0; font-size: 13px; font-weight: 600; color: var(--text-muted); }
.card-when__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.card-when__custom { display: flex; gap: 6px; align-items: center; }
.card-when__custom[hidden] { display: none; }
.card-when__custom .field { flex: 1; min-width: 0; min-height: 36px; padding: 6px 10px; font-size: 14px; }
/* Сервису нужно разрешение (кнопка «Разрешить» в чате): спокойная врезка
   внутри ответа ассистента; после нажатия кнопка гаснет и пишет «Разрешено» */
.chat-consent {
    margin-top: var(--space-2); padding: 10px 12px;
    background: var(--fill); border-radius: var(--radius-md);
}
.chat-consent__text { margin: 0 0 8px; font-size: 14px; line-height: 20px; }
.chat-consent__row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.chat-consent__hint { font-size: 12px; color: var(--text-muted); }
.chat-consent.is-done .btn-ego { opacity: .7; cursor: default; }
/* Главное действие сервиса на карточке в чате («Откликнуться») */
.card-cta { display: flex; width: 100%; justify-content: center; margin: var(--space-2) 0; text-decoration: none; }
.card-more {
    display: inline-block;
    color: var(--violet-text); font-size: 13px; font-weight: 600;
    text-decoration: none;
}
.card-more::after { content: " →"; }
.card-more:hover { text-decoration: underline; }

/* Live-режим живёт в самой кнопке с волной (решение оператора 2026-10-13):
   отдельного экрана и отдельной волны нет. Пока идёт разговор, шесть
   столбиков иконки двигаются в такт голосу (высоту задаёт voice.js через
   scaleY), а цвет переливается по спектру бренда. Повторное нажатие —
   «Завершить». */
.live-btn svg path {
    transform-box: fill-box;
    transform-origin: center;
    transition: transform 90ms linear;
}
.live-btn.is-live {
    background: var(--violet-soft);
    color: var(--violet);
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--violet) 40%, transparent);
}
.live-btn.is-live svg { stroke-width: 2.4; }
/* Перелива по спектру больше нет (брендбук 2026-10, Р-128: один акцент).
   Кнопка горит цветом действия, а «живость» передают сами столбики,
   которые двигаются в такт голосу */
/* Подключаемся — мягкая пульсация; ассистент говорит — ореол ярче */
.live-btn.is-live[data-state="connecting"] { animation: live-ring 1.4s ease-out infinite; }
.live-btn.is-live[data-state="speaking"],
.live-btn.is-live[data-state="capturing"] {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--violet) 35%, transparent);
}
@keyframes live-ring {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--violet) 45%, transparent); }
    100% { box-shadow: 0 0 0 10px transparent; }
}
/* Микрофон занят живым разговором — голосовое сообщение в это время не пишется */
#mic:disabled { opacity: .35; cursor: default; }

.photo-viewer {
    position: fixed; inset: 0; z-index: 70;
    display: flex; align-items: center; justify-content: center;
    background: var(--overlay);
    backdrop-filter: blur(8px);
}
.photo-viewer[hidden] { display: none; }
.photo-viewer img { max-width: 92vw; max-height: 86vh; border-radius: var(--radius-md); }
.photo-close {
    position: absolute; top: var(--space-4); right: var(--space-4);
    background: var(--surface);
}


/* ═══ 9. Задачи и календарь (E-20…E-23) ═══════════════════════════════════ */

@media (min-width: 1200px) {
    /* На ПК календарь и список стоят рядом: месяц целиком виден постоянно,
       и переключаться между «когда» и «что» не нужно (docs/design.md §4.1) */
    .tasks-layout {
        display: grid;
        grid-template-columns: 320px minmax(0, 1fr);
        gap: var(--space-6);
        align-items: start;
    }
    .tasks-layout > .calendar { position: sticky; top: calc(var(--h-topbar) + var(--space-4)); }
    /* Список задач в правой колонке начинается с фильтров, а не с отступа */
    .tasks-list-side > :first-child { margin-top: 0 !important; }
}

/* Переключатель вида календаря «Месяц / Список» (docs/design.md §9.9): дорожка
   на `fill`, выбранный — плашка `surface` с границей. На телефоне во всю
   ширину, на ПК — компактно слева */
.view-switch {
    display: flex; gap: 2px;
    padding: 3px; margin-bottom: var(--space-3);
    background: var(--fill); border-radius: var(--radius-pill);
}
.view-switch > button {
    flex: 1 1 0; height: var(--h-button-sm);
    border: 1px solid transparent; border-radius: var(--radius-pill);
    background: transparent; color: var(--text-secondary);
    font: inherit; font-size: var(--text-small); font-weight: 700;
    cursor: pointer;
}
.view-switch > button[aria-selected="true"] {
    background: var(--surface); color: var(--text); border-color: var(--border);
}
@media (min-width: 768px) {
    .view-switch { max-width: 320px; }
}
/* «Список»: сетки месяца и заголовка дня нет, лента во всю ширину */
.tasks-layout.is-list > .calendar,
.tasks-layout.is-list #day-title { display: none; }
@media (min-width: 1200px) {
    .tasks-layout.is-list { grid-template-columns: minmax(0, 1fr); max-width: 760px; }
}
/* «День» (дизайн «Панель дня», 2026-10-29): сетки месяца и заголовка дня
   нет, вместо списка — неделя и шкала часов во всю ширину */
.tasks-layout.is-day > .calendar,
.tasks-layout.is-day #day-title,
.tasks-layout.is-day #task-list { display: none; }
@media (min-width: 1200px) {
    .tasks-layout.is-day { grid-template-columns: minmax(0, 1fr); max-width: 760px; }
}
.day-view[hidden] { display: none; }
.day-head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); }
.day-head-title {
    flex: 1; margin: 0; font-family: var(--font-display);
    font-size: 20px; line-height: 26px; font-weight: 600;
}
.day-today {
    height: 32px; padding: 0 var(--space-3);
    border: 1px solid var(--border); border-radius: var(--radius-pill);
    background: var(--surface); color: var(--text);
    font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
}
.day-today[hidden] { display: none; }
.day-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; margin-bottom: var(--space-4); }
.day-week-cell {
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    padding: var(--space-2) 0; border: 0; border-radius: 14px;
    background: transparent; color: var(--text-muted);
    font: inherit; font-size: 12px; cursor: pointer;
}
.day-week-cell b { font-size: 17px; color: var(--text); font-variant-numeric: tabular-nums; }
.day-week-cell:hover { background: var(--fill); }
.day-week-cell.is-today b { text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 2px; }
.day-week-cell.is-selected { background: var(--text); color: var(--bg); }
.day-week-cell.is-selected b { color: var(--bg); }
[data-bs-theme="light"] .day-week-cell.is-selected { background: var(--lime); color: var(--on-bright); }
[data-bs-theme="light"] .day-week-cell.is-selected b { color: var(--on-bright); }
.day-allday:empty { display: none; }
.day-allday { margin-bottom: var(--space-4); }
.day-allday-title {
    margin: 0 0 var(--space-2); font-size: var(--text-micro); font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted);
}
.day-line { position: relative; margin-bottom: var(--space-6); }
.day-hour {
    position: absolute; left: 0; right: 0; height: 0;
    border-top: 1px solid var(--border);
}
.day-hour span {
    position: absolute; left: 0; top: -9px; padding-right: 6px;
    background: var(--bg); font-size: 12px; color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.day-event {
    position: absolute; left: 52px; right: 0; height: 48px;
    display: flex; align-items: center; gap: var(--space-3);
    padding: 0 var(--space-3);
    border-radius: 14px; background: var(--surface-raised); border: 1px solid var(--border);
    cursor: pointer; z-index: 1;
    transition: border-color var(--motion-fast) var(--ease-out);
}
.day-event:hover { border-color: var(--text-muted); }
.day-event .task-check { margin-top: 0; }
.day-event-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.day-event-body b, .day-event-body span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.day-event-body b { font-size: 14px; line-height: 18px; }
.day-event-body span { font-size: 12px; line-height: 16px; color: var(--text-muted); }
.day-event.is-done b { text-decoration: line-through; color: var(--text-muted); }
.day-now { position: absolute; left: 44px; right: 0; height: 2px; background: var(--danger); z-index: 2; pointer-events: none; }
.day-now::before {
    content: ""; position: absolute; left: -5px; top: -4px;
    width: 10px; height: 10px; border-radius: 50%; background: var(--danger);
}

/* Фильтр по статусу в календаре — одной строкой и мельче обычных чипов: это
   уточнение списка, а не главное действие экрана (оператор 2026-10-20). Не
   влезло — ряд листается вбок, а не переносится */
.chip-row-compact {
    display: flex; flex-wrap: nowrap; gap: var(--space-1);
    overflow-x: auto; scrollbar-width: none;
}
.chip-row-compact::-webkit-scrollbar { display: none; }
.chip-row-compact .chip {
    flex: none; height: 30px; padding: 0 var(--space-3);
    font-size: var(--text-micro);
}
/* Просроченное: строка в «Месяце» и кнопка в заголовке группы «Списка» */
.overdue-bar {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--border); border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--danger-text); font-size: var(--text-small); font-weight: 700;
}
.overdue-bar[hidden] { display: none; }
.overdue-bar__action, .agenda-action {
    border: none; background: transparent; padding: var(--space-1) 0;
    color: var(--danger-text); font: inherit; font-size: var(--text-small); font-weight: 700;
    text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.agenda-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); margin: var(--space-4) 0 var(--space-2); }
.agenda-head .agenda-day { margin: 0; }
#task-list > .agenda-head:first-child { margin-top: 0; }
.agenda-day { margin: var(--space-4) 0 0; font-size: var(--text-body); font-weight: 700; }
#task-list > .agenda-day:first-child { margin-top: 0; }
.agenda-day--overdue { color: var(--danger-text); }
/* Просроченное (2026-11-02): красная рамка, «Просрочено на N дней · срок»
   и «На сегодня» — видно, что именно и насколько, без открытия карточки */
.agenda-hint { margin: 0 0 var(--space-2); }
.task-row--overdue { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
.task-overdue-meta { color: var(--danger-text); font-weight: 600; }
.task-today {
    margin-top: var(--space-2); height: 32px; padding: 0 var(--space-3);
    border: 1px solid var(--border); border-radius: 999px; background: var(--surface-raised);
    color: var(--text); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
}
.overdue-bar__text { border: 0; background: transparent; padding: 0; color: inherit; font: inherit; text-align: left; cursor: pointer; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Список задач: карточки одна под другой, промежуток из шкалы */
#task-list { display: grid; gap: var(--space-3); }

.calendar {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
}

.calendar-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}

.calendar-weekdays, .calendar-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 2px;
}
.calendar-weekdays {
    margin-bottom: var(--space-1);
    font-size: var(--text-micro); font-weight: 700;
    color: var(--text-muted); text-align: center;
    text-transform: uppercase; letter-spacing: 0.06em;
}

.calendar-day {
    position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px;
    min-height: 44px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text);
    font-family: inherit; font-size: var(--text-small); font-weight: 700;
    cursor: pointer;
    font-variant-numeric: tabular-nums;
}
.calendar-day:hover { background: var(--fill); }
.calendar-day.is-muted { color: var(--text-muted); font-weight: 400; }
.calendar-day.is-today { border-color: var(--accent); }
.calendar-day.is-selected { background: var(--accent); color: var(--on-violet); }
.calendar-day.is-selected .dot { box-shadow: 0 0 0 1px var(--accent); }

.calendar-dots { display: flex; gap: 3px; height: 6px; }
.calendar-dots .dot { width: 5px; height: 5px; }

.task-row {
    display: flex; align-items: flex-start; gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}
.task-row.is-urgent { border-left: 3px solid var(--danger); }
.task-row.is-done .task-title { color: var(--text-muted); text-decoration: line-through; }

.task-check {
    width: var(--size-checkbox); height: var(--size-checkbox);
    flex: none; margin-top: 2px;
    border: 2px solid var(--border-strong);
    border-radius: var(--radius-xs);
    background: transparent;
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    color: transparent;
}
.task-check[aria-checked="true"],
.task-check.is-done {
    background: var(--success); border-color: var(--success); color: var(--ink);
}
.task-check svg { width: 14px; height: 14px; }
/* Галочка рисуется рамкой: tasks.js ставит класс is-done, иконку не вставляет */
.task-check { position: relative; }
.task-check.is-done::after {
    content: ""; width: 6px; height: 11px; margin-top: -2px;
    border: solid var(--ink); border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
/* Квадрат 22 px мал для пальца: зона нажатия расширена до 42 px без
   изменения вида (docs/design.md — минимальная цель касания) */
.task-check::before { content: ""; position: absolute; inset: -10px; }
.task-title-done { color: var(--text-muted); text-decoration: line-through; }

.step-row {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--border);
}
.step-row:last-child { border-bottom: none; }


/* ═══ 10. Модули (E-30…E-35) ══════════════════════════════════════════════ */

/* Каталог сервисов. `auto-fill` вместо фиксированного числа колонок —
   промежуточные ширины не требуют своего медиазапроса (docs/design.md §3.4) */
.module-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-3);
}

@media (min-width: 600px) {
    .module-grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
}

/* Строка поиска над каталогом. Появляется всегда, а не «когда модулей много»:
   поле, которое то есть, то нет, человек не запоминает и искать им не начинает */
.mod-search {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 0 var(--space-3);
    margin-bottom: var(--space-3);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--text-muted);
}

.mod-search:focus-within { border-color: var(--accent); box-shadow: var(--focus-ring); }

/* Фокус рисует только полоса: общее правило `.field:focus` давало полю свою
   рамку и кольцо, и в фокусе получалось поле внутри поля */
.mod-search__input:focus,
.mod-search__input:focus-visible { border: none; box-shadow: none; outline: none; }

.mod-search__input {
    flex: 1;
    min-width: 0;
    /* Рамку и фон рисует полоса вокруг, а не само поле: иначе получается
       рамка в рамке. Класс `.field` при этом остаётся — он задаёт размер
       текста и высоту, общие у всех полей ввода */
    border: none;
    background: none;
    box-shadow: none;
    color: var(--text);
    font-size: var(--text-body);
    padding: var(--space-3) 0;
    outline: none;
}

/* Ячейка каталога: карточка-ссылка и звёздочка рядом с ней. Кнопка внутри
   ссылки — недопустимая разметка, поэтому они соседи, а не вложены */
.module-cell { position: relative; display: flex; }
.module-cell > .module-card { flex: 1; min-width: 0; }

.module-star {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text-muted);
    cursor: pointer;
    transition: color var(--motion-fast) var(--ease-out),
                background var(--motion-fast) var(--ease-out);
}

.module-star:hover { background: var(--surface-2, var(--surface)); color: var(--text); }
.module-star.is-on { color: var(--amber); }
.module-star:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.module-star .mod-icon { width: 18px; height: 18px; }

/* Название не должно заезжать под звёздочку: она стоит поверх карточки */
.module-cell .module-card__head { padding-right: 30px; }

/* Полоса разделов над каталогом. Разделы приходят из манифестов, а не зашиты:
   партнёр выбирает свой из закрытого списка (docs/modules-ui.md §3.6) */
.module-filters {
    display: flex;
    gap: var(--space-2);
    overflow-x: auto;
    padding-bottom: var(--space-2);
    margin-bottom: var(--space-4);
    scrollbar-width: none;
}

.module-filters::-webkit-scrollbar { display: none; }
.module-filters .chip { flex: none; }

/* Карточка сервиса: знак, название, что умеет, состояние. Цвет знака мы
   выбираем сами по коду модуля — партнёр цветов не задаёт (CLAUDE.md §11) */
.module-card {
    position: relative;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto auto;
    gap: var(--space-1) var(--space-3);
    padding: var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    color: inherit;
    text-decoration: none;
    overflow: hidden;
    transition: transform var(--motion-fast) var(--ease-out),
                border-color var(--motion-fast) var(--ease-out),
                box-shadow var(--motion-fast) var(--ease-out);
}

/* Цветная полоса сверху снята вместе с цветами сервисов (брендбук: один
   акцент на экране, Р-128) */

.module-card:hover {
    text-decoration: none;
    transform: translateY(-2px);
    border-color: var(--border-strong);
    box-shadow: var(--shadow-1);
}

.module-card:focus-visible { outline: none; box-shadow: var(--focus-ring); }

.module-card__head { grid-column: 2; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.module-card__title { font-size: var(--text-body-lg); font-weight: 700; letter-spacing: var(--tracking-heading); }
.module-card__summary {
    font-size: var(--text-small);
    color: var(--text-secondary);
    line-height: var(--lh-small);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.module-card__foot {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
    font-size: var(--text-micro);
    color: var(--text-muted);
}

.module-card__state { display: inline-flex; align-items: center; gap: var(--space-2); }

/* Плашка иконки сервиса — восьмиугольник, как кольцо знака EGO
   (2026-10-15): плитки каталога узнаются как «наши», даже когда сервисы
   чужие. Рамки нет — срез по clip-path обрезал бы её на углах */
.module-logo {
    width: 44px; height: 44px; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    /* Плашка «наоборот» — цвет текста, иконка цветом фона: как иконка
       приложения (знак бумагой на чернилах). Сигнал сюда не идёт — залитый
       акцент на экране один (design-colors.md §1) */
    background: var(--text);
    color: var(--bg);
    clip-path: polygon(26% 0, 74% 0, 100% 26%, 100% 74%, 74% 100%, 26% 100%, 0 74%, 0 26%);
    object-fit: cover;
}

.module-logo .mod-icon { width: 24px; height: 24px; }

/* Недоступный по плану модуль гасим, но оставляем читаемым: исчезновение
   читается как потеря данных (docs/screens.md §1.5) */
.module-card.is-locked { opacity: .6; }

/* ─── Полоса управления модулем (E-31) ───────────────────────────────────── */

.mod-bar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-3);
}

.mod-bar__text { flex: 1 1 auto; min-width: 0; }
.mod-bar__name {
    font-size: var(--text-body-lg);
    font-weight: 700;
    letter-spacing: var(--tracking-heading);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.mod-bar__state {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-micro);
    color: var(--text-muted);
}
.mod-bar__tools { display: flex; align-items: center; gap: var(--space-1); flex: none; }
/* Шапка окна сервиса (2026-10-21): кнопки в самой шапке, состояние — точкой
   у названия. Раньше под шапкой стояла ещё полоса «работает» с кнопками —
   вместе они съедали четверть экрана телефона (оператор). На телефоне полосы
   нет совсем: название уже в шапке. Цели нажатия остаются 44×44 */
.mod-topbar { gap: var(--space-2); }
.mod-topbar h1.t-screen-title { flex: 0 1 auto; }
.mod-topbar__dot { flex: none; }
.mod-topbar__tools { display: flex; align-items: center; gap: 0; flex: none; margin-left: auto; }
@media (max-width: 479.98px) {
    .mod-bar { display: none; }
    .mod-topbar__ask { display: none; }
}
@media (min-width: 480px) {
    .mod-topbar__dot { display: none; }
}

/* Свёрнутая панель: права и умения. Развёрнутой она бывает редко, поэтому
   стоит под полосой, а не занимает место постоянно */
.mod-panel {
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
    margin-bottom: var(--space-3);
    display: grid;
    gap: var(--space-4);
}

.mod-panel__title {
    font-size: var(--text-micro);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: var(--tracking-label);
    color: var(--text-muted);
    margin: 0 0 var(--space-2);
}

.mod-panel__hint { font-size: var(--text-small); color: var(--text-secondary); margin: 0 0 var(--space-3); }

.mod-panel__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--border);
}
.mod-panel__row:last-child { border-bottom: none; }
.mod-panel__label { font-size: var(--text-small); color: var(--text); }

/* Строка памяти модуля: подпись с объяснением слева, значение справа. На узком
   экране длинный токен рядом с объяснением не помещается — поэтому колонкой */
.mod-panel__row--stack { align-items: flex-start; flex-wrap: wrap; }
.mod-panel__row--stack .mod-panel__label { display: flex; flex-direction: column; gap: 2px; }
.mod-panel__note { font-size: var(--text-micro); color: var(--text-muted); }

/* Звёздочка в полосе управления модулем: тот же смысл, что в каталоге */
#module-star.is-on { color: var(--amber); }

.mod-panel__list { margin: 0; padding-left: var(--space-5); font-size: var(--text-small); color: var(--text-secondary); }

/* Переключатель права: текст на кнопке, а не безымянный тумблер — человек
   должен читать, что именно он разрешает (docs/security.md §6) */
.mod-switch {
    flex: none;
    height: var(--h-button-sm);
    padding: 0 var(--space-3);
    border-radius: var(--radius-pill);
    border: 1px solid var(--border-strong);
    background: var(--surface);
    color: var(--text-secondary);
    font-family: inherit;
    font-size: var(--text-micro);
    cursor: pointer;
}

.mod-switch.is-on { background: var(--success-soft); border-color: transparent; color: var(--success-text); font-weight: 600; }
.mod-switch:focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* Одна строка «нужно разрешение» вместо панели на пол-экрана */
.mod-ask {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
    padding: var(--space-3);
    border-radius: var(--radius-md);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: var(--text-small);
    margin-bottom: var(--space-3);
}

.mod-ask__text { flex: 1 1 220px; }

.btn-ego-sm { height: var(--h-button-sm); padding: 0 var(--space-4); font-size: var(--text-micro); }

/* Ответ партнёра — в помеченном блоке: человек всегда видит, где кончаемся
   мы и начинается чужой сервис (docs/design.md §9.10) */
.partner-block {
    padding: var(--space-4);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    background: var(--fill);
}


/* ═══ 11. Профиль (E-40…E-50) ═════════════════════════════════════════════ */

/* Карточка человека: аватар, под ним имя и город. Имя сбоку от аватара в
   узкой колонке ломалось на две строки и распирало карточку */
.profile-head {
    display: flex; flex-direction: column; align-items: center;
    gap: var(--space-2);
    text-align: center;
    margin-bottom: var(--space-4);
    padding: var(--space-2) var(--space-5) var(--space-4);
}
.profile-head .avatar { margin-bottom: var(--space-2); }
.profile-head > .t-screen-title { overflow-wrap: anywhere; }

@media (min-width: 992px) {
    .profile-layout {
        display: grid;
        grid-template-columns: 300px minmax(0, 1fr);
        gap: var(--space-6);
        align-items: start;
    }
    /* Карточка человека и подписка остаются на виду, пока листаются разделы */
    .profile-aside { position: sticky; top: calc(var(--h-topbar) + var(--space-4)); }
}

/* Аватар — контейнер, а не картинка: пока фотографии нет, в нём стоит буква
   имени, и подменять один элемент другим ради этого незачем */
.avatar {
    position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    width: var(--avatar-profile); height: var(--avatar-profile);
    flex: none;
    border-radius: 50%;
    background: var(--accent-soft);
    border: 1px solid var(--border);
    color: var(--accent-text);
    font-size: var(--text-h2); font-weight: 800;
    text-transform: uppercase;
}
/* Круг режет сама картинка, а не контейнер: `overflow: hidden` на контейнере
   срезал бы значок «сменить фото», который висит на его краю */
.avatar img {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    border-radius: 50%;
}
.avatar-sm { width: var(--avatar-chat); height: var(--avatar-chat); font-size: var(--text-small); }

.avatar-editable { cursor: pointer; }

/* Значок «сменить фото». Иконка приходит разметкой, а не псевдоэлементом:
   набор один — Lucide, и рисовать камеру фоном значило бы завести второй */
.avatar-badge {
    position: absolute; right: -2px; bottom: -2px;
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border-radius: 50%;
    background: var(--gradient-brand);
    color: var(--on-violet);
    border: 2px solid var(--bg);
    box-shadow: var(--glow-primary);
}

/* Автодополнение города: список поверх формы */
.city-picker { position: relative; }
.city-suggest {
    position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 40;
    max-height: 260px; overflow-y: auto;
    background: var(--surface-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-2);
}
.city-option {
    display: block; width: 100%;
    padding: var(--space-3) var(--space-4);
    background: transparent; border: none; text-align: left;
    color: var(--text); font-family: inherit; font-size: var(--text-small);
    cursor: pointer;
}
.city-option:hover { background: var(--fill); }

/* Выбор места на карте (E-41).

   Окно, а не полноэкранный слой: на ПК карта во весь монитор выглядит как
   отдельное приложение, а вернуться в форму хочется одним взглядом. Ширина —
   та же колонка, что у всего контента. На телефоне окно занимает экран
   целиком: там иначе не бывает. */
.map-pick {
    position: fixed; inset: 0; z-index: 60;
    display: flex; align-items: center; justify-content: center;
    padding: 0;
    background: var(--overlay);
    backdrop-filter: blur(2px);
}

.map-pick-dialog {
    position: relative;
    display: flex; flex-direction: column;
    width: 100%; height: 100%;
    background: var(--surface);
    overflow: hidden;
}

@media (min-width: 768px) {
    .map-pick { padding: var(--space-6); }
    .map-pick-dialog {
        width: min(var(--reading), 100%);
        height: min(640px, 100%);
        border: 1px solid var(--border);
        border-radius: var(--radius-xl);
        box-shadow: var(--shadow-2);
    }
}

/* Карта занимает всё окно, кроме нижней панели: раньше между ними оставалась
   белая полоса — контейнер карты не тянулся, а `min-height` держал высоту */
.map-pick-map { flex: 1; min-height: 0; width: 100%; }
.map-pick-map .maplibregl-map { height: 100%; }

.map-pick-foot {
    display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
    padding: var(--space-4);
    padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0));
    border-top: 1px solid var(--border);
    background: var(--surface);
}
.map-pick-hint { flex: 1; min-width: 160px; font-size: var(--text-small); color: var(--text-secondary); }
/* Кнопка подтверждения не на всю ширину: рядом с подсказкой она читается как
   действие, а не как дно экрана */
.map-pick-foot .btn-ego { flex: none; width: auto; }

/* Кнопки поверх карты: круглые, на подложке — иначе иконка теряется на тайлах */
.map-pick-btn {
    position: absolute; z-index: 2;
    width: var(--h-button); height: var(--h-button);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-1);
}
.map-pick-btn:hover { background: var(--fill); }
.map-pick-close { top: var(--space-3); right: var(--space-3); }
.map-pick-locate { top: var(--space-3); left: var(--space-3); }
/* Пульсирующая точка: видно, что место выбрано именно здесь */
.pick-dot {
    width: 18px; height: 18px; border-radius: 50%;
    background: var(--violet);
    box-shadow: 0 0 0 6px color-mix(in srgb, var(--violet) 25%, transparent);
}


/* ═══ 12. Публичные страницы и гайд ═══════════════════════════════════════ */

.doc-notice {
    padding: var(--space-4);
    background: var(--warning-soft);
    border: 1px solid color-mix(in srgb, var(--warning) 40%, transparent);
    border-radius: var(--radius-lg);
    font-size: var(--text-small);
}

.doc-body { max-width: var(--measure); }
.doc-body h2 { margin: var(--space-8) 0 var(--space-3); }
.doc-body p { margin-bottom: var(--space-3); color: var(--text-secondary); }

/* Вопрос-ответ: стрелка складывается вместе с ответом */
details.faq-item {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
}
details.faq-item + details.faq-item { margin-top: var(--space-3); }
details.faq-item summary {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-3);
    font-weight: 700; cursor: pointer; list-style: none;
}
details.faq-item summary::-webkit-details-marker { display: none; }
details.faq-item summary::after {
    content: "";
    width: 10px; height: 10px; flex: none;
    border-right: 2px solid var(--text-muted);
    border-bottom: 2px solid var(--text-muted);
    transform: rotate(45deg);
    transition: transform var(--motion-fast) var(--ease-out);
}
details.faq-item[open] summary::after { transform: rotate(-135deg); }

.guide-slide { text-align: center; max-width: var(--form); margin: 0 auto; }
.guide-glyph {
    display: inline-flex; align-items: center; justify-content: center;
    width: 96px; height: 96px;
    border-radius: var(--radius-2xl);
    background: var(--accent-soft);
    color: var(--accent-text);
    margin-bottom: var(--space-6);
}
.guide-glyph svg { width: 44px; height: 44px; }
.guide-dots { display: flex; gap: var(--space-2); justify-content: center; }
.guide-dot {
    width: 8px; height: 8px; border-radius: var(--radius-pill);
    background: var(--fill-strong);
    transition: width var(--motion) var(--ease-out), background var(--motion) var(--ease-out);
}
/* Текущий слайд — не другой цвет, а другая длина: точки остаются точками */
.guide-dot.is-current { width: 24px; background: var(--accent); }


/* ═══ 13. Экраны входа (E-02, E-05…E-08, E-57) ════════════════════════════ */

.screen--auth {
    display: flex; flex-direction: column; justify-content: center;
    min-height: 100dvh;
    max-width: none;
    padding: var(--space-6) var(--page-padding);
}

.auth-card {
    width: 100%;
    max-width: var(--auth-card);
    margin: 0 auto;
    padding: var(--space-6);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-1);
}
/* Регистрация шире: поля стоят в две колонки, и в 420 они не помещаются */
.auth-card--wide { max-width: 560px; }

.auth-title {
    margin-bottom: var(--space-2);
    font-size: var(--text-h2); line-height: var(--lh-h2);
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: var(--tracking-heading);
}
.auth-sub { margin-bottom: var(--space-6); color: var(--text-secondary); font-size: var(--text-small); }

.auth-field { margin-bottom: var(--space-4); }
.auth-field-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-2);
}

/* Две колонки: имя и фамилия, дата и пол. На телефоне — одна */
.auth-two { display: grid; gap: var(--space-3); }
@media (min-width: 480px) { .auth-two { grid-template-columns: 1fr 1fr; } }

.auth-alert {
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-4);
    background: var(--danger-soft);
    border: 1px solid color-mix(in srgb, var(--danger) 40%, transparent);
    border-radius: var(--radius-md);
    font-size: var(--text-small);
    color: var(--danger-text);
}
.auth-alert--ok {
    background: var(--success-soft);
    border-color: color-mix(in srgb, var(--success) 40%, transparent);
    color: var(--success-text);
}

.auth-links {
    display: flex; flex-wrap: wrap; gap: var(--space-3);
    justify-content: center;
    margin-top: var(--space-5);
    font-size: var(--text-small);
}

.auth-consent { display: flex; gap: var(--space-3); font-size: var(--text-small); }
/* Квадратик не сжимается рядом с длинной подписью: иначе в столбике отметок
   они выходили разного размера */
.auth-consent input[type="checkbox"] { flex: none; width: 18px; height: 18px; margin-top: 2px; }

/* Капча: картинка над полем, а не сбоку — узкая колонка сжимает её до
   нечитаемости (docs/design.md §9.2) */
.captcha { margin-bottom: var(--space-4); }
.captcha-frame {
    display: flex; align-items: center; gap: var(--space-2);
    margin-bottom: var(--space-2);
}
/* Картинку рисует сервер на светлом фоне, тёмного варианта у ручки нет: в
   тёмной теме она показывается на светлом острове, иначе читается как
   непрогруженный элемент (docs/design-themes.md §5.5, долг Д-125) */
.captcha-frame img {
    flex: 1;
    max-width: 260px;
    border-radius: var(--radius-sm);
    background: #FFFFFF;
    padding: var(--space-1);
    border: 1px solid var(--border);
}
.captcha-loading { opacity: .4; }


/* ═══ 14. Слои: шторка, тосты, скелетоны, пустые состояния ════════════════ */

.sheet-backdrop {
    position: fixed; inset: 0; z-index: 50;
    background: var(--overlay);
    backdrop-filter: blur(2px);
}
.sheet-backdrop[hidden], .sheet[hidden] { display: none; }

.sheet {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 51;
    max-height: 90dvh; overflow-y: auto;
    padding: var(--space-3) var(--page-padding)
             calc(var(--space-6) + env(safe-area-inset-bottom, 0));
    background: var(--surface-raised);
    border-top: 1px solid var(--border);
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    box-shadow: var(--shadow-2);
    animation: ego-sheet-in var(--motion-layer) var(--ease-emphasized);
}
@keyframes ego-sheet-in { from { transform: translateY(16px); opacity: 0; } }

/* Крестик в правом верхнем углу шторки; заголовок отодвигается, чтобы
   длинное название задачи не уходило под кнопку */
.sheet-close {
    position: absolute; top: var(--space-3); right: var(--space-3);
}
.sheet-close + .t-title,
.sheet-close + form .t-title { padding-right: var(--space-10); }

.sheet-handle {
    width: 36px; height: 4px;
    margin: 0 auto var(--space-4);
    background: var(--border-strong);
    border-radius: var(--radius-pill);
}

/* На ПК шторка снизу неуместна: диалог показывается по центру окном
   (docs/design.md §3.4, п. 10 — правило читается и в обратную сторону) */
@media (min-width: 768px) {
    .sheet {
        left: 50%; bottom: auto; top: 50%;
        transform: translate(-50%, -50%);
        width: min(560px, calc(100vw - var(--space-16)));
        max-height: 80dvh;
        border: 1px solid var(--border);
        border-radius: var(--radius-xl);
        padding: var(--space-6);
        animation: ego-modal-in var(--motion-layer) var(--ease-emphasized);
    }
    @keyframes ego-modal-in {
        from { transform: translate(-50%, calc(-50% + 12px)); opacity: 0; }
    }
    .sheet-handle { display: none; }
}

.toast-stack {
    position: fixed; z-index: 80;
    left: var(--page-padding); right: var(--page-padding);
    bottom: calc(var(--h-tabbar) + var(--space-4) + env(safe-area-inset-bottom, 0));
    display: flex; flex-direction: column; gap: var(--space-2);
    align-items: center;
    pointer-events: none;
}
@media (min-width: 768px) {
    .toast-stack {
        left: auto; right: var(--space-6); bottom: var(--space-6);
        align-items: flex-end;
    }
}

.toast {
    max-width: 380px;
    padding: var(--space-3) var(--space-4);
    background: var(--surface-raised);
    color: var(--text);
    border: 1px solid var(--border);
    border-left: 3px solid var(--text-muted);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-2);
    font-size: var(--text-small);
    animation: ego-toast-in var(--motion) var(--ease-out);
}
@keyframes ego-toast-in { from { transform: translateY(8px); opacity: 0; } }
.toast-success { border-left-color: var(--success); }
.toast-error { border-left-color: var(--danger); }

.skeleton {
    position: relative;
    overflow: hidden;
    background: var(--fill);
    border-radius: var(--radius-sm);
}
.skeleton::after {
    content: "";
    position: absolute; inset: 0;
    background: linear-gradient(90deg, transparent,
        color-mix(in srgb, var(--surface) 70%, transparent), transparent);
    animation: ego-shimmer 1.2s linear infinite;
}
@keyframes ego-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.skeleton-card { height: 72px; border-radius: var(--radius-lg); }
.skeleton-line { height: 12px; }

.empty-state {
    display: flex; flex-direction: column; align-items: center;
    gap: var(--space-3);
    padding: var(--space-12) var(--space-4);
    text-align: center;
}
.empty-state > svg {
    width: 32px; height: 32px;
    padding: 16px;
    box-sizing: content-box;
    background: var(--accent-soft);
    border-radius: var(--radius-2xl);
    color: var(--accent-text);
}

.install-hint {
    position: fixed; z-index: 40;
    left: var(--page-padding); right: var(--page-padding);
    bottom: calc(var(--h-tabbar) + var(--space-3) + env(safe-area-inset-bottom, 0));
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: var(--surface-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-2);
}
@media (min-width: 768px) {
    .install-hint { left: auto; right: var(--space-6); bottom: var(--space-6); max-width: 420px; }
}


/* ═══ 15. Знак ════════════════════════════════════════════════════════════ */

/* Знак и вордмарк берутся мастерами из brand/logo (генератор кладёт их в
   static/icons). Версий две: у знака свои цвета в каждой теме, и перекрасить
   одну в другую нельзя — это разные картинки (брендбук 2026-10, Р-128).
   Знак не квадратный (80×100), поэтому вписывается, а не растягивается */
.logo-mark, .logo-wordmark { display: inline-block; position: relative; flex: none; }
.logo-mark img { display: block; width: 100%; height: 100%; object-fit: contain; }
.logo-wordmark img { display: block; height: 100%; width: auto; }

.logo-mark .on-dark, .logo-wordmark .on-dark { display: none; }

:root[data-theme="dark"] :is(.logo-mark, .logo-wordmark) .on-light,
.theme-dark :is(.logo-mark, .logo-wordmark) .on-light { display: none; }
:root[data-theme="dark"] :is(.logo-mark, .logo-wordmark) .on-dark,
.theme-dark :is(.logo-mark, .logo-wordmark) .on-dark { display: block; }

@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] :is(.logo-mark, .logo-wordmark) .on-light { display: none; }
    :root[data-theme="auto"] :is(.logo-mark, .logo-wordmark) .on-dark { display: block; }
}
/* Светлый остров возвращает светлую версию знака внутри тёмной страницы */
.theme-light :is(.logo-mark, .logo-wordmark) .on-light { display: block; }
.theme-light :is(.logo-mark, .logo-wordmark) .on-dark { display: none; }


/* ═══ 16. Утилиты ═════════════════════════════════════════════════════════ */

[hidden] { display: none !important; }
/* `.is-hidden` намеренно не объявлен глобально: на витрине этот класс означает
   «ещё не появился» (прозрачность и сдвиг), а не «убран из потока», и
   display: none там сломал бы появление секций — landing.css §движение */
/* Стрелка «вперёд» — та же иконка, отражённая: отдельная в наборе не нужна */
.flip { transform: scaleX(-1); }

/* Уважаем системную настройку «меньше движения» (docs/design.md §8) */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 1ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
        scroll-behavior: auto !important;
    }
    .skeleton::after { display: none; }
}

/* Live-режим: аватар */
.live-avatar {
    width: 72px; height: 72px;
    display: flex; align-items: center; justify-content: center;
    background: var(--gradient-brand);
    border-radius: 50%;
    margin-bottom: var(--space-4);
    box-shadow: 0 0 0 8px rgba(124, 58, 237, .15);
    animation: live-pulse 2s ease-in-out infinite;
}
@keyframes live-pulse {
    0%, 100% { box-shadow: 0 0 0 8px rgba(124, 58, 237, .15); }
    50% { box-shadow: 0 0 0 16px rgba(124, 58, 237, .05); }
}

@media (max-width: 767.98px) {
/* fixed только на мобиле — на ПК tabbar скрыт, sticky работает */
    /* ═══ E-10 (Чат): composer фиксирован над tabbar ══════════════════════════ */
    /* Tabbar: position fixed, bottom:0. Composer должен быть ровно над ним.     */
    html[data-screen="E-10"] .composer {
        position: fixed;
        bottom: calc(var(--h-tabbar) + env(safe-area-inset-bottom, 0));
        left: 0;
        right: 0;
        margin: 0;
        /* Чуть выше таббара и ленты (30), но ниже шторок (50), live-режима
           (60) и просмотра фото (70). Раньше стояло 100, и панель ввода
           всплывала поверх открытого фото */
        z-index: 31;
    }
}

/* ═══ iOS standalone (Add to Home Screen) ═════════════════════════════════
 *
 * Нельзя вкладывать @media внутрь @media в обычном CSS — поэтому каждое
 * правило в отдельном блоке с комбинированным условием.
 *
 * Проблемы в standalone на iPhone:
 *  A) Лишний зазор сверху (Задачи/Модули/Профиль):
 *     .screen padding-top включает env(safe-area-inset-top), но topbar
 *     уже занял эту высоту — итого safe-area дублируется.
 *     Решение: убрать safe-area-inset-top из .screen padding-top.
 *
 *  B) Лишний зазор снизу в чате (между последним сообщением и composer):
 *     composer fixed, syncFeedPadding в JS считает реальную высоту,
 *     но CSS padding-bottom chat-feed тоже прибавляет 72px — двойной отступ.
 *     Решение: в standalone убираем статичный CSS padding-bottom из .chat-feed,
 *     JS-расчёт делает это точно.
 *
 *  C, D) были правки полноэкранного live-слоя — слой убран 2026-10-13.
 */

/* A: правило «.screen padding-top = высота шапки» снято 2026-10-09. Шапка
   (.topbar) — sticky и стоит в потоке, а не поверх экрана, поэтому отступ
   на её высоту давал двойной зазор: 68 px пустоты между шапкой и первым
   блоком в профиле, календаре и остальных разделах установленного приложения.
   safe-area сверху уже учтена в самой шапке (padding-top с env()). */

/* B: убираем статичный нижний отступ в chat-feed — JS считает точно */
@media all and (display-mode: standalone) {
    html, body {
        overscroll-behavior: none;
    }

    /* Отступ ленты снизу считает chat.js (syncFeedPadding) и ставит прямо на
       элемент. Обнулять его здесь нельзя: если расчёт не сработал, ответ
       уходил под панель ввода — остаётся запасной отступ из раздела 7 */

    /* C, D: полноэкранного live-слоя больше нет (2026-10-13) */
}

/* Composer на мобиле в standalone: не дублируем safe-area-inset-bottom */
@media all and (display-mode: standalone) and (max-width: 767.98px) {
    .composer {
        padding-bottom: var(--space-3);
    }
}


/* Chat skeleton — показывается пока грузится история */
.chat-skeleton {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4);
    max-width: var(--reading);
    margin: 0 auto;
}
.chat-skeleton-msg {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.chat-skeleton-msg.is-user { align-items: flex-end; }
.chat-skeleton-msg.is-user .skeleton { max-width: 60%; }
.chat-skeleton-msg.is-ai .skeleton { max-width: 85%; }
.chat-skeleton-msg .skeleton-line { border-radius: var(--radius-sm); }
.chat-skeleton-msg .skeleton-line:last-child { width: 65%; }

/* Карточка привязанной карты (П6) */
.payment-card-display {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: var(--fill);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-3);
}
.payment-card-icon { font-size: 24px; }
.payment-card-info { flex: 1; }
.payment-card-info .t-caption { color: var(--text-muted); }

/* История чатов — боковой drawer (П8) */
.chat-drawer {
    position: fixed;
    /* Справа — от кнопки «Все чаты»; слева выезжает меню (E-15) */
    top: 0; right: 0;
    width: min(340px, 88vw);
    height: 100dvh;
    background: var(--surface-raised);
    box-shadow: var(--shadow-2);
    z-index: 300;
    display: flex; flex-direction: column;
    padding: var(--space-4);
    transform: translateX(100%);
    transition: transform 0.28s cubic-bezier(.4,0,.2,1);
    overflow-y: auto;
}
.chat-drawer:not([hidden]) {
    display: flex;
    transform: translateX(0);
}
.chat-drawer[hidden] { display: none; }
.chat-drawer-overlay {
    position: fixed; inset: 0;
    background: rgba(0,0,0,.45);
    z-index: 299;
    backdrop-filter: blur(2px);
}
.chat-drawer-overlay[hidden] { display: none; }
.chat-drawer-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: var(--space-3);
}
.chat-list { display: flex; flex-direction: column; gap: var(--space-2); flex: 1; }
.chat-list-item {
    padding: var(--space-3);
    border-radius: var(--radius-lg);
    cursor: pointer;
    transition: background 0.15s;
    border: 1px solid transparent;
}
.chat-list-item:hover { background: var(--fill); }
.chat-list-item.is-active {
    background: var(--fill);
    border-color: var(--violet);
}
.chat-list-item-title {
    font-size: var(--text-body);
    font-weight: 500;
    line-height: 1.3;
    margin-bottom: 2px;
    /* Название переносится, а не режется многоточием: по нему человек ищет
       диалог (2026-10-13). Длину держит сервер — до 60 символов */
    white-space: normal; overflow-wrap: anywhere;
}
.chat-list-item-preview {
    font-size: var(--text-caption);
    color: var(--text-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-list-item-date {
    font-size: 10px; color: var(--text-muted); margin-top: 2px;
}

/* ─── Чип-кнопка (компактная с иконкой + текстом) ──────────────────────── */
.btn-chip {
    display: inline-flex; align-items: center; gap: var(--space-1);
    padding: 6px 12px; border-radius: var(--radius-full);
    border: 1px solid var(--border-strong);
    background: var(--fill); color: var(--text);
    font-family: inherit; font-size: 13px; font-weight: 600;
    cursor: pointer; white-space: nowrap;
    transition: background 0.15s;
}
.btn-chip:hover { background: var(--fill-strong); }

/* ─── Список чатов: кнопка удаления ─────────────────────────────────────── */
.chat-list-item {
    display: flex; align-items: center; gap: var(--space-2);
}
.chat-list-item-body {
    flex: 1; min-width: 0; cursor: pointer;
    padding: var(--space-2) 0;
}
.chat-list-item-delete {
    flex-shrink: 0; color: var(--text-muted); font-size: 14px;
    opacity: 0.5; padding: 4px 6px;
    transition: opacity 0.15s, color 0.15s;
}
.chat-list-item-delete:hover { opacity: 1; color: var(--danger-text); }
/* Переименование диалога: карандаш рядом с крестиком, поле на месте названия */
.chat-list-item-edit {
    flex: none; opacity: .55; color: var(--text-muted);
}
.chat-list-item-edit:hover { opacity: 1; color: var(--violet); }
.chat-list-item.is-editing .chat-list-item-edit { opacity: 1; color: var(--violet); }
/* Две кнопки в узкой шторке: компактные, чтобы название не резалось */
.chat-list-item .chat-list-item-edit,
.chat-list-item .chat-list-item-delete {
    width: 30px; height: 30px; min-width: 30px; padding: 0;
}
.chat-list-item { gap: 2px; }
/* Пока правится название, крестик не нужен — место отдаём полю */
.chat-list-item.is-editing .chat-list-item-delete { display: none; }
.chat-list-item-input {
    width: 100%; min-width: 0;
    padding: 4px 8px; margin: -4px 0 2px -8px;
    font: inherit; font-weight: 600; color: var(--text);
    background: var(--surface);
    border: 1px solid var(--violet); border-radius: var(--radius-sm, 8px);
    box-shadow: var(--focus-ring);
    outline: none;
}

/* ─── Кнопка «Чаты» в topbar чата — в стиле appnav-link ────────────────── */
.topbar-chats-btn {
    display: inline-flex; align-items: center; gap: var(--space-2);
    height: var(--h-button); padding: 0 var(--space-3);
    border: none; background: none;
    border-radius: var(--radius-pill);
    color: var(--text-secondary);
    font-family: inherit; font-size: var(--text-small); font-weight: 700;
    cursor: pointer;
    transition: background var(--motion-fast) var(--ease-out),
                color var(--motion-fast) var(--ease-out);
}
.topbar-chats-btn:hover { color: var(--text); background: var(--fill); }
.topbar-chats-btn svg { flex-shrink: 0; }

/* ─── Кнопка «вернуться вниз» в чате ───────────────────────────────────── */
.scroll-down-btn {
    position: fixed;
    bottom: calc(var(--h-tabbar) + 80px + env(safe-area-inset-bottom, 0));
    left: 50%; transform: translateX(-50%);
    z-index: 25;
    width: 40px; height: 40px;
    border-radius: 50%;
    border: none;
    background: var(--violet);
    color: var(--on-violet);
    display: flex; align-items: center; justify-content: center;
    box-shadow: none;
    cursor: pointer;
    transition: opacity 0.2s, transform 0.2s;
}
.scroll-down-btn svg { transform: rotate(-90deg); }
.scroll-down-btn[hidden] { display: none; }
@media (min-width: 768px) {
    .scroll-down-btn { bottom: 100px; }
}

/* ─── Напоминание о задаче (E-21/E-22, Р-120) ─────────────────────────────
   Строка «🔔 Напомню за 1 час — в 19:00 · Изменить»: видно, когда придёт пуш,
   а выбор открывается по нажатию, а не висит рядом со всеми полями формы */
.remind-line {
    display: flex; align-items: center; gap: var(--space-2);
    width: 100%;
    padding: var(--space-3) var(--space-4);
    background: var(--fill);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    color: var(--text);
    font: inherit; font-size: var(--text-small);
    text-align: left;
    cursor: pointer;
}
.remind-line:hover { border-color: var(--border-strong); }
.remind-line:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.remind-line svg { flex-shrink: 0; color: var(--accent); }
.remind-line__text { flex: 1; min-width: 0; }
.remind-line__action { flex-shrink: 0; color: var(--accent-text, var(--violet-text)); font-weight: 600; }
.remind-line[hidden] { display: none; }

/* Дата рождения тремя списками (E-51): день и год узкие, месяц — по остатку */
.date-selects { display: grid; grid-template-columns: 5.5rem 1fr 7.5rem; gap: var(--space-2); }
.date-selects .field { padding-left: var(--space-3); padding-right: var(--space-6); }

/* ─── «Устройства» (E-45): разделы и завершение сеансов (Р-123) ─────────── */
.devices-section { margin: var(--space-4) 0 var(--space-2); }
.devices-section:first-child { margin-top: 0; }
#sessions .card-ego + .card-ego { margin-top: var(--space-2); }
#sessions { margin-top: var(--space-5); }
#sessions:empty { display: none; }
.devices-wait { margin-top: 2px; color: var(--amber-text); }
.devices-revoke { flex: none; }
/* Первое нажатие «взвело» кнопку — она краснеет и спрашивает «Точно?» */
.devices-revoke.is-armed, .devices-end-all.is-armed { color: var(--danger-text); }
/* Как в Telegram: красный текст — действие заметное, но не главное на экране */
.devices-end-all { width: 100%; color: var(--danger-text); }
.devices-end-all.is-armed { background: var(--danger); border-color: var(--danger); color: var(--on-danger); }


/* Текстовая кнопка справа в карточке («Выключить», «Завершить») не сжимается
   и не переносит слово: ужимается текст слева (2026-10-14) */
.card-ego > .btn-ego-text { flex: none; white-space: nowrap; }


/* ═══ Баннер «Включить уведомления?» в чате ═══════════════════════════════ */
/* Раньше стили и тексты были вписаны в chat.js строками; теперь вид здесь,
   а тексты — в словаре (`chat.push_banner.*`) */
.push-banner {
    position: fixed; z-index: 200;
    left: 12px; right: 12px;
    bottom: calc(var(--h-tabbar) + env(safe-area-inset-bottom, 0px) + 8px);
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: var(--surface-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-2);
    animation: slideUp .3s ease;
}
@media (min-width: 768px) { .push-banner { left: auto; max-width: 440px; } }
@keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
.push-banner__bell { font-size: 24px; flex: none; }
.push-banner__copy { flex: 1; min-width: 0; }
.push-banner__title { font-weight: 600; font-size: var(--text-small); color: var(--text); }
.push-banner__text { margin-top: 2px; font-size: var(--text-micro); color: var(--text-muted); }
.push-banner .btn-ego { flex: none; }
.push-banner__close {
    flex: none; padding: 4px;
    background: transparent; border: none; cursor: pointer;
    color: var(--text-muted); font-size: 20px; line-height: 1;
}


/* ═══ Правовые документы (E-54…E-61) ═════════════════════════════════════ */
/* Текст из .docx юристов: полное название, главы, подзаголовки, списки.
   Колонка чтения — как у остальных текстовых страниц (design.md §4.2) */
.doc { max-width: var(--reading); }
.doc-heading {
    margin: 0 0 var(--space-6);
    font-family: var(--font-display);
    font-size: var(--text-h3); line-height: var(--lh-h3); font-weight: 600;
}
.doc-section { margin-bottom: var(--space-8); }
.doc-title { margin-bottom: var(--space-3); }
.doc-sub { margin: var(--space-4) 0 var(--space-2); font-size: var(--text-body); font-weight: 700; }
.doc-section p { margin-bottom: var(--space-3); }
.doc-list { margin: 0 0 var(--space-3); padding-left: 1.4em; color: var(--text-secondary); }
.doc-list li { margin-bottom: var(--space-2); line-height: var(--lh-body); }
/* Почта — кнопка копирования, но выглядит как ссылка: в тексте договора
   кнопка с рамкой ломала бы строку */
.doc-copy {
    display: inline; padding: 0;
    background: none; border: none;
    font: inherit; font-weight: 600; color: var(--text);
    text-decoration: underline; text-underline-offset: 3px;
    cursor: copy;
}
.doc-copy::after { content: " ⧉"; font-size: .85em; color: var(--text-muted); }
.doc-copy.is-copied::after { content: " ✓"; color: var(--success-text); }
.doc a { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }

/* Строка согласия в настройках (E-50): подпись слева, переключатель справа */
.consent-row {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
    padding: var(--space-3) 0;
    border-top: 1px solid var(--border);
}


/* ═══ Шапка экрана: меню · знак · действие (2026-10-15) ═══════════════════ */
/* Три колонки, средняя по центру экрана, а не «между соседями»: знак стоит
   ровно посередине при любой ширине кнопок справа и слева */
.topbar-3 { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--space-2); }
/* Колонки заданы явно: на ПК меню и знак скрыты, и без этого действие
   уехало бы в первую колонку */
.topbar-menu { grid-column: 1; justify-self: start; }
.topbar-logo { grid-column: 2; justify-self: center; display: inline-flex; align-items: center; white-space: nowrap; }
.topbar-end { grid-column: 3; justify-self: end; display: flex; align-items: center; gap: var(--space-2); }
/* «☰» на ПК — та же круглая кнопка 44 с заливкой, что на телефоне */
.appnav-menu {
    margin-right: var(--space-1);
    width: 44px; height: 44px; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: var(--radius-pill);
    background: var(--fill); color: var(--text);
}
.appnav-menu:hover { background: var(--fill-strong); }

/* ═══ Боковое меню (E-15) ═════════════════════════════════════════════════ */
/* Выезжает слева, как и кнопка, которая его открывает. Список чатов выезжает
   справа — от своей кнопки «Все чаты» */
html.menu-open { overflow: hidden; }
.app-menu-overlay {
    position: fixed; inset: 0; z-index: 310;
    background: var(--overlay);
}
.app-menu-overlay[hidden], .app-menu[hidden] { display: none; }
.app-menu {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 311;
    width: min(340px, 88vw);
    display: flex; flex-direction: column; gap: var(--space-4);
    padding: calc(var(--space-4) + env(safe-area-inset-top, 0px)) var(--space-4)
             calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
    background: var(--surface);
    border-right: 1px solid var(--border);
    box-shadow: var(--shadow-2);
    overflow-y: auto;
    animation: menu-in var(--motion) var(--ease-out);
}
@keyframes menu-in { from { transform: translateX(-100%); } to { transform: none; } }
.app-menu-head { display: flex; align-items: center; justify-content: space-between; }

.app-menu-user {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-3);
    border: 1px solid var(--border); border-radius: var(--radius-lg);
    background: var(--surface-raised);
    color: var(--text); text-decoration: none;
}
.app-menu-user:hover { text-decoration: none; border-color: var(--border-strong); }
.app-menu-avatar {
    width: 48px; height: 48px; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%; overflow: hidden;
    background: var(--fill); font-weight: 800; font-size: 20px;
}
.app-menu-avatar img { width: 100%; height: 100%; object-fit: cover; }
.app-menu-who { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.app-menu-name { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-menu-sub { font-size: var(--text-small); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.app-menu-tokens {
    display: grid; gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-lg);
    background: var(--fill);
    color: var(--text); text-decoration: none;
}
.app-menu-tokens:hover { text-decoration: none; background: var(--fill-strong); }
.app-menu-tokens-label { font-size: var(--text-micro); font-weight: 700; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--text-muted); }
.app-menu-tokens-value { display: flex; align-items: baseline; gap: var(--space-2); font-family: var(--font-display); font-size: 24px; font-weight: 600; font-variant-numeric: tabular-nums; }
.app-menu-plan { font-family: var(--font-family); font-size: var(--text-micro); font-weight: 700; color: var(--text-muted); }
.app-menu-bar { display: block; height: 4px; border-radius: var(--radius-pill); background: var(--border); overflow: hidden; }
.app-menu-bar span { display: block; height: 100%; width: 0; background: var(--text); }

.app-menu-caption { margin: 0 0 var(--space-2); font-size: var(--text-micro); font-weight: 700; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--text-muted); }
/* Тема — сегменты в одну строку: выбор виден целиком, без выпадающего списка */
.app-menu-theme { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px; border-radius: var(--radius-md); background: var(--fill); }
/* Переключатель темы — компактный (2026-10-15): значок и подпись в строку,
   высота 36 — это настройка «поставил и забыл», а не главное в меню */
.app-menu-theme button {
    display: inline-flex; flex-direction: row; align-items: center; justify-content: center; gap: 6px;
    min-width: 0; min-height: 36px; padding: 4px;
    border: none; border-radius: var(--radius-sm);
    background: transparent; color: var(--text-muted);
    font: inherit; font-size: var(--text-micro); font-weight: 600; cursor: pointer;
}
.app-menu-theme button[aria-checked="true"] { background: var(--surface-raised); color: var(--text); box-shadow: inset 0 0 0 1px var(--border-strong); }

.app-menu-links { display: flex; flex-direction: column; border-top: 1px solid var(--border); }
.app-menu-link {
    display: flex; align-items: center; gap: var(--space-3);
    min-height: 48px; padding: 0 var(--space-2);
    border-bottom: 1px solid var(--border);
    color: var(--text); text-decoration: none; font-weight: 600;
}
.app-menu-link:hover { text-decoration: none; background: var(--fill); }
/* Настройки сервисов (меню и «Настройки»): значок сервиса из нашего набора,
   название и подпись «Настройки сервиса» */
.service-link { gap: var(--space-3); }
.service-glyph {
    flex: none; width: 20px; height: 20px; background: var(--text-muted);
    -webkit-mask: no-repeat center / contain; mask: no-repeat center / contain;
}
.service-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; line-height: 1.25; }
.service-sub { font-size: var(--text-micro); font-weight: 500; color: var(--text-muted); }
/* В «Настройках» сервисы — список внутри карточки, как строки «Аккаунта» выше:
   без своих рамок, разделителем между строками и стрелкой справа. Раньше каждая
   строка была отдельной рамкой, и рамки слипались (оператор 2026-10-20) */
.settings-services { display: grid; }
.settings-services .menu-row {
    padding: var(--space-3) 0;
    min-height: 56px;
    background: transparent;
    border: none;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
}
.settings-services .menu-row:last-child { border-bottom: none; padding-bottom: 0; }
.settings-services .menu-row:hover { background: transparent; }
.settings-services .service-glyph { width: 22px; height: 22px; background: var(--text-secondary); }
.settings-services .service-text { flex: 1; }
.service-title { font-size: var(--text-body); font-weight: 600; color: var(--text); }
.service-chevron {
    flex: none; width: 18px; height: 18px; background: var(--text-muted);
    -webkit-mask: url("/static/vendor/icons/back.svg") no-repeat center / contain;
    mask: url("/static/vendor/icons/back.svg") no-repeat center / contain;
    transform: scaleX(-1);
}
.app-menu-link svg { color: var(--text-muted); }
.app-menu-logout {
    display: flex; align-items: center; gap: var(--space-3);
    margin-top: auto; min-height: 48px; padding: 0 var(--space-1);
    border: none; border-radius: var(--radius-sm); background: transparent;
    color: var(--danger-text); font: inherit; font-weight: 600; cursor: pointer; text-align: left;
}
.app-menu-logout:hover { background: var(--fill); }
.app-menu-version { margin: var(--space-2) 0 0; font-size: var(--text-micro); color: var(--text-muted); }

/* Плашки по краям шапки — «Меню» слева, «Все чаты» / «+ Задача» справа.
   Одинаковые высота, заливка и скругление: две стороны уравновешены, и знак
   посередине не выглядит сдвинутым (2026-10-15). Цель нажатия — 40 px */
.topbar-pill {
    display: inline-flex; align-items: center; gap: var(--space-2);
    height: 44px; padding: 0 var(--space-4) 0 var(--space-3);
    border: none; border-radius: var(--radius-pill);
    background: var(--fill); color: var(--text);
    font: inherit; font-size: var(--text-small); font-weight: 600;
    white-space: nowrap; cursor: pointer;
    transition: background var(--motion-fast) var(--ease-out);
}
.topbar-pill:hover { background: var(--fill-strong); }
.topbar-pill svg { flex: none; }
/* Кнопка-значок без подписи: меню (☰) и «Все чаты» (2026-10-15, запрос
   оператора — слова в шапке лишние, значки узнаются сами). Круг 44 — цель
   нажатия по design.md §3.4 */
.topbar-pill--icon { width: 44px; height: 44px; padding: 0; justify-content: center; }
/* Название экрана в центре (календарь) — на телефоне мельче, чтобы не
   налезать на плашки */
@media (max-width: 767px) {
    .topbar-3 h1.topbar-logo { font-size: 18px; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
}
/* Узкий телефон: подписи прячем (для экранного диктора они остаются через
   aria-label), плашки становятся одинаковыми круглыми кнопками 40×40 —
   иначе знак или название экрана налезают на них */
@media (max-width: 379px) {
    .topbar-pill { width: 40px; padding: 0; justify-content: center; }
    .topbar-pill span {
        position: absolute; width: 1px; height: 1px; overflow: hidden;
        clip: rect(0 0 0 0); white-space: nowrap;
    }
}

/* ═══ Сигнал в светлой теме (Р-132, запрос оператора 2026-10-15) ══════════
   В тёмной теме лаймовый «сигнал» — заливка главных кнопок и выбранного, в
   светлой его не было вовсе, и тема выглядела чёрно-белой. Возвращаем его
   немного и только **заливкой** с чернильным содержимым (17 : 1): текстом
   или линией на светлом фоне сигнал не виден (1.04 : 1, design-colors.md §1).
   Где именно — «где я» и «сколько»: выбранная вкладка, текущий пункт верхней
   панели, выбранный день календаря, выбранная тема в меню, полосы прогресса
   (токены, шаги). Кнопки и свои сообщения в чате остаются чернильными —
   иначе сигнал перестал бы быть акцентом. Селектор — по `data-bs-theme`:
   при теме «авто» `data-theme` равен `auto`, а этот атрибут всегда точный */
[data-bs-theme="light"] .tab[aria-current="page"] .tab-pill,
[data-bs-theme="light"] .appnav-link.is-current,
[data-bs-theme="light"] .calendar-day.is-selected,
[data-bs-theme="light"] .app-menu-theme [aria-checked="true"] {
    background: var(--lime);
    color: var(--on-bright);
    box-shadow: none;
}
[data-bs-theme="light"] .calendar-day.is-selected .dot { box-shadow: 0 0 0 1px var(--on-bright); }
[data-bs-theme="light"] .progress-ego > *,
[data-bs-theme="light"] .app-menu-bar span { background: var(--lime); }

/* «Скопировать» в приглашениях (E-42): кнопка не ужимается и не рвёт слово
   («Скопироват-ь», 2026-10-15) — ужимается и переносится ссылка слева */
.copy-btn { flex: none; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.min-w-0 { min-width: 0; }

/* Строка «Данные из формы получит сервис…» над кнопкой отправки (политика
   п. 5.3, 6.6) — мелко, но перед кнопкой, а не под ней */
.mod-form__notice { margin: 4px 0 12px; font-size: var(--text-small); color: var(--text-muted); }
.mod-form__notice a { color: var(--text-secondary); }


/* ═══ Дизайн «Минимум» (2026-10-27, утверждён оператором) ═══════════════════
   Нижняя панель вкладок остаётся на всех экранах (оператор, 2026-10-27:
   без неё из профиля некуда уйти). Шапка — значки без плашек.
   Поле ввода — одна «капсула» с кнопками внутри, главная кнопка залита
   сигналом. Ответы ассистента — текстом на фоне, без рамки; своё сообщение —
   инверсия темы. Всё из токенов, обе темы (CLAUDE.md №11).
   Откат к виду до этой правки — ветка `backup-before-app-minimal` */


.topbar { border-bottom: none; }
.topbar-pill { background: transparent; }
.topbar-pill:hover { background: var(--fill); }

/* Поле ввода — капсула */
.composer { border-top: none; background: var(--bg); }
.composer-row {
    align-items: center; gap: var(--space-1);
    padding: var(--space-1) var(--space-1) var(--space-1) var(--space-2);
    background: var(--surface-raised);
    border: 1px solid var(--border-strong);
    border-radius: 24px;
}
.composer-row:focus-within { border-color: var(--text); }
.composer-input,
.composer-input:focus {
    background: transparent; border-color: transparent; box-shadow: none;
    padding-left: var(--space-2); padding-right: var(--space-2);
}
.composer-row .btn-icon.is-accent-soft { background: transparent; color: var(--text); opacity: 1; }
.composer-row .btn-icon.is-accent-soft:hover { color: var(--text); background: var(--fill); }
/* Один акцент (оператор 2026-10-30, по навыку mobile-app-ui-design: сигнал —
   только у главного действия). Скрепка, микрофон и волна — значки цвета
   текста без подложки; лаймом горит одна кнопка «Отправить», когда есть
   что отправить. Прежде лаймом горел микрофон, а скрепка и волна были
   серыми и выглядели неактивными */
.composer-send {
    width: 48px; height: 48px; border-radius: 16px;
    background: var(--lime); color: var(--on-lime);
    box-shadow: none;
}
.composer-send:hover { background: var(--lime-hover); color: var(--on-lime); }

/* Реплики остаются прежними (оператор, 2026-10-27: инверсия и ответ без
   подложки читались хуже) */

/* Пустой разговор — «главная», дизайн «Панель дня» (вариант Б, 2026-10-29).
   Крупно то, что важно: время ближайшего дела и температура; подписи мелко.
   Акцент один — «Сделано» сигналом на чернильной карточке. Теней и
   градиентов нет, кольцо прогресса — линия SVG */
.chat-home {
    align-items: stretch; text-align: left; gap: var(--space-3);
    max-width: var(--reading); margin: 0 auto; width: 100%;
    padding: var(--space-6) var(--page-padding) var(--space-6);
}
.chat-home > svg { display: none; }
.home-head { padding-bottom: var(--space-2); }
.home-date { margin: 0; font-size: var(--text-small); color: var(--text-muted); min-height: 20px; }
.home-date::first-letter { text-transform: uppercase; }
.home-hello {
    margin: 0; font-family: var(--font-display);
    font-size: 24px; line-height: 30px; font-weight: 600; letter-spacing: -.01em;
}
.home-next {
    display: flex; flex-direction: column; gap: var(--space-1);
    padding: var(--space-5);
    border-radius: 24px;
    /* В цвет темы, а не инверсией (оператор 2026-10-29: белая карточка в
       тёмной теме выбивалась); выделяют её размер и кнопка сигналом */
    background: var(--surface-raised); color: var(--text);
    border: 1px solid var(--border-strong);
    transition: background var(--motion) var(--ease-out);
}
.home-next[hidden] { display: none; }
.home-next p { margin: 0; }
.home-next-label {
    font-size: var(--text-micro); font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; opacity: .7;
}
.home-next-when { display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap; }
.home-next-when b {
    font-family: var(--font-display); font-size: 40px; line-height: 44px; font-weight: 600;
    font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.home-next-when span { font-size: var(--text-small); opacity: .7; }
.home-next.is-late .home-next-when span { opacity: 1; font-weight: 700; }
.home-next-title { font-size: 20px; line-height: 26px; font-weight: 700; overflow-wrap: anywhere; }
.home-next-acts { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.home-btn {
    display: inline-flex; align-items: center; gap: var(--space-2);
    min-height: 44px; padding: 0 var(--space-4);
    border-radius: 14px; border: 1px solid transparent;
    font: inherit; font-size: var(--text-small); font-weight: 700;
    text-decoration: none; cursor: pointer;
    transition: transform var(--motion-fast) var(--ease-out), opacity var(--motion-fast) var(--ease-out);
}
.home-btn:hover { text-decoration: none; opacity: .9; }
.home-btn:active { transform: scale(.97); }
.home-btn:disabled { opacity: .5; cursor: default; }
.home-btn svg { width: 16px; height: 16px; }
.home-btn-done { background: var(--lime); color: var(--on-lime); }
.home-btn-ghost { color: inherit; border-color: var(--border-strong); background: transparent; }
/* «Сделано» нажато: карточка на миг загорается сигналом — момент удачи
   заметен, а через секунду на её месте следующее дело */
.home-next.is-done { background: var(--lime); color: var(--on-lime); border-color: var(--lime); }
.home-next.is-done .home-next-acts, .home-next.is-done .home-next-when { visibility: hidden; }
.home-next-empty { border-color: var(--border); }
/* Панель поверх переписки — сводка дня: отделена линией и крестиком */
.chat-home { position: relative; }
.home-close { position: absolute; top: var(--space-4); right: calc(var(--page-padding) - 10px); }
/* Под крестиком — место: приветствие не заходит под него */
.chat-home:has(.home-close:not([hidden])) .home-head { padding-right: 40px; }
.home-close[hidden] { display: none; }
/* Лента перевёрнута: панель — первый узел, на экране под перепиской */
.chat-home:has(~ .chat-messages:not(:empty)) {
    border-top: 1px solid var(--border); margin-top: var(--space-4);
}
.home-free-hint { font-size: var(--text-small); color: var(--text-muted); }

.home-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.home-tiles:not(:has(.home-tile:not([hidden]))) { display: none; }
.home-tile {
    display: flex; flex-direction: column; gap: var(--space-1);
    min-height: 124px; padding: var(--space-4);
    border-radius: 20px; background: var(--surface-raised); border: 1px solid var(--border);
    color: var(--text); text-decoration: none;
    transition: border-color var(--motion-fast) var(--ease-out);
}
.home-tile[hidden] { display: none; }
.home-tile:hover { text-decoration: none; border-color: var(--text-muted); color: var(--text); }
.home-tile-k { display: flex; align-items: center; gap: var(--space-2); font-size: 13px; color: var(--text-muted); }
.home-tile-k svg { width: 16px; height: 16px; }
.home-tile-v {
    margin-top: auto; font-family: var(--font-display);
    font-size: 30px; line-height: 34px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.home-tile-s { font-size: 12px; line-height: 16px; color: var(--text-muted); }
.home-ring { width: 56px; height: 56px; margin-top: auto; }
.home-ring circle { fill: none; stroke-width: 6; }
.home-ring-bg { stroke: var(--fill); }
.home-ring-fg { stroke: var(--text); stroke-linecap: round; stroke-dasharray: 0 145; transition: stroke-dasharray var(--motion-layer) var(--ease-out); }

.home-shelf { display: flex; gap: var(--space-3); padding: var(--space-1) 0; }
.home-shelf[hidden] { display: none; }
.home-app {
    display: flex; flex-direction: column; align-items: center; gap: 6px;
    width: 68px; text-align: center; font-size: 11px; line-height: 14px;
    color: var(--text); text-decoration: none;
}
.home-app:hover { text-decoration: none; color: var(--text); }
.home-app-plate {
    display: grid; place-items: center; width: 52px; height: 52px;
    border-radius: 16px; background: var(--surface-raised); border: 1px solid var(--border);
}
.home-app:hover .home-app-plate { border-color: var(--text-muted); }
.home-app .mod-icon {
    display: inline-block; width: 22px; height: 22px; background-color: currentColor;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
    -webkit-mask-position: center; mask-position: center;
    -webkit-mask-size: contain; mask-size: contain;
}
.home-app-name { max-width: 68px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-home-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0; }
.chat-home-chip {
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--border-strong); border-radius: var(--radius-pill);
    background: transparent; color: var(--text-muted);
    font: inherit; font-size: var(--text-small); cursor: pointer;
}
.chat-home-chip:hover { color: var(--text); border-color: var(--text); }

/* Меню, вариант B (оператор, 2026-10-27): карточка «человек + токены»,
   модули значками, разделы двумя группами как в настройках телефона,
   тема и выход внизу */
.app-menu { background: var(--bg); gap: var(--space-3); }
.app-menu-card {
    display: flex; flex-direction: column;
    border: 1px solid var(--border); border-radius: var(--radius-lg);
    background: var(--surface-raised); overflow: hidden;
}
.app-menu-card .app-menu-user { border: none; border-radius: 0; background: transparent; }
.app-menu-card .app-menu-tokens {
    border-radius: 0; background: transparent; gap: var(--space-2);
    padding: var(--space-3); border-top: 1px solid var(--border);
}
.app-menu-card .app-menu-tokens:hover, .app-menu-card .app-menu-user:hover { background: var(--fill); }
.app-menu-card .app-menu-tokens-value { font-size: 20px; }
.app-menu-card .app-menu-tokens-label {
    font-family: var(--font-family); text-transform: none; letter-spacing: 0;
    font-size: var(--text-small); font-weight: 500;
}
.app-menu-card .app-menu-plan { margin-left: auto; }

.app-menu-tiles { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-2); }
#menu-services:not([hidden]), .app-menu-tiles .app-menu-services { display: contents; }
.app-menu-tile {
    width: 64px; display: flex; flex-direction: column; align-items: center; gap: 6px;
    color: var(--text); text-decoration: none; text-align: center;
}
.app-menu-tile:hover { text-decoration: none; }
.app-menu-tile__glyph { width: 52px; height: 52px; border-radius: 16px; flex: none; }
.app-menu-tile .service-glyph { width: 24px; height: 24px; background: var(--text); }
.app-menu-tile .service-text { display: contents; }
.app-menu-tile .service-sub { display: none; }
.app-menu-tile .service-title {
    font-size: 12px; font-weight: 500; line-height: 16px; max-width: 64px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.app-menu-tile__glyph {
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--fill); color: var(--text);
}
.app-menu-tile:hover .app-menu-tile__glyph { background: var(--fill-strong); }

.app-menu-group {
    display: flex; flex-direction: column;
    border: 1px solid var(--border); border-radius: var(--radius-lg);
    background: var(--surface-raised); overflow: hidden;
}
.app-menu-group .app-menu-link { min-height: 48px; padding: 0 var(--space-3); font-weight: 500; }
.app-menu-group .app-menu-link:last-child { border-bottom: none; }
.app-menu-group .app-menu-link span { flex: 1; }
.app-menu-group .app-menu-link svg:last-child { color: var(--text-muted); }

.app-menu-theme-bottom { margin-top: auto; }
.app-menu-logout { margin-top: 0; justify-content: center; }
.app-menu-version { text-align: center; margin-top: 0; }

/* ─── E-30 «Модули» плитками (дизайн «Панель дня», вариант Б, 2026-10-29) ─
   Плитка: значок на спокойной плашке, крупно — название, под ним в две
   строки — что модуль делает; звёздочка «в избранное» в углу. Избранные —
   первыми. Значки одного вида у всех, партнёр цвет не задаёт. По две плитки
   на телефоне, по три на планшете, по четыре на ПК */
.svc-grid {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3); margin-top: var(--space-3);
}
@media (min-width: 768px) { .svc-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .svc-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4); } }
.svc-grid .mod-skeleton { height: 150px !important; }
.svc-cell { min-width: 0; }
.svc-tile {
    flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2);
    min-height: 150px; padding: var(--space-4);
    border-radius: 20px; background: var(--surface-raised); border: 1px solid var(--border);
    color: var(--text); text-decoration: none;
    transition: border-color var(--motion-fast) var(--ease-out);
}
.svc-tile:hover { text-decoration: none; color: var(--text); border-color: var(--text-muted); }
.svc-tile.is-locked { opacity: .6; }
.svc-tile__logo {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; border-radius: 14px;
    background: var(--fill); color: var(--text); margin-bottom: var(--space-1);
}
.svc-tile__logo .mod-icon { width: 22px; height: 22px; }
.svc-tile__name {
    padding-right: 28px; font-size: 15px; line-height: 20px; font-weight: 700;
    overflow-wrap: anywhere;
}
.svc-tile__deed {
    margin-top: -4px; font-size: 13px; line-height: 18px; color: var(--text-muted);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.svc-tile__note { margin-top: auto; font-size: 12px; display: inline-flex; align-items: center; gap: 6px; }
.svc-tile__note::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.svc-tile__note.is-down { color: var(--danger-text); }
.svc-tile__note.is-warn { color: var(--amber-text); }
/* Звёздочка — цветом текста, не жёлтая: акцент на экране один */
.svc-cell .module-star { top: var(--space-3); right: var(--space-3); }
.svc-cell .module-star.is-on { color: var(--text); }

/* Кнопка «Позвонить» под ответом (консьерж, вариант А, 2026-10-28) */
.chat-call {
    margin-top: var(--space-3); padding: var(--space-3);
    border: 1px solid var(--border); border-radius: var(--radius-lg);
    background: var(--surface-raised);
}
.chat-call__place { margin: 0 0 var(--space-2); font-weight: 600; }
.chat-call__label { margin: 0; font-size: 12px; color: var(--text-muted); }
.chat-call__script { margin: 2px 0 var(--space-3); font-size: 14px; line-height: 20px; white-space: pre-line; }
.chat-call__row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.chat-call__hint { margin: var(--space-2) 0 0; font-size: 12px; color: var(--text-muted); }

/* Кнопки времени под событием без часа (2026-10-30) */
.chat-time { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-top: var(--space-3); }
.chat-time__btn {
    min-height: 36px; padding: 0 var(--space-3);
    border: 1px solid var(--border); border-radius: 999px;
    background: var(--surface-raised); color: var(--text);
    font: inherit; font-size: 14px; font-weight: 600;
}
.chat-time__btn:hover { border-color: var(--text-muted); }
.chat-time__btn:disabled { opacity: .5; }
.chat-time__btn--main { background: var(--violet); color: var(--on-violet); border-color: transparent; }
.chat-time__btn--main:hover { border-color: transparent; opacity: .9; }
/* Поле времени — капсула той же высоты; на телефоне по нажатию открывается
   крутилка часов системы */
.chat-time .chat-time__field {
    width: auto; flex: none; height: 36px; box-shadow: none;
    min-height: 36px; padding: 0 var(--space-3);
    border: 1px solid var(--border); border-radius: 999px;
    background: var(--surface-raised); color: var(--text);
    font: inherit; font-size: 16px; font-weight: 600; font-variant-numeric: tabular-nums;
    color-scheme: light;
}
.chat-time .chat-time__field:focus-visible { outline: none; box-shadow: var(--focus-ring); }
/* Крутилка системы — в цвет темы приложения, а не системы */
:root[data-theme="dark"] .chat-time .chat-time__field { color-scheme: dark; }
@media (prefers-color-scheme: dark) { :root[data-theme="auto"] .chat-time .chat-time__field { color-scheme: dark; } }
.chat-time__btn--ghost { background: transparent; color: var(--text-muted); font-weight: 500; }
.chat-time__done { margin: 0; font-size: 13px; color: var(--text-muted); }

/* Фишки на каждый день (Р-160): карточки под ответом — дело, покупки,
   трата, итог трат, итог дня. Тот же язык, что у «Позвонить»: поверхность
   на ступень выше пузыря, без цвета; акцент — только у главной кнопки */
.task-streak { flex: none; padding: 2px 8px; border-radius: 999px; background: var(--lime); color: var(--on-lime); font-size: 12px; font-weight: 700; white-space: nowrap; }
a.chat-time__btn { display: inline-flex; align-items: center; text-decoration: none; }
.bubble-assistant:has(.life-card) { width: 92%; }
.life-card {
    margin-top: var(--space-3); padding: var(--space-3);
    border: 1px solid var(--border); border-radius: var(--radius-lg);
    background: var(--surface-raised);
}
.life-card__head { display: flex; align-items: center; gap: var(--space-2); font-weight: 700; }
.life-card__head--gap { margin-top: var(--space-3); font-size: 14px; }
.life-card__title { font-weight: 700; font-size: 15px; line-height: 20px; }
.life-card__sub { margin-top: 2px; font-size: 13px; line-height: 18px; color: var(--text-muted); }
.life-card__acts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-top: var(--space-2); }
.life-ico { width: 18px; height: 18px; flex: none; background: currentColor; -webkit-mask: center / contain no-repeat; mask: center / contain no-repeat; }
.life-check { display: flex; align-items: center; gap: var(--space-2); min-height: 40px; border-top: 1px solid var(--border); cursor: pointer; font-size: 15px; }
.life-card__head + .life-check, .life-card__head + .life-card__sub + .life-check { border-top: 0; }
.life-check input { width: 20px; height: 20px; flex: none; accent-color: var(--text); }
.life-check.is-done span { text-decoration: line-through; color: var(--text-muted); }
.life-progress { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-2); font-size: 14px; }
/* Полоса лимита — строкой под названием и суммой: на 320 px трёх колонок в карточке не уместить. */
.life-bar { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--space-2); row-gap: 4px; margin-top: var(--space-2); font-size: 14px; }
.life-bar .life-bar__track { grid-column: 1 / -1; grid-row: 2; }
.life-bar .life-bar__sum { grid-column: 2; grid-row: 1; }
.life-bar__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.life-bar__track { flex: 1; height: 8px; border-radius: 999px; background: var(--fill); overflow: hidden; }
.life-bar__track i { display: block; height: 100%; border-radius: 999px; background: var(--text); }
.life-bar__sum { white-space: nowrap; }
.life-left { margin-top: var(--space-3); padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-md); }
.life-line { margin-top: 2px; font-size: 14px; line-height: 20px; }
.life-row { display: flex; align-items: center; gap: var(--space-2); min-height: 40px; border-top: 1px solid var(--border); font-size: 14px; }
.life-card__head + .life-row { border-top: 0; }
.life-row__main { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
.life-row__side { color: var(--text-muted); white-space: nowrap; font-size: 13px; }
.life-row__side.is-soon { color: var(--danger-text); font-weight: 600; }
.life-row__time { width: 48px; flex: none; font-variant-numeric: tabular-nums; }
.life-row__btn { height: 30px; font-size: 13px; }
.life-note { margin-top: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); background: var(--fill); font-size: 14px; line-height: 20px; white-space: pre-line; }
.life-bar__track i.is-over { background: var(--danger); }

/* Панель дня на телефоне: всё помещается на один экран между шапкой и полем
   ввода (390 × 844), иначе лента, прижатая к низу, прятала приветствие */
@media (max-width: 767.98px) {
    .chat-home { gap: var(--space-2); padding-top: var(--space-3); padding-bottom: var(--space-3); }
    .home-head { padding-bottom: 0; }
    .home-hello { font-size: 20px; line-height: 26px; }
    .home-next { padding: var(--space-4); border-radius: 20px; }
    .home-next-when b { font-size: 34px; line-height: 38px; }
    .home-next-title { font-size: 18px; line-height: 24px; }
    .home-next-acts { margin-top: var(--space-2); }
    .home-tile { min-height: 104px; padding: var(--space-3) var(--space-4); }
    .home-tile-v { font-size: 26px; line-height: 30px; }
    .home-ring { width: 48px; height: 48px; }
    .home-tile-s { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    /* Подсказки — одной строкой с прокруткой вбок, а не в три ряда */
    .chat-home-chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 calc(-1 * var(--page-padding)); padding: 0 var(--page-padding); }
    .chat-home-chips::-webkit-scrollbar { display: none; }
    .chat-home-chip { flex: none; }
}

/* «EGO умеет и это» на панели дня и «следующий шаг» под карточкой
   (подсказки, 2026-11-02). Плитка — как плитки дня, но ниже; рамка
   акцентная: это новое для человека, а не его данные */
.home-try { display: flex; flex-direction: column; gap: var(--space-2); }
.home-try[hidden] { display: none; }
.home-try__head { margin: 0; font-size: var(--text-small); color: var(--text-muted); }
.home-try__row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); }
.home-try__tile {
    display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0;
    padding: var(--space-3); border: 1px solid var(--violet); border-radius: var(--radius-lg);
    background: var(--surface-raised); color: var(--text); font: inherit; text-align: left; cursor: pointer;
    transition: transform .2s cubic-bezier(.22, 1, .36, 1), border-color .2s;
}
.home-try__tile:hover { transform: translateY(-2px); }
.home-try__tile:active { transform: scale(.98); }
.home-try__tile:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
.home-try__tile b { font-size: 15px; line-height: 20px; }
.home-try__icon {
    width: 20px; height: 20px; margin-bottom: 4px; background-color: currentColor;
    -webkit-mask: center / contain no-repeat; mask: center / contain no-repeat;
}
.home-try__sub {
    font-size: 13px; line-height: 18px; color: var(--text-muted);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.life-hint { margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px dashed var(--border); }
.life-hint__text { display: flex; gap: var(--space-2); margin: 0; font-size: 14px; line-height: 20px; }
.life-hint__dot { flex: none; width: 8px; height: 8px; margin-top: 6px; border-radius: 50%; background: var(--violet); }
@media (max-width: 560px) {
    .home-try__row { display: flex; overflow-x: auto; scrollbar-width: none;
        margin: 0 calc(-1 * var(--page-padding)); padding: 0 var(--page-padding); }
    .home-try__row::-webkit-scrollbar { display: none; }
    .home-try__tile { flex: none; width: 168px; }
}
@media (prefers-reduced-motion: reduce) { .home-try__tile { transition: none; } .home-try__tile:hover { transform: none; } }

/* План дня: дело, которое план не двигает, — приглушённо (2026-11-02) */
.life-row.is-kept .life-row__time, .life-row.is-kept .life-row__main { color: var(--text-muted); font-weight: 400; }

/* E-62 «Моё» (вариант В, 2026-11-03): карточки-итоги, разделы списком.
   Карточки — как плитки панели дня; крупная цифра — шрифт заголовков */
.mine { display: flex; flex-direction: column; gap: var(--space-3); padding-bottom: 96px; }
.mine-dash { display: flex; flex-direction: column; gap: var(--space-2); }
.mine-dash[hidden], .mine-section[hidden] { display: none; }
.mine-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
.mine-card {
    display: flex; flex-direction: column; gap: 4px; min-width: 0;
    padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-lg);
    background: var(--surface-raised); color: var(--text); text-decoration: none;
    transition: border-color .2s;
}
a.mine-card:hover { border-color: var(--text-muted); color: var(--text); text-decoration: none; }
.mine-card__head {
    display: flex; align-items: center; gap: var(--space-2); margin-bottom: 4px;
    font-size: 15px; font-weight: 700; color: var(--text); text-decoration: none;
}
.mine-card__head:hover { color: var(--text); text-decoration: none; }
.mine-card__head svg:last-child:not(:first-child) { margin-left: auto; color: var(--text-muted); }
.mine-big { font-family: var(--font-display); font-size: 22px; line-height: 28px; font-weight: 700; }
.mine-big.is-danger { color: var(--danger); }
.mine-big.is-empty { color: var(--text-muted); }
.mine-sub { font-size: 13px; line-height: 18px; color: var(--text-muted); overflow-wrap: anywhere; }
.mine-bars { display: flex; flex-direction: column; gap: var(--space-2); }
.mine-bars:empty { display: none; }
.mine-bar { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--space-2); row-gap: 4px; font-size: 14px; }
.mine-bar > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mine-bar__track { grid-column: 1 / -1; height: 8px; border-radius: 999px; background: var(--fill); overflow: hidden; }
.mine-bar__track i { display: block; height: 100%; border-radius: 999px; background: var(--text); }
.mine-bar__track i.is-over { background: var(--danger); }
.mine-card .mine-bar + .mine-bar { margin-top: var(--space-2); }
.mine-search:focus-within { box-shadow: 0 0 0 2px var(--text-muted); }
.mine-search {
    display: flex; align-items: center; gap: var(--space-2); height: 40px; margin: 0; padding: 0 var(--space-3);
    border-radius: 999px; background: var(--fill); color: var(--text-muted);
}
.mine-search[hidden] { display: none; }
.mine-search input.field:focus { border: 0; box-shadow: none; }
.mine-search input.field { flex: 1; min-width: 0; height: auto; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; color: var(--text); font: inherit; font-size: 16px; outline: none; }
.mine-section { display: flex; flex-direction: column; gap: var(--space-3); }
.mine-list { border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface-raised); overflow: hidden; }
.mine-row { display: flex; align-items: center; gap: var(--space-3); min-height: 56px; margin: 0; padding: var(--space-2) var(--space-3); }
.mine-row + .mine-row { border-top: 1px solid var(--border); }
.mine-row__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.mine-row__text b { font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }
.mine-row__text span { font-size: 13px; color: var(--text-muted); }
.mine-row__side { font-size: 15px; font-weight: 700; white-space: nowrap; }
.mine-row__side.is-danger { color: var(--danger); }
.mine-row__btn {
    height: 32px; padding: 0 var(--space-3); border: 1px solid var(--border); border-radius: 999px;
    background: transparent; color: var(--text); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
}
.mine-check { cursor: pointer; }
.mine-check input { width: 20px; height: 20px; accent-color: var(--text); flex: none; }
.mine-check.is-done .mine-row__text { color: var(--text-muted); text-decoration: line-through; }
.mine-caption { margin: 0; font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); }
.mine-note { margin: 0; font-size: 13px; line-height: 18px; color: var(--text-muted); }
.mine-total { gap: 2px; }
.mine-notes { display: flex; flex-direction: column; gap: var(--space-2); }
.mine-noteitem {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--space-2);
    padding: var(--space-3); border-radius: var(--radius-md); background: var(--fill); font-size: 15px;
}
.mine-noteitem span { overflow-wrap: anywhere; }
.mine-noteitem small { grid-column: 1; font-size: 12px; color: var(--text-muted); }
.mine-noteitem__del { grid-column: 2; grid-row: 1 / span 2; align-self: center; color: var(--text-muted); }
.mine-add { width: 100%; }
.mine-empty { display: flex; flex-direction: column; align-items: center; gap: var(--space-3); padding: var(--space-5) var(--space-2); text-align: center; }
.mine-empty p { margin: 0; max-width: 320px; color: var(--text-muted); font-size: 15px; line-height: 22px; }
.mine-empty button { width: 100%; max-width: 420px; }
.mine-empty__ico { display: flex; align-items: center; justify-content: center; width: 56px; height: 56px; border-radius: 18px; background: var(--fill); }
.mine-ico { display: inline-block; width: 18px; height: 18px; flex: none; background: currentColor; -webkit-mask: center / contain no-repeat; mask: center / contain no-repeat; }
@media (min-width: 768px) { .mine { max-width: 720px; margin: 0 auto; } .mine-grid { gap: var(--space-3); } }

/* Карточка «Моё» в меню и ссылка «Всё моё» на панели дня */
.app-menu-mine {
    display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3);
    border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface-raised);
    color: var(--text); text-decoration: none;
}
.app-menu-mine:hover { background: var(--fill); color: var(--text); text-decoration: none; }
.app-menu-mine__ico { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; flex: none; border-radius: 12px; background: var(--fill); }
.app-menu-mine__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.app-menu-mine__text b { font-size: 16px; }
.app-menu-mine__text span { font-size: 13px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-menu-mine > svg:last-child { color: var(--text-muted); }
.home-mine {
    display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3);
    border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface-raised);
    color: var(--text); text-decoration: none; font-size: 15px;
}
.home-mine:hover { color: var(--text); text-decoration: none; border-color: var(--text-muted); }
.home-mine b { font-weight: 700; white-space: nowrap; }
.home-mine span { color: var(--text-muted); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.home-mine svg:last-child { margin-left: auto; color: var(--text-muted); flex: none; }

/* «Итоги и напоминания» в списке разговоров (Р-164): закреплён первым */
.chat-list-item.is-feed .chat-list-item-title { display: flex; align-items: center; gap: var(--space-2); font-weight: 700; }
.chat-list-feed-ico {
    width: 16px; height: 16px; flex: none; background: currentColor;
    -webkit-mask: url("/static/vendor/icons/bell.svg") center / contain no-repeat;
    mask: url("/static/vendor/icons/bell.svg") center / contain no-repeat;
}

/* Шторка «скажи — и проверь» в «Моё» (Р-165) */
.mine-say { display: flex; gap: var(--space-2); align-items: center; }
.mine-say .field { flex: 1; min-width: 0; }
.mine-mic { flex: none; width: 48px; height: 48px; border: 1px solid var(--border-strong); border-radius: 50%; }
.mine-mic.is-recording { background: var(--violet); color: var(--on-violet); border-color: var(--violet); }
.mine-say-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin: var(--space-2) 0 var(--space-3); }
.mine-say-go { flex: none; }
.mine-fields { display: flex; flex-direction: column; gap: var(--space-3); margin-bottom: var(--space-3); padding-top: var(--space-3); border-top: 1px dashed var(--border); }
.mine-field { display: flex; flex-direction: column; gap: 4px; }
.mine-field .field-label { margin: 0; }
.mine-seg { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.mine-delete { width: 100%; margin-top: var(--space-2); color: var(--danger); }
.mine-row.is-editable, .mine-limit, .mine-noteitem__text { cursor: pointer; }
.mine-row.is-editable:hover { background: var(--fill); }
.mine-limit { display: block; width: 100%; padding: 0; border: 0; background: transparent; color: inherit; font: inherit; text-align: left; }
.mine-limit + .mine-limit { margin-top: var(--space-3); }
.mine-noteitem__text { padding: 0; border: 0; background: transparent; color: inherit; font: inherit; text-align: left; overflow-wrap: anywhere; }

/* ═══ Острова (Р-167, «Один акцент») и профиль-бенто (E-40) ═══════════════
   Остров — плитка с живыми данными: в светлой теме тёмная «карта», в тёмной —
   тона обычной карточки (токены --island*). Цветных свечений нет: салатовым
   светится только главное сейчас (`island--accent`), залита сигналом только
   одна плитка на экране (`island--signal`), красный — горящий срок. Значок
   раздела — водяным знаком в углу на 6 % */
.island {
    position: relative; overflow: hidden; isolation: isolate;
    display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-2); min-width: 0;
    padding: var(--space-4); border-radius: 22px;
    background: var(--island); border: 1px solid var(--island-border); color: var(--island-text);
    text-decoration: none; transition: transform .3s cubic-bezier(.22, 1, .36, 1), border-color .2s;
}
a.island:hover { color: var(--island-text); text-decoration: none; transform: translateY(-2px); border-color: #3A3A42; }
a.island:active { transform: scale(.98); }
a.island:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }
.island__glow { position: absolute; z-index: -1; right: -60px; top: -70px; width: 190px; height: 190px; border-radius: 50%; background: var(--lime); opacity: .22; filter: blur(50px); pointer-events: none; }
.island__mark {
    position: absolute; z-index: -1; right: -16px; bottom: -20px; width: 104px; height: 104px; opacity: .06;
    background: currentColor; -webkit-mask: var(--mark) center / contain no-repeat; mask: var(--mark) center / contain no-repeat;
    pointer-events: none;
}
.island__label { display: flex; align-items: center; gap: 6px; font-size: 12px; line-height: 16px; color: var(--island-muted); min-width: 0; }
.island__label > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.island__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.island__value { font-family: var(--font-display); font-size: 22px; line-height: 26px; font-weight: 700; overflow-wrap: anywhere; }
.island__value.is-danger { color: var(--coral); }
.island__sub { font-size: 12px; line-height: 16px; color: var(--island-muted); overflow-wrap: anywhere; }
.island__ring {
    --p: 0; width: 50px; height: 50px; margin-bottom: 6px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: conic-gradient(var(--lime) calc(var(--p) * 1%), var(--island-track) 0);
}
.island__ring > span {
    width: 38px; height: 38px; border-radius: 50%; background: var(--island);
    display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 800;
}
.island__bar { display: block; height: 6px; margin-bottom: 8px; border-radius: 999px; background: var(--island-track); overflow: hidden; }
.island__bar i { display: block; height: 100%; width: 0; border-radius: 999px; background: var(--island-text); }
.island__bar[hidden], .island__dots[hidden] { display: none; }
.island__dots { display: flex; gap: 4px; margin-bottom: 8px; }
.island__dots i { width: 14px; height: 14px; border-radius: 5px; background: var(--island-track); }
.island__dots i.is-on { background: var(--lime); }
.island--signal { background: var(--lime); border-color: var(--lime); color: #0B0B0E; }
a.island--signal:hover { color: #0B0B0E; border-color: #0B0B0E; }
.island--signal .island__label, .island--signal .island__sub { color: #0B0B0E; }

.bento { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: minmax(150px, auto); gap: var(--space-3); }
.bento-card {
    grid-column: span 2; grid-row: span 2; position: relative; overflow: hidden; isolation: isolate;
    display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-6);
    border-radius: 28px; background: var(--island); border: 1px solid var(--island-border); color: var(--island-text); text-decoration: none;
}
.bento-card:hover { color: var(--island-text); text-decoration: none; border-color: #3A3A42; }
.bento-card:focus-visible { outline: 2px solid var(--lime); outline-offset: 2px; }
.bento-card__glow { position: absolute; z-index: -1; right: -70px; top: -90px; width: 280px; height: 280px; border-radius: 50%; background: var(--lime); opacity: .22; filter: blur(60px); }
.bento-card__mark { position: absolute; z-index: -1; right: -40px; bottom: -60px; width: 260px; height: 260px; opacity: .06; }
.bento-card__top { display: flex; align-items: center; justify-content: space-between; }
.bento-plan { height: 28px; padding: 0 var(--space-3); border-radius: 999px; display: inline-flex; align-items: center; font-size: 13px; font-weight: 800; border: 1px solid #3A3A42; color: var(--island-muted); }
.bento-plan.is-paid { background: var(--lime); border-color: var(--lime); color: #0B0B0E; }
.bento-card__who { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.bento-avatar { width: 64px; height: 64px; font-size: 24px; flex: none; background: #26262C; color: #F4F3EF; border-color: #2E2E35; box-shadow: 0 0 0 3px var(--island), 0 0 0 6px var(--lime); }
.bento-card__name { display: flex; flex-direction: column; min-width: 0; }
.bento-card__name b { font-family: var(--font-display); font-size: 22px; line-height: 28px; overflow-wrap: anywhere; }
.bento-card__name span { font-size: 13px; color: var(--island-muted); }
.bento-card__foot { margin-top: auto; display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-3); }
.bento-card__label { display: block; font-size: 12px; color: var(--island-muted); }
.bento-card__tokens { font-family: var(--font-display); font-size: 44px; line-height: 48px; font-weight: 700; }
.bento-card__until { font-size: 13px; color: var(--island-muted); text-align: right; }
.bento-card__bar { height: 8px; border-radius: 999px; background: var(--island-track); overflow: hidden; }
.bento-card__bar i { display: block; height: 100%; width: 0; border-radius: 999px; background: var(--lime); transition: width .6s cubic-bezier(.22, 1, .36, 1); }
.bento-links { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: var(--space-3) 0 96px; }
.bento-links a {
    display: inline-flex; align-items: center; gap: var(--space-2); height: 40px; padding: 0 var(--space-3);
    border: 1px solid var(--border); border-radius: 999px; color: var(--text); font-size: 14px; font-weight: 600; text-decoration: none;
}
.bento-links a:hover { border-color: var(--text-muted); color: var(--text); text-decoration: none; }
.bento-links svg { color: var(--text-muted); }
@media (max-width: 767.98px) {
    .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: minmax(128px, auto); gap: var(--space-2); }
    .bento-card { grid-column: span 2; grid-row: auto; padding: var(--space-5); min-height: 240px; }
    .bento-card__tokens { font-size: 36px; line-height: 40px; }
    .bento-avatar { width: 52px; height: 52px; }
    .bento-card__name b { font-size: 18px; line-height: 24px; }
    .island__value { font-size: 20px; line-height: 24px; }
}
@media (prefers-reduced-motion: reduce) { .island, .bento-card__bar i { transition: none; } a.island:hover { transform: none; } }

/* ─── Острова на остальных экранах (Р-167) ────────────────────────────────
   Главная: «Дальше» — главный остров со свечением; плитки погоды и дел,
   подсказки «EGO умеет и это» — острова. «Моё»: итоги — острова. Календарь:
   выбранный день и сводка «Сегодня». Модули: избранные — острова. Меню и
   настройки: карта человека — остров, плитки разделов — острова */
.home-next:not(.home-next-empty), .home-next-empty {
    position: relative; overflow: hidden; isolation: isolate;
    background: var(--island); color: var(--island-text); border-color: var(--island-border);
}
.home-next:not(.home-next-empty)::before {
    content: ""; position: absolute; z-index: -1; right: -60px; top: -80px; width: 220px; height: 220px;
    border-radius: 50%; background: var(--lime); opacity: .22; filter: blur(56px); pointer-events: none;
}
.home-next .home-btn-ghost { border-color: #3A3A42; color: var(--island-text); }
.home-next .home-free-hint { color: var(--island-muted); }
.home-next.is-done { background: var(--lime); color: var(--on-lime); border-color: var(--lime); }
.home-tile { background: var(--island); border-color: var(--island-border); color: var(--island-text); border-radius: 22px; }
.home-tile:hover { color: var(--island-text); border-color: #3A3A42; }
.home-tile-k, .home-tile-s { color: var(--island-muted); }
.home-ring-bg { stroke: var(--island-track); }
.home-ring-fg { stroke: var(--lime); }
.home-try__tile { background: var(--island); border-color: var(--island-border); color: var(--island-text); }
.home-try__sub { color: var(--island-muted); }
.home-mine { background: var(--island); border-color: var(--island-border); color: var(--island-text); }
.home-mine:hover { color: var(--island-text); border-color: #3A3A42; }
.home-mine span, .home-mine svg:last-child { color: var(--island-muted); }

.mine-dash .mine-card { background: var(--island); border-color: var(--island-border); color: var(--island-text); border-radius: 22px; }
.mine-dash a.mine-card:hover { border-color: #3A3A42; color: var(--island-text); }
.mine-dash .mine-card__head, .mine-dash .mine-card__head:hover { color: var(--island-text); }
.mine-dash .mine-sub, .mine-dash .mine-big.is-empty, .mine-dash .mine-card__head svg:last-child:not(:first-child) { color: var(--island-muted); }
.mine-dash .mine-big.is-danger { color: var(--coral); }
.mine-dash .mine-bar__track { background: var(--island-track); }
.mine-dash .mine-bar__track i { background: var(--island-text); }
.mine-dash .mine-bar__track i.is-over { background: var(--coral); }
.mine-dash .mine-search { background: var(--island-track); color: var(--island-muted); }
.mine-dash .mine-search input.field { color: var(--island-text); }
.mine-section .mine-card.mine-total { background: var(--island); border-color: var(--island-border); color: var(--island-text); }
.mine-section .mine-total .mine-sub { color: var(--island-muted); }

.day-week-cell.is-selected, [data-bs-theme="light"] .day-week-cell.is-selected { background: var(--island); color: var(--island-muted); }
.day-week-cell.is-selected b, [data-bs-theme="light"] .day-week-cell.is-selected b { color: var(--island-text); }
.day-sum { flex-direction: row; align-items: center; justify-content: flex-start; gap: var(--space-3); margin-bottom: var(--space-4); padding: var(--space-3) var(--space-4); }
.day-sum[hidden] { display: none; }
.day-sum .island__ring { margin: 0; flex: none; }

.svc-tile.is-fav { background: var(--island); border-color: var(--island-border); color: var(--island-text); }
.svc-tile.is-fav:hover { color: var(--island-text); border-color: #3A3A42; }
.svc-tile.is-fav .svc-tile__deed { color: var(--island-muted); }
.svc-tile.is-fav .svc-tile__logo { background: var(--island-track); color: var(--island-text); }
.svc-cell:has(.svc-tile.is-fav) .module-star { color: var(--island-text); }

.app-menu-card { background: var(--island); border-color: var(--island-border); color: var(--island-text); position: relative; isolation: isolate; }
.app-menu-card::before {
    content: ""; position: absolute; z-index: -1; right: -50px; top: -60px; width: 170px; height: 170px;
    border-radius: 50%; background: var(--lime); opacity: .2; filter: blur(46px); pointer-events: none;
}
.app-menu-card .app-menu-user, .app-menu-card .app-menu-tokens { color: var(--island-text); }
.app-menu-card .app-menu-tokens { border-top-color: #24242A; }
.app-menu-card .app-menu-tokens:hover, .app-menu-card .app-menu-user:hover { background: rgba(255, 255, 255, .05); }
.app-menu-card .app-menu-sub, .app-menu-card .app-menu-tokens-label, .app-menu-card .app-menu-plan,
.app-menu-card .app-menu-user > svg { color: var(--island-muted); }
.app-menu-card .app-menu-bar { background: var(--island-track); }
.app-menu-card .app-menu-bar span { background: var(--lime); }
.app-menu-card .app-menu-avatar { background: #26262C; color: #F4F3EF; border-color: #2E2E35; box-shadow: 0 0 0 2px var(--island), 0 0 0 4px var(--lime); }
.app-menu-islands { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
.app-menu-islands .island { min-height: 92px; padding: var(--space-3); border-radius: 18px; gap: 4px; }
.app-menu-islands .island__value { font-size: 15px; line-height: 20px; font-family: inherit; font-weight: 700; }
.app-menu-islands .island__mark { width: 72px; height: 72px; right: -12px; bottom: -14px; }

.settings-card { display: flex; align-items: center; gap: var(--space-3); flex-direction: row; justify-content: flex-start; margin-bottom: var(--space-3); padding: var(--space-4); }
.settings-card .bento-avatar { width: 48px; height: 48px; font-size: 18px; }
.settings-card .island__body { flex: 1; }
.settings-card .island__value { font-size: 17px; line-height: 22px; }

/* ─── Покупка под рукой, компактный профиль, подсказки на телефоне ─────────
   (оператор, 2026-11-03). Покупка платного аккаунта — на карте с токенами в
   профиле и под токенами в меню: её ищут там, где токены. Профиль на
   телефоне — плитки ниже и плотнее, чтобы экран читался без долгой
   прокрутки. «EGO умеет и это» на телефоне — столбиком строк, а не лентой
   вбок: обрезанная плитка у края выглядела криво */
.bento-card__cta {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-3); border-radius: 14px;
    background: var(--lime); color: #0B0B0E; font-size: 14px; line-height: 20px; font-weight: 700;
}
.bento-card__cta[hidden] { display: none; }
.bento-card__cta > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-menu-upgrade {
    display: block; margin-top: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: 12px;
    background: var(--lime); color: #0B0B0E; font-family: var(--font-family); font-size: 14px; line-height: 20px; font-weight: 700; text-align: center;
}
.app-menu-upgrade[hidden] { display: none; }
/* Карта в меню не сжимается колонкой меню: иначе кнопка покупки обрезалась */
.app-menu-card { flex: none; }
.paid-offer { border-color: var(--lime); }

@media (max-width: 767.98px) {
    .bento { grid-auto-rows: minmax(96px, auto); }
    .bento-card { min-height: 0; padding: var(--space-4); gap: var(--space-3); }
    .bento-card__mark { width: 180px; height: 180px; }
    .bento-avatar { width: 44px; height: 44px; font-size: 18px; box-shadow: 0 0 0 2px var(--island), 0 0 0 4px var(--lime); }
    .bento-card__name b { font-size: 17px; line-height: 22px; }
    .bento-card__tokens { font-size: 30px; line-height: 34px; }
    .bento .island { padding: var(--space-3); border-radius: 18px; gap: var(--space-1); }
    .bento .island__value { font-size: 18px; line-height: 22px; }
    .bento .island__ring { width: 36px; height: 36px; margin-bottom: 2px; }
    .bento .island__ring > span { width: 28px; height: 28px; font-size: 10px; }
    .bento .island__mark { width: 72px; height: 72px; right: -12px; bottom: -14px; }
    .bento .island__bar { margin-bottom: 4px; }
}

@media (max-width: 560px) {
    .home-try__row { display: flex; flex-direction: column; overflow: visible; margin: 0; padding: 0; gap: var(--space-2); }
    .home-try__tile {
        width: auto; flex: none; display: grid; grid-template-columns: 20px minmax(0, 1fr); column-gap: var(--space-3); row-gap: 0;
        align-items: center; padding: var(--space-2) var(--space-3);
    }
    .home-try__icon { margin: 0; grid-row: span 2; }
    .home-try__tile b { font-size: 14px; line-height: 20px; }
    .home-try__sub { -webkit-line-clamp: 2; font-size: 13px; }
    /* Пояснение у «Органайзера» на телефоне не помещалось и рвалось многоточием */
    .home-mine span { display: none; }
    .chat-home-chips { flex-wrap: wrap; overflow: visible; margin: 0; padding: 0; }
}

/* «Итоги и напоминания» в списке диалогов: без кнопок, строка-пояснение —
   в две строки, а не обрывком (оператор, 2026-11-03) */
.chat-list-item.is-feed .chat-list-item-preview {
    white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}

/* EGO Plus (оператор, 2026-11-03, вариант А): у оплативших под знаком EGO —
   мелкое разреженное «PLUS», по центру; у остальных подписи нет вовсе. Знак не
   трогаем: подпись — отдельный элемент, видна по `data-plan="plus"` */
.plus-badge { display: none; }
[data-plan="plus"] .topbar-logo, [data-plan="plus"] .appnav-brand { flex-direction: column; align-items: center; gap: 3px; }
[data-plan="plus"] .plus-badge {
    display: block; padding-left: .32em; line-height: 1;
    font-family: var(--font-display); font-size: 9px; font-weight: 800; letter-spacing: .32em;
    color: var(--text);
}
/* В тёмной теме — сигнальным; `data-bs-theme` boot.js ставит уже решённой темой */
[data-bs-theme="dark"] .plus-badge { color: var(--lime); }
