/**
 * Skyny - Optimized Global Styles
 * Optimized: 2026-02-02
 */

/* ========================================
   0. FONT FACES
   ======================================== */
@font-face {
    font-family: 'Neue Machina';
    src: url('/static/fonts/NeueMachina-Medium.woff2') format('woff2');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

/* ========================================
   1. DESIGN TOKENS (Base Variables)
   ======================================== */

/* --- Tabler icon alignment --- */
.ti {
    vertical-align: middle;
}

/* --- Video Elements Override (only decorative videos should hide native controls) --- */
video:not([controls])::-webkit-media-controls-enclosure {
    display: none !important;
}
video:not([controls])::-webkit-media-controls {
    display: none !important;
}
video {
    transform: translateZ(0);
    outline: none;
}

:root {
/* --- Shared Metrics --- */
    --announcement-height: 3.25rem;
    --safe-area-top: 0px;
    --radius-sm: 0.375rem;
    --radius-md: 0.5rem;
    --radius-base: 0.75rem;
    --radius-lg: 1.5rem;
    --radius-xl: 2rem;
    --radius-2xl: 2.5rem;
    --radius-3xl: 3rem;
    --radius-pill: 9999px;
    --radius-chat-tail: 4px;
    --chat-radius: 1rem;
    --chat-radius-xl: 1.25rem;
    /* Схлопнутая высота композера: 40px контролы + 2×10px inset (.chat-input-zone).
       Единый источник для min-height зоны и pill-радиуса (= половина). */
    --chat-input-shell-min-height: calc(2.5rem + 2 * var(--composer-inset, 0.625rem));
    --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --font-display: 'Neue Machina', var(--font-sans);
    --font-mono: "SF Mono", "Consolas", monospace;
    --text-2xs: 0.7rem;
    --text-xs: 0.75rem;
    --text-sm: 0.875rem;
    --text-base: 1rem;
    --text-lg: 1.125rem;
    --text-xl: 1.25rem;
    --text-2xl: 1.5rem;
    --text-3xl: 1.875rem;
    --text-4xl: 2.25rem;
    --text-5xl: 3rem;
    --text-6xl: 3.75rem;
    --font-weight-medium: 500;
    --font-weight-semibold: 600;
    --font-weight-bold: 700;
    --motion-ease-standard: cubic-bezier(0.22, 1, 0.36, 1);
    --motion-ease-premium: cubic-bezier(0.16, 1, 0.3, 1);
    --motion-ease-elastic: cubic-bezier(0.34, 1.56, 0.64, 1);
    --motion-ease-exit: cubic-bezier(0.4, 0, 1, 1);
    --motion-duration-micro: 120ms;
    --motion-duration-fast: 180ms;
    --motion-duration-drawer: 220ms;
    --motion-duration-shell: 320ms;
    --motion-duration-base: 300ms;
    --motion-duration-slow: 450ms;
    --motion-duration-dramatic: 700ms;
    --transition: var(--motion-duration-base) var(--motion-ease-standard);
    --transition-fast: var(--motion-duration-fast) var(--motion-ease-standard);
    --transition-slow: var(--motion-duration-slow) var(--motion-ease-premium);
    --motion-stagger-step: 35ms;
    --gap-2xs: 0.125rem;
    --gap-xs: 0.375rem;
    --gap-sm: 0.5rem;
    --shell-header-slot: 2.6rem;
    /* Единый размер логотипа бренда: signin / юр.страницы / вьюер / рейл /
       мобильная шапка. Исключение — свёрнутый рейл (узкий 60px): там лого
       возвращается к размеру слота навигации (--shell-rail-slot-size). */
    --brand-logo-size: 3rem;
    /* Single source of truth for the horizontal inset on mobile shell pages.
       Used by .shell-mobile-header-host padding, .home-hero margin, and the
       home cards container, so they all align to the same vertical edges. */
    --shell-mobile-gutter: 0.75rem;

    /* --- Glass Configuration --- */
    --blur-lg: 14px;  /* Standard Glass Panels */
    --glass-blur: var(--blur-lg);

    /* --- Progressive Blur Layers (soft + strong) --- */
    --progressive-blur-2: 4px;   /* Soft layer */
    --progressive-blur-3: 8px;   /* Sidebar glass alias source */
    --progressive-blur-4: 16px;  /* Strong layer */
    /* Single-value alias for components that only need one blur strength */
    --progressive-blur: var(--progressive-blur-3);
    --surface-fade-top-soft-mask: linear-gradient(to bottom, black 30%, transparent 100%);
    --surface-fade-top-strong-mask: linear-gradient(to bottom, black 20%, transparent 65%);
    --surface-fade-top-tint-color: var(--bg-elevated);
    --surface-fade-top-tint-gradient: linear-gradient(to bottom, var(--surface-fade-top-tint-color) 20%, transparent 100%);
    --surface-fade-top-tint-opacity: 0.95;
    
    /* --- Base Palette (Static Colors) --- */
    --primary-500: #c8ff00;
    --primary-600: #b5e600;
    --primary-700: #a0cc00;
    --ambient-accent-500: #a1a1aa;
    --ambient-accent-600: #8c8c96;
    --ambient-accent-700: #71717a;
    --primary-10: color-mix(in srgb, var(--primary-500) 10%, transparent);
    --primary-20: color-mix(in srgb, var(--primary-500) 20%, transparent);
    --red-500: #ef4444; /* декоративный — только settings-gradient; статус-UI нейтральный, без красного/зелёного */
    --promo-bg: var(--primary-500);
    --promo-text: #070707;
    --overlay-text: #ffffff;

    /* --- Derived Palette (color-mix tokens) --- */
    --promo-text-38: color-mix(in srgb, var(--promo-text) 38%, transparent);
    --primary-14: color-mix(in srgb, var(--primary-500) 14%, transparent);
    --primary-18: color-mix(in srgb, var(--primary-500) 18%, transparent);
    --primary-icon: color-mix(in srgb, var(--primary-500) 70%, var(--text-main));
    --text-main-5: color-mix(in srgb, var(--text-main) 5%, transparent);
    --text-main-6: color-mix(in srgb, var(--text-main) 6%, transparent);
    --text-main-18: color-mix(in srgb, var(--text-main) 18%, transparent);
    --bg-raised-55: color-mix(in srgb, var(--bg-raised) 55%, transparent);
    --bg-raised-75: color-mix(in srgb, var(--bg-raised) 75%, transparent);
    --bg-input-45: color-mix(in srgb, var(--bg-input) 45%, transparent);

    /* --- Theme Defaults (Dark Mode) --- */
    --bg-app: #050505;
    --bg-panel: #0c0c0d;
    --bg-input: #101010;
    --bg-elevated: #18181b;
    --bg-raised: #27272a;
    --bg-raised-hover: #3f3f46;
    /* Hover-разбел на непрозрачных поверхностях — из общей in-glass-шкалы (см. --surface-tint). */
    --bg-hover: color-mix(in srgb, var(--surface-tint) 8%, transparent);
    /* Стеклянная подложка (глобальное «стекло»). Литерал намеренно: тёмное стекло — это
       серый film, не выводится из лестницы --bg-* симметрично светлой теме. Единый источник. */
    --chat-input-bg: rgba(53, 53, 53, 0.4);

    --text-main: #ffffff;
    --text-muted: #a3a3a3;
    --text-subtle: #71717a;
    --text-inverse: #000000;
    --primary-text: #111111;

    /* Default chrome-icon color (theme-aware via --text-muted).
       Used by sidebar nav, chat-history avatars, social icons, etc. */
    --icon-default: var(--text-muted);
    --icon-hover: var(--text-main);

    /* ============================================================
       НЕЙТРАЛЬНЫЕ ПОВЕРХНОСТИ — контракт из 3 категорий
       (подробнее — .github/copilot-instructions.md):
         A. Сплошные на фоне темы — лестница --bg-* выше (тема-зависимы).
         B. Полупрозрачные ВНУТРИ стекла — шкала --surface-* от одного --surface-tint.
         C. Оверлеи НАД медиа — --overlay-* (чёрный скрим, НЕ зависят от темы).
       ============================================================ */

    /* B. In-glass translucent: один tint на тему + шкала через color-mix.
       В [data-theme="light"] флипается ТОЛЬКО --surface-tint. */
    --surface-tint: #ffffff;
    --surface-soft:   color-mix(in srgb, var(--surface-tint) 6%,  transparent); /* rest-плашка в стекле */
    --surface-active: color-mix(in srgb, var(--surface-tint) 10%, transparent); /* selected/active */
    --surface-strong: color-mix(in srgb, var(--surface-tint) 14%, transparent); /* hover/emphasis */
    /* Тёмный дим (НЕ tint, чёрный в обеих темах) — утопленные колодцы, icon-кнопки поверх поверхности. */
    --surface-dim: rgba(0, 0, 0, 0.2);
    /* Контентные подложки — фиксированы (цвет диктует контент, не тема): */
    --surface-paper: #ffffff;   /* HTML-док, QR, платёжная картинка — нужен белый лист */
    --media-letterbox: #000000; /* чёрные поля под <video>/превью */
    /* Подложка под акцентным инлайн-текстом (ссылки, инлайн-код): в тёмной теме
       лайм читается сам, поэтому нейтральный серый чип; в светлой — тёмный
       пузырёк (см. переопределение в [data-theme="light"]), иначе лайма не видно. */
    --surface-accent: var(--surface-soft);

    /* C. Оверлеи над медиа (чёрный скрим + светлый текст; в [data-theme="light"] НЕ трогаем).
       Активная кнопка над медиа = bg:--overlay-text (#fff) + text:--primary-text (#111);
       текст/иконки над медиа = --overlay-text (объявлен в Base Palette выше). */
    --overlay-scrim: rgba(0, 0, 0, 0.4);
    --overlay-pill-bg-soft: rgba(0, 0, 0, 0.45);
    --overlay-pill-bg: rgba(0, 0, 0, 0.55);
    --overlay-pill-bg-strong: rgba(0, 0, 0, 0.72);
    --overlay-control-bg: rgba(255, 255, 255, 0.2); /* неактивная кнопка-контрол над медиа */

    /* Затемнение всего UI за модалкой — тема-зависимо (мягче в светлой). НЕ категория C. */
    --overlay-backdrop: rgba(0, 0, 0, 0.6);
    --overlay-backdrop-soft: rgba(0, 0, 0, 0.5);
    --spinner-track: color-mix(in srgb, var(--text-main) 18%, transparent);
    --spinner-mid: color-mix(in srgb, var(--text-main) 42%, transparent);
    --spinner-head: color-mix(in srgb, var(--text-main) 72%, transparent);

    /* --- Accent Gradient --- */
    --accent-cool: #3b82f6;
    --accent-warm: #ff7a00;
    --gradient-warm: #fb923c;
    /* Серый градиент заголовков: .hero-title (медиа) и h1 в чат-рендеринге. */
    --heading-gradient: linear-gradient(90deg, var(--text-main), var(--text-muted));
    --scrollbar-thumb-light: #d1d5db;
    --settings-thumb-shadow: rgba(249, 115, 22, 0.4);

    /* --- Payment (SBP) --- */
    --sbp-stop-1: #7021d6;
    --sbp-stop-2: #d93568;
    
    /* --- Z-Index Layers --- */
    --z-dropdown: 9000;  /* Dropdowns: above everything except modals */
    --z-backdrop: 60;  /* Sidebar/Menu overlay */
    --z-sidebar: 70;   /* Sidebar/Menu panel */
    --z-modal: 9999;
    --z-fullscreen-modal: 10000; /* Fullscreen overlays (generation detail, etc.) */
    --z-dialog-above-overlay: 10100; /* Dialogs stacked on top of fullscreen overlays (lightbox, camera angle, relight) */

    /* --- Shadows --- */
    --shadow-glass: 0 8px 32px 0 rgba(0, 0, 0, 0.25);
    --shadow-surface: 0 1px 2px rgba(0, 0, 0, 0.18);
    --shadow-dropdown: 0 16px 40px -24px rgba(0, 0, 0, 0.6);
    --shadow-icon: 0 6px 12px -6px rgba(0, 0, 0, 0.4);
    --shadow-modal: 0 24px 50px -28px rgba(0, 0, 0, 0.7);
    --shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-code: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
    --shadow-lightbox: 0 16px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.06);
    --glow-spotlight: rgba(255, 255, 255, 0.4);

    /* --- Accent Glow / Ring (производные от --primary-500: перекрашиваются
       вместе с data-accent). Ring — hairline-кольцо инсетом (без сдвига layout),
       glow — мягкое внешнее свечение. Комбинируются: box-shadow: ring, glow. --- */
    --ring-accent-soft: inset 0 0 0 1px color-mix(in srgb, var(--primary-500) 40%, transparent);
    --ring-accent-strong: inset 0 0 0 1.5px color-mix(in srgb, var(--primary-500) 75%, transparent);
    --glow-accent-soft: 0 0 20px -4px var(--primary-20);
    --glow-accent-strong: 0 0 34px -6px color-mix(in srgb, var(--primary-500) 38%, transparent);

    /* --- Layout Grid (Page/App) --- */
    --layout-max-width: 64rem;
    --layout-pad-y: 2rem;
    --app-gutter-x: 1rem;      /* 16px, aligns with px-4 */
    --app-gutter-x-md: 1.5rem; /* 24px, aligns with md:px-6 */
    --app-frame-inset-desktop: 12px; /* shared desktop inset for floating panels + docked input */
    --shell-secondary-panel-width: 18rem;
    --media-sidebar-width: 18rem;
    --media-sidebar-grid-columns: 1;
    --media-sidebar-resize-gap: 0.75rem;

    /* Chat mobile composer gutters (closer to screen edges) */
    --chat-mobile-gutter-x: 0.5rem;

    /* Drawer / Modal max-height (mobile-first: 80% viewport) */
    --drawer-max-h: 80vh;

}

/* --- Payment Outcome (benefit highlight) --- */
.payment-outcome-item.is-benefit {
    background: linear-gradient(180deg, color-mix(in srgb, var(--primary-10) 66%, var(--bg-elevated)) 0%, color-mix(in srgb, var(--primary-10) 24%, transparent) 100%);
    box-shadow: 0 18px 30px -28px color-mix(in srgb, var(--primary-500) 28%, transparent);
}
.payment-outcome-item.is-benefit .payment-outcome-value {
    font-family: var(--font-display);
    font-size: clamp(var(--text-lg), 2.1vw, var(--text-2xl));
    line-height: 1;
    color: color-mix(in srgb, var(--primary-600) 72%, var(--text-main));
}

/* --- Subscription Plan Cards (featured) --- */
.subscription-plan-card.is-featured::before {
    content: '';
    position: absolute;
    inset: -18% auto auto 58%;
    width: 10rem;
    height: 10rem;
    border-radius: 50%;
    background: radial-gradient(circle, color-mix(in srgb, var(--primary-18) 72%, transparent) 0%, transparent 72%);
    pointer-events: none;
}
.subscription-plan-card.is-featured .subscription-plan-action.btn-primary {
    box-shadow: 0 20px 34px -24px color-mix(in srgb, var(--primary-500) 42%, transparent);
}
.subscription-plan-slider__heading {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.45rem;
}
.subscription-plan-slider__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.26rem 0.55rem;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--primary-500) 16%, var(--bg-elevated));
    color: color-mix(in srgb, var(--primary-600) 78%, var(--text-main));
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* ── Accent Color Overrides ── */
[data-accent="mint"]  { --primary-500: #34d399; --primary-600: #10b981; --primary-700: #059669; }
[data-accent="zinc"]  { --primary-500: #a1a1aa; --primary-600: #8c8c96; --primary-700: #71717a; }
[data-accent="sky"]   { --primary-500: #38bdf8; --primary-600: #0ea5e9; --primary-700: #0284c7; }
[data-accent="violet"]{ --primary-500: #a78bfa; --primary-600: #8b5cf6; --primary-700: #7c3aed; }

/* Safe-area env vars (only if supported) */
@supports (padding-top: env(safe-area-inset-top)) {
    :root {
        --safe-area-top: env(safe-area-inset-top);
    }
}

/* Announcement banner: collapses via max-height transition */
.global-announcement {
    position: relative;
    z-index: 90;
    overflow: hidden;
    box-sizing: border-box;
    max-height: calc(var(--announcement-height) + var(--safe-area-top));
    height: calc(var(--announcement-height) + var(--safe-area-top));
    padding-top: var(--safe-area-top);
    background: var(--promo-bg);
    color: var(--promo-text);
    transition: max-height var(--motion-duration-base) var(--motion-ease-standard);
}

.global-announcement.closed {
    max-height: 0;
}

.global-announcement__inner {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: var(--announcement-height);
    width: 100%;
    padding: 0 3.25rem;
}

.global-announcement__text {
    font-size: var(--text-lg);
    font-weight: var(--font-weight-medium);
    line-height: 1;
    text-align: center;
}

.global-announcement__close {
    position: absolute;
    right: 0.875rem;
    top: 50%;
    transform: translateY(-50%);
    width: 2rem;
    height: 2rem;
    border: 0;
    background: transparent;
    color: var(--promo-text);
    opacity: 0.7;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    transition: opacity var(--transition-fast), background-color var(--transition-fast);
}

@media (hover: hover) {
    .global-announcement__close:hover {
        opacity: 1;
        background: color-mix(in srgb, var(--promo-text) 10%, transparent);
    }
}

.global-announcement__close:focus-visible {
    box-shadow: 0 0 0 2px var(--promo-text-38);
}

@media (max-width: 767.98px) {
    :root {
        --announcement-height: 2.25rem;
    }

    .global-announcement__inner {
        padding: 0 2.75rem 0 0.75rem;
    }

    .global-announcement__text {
        font-size: var(--text-sm);
        line-height: 1.2;
    }

    .global-announcement__close {
        right: 0.5rem;
        width: 1.875rem;
        height: 1.875rem;
    }
}

/* ========================================
   Subscription Banner (NS ULTRA)
   ======================================== */
.ultra-banner {
    position: relative;
    border-radius: var(--radius-lg);
    overflow: hidden;
    pointer-events: auto;
    min-height: 5.5rem;
}

.ultra-banner__bg {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background: color-mix(in srgb, var(--ambient-accent-700) 60%, black);
}

.ultra-banner__video {
    position: absolute;
    left: 0;
    top: -100%;
    width: 100%;
    height: 200%;
    object-fit: cover;
    object-position: center top;
    pointer-events: none;
}

.ultra-banner__bg::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    background:
        linear-gradient(135deg,
            color-mix(in srgb, var(--ambient-accent-700) 70%, black) 0%,
            color-mix(in srgb, var(--ambient-accent-600) 40%, transparent) 50%,
            transparent 100%);
}

.ultra-banner__content {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    padding: 1.25rem 1.5rem;
    gap: 1rem;
}

.ultra-banner__text {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
    flex: 1 1 16rem;
}

.ultra-banner__label {
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-style: italic;
    font-weight: var(--font-weight-medium);
    color: var(--overlay-text);
    line-height: 1.2;
}

.ultra-banner__brand {
    font-family: var(--font-display);
    font-size: 1.75rem;
    font-weight: var(--font-weight-medium);
    color: var(--overlay-text);
    line-height: 1.1;
    letter-spacing: 0.12em;
}

.ultra-banner__subtitle {
    max-width: 28rem;
    font-size: var(--text-sm);
    line-height: 1.45;
    color: color-mix(in srgb, var(--overlay-text) 82%, transparent);
}

.ultra-banner__actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 0.5rem;
    flex-shrink: 0;
    margin-left: auto;
}

.ultra-banner__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    padding: 0.75rem 1.75rem;
    border-radius: var(--radius-lg);
    background: var(--overlay-scrim);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    color: var(--overlay-text);
    font-size: var(--text-base);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    white-space: nowrap;
    transition: background var(--transition-fast), transform var(--transition-fast);
}

.ultra-banner--warning .ultra-banner__content {
    align-items: flex-start;
}

@media (hover: hover) {
    .ultra-banner__btn:hover {
        background: var(--overlay-pill-bg);
        transform: translateY(-1px);
    }
}

@media (max-width: 479.98px) {
    .ultra-banner {
        min-height: 4.5rem;
    }

    .ultra-banner__content {
        padding: 1rem 1.25rem;
    }

    .ultra-banner__actions {
        width: 100%;
        margin-left: 0;
        justify-content: flex-start;
    }

    .ultra-banner__label {
        font-size: 1rem;
    }

    .ultra-banner__brand {
        font-size: 1.35rem;
    }

    .ultra-banner__btn {
        flex: 1 1 auto;
        padding: 0.625rem 1.25rem;
        font-size: var(--text-sm);
    }
}

@media (min-width: 768px) {
    :root {
        --layout-pad-y: 3rem;
        --app-gutter-x: var(--app-gutter-x-md);
    }
}

/* --- Z-Index Utilities --- */
.z-dropdown { z-index: var(--z-dropdown) !important; }
.z-backdrop { z-index: var(--z-backdrop) !important; }
.z-sidebar  { z-index: var(--z-sidebar)  !important; }
.z-modal    { z-index: var(--z-modal)    !important; }

/* Системное модальное окно (alert/confirm) должно всплывать поверх
   fullscreen overlay'ев (generation detail и т.п.), иначе диалог подтверждения
   удаления «прячется» за overlay'ем. См. fullscreen-dialog-stacking. */
#app-modal { z-index: var(--z-dialog-above-overlay); }

/* ctxMenu-портал, открытый ИЗ модалки (параметры ассистента), должен всплывать
   над ней. Портал не телепортируется и стоит в DOM раньше позже-телепортнутой
   модалки → при равном z-index (--z-modal) модалка перекрывает меню. !important
   поднимает портал выше (инлайновый z-index:9999 — без important). */
.dropdown-above-modal { z-index: var(--z-dialog-above-overlay) !important; }

:is(.settings-panel, .model-modal, .payment-modal, .assistant-modal, .prompt-library-panel) {
    transition: opacity var(--motion-duration-base) var(--motion-ease-premium), transform var(--motion-duration-base) var(--motion-ease-premium), box-shadow var(--transition), background-color var(--transition);
    will-change: opacity, transform;
}

.dropdown-panel,
.chat-input-state-shell {
    transition: opacity var(--motion-duration-fast) var(--motion-ease-premium), transform var(--motion-duration-fast) var(--motion-ease-premium), box-shadow var(--transition), background-color var(--transition), border-radius var(--transition);
    will-change: opacity, transform;
}

/* ========================================
   2. THEME OVERRIDES
   ======================================== */
[data-theme="light"] {
    --bg-app: #f3f4f6;
    --bg-panel: #ffffff;
    --bg-input: #f0f2f5;
    --bg-elevated: #ebedf0;
    --bg-raised: #e5e7eb;
    --bg-raised-hover: #d4d4d8;
    --chat-input-bg: rgba(255, 255, 255, 0.7);

    --text-main: #111827;
    --text-muted: #6b7280;
    --text-subtle: #6b7280;
    --text-inverse: #ffffff;
    --primary-text: #111111;

    --settings-thumb-shadow: rgba(249, 115, 22, 0.35);

    /* B. Достаточно флипнуть tint — шкала --surface-soft/active/strong и --bg-hover
       пересчитаются на чёрный. surface-dim чуть мягче на свету. */
    --surface-tint: #000000;
    --surface-dim: rgba(0, 0, 0, 0.1);
    /* Тёмный пузырёк под акцентным инлайн-текстом — чтобы лайм читался на светлом фоне. */
    --surface-accent: #18181b;
    /* Затемнение за модалкой — мягче на свету. C-оверлеи (--overlay-scrim/pill*) НЕ трогаем. */
    --overlay-backdrop: rgba(0, 0, 0, 0.25);
    --overlay-backdrop-soft: rgba(0, 0, 0, 0.4);

    /* Panel fade gradients should blend into the white panel surface, not the
       grayer --bg-elevated token used in dark mode. */
    --surface-fade-top-tint-color: var(--bg-panel);

    /* Shadows — subtle but present for visual depth */
    --shadow-glass: 0 1px 3px rgba(0, 0, 0, 0.06);
    --shadow-surface: 0 1px 2px rgba(0, 0, 0, 0.05);
    --shadow-dropdown: 0 12px 36px -8px rgba(0, 0, 0, 0.12);
    --shadow-icon: 0 1px 3px rgba(0, 0, 0, 0.08);
    --shadow-modal: 0 16px 48px -12px rgba(0, 0, 0, 0.15);
    --shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.06);
    --shadow-code: 0 1px 3px rgba(0, 0, 0, 0.04);
    --shadow-lightbox: 0 8px 32px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.08);
    --glow-spotlight: rgba(0, 0, 0, 0.2);

    /* Свечение акцента на светлом фоне «грязнит» — ослабляем и темним (700). */
    --glow-accent-soft: 0 0 14px -6px var(--primary-20);
    --glow-accent-strong: 0 0 22px -8px color-mix(in srgb, var(--primary-700) 30%, transparent);
}

[data-theme="light"] .bg-svg {
    --ambient-accent-500: #767a86;
    --ambient-accent-600: #5f6470;
    --ambient-accent-700: #4a4f5b;
}

[data-theme="light"] :is(.bg-svg-desktop-copy path, .bg-svg-mobile-letter) {
    fill-opacity: 0.25;
}

/* Light mode: theme-specific class overrides */
[data-theme="light"] .icon-circle-primary {
    background-color: var(--primary-500);
    color: var(--primary-text);
}

[data-theme="light"] .icon-chip-primary {
    background-color: var(--primary-20);
    color: var(--primary-500);
}

[data-theme="light"] .think-accordion {
    background-color: var(--bg-elevated);
    box-shadow: var(--shadow-surface);
}

/* Кнопки действий под сообщением — то же стекло, что и контейнер чата
   (активная/выбранная — плотный акцент, без стекла). */
/* Кнопки действий под сообщением — полупрозрачный токен БЕЗ backdrop-filter (перф при скролле). */
.btn.chat-message-action-btn:not(.chat-message-action-btn-active) {
    background-color: var(--chat-input-bg);
    box-shadow: var(--shadow-glass);
}

@media (hover: hover) {
    .btn.chat-message-action-btn:not(.chat-message-action-btn-active):hover {
        background-color: var(--surface-strong);
    }
}

.chat-message-action-btn-active {
    background-color: var(--bg-raised);
}

[data-theme="light"] .chat-message-action-btn-active {
    box-shadow: var(--shadow-surface);
}

[data-theme="light"] .upload-overlay {
    background-color: color-mix(in srgb, var(--bg-panel) 60%, transparent);
}

/* ========================================
   3. RESET & BASE
   ======================================== */
*, *::before, *::after { 
    box-sizing: border-box;
}

/* Smooth theme transitions (background, color, shadow) */
html[data-theme] body,
html[data-theme] .surface,
html[data-theme] .modal-card,
html[data-theme] .dropdown-panel,
html[data-theme] .btn,
html[data-theme] .input-field {
    transition: background-color var(--motion-duration-base) var(--motion-ease-standard),
                color var(--motion-duration-base) var(--motion-ease-standard),
                box-shadow var(--motion-duration-base) var(--motion-ease-standard);
}

html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
    scrollbar-gutter: stable;
    background-color: var(--bg-app);
    color: var(--text-main);
    font-family: var(--font-sans);
}

body {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background-color: var(--bg-app);
    position: relative;
}

/* Inline background SVG — positioned behind all content */
.bg-svg {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
}
.bg-svg-base { fill: var(--bg-app); }
/* Glow ellipse behind the wordmark — brighter in dark theme so it actually
   reads against near-black --bg-app. Light theme keeps the original wash. */
.bg-svg-glow-stop-near { stop-opacity: 0.17; }
.bg-svg-glow-stop-mid  { stop-opacity: 0.10; }
[data-theme="light"] .bg-svg-glow-stop-near { stop-opacity: 0.12; }
[data-theme="light"] .bg-svg-glow-stop-mid  { stop-opacity: 0.07; }
.bg-svg-mobile-copy { display: none; }
.bg-svg-mobile-letter {
    font-family: var(--font-display);
    font-size: 980px;
    font-weight: var(--font-weight-medium);
    line-height: 1;
}

@media (max-width: 767.98px) {
    .bg-svg-desktop-copy { display: none; }
    .bg-svg-mobile-copy { display: block; }
}

/* Scrollbars */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; margin-block: 4px; }
::-webkit-scrollbar-thumb { background: var(--bg-raised); border-radius: var(--radius-chat-tail); }
[data-theme="light"] ::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb-light); }

/* Чистая скролл-область: нативный индикатор скрыт (модалки, панели, списки,
   textarea), скролл работает колесом/тачем/клавиатурой. Единый маркер. */
.custom-scrollbar { scrollbar-width: none; -ms-overflow-style: none; }
.custom-scrollbar::-webkit-scrollbar { display: none; }

/* 
 * CRITICAL: Visibility Helpers
 * We delegate .hidden to Tailwind to avoid !important conflicts with responsive display classes (e.g. hidden md:flex)
 */
[hidden], [x-cloak] { display: none !important; }

/* ========================================
   4. GLASS & COMPONENTS
   ======================================== */

/* --- Glass Blur (shared translucent panel style) --- */
.signin-card,
.auth-btn,
.signin-glass-input,
:is(.settings-panel, .model-modal, .payment-modal, .assistant-modal, .prompt-library-panel),
.sidebar-shell,
.chat-input-shell,
.modal-controls-panel,
.shell-mobile-chat-header-btn,
.shell-desktop-header__toggle,
.shell-user-pill,
.shell-user-pill--standalone,
.shell-tabs {
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
}

/* --- Specific Components --- */

/* Signin Video Background */
.signin-video-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
}

.signin-floating-logo {
    top: 1.25rem;
    transition: top var(--motion-duration-base) var(--motion-ease-standard);
}

/* Signin bg is fixed (ignores flow), so logo needs explicit offset when banner is visible */
body[data-announcement-open="1"] .signin-floating-logo {
    top: calc(var(--announcement-height) + var(--safe-area-top) + 1.25rem);
}

/* Signin Card (glass-blur like chat input) */
.signin-card {
    box-shadow: var(--shadow-glass);
    transform: translateZ(0);
    backface-visibility: hidden;
}
@media (min-width: 640px) {
    .signin-card {
        height: 100%;
        border-radius: 0 var(--radius-2xl) var(--radius-2xl) 0 !important;
    }
}
@media (max-width: 639px) {
    .signin-card {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        max-width: 100%;
        border-radius: var(--radius-xl) var(--radius-xl) 0 0 !important;
        padding: 1.25rem 1.25rem calc(env(safe-area-inset-bottom, 0.5rem) + 0.5rem);
    }

    .signin-floating-logo {
        top: 0.5rem;
    }
    body[data-announcement-open="1"] .signin-floating-logo {
        top: calc(var(--announcement-height) + var(--safe-area-top) + 0.5rem);
    }
}

/* ===== Шторка авторизации: сайдбар-оверлей поверх публичных страниц.
   Переиспользует карточку .signin-card (_auth_panel.html), но без полноэкранного
   фона — выезжает слева, страница видна за затемнением. /login (signin.html)
   остаётся отдельной полноэкранной страницей. Разметка — _auth_overlay.html. */
.auth-overlay__scrim {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: color-mix(in srgb, #000 55%, transparent);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s var(--motion-ease-standard),
                visibility 0.25s var(--motion-ease-standard);
}
.auth-overlay__scrim.is-open {
    opacity: 1;
    visibility: visible;
}

.auth-overlay__drawer {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 61;
    width: min(86vw, 360px);
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform 0.32s var(--motion-ease-standard),
                visibility 0.32s var(--motion-ease-standard);
    will-change: transform;
}
.auth-overlay__drawer.is-open {
    transform: translateX(0);
    visibility: visible;
}
/* Десктоп: боковая панель сидит ниже промо-баннера, чтобы он был виден сверху.
   (На мобиле шторка — нижний лист, ему смещение по top не нужно.) */
@media (min-width: 640px) {
    body[data-announcement-open="1"] .auth-overlay__drawer {
        top: calc(var(--announcement-height) + var(--safe-area-top));
    }
}

/* Внутри оверлея карточка просто заполняет drawer: гасим
   standalone-позиционирование .signin-card (fixed bottom-sheet / height:100%). */
.auth-overlay__card.signin-card {
    position: relative !important;
    inset: auto !important;
    width: 100% !important;
    height: 100% !important;
    max-width: 100% !important;
    overflow-y: auto;
    border-radius: 0 var(--radius-2xl) var(--radius-2xl) 0 !important;
}

/* Плавающий логотип «в шапке» (вне карточки, поверх затемнения) — как на /login.
   top и смещение под баннер берём из .signin-floating-logo. */
.auth-overlay__brand {
    position: fixed;
    left: 1.25rem;
    z-index: 62;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s var(--motion-ease-standard),
                visibility 0.25s var(--motion-ease-standard);
}
.auth-overlay__brand.is-open {
    opacity: 1;
    visibility: visible;
}
.auth-overlay__close {
    position: absolute;
    top: 1.25rem;
    right: 1.25rem;
    z-index: 2;
    padding: 0.5rem;
}

/* Мобайл: шторка — нижний лист (как на странице /login), выезжает снизу. */
@media (max-width: 639px) {
    .auth-overlay__drawer {
        top: auto;
        left: 0;
        right: 0;
        bottom: 0;
        width: 100%;
        transform: translateY(100%);
    }
    .auth-overlay__drawer.is-open {
        transform: translateY(0);
    }
    .auth-overlay__card.signin-card {
        height: auto !important;
        max-height: 88dvh;
        border-radius: var(--radius-xl) var(--radius-xl) 0 0 !important;
        padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
    }
    /* На мобиле закрытие — свайпом вниз / тапом по фону: крестик и логотип прячем.
       Для лого нужен двойной класс — иначе .site-logo (ниже по файлу) вернёт display:flex. */
    .auth-overlay__close,
    .auth-overlay__brand.site-logo {
        display: none;
    }
}

/* Auth Buttons (Signin) */
.site-logo {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    color: var(--text-main);
    transition: var(--transition);
    text-decoration: none;
}
@media (hover: hover) {
    .site-logo:hover { opacity: 0.8; }
}
/* Единый знак бренда — один ассет через CSS-маску, перекрашивается currentColor
   (наследует цвет контейнера, т.е. тему). Источник: круглый знак favicon.svg
   (альфа-канал задаёт форму, цвет файла не важен). Размер — от контейнера.
   Заменяет инлайн-SVG по всему проекту. */
.brand-logo {
    display: block;
    flex-shrink: 0;
    background-color: currentColor;
    -webkit-mask: url("/static/media/favicon.svg") center / contain no-repeat;
            mask: url("/static/media/favicon.svg") center / contain no-repeat;
}

.auth-btn {
    box-shadow: var(--shadow-glass);
    transition: var(--transition);
}
@media (hover: hover) {
    .auth-btn:hover {
        background-color: var(--bg-hover);
    }
}
.auth-social-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: var(--radius-pill);
    overflow: hidden;
    transition: var(--transition);
    cursor: pointer;
}
@media (hover: hover) {
    .auth-social-icon:hover {
        opacity: 0.8;
    }
}
.auth-social-icon img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}
.auth-divider {
    color: var(--text-subtle);
}
.signin-glass-input {
    width: 100%;
    box-shadow: var(--shadow-inset);
    color: var(--text-main);
    outline: none;
    border: none;
    transition: var(--transition);
}

/* Settings Modal / Drawer */
:is(.settings-panel, .model-modal, .assistant-modal, .prompt-library-panel) {
    border-radius: var(--radius-3xl) var(--radius-3xl) 0 0;
    box-shadow: var(--shadow-modal);
}
@media (min-width: 640px) {
    :is(.settings-panel, .model-modal, .assistant-modal, .prompt-library-panel) {
        border-radius: var(--radius-xl);
    }
}
.settings-thumb {
    background-color: var(--bg-panel);
    box-shadow: 0 0 15px var(--settings-thumb-shadow);
    border-radius: var(--radius-pill);
}

/* Preview Iframe */
.preview-iframe { background-color: var(--bg-panel); }

/* Shape & Flex Utilities */
.shape { border-radius: var(--radius-lg); }
.shape-pill { border-radius: var(--radius-pill); }

/* Composer shells: slightly larger corner radius than generic .shape */
.chat-input-shell.shape { border-radius: var(--radius-xl); }
/* Pill-состояние композера: КОНЕЧНЫЙ радиус (половина схлопнутой высоты),
   а не --radius-pill. Transition интерполирует ЗАДАННОЕ значение, и от 9999px
   видимый радиус весь переход сидит в клампе h/2, «допрыгивая» до целевого
   в последних кадрах. */
.chat-input-shell.shape-pill { border-radius: calc(var(--chat-input-shell-min-height) / 2); }
.text-2xs { font-size: var(--text-2xs); line-height: 1rem; }

.flex-center { display: inline-flex; align-items: center; justify-content: center; }

/* Button Utilities */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--gap-sm);
    font-weight: var(--font-weight-semibold);
    border-radius: var(--radius-lg);
    padding: 0.5rem 1rem;
    font-size: var(--text-base);
    transition:
        background-color var(--transition),
        color var(--transition),
        box-shadow var(--transition),
        opacity var(--transition-fast),
        filter var(--transition);
}
.btn-lg { padding: 0.75rem 1.5rem; font-size: var(--text-base); }
.btn-block { width: 100%; }
.btn-primary {
    background-color: var(--primary-500);
    background-image: linear-gradient(135deg, var(--primary-600), var(--primary-500));
    color: var(--primary-text);
}
@media (hover: hover) {
    .btn-primary:hover {
        background-color: var(--primary-600);
        filter: saturate(1.08) brightness(1.03);
    }
}
@media (hover: hover) {
    .btn:hover {
        filter: saturate(1.02);
    }
}
.btn:active {
    filter: saturate(0.98);
}
.btn-secondary {
    background-color: var(--bg-elevated);
    color: var(--text-main);
}
.btn-ghost {
    background-color: var(--bg-input);
    color: var(--text-main);
}
.btn:disabled,
.btn.is-disabled {
    background-color: var(--bg-input);
    background-image: none;   /* сбрасываем градиент .btn-primary, иначе disabled выглядит активной */
    color: var(--text-muted);
    box-shadow: none;
    cursor: not-allowed;
}

/* Utility Classes */
.ff-display { font-family: var(--font-display); }
.text-legal  { font-size: 10px; }
.btn-surface  { background-color: var(--bg-app); color: var(--text-main); }
@media (hover: hover) {
    .btn-secondary:hover,
    .btn-ghost:hover,
    .btn-surface:hover {
        background-color: var(--bg-hover);
    }
}

/* Motion Utilities */
.motion {
    transition-property: transform, opacity, color, background-color, box-shadow, filter;
    transition-duration: var(--motion-duration-base);
    transition-timing-function: var(--motion-ease-premium);
}

@keyframes loading-spinner-rotate {
    to { transform: rotate(360deg); }
}

.loading-spinner {
    --spinner-size: 1.25rem;
    --spinner-thickness: 0.2rem;
    width: var(--spinner-size);
    height: var(--spinner-size);
    border-radius: var(--radius-pill);
    display: inline-block;
    background: conic-gradient(from 180deg, var(--spinner-head) 0deg, var(--spinner-mid) 220deg, var(--spinner-track) 285deg, transparent 330deg 360deg);
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--spinner-thickness)), var(--text-inverse) calc(100% - var(--spinner-thickness)));
    mask: radial-gradient(farthest-side, transparent calc(100% - var(--spinner-thickness)), var(--text-inverse) calc(100% - var(--spinner-thickness)));
    animation: loading-spinner-rotate 0.9s linear infinite;
}

.loading-spinner-xs {
    --spinner-size: 1rem;
    --spinner-thickness: 0.18rem;
}
.loading-spinner-sm { --spinner-size: 1.5rem; }

/* Surface */
.surface {
    background-color: var(--bg-panel);
    box-shadow: var(--shadow-surface);
}
.pager-btn {
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius-md);
    background-color: var(--bg-app);
    color: var(--text-muted);
    transition: var(--transition);
}
@media (hover: hover) {
    .pager-btn:hover {
        color: var(--primary-500);
    }
}
.dropdown-panel,
.model-flyout {
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    box-shadow: var(--shadow-glass);
}

.dropdown-panel {
    position: absolute;
    z-index: var(--z-dropdown);
    border-radius: var(--radius-lg);
}

/* Dropdown menus (unified look across the app)
   Apply via: class="dropdown-panel dropdown-menu ..." */
.dropdown-menu {
    display: flex;
    flex-direction: column;
    padding: 0.1875rem;
    max-height: min(60vh, 13.4375rem);
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.dropdown-menu::-webkit-scrollbar {
    display: none;
    width: 0;
    height: 0;
}

.dropdown-menu__title {
    padding: 0.4375rem 0.75rem 0.3125rem;
    font-size: var(--text-2xs);
    line-height: 1.2;
    font-weight: var(--font-weight-semibold);
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-subtle);
}

/* Некликабельная строка-описание в дропдауне (item.kind === 'description'),
   например краткое описание коннектора над кнопкой «Настройки». */
.dropdown-menu__desc {
    padding: 0.125rem 0.75rem 0.375rem;
    font-size: var(--text-xs);
    line-height: 1.35;
    color: var(--text-muted);
}

/* Поле ввода — стеклянный фон-тинт, но БЕЗ собственного backdrop-filter: почти всегда
   лежит внутри стеклянной модалки/сайдбара, второй блюр дал бы двойной (категория B). */
.input-field {
    width: 100%;
    background-color: var(--chat-input-bg);
    box-shadow: var(--shadow-inset);
    border-radius: var(--radius-base);
    color: var(--text-main);
    transition: var(--transition);
    outline: none;
    border: none;
}
.input-field-ghost {
    background-color: transparent;
    color: var(--text-main);
    outline: none;
}

/* ── Нативные чекбоксы = переключатели (глобально): та же анатомия, что у
      .media-params-pill__switch — «колодец»-трек + светлый ползунок, включение
      заливает трек акцентом. appearance:none делает input нестилизуемым
      браузером, ::after-ползунок на таких инпутах поддержан всеми evergreen. ── */
input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    position: relative;
    flex-shrink: 0;
    width: 2.1rem;
    height: 1.2rem;
    margin: 0;
    border-radius: var(--radius-pill);
    background: var(--surface-dim);
    cursor: pointer;
    vertical-align: middle;
    transition: background var(--transition);
}

input[type="checkbox"]::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 0.15rem;
    width: 0.9rem;
    height: 0.9rem;
    border-radius: var(--radius-pill);
    background: var(--surface-paper);
    box-shadow: var(--shadow-surface);
    transform: translateY(-50%);
    transition: transform var(--transition);
}

input[type="checkbox"]:checked {
    background: var(--primary-500);
}

input[type="checkbox"]:checked::after {
    transform: translateY(-50%) translateX(0.9rem);
}

input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--primary-500);
    outline-offset: 2px;
}

input[type="checkbox"]:disabled {
    opacity: 0.5;
    cursor: default;
}

.service-card {
    transition: box-shadow var(--motion-duration-base) var(--motion-ease-standard), filter var(--transition), background-color var(--transition);
}
@media (hover: hover) {
    .service-card:hover {
        filter: saturate(1.04);
    }
}
/* Чип в стекле (категория B): полупрозрачная подложка, сквозь которую читается блюр. */
.surface-chip {
    background-color: var(--surface-active);
    border-radius: var(--radius-pill);
    transition: background-color var(--transition), box-shadow var(--transition), color var(--transition);
}
@media (hover: hover) {
    .surface-chip:hover {
        background-color: var(--surface-strong);
        box-shadow: var(--shadow-surface);
    }
}
/* ── Inline media params tabs ── */
.media-params-block {
    display: flex;
    flex-direction: column;
    gap: 0.32rem;
    width: 100%;
    min-width: 0;
}

.media-params-bar {
    display: flex;
    align-items: center;
    gap: 0.24rem;
    width: 100%;
    min-width: 0;
    padding: 0;
    background: transparent;
}

.media-params-bar__strip {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    align-content: flex-start;
    flex: 1 1 auto;
    min-width: 0;
    gap: 0.25rem;
    max-height: 2.4rem;
    overflow: hidden;
}

.media-params-bar__meta {
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.28rem;
    flex: 0 0 auto;
    min-width: 0;
}

.media-params-bar__slot {
    position: relative;
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
}

.media-params-bar__slot.is-overflow {
    visibility: hidden;
    pointer-events: none;
}

.media-params-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.44rem;
    min-height: 2.4rem;
    padding: 0.44rem 0.78rem;
    max-width: 12rem;
    border: none;
    border-radius: var(--radius-lg);
    background: var(--surface-active);
    color: var(--text-main);
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    line-height: 1.15;
    white-space: nowrap;
    transition: background-color var(--transition), color var(--transition);
}

.media-params-pill__icon {
    flex-shrink: 0;
    font-size: 1.15rem;
    color: var(--text-main);
}

.media-params-pill__icon.media-params-pill__icon--aspect-preview {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.05rem;
    height: 1.05rem;
    font-size: 0;
}

.media-params-pill__icon.media-params-pill__icon--aspect-preview::before {
    content: '';
    width: var(--aspect-preview-width, 0.9rem);
    height: var(--aspect-preview-height, 0.9rem);
    border-radius: 0.18rem;
    box-shadow: inset 0 0 0 1.5px currentColor;
}

.media-params-pill__value {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

@media (hover: hover) {
    .media-params-pill:hover {
        background: var(--surface-strong);
    }
}

.media-params-pill.is-open {
    background: var(--surface-strong);
}

/* Toggle-переключатель в пилюле (вкл/выкл): тёмный «колодец»-трек + белый ползунок;
   при включении трек заливается акцентом (--primary-500), ползунок едет вправо.
   Сама пилюля фоном НЕ подсвечивается — состояние несёт только переключатель. */
.media-params-pill__switch {
    position: relative;
    flex-shrink: 0;
    width: 1.85rem;
    height: 1.05rem;
    border-radius: var(--radius-pill);
    background: var(--surface-dim);
    transition: background var(--transition);
}

.media-params-pill__switch::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 0.125rem;
    width: 0.8rem;
    height: 0.8rem;
    border-radius: var(--radius-pill);
    background: var(--text-main);
    box-shadow: var(--shadow-surface);
    transform: translateY(-50%);
    transition: transform var(--transition);
}

.media-params-pill__switch.is-on {
    background: var(--primary-500);
}

.media-params-pill__switch.is-on::after {
    transform: translateY(-50%) translateX(0.8rem);
}

.media-params-bar__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.4rem;
    height: 2.4rem;
    padding: 0;
    border: none;
    border-radius: var(--radius-lg);
    background: var(--surface-active);
    color: var(--text-main);
    transition: background-color var(--transition), color var(--transition);
}

.media-params-bar__toggle i {
    font-size: 1.15rem;
    transition: transform 200ms var(--motion-ease-standard);
}

.media-params-bar__toggle.is-open i {
    transform: rotate(180deg);
}

@media (hover: hover) {
    .media-params-bar__toggle:hover {
        background: var(--surface-strong);
    }
}

.media-params-bar__toggle:focus-visible {
    outline: none;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary-500) 28%, transparent);
}

.media-composer-price {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    gap: 0.3rem;
    color: var(--text-subtle);
    font-size: var(--text-sm);
    font-weight: var(--font-weight-medium);
    line-height: 1;
    white-space: nowrap;
}

.media-composer-price__label {
    color: var(--text-muted);
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-medium);
    line-height: 1;
}

.media-composer-price__detail {
    color: var(--text-muted);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
    line-height: 1;
    white-space: nowrap;
}

.media-composer-price__value {
    line-height: 1;
}

.media-params-expanded {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    pointer-events: none;
    transition:
        grid-template-rows var(--motion-duration-base) var(--motion-ease-premium),
        opacity var(--motion-duration-fast) var(--motion-ease-premium);
}

.media-params-expanded.is-open {
    grid-template-rows: 1fr;
    opacity: 1;
    pointer-events: auto;
}

.media-params-expanded__inner {
    overflow: hidden;
    min-height: 0;
    padding-top: 0;
    transition: padding-top var(--motion-duration-fast) var(--motion-ease-premium);
}

.media-params-expanded.is-open .media-params-expanded__inner {
    padding-top: 0.4rem;
}

.media-params-expanded__footer {
    display: flex;
    justify-content: flex-end;
    margin-top: 0.32rem;
}

.media-params-expanded__reset {
    display: inline-flex;
    align-items: center;
    gap: 0.32rem;
    padding: 0.28rem 0.6rem;
    border: none;
    border-radius: var(--radius-lg);
    background: transparent;
    color: var(--text-muted);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
    cursor: pointer;
    transition: background-color var(--transition), color var(--transition);
}

.media-params-expanded__reset i {
    font-size: 0.95rem;
}

@media (hover: hover) {
    .media-params-expanded__reset:hover {
        background: var(--bg-hover);
        color: var(--text-main);
    }
}

.media-params-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    width: 100%;
    align-items: stretch;
}

.media-params-grid__item {
    display: flex;
    min-width: 0;
    flex: 0 1 8.6rem;
    width: min(100%, 8.6rem);
    align-self: stretch;
}

.media-params-grid__item.is-compact {
    flex-basis: 7.8rem;
    width: min(100%, 7.8rem);
}

.media-params-grid__item.is-range {
    flex-basis: 10.6rem;
    width: min(100%, 10.6rem);
}

.media-params-grid__item.is-wide {
    flex-basis: 100%;
    width: 100%;
}

.media-composer-top-stack {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 0.32rem;
    margin-bottom: 0.42rem;
}

/* Scroll-region / dock-region inside media composer.
   Desktop: both regions flow naturally (no max-height).
   Mobile: scroll-region caps composer height and scrolls, dock stays pinned. */
.media-composer-scroll-region {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.media-composer-dock-region {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex-shrink: 0;
}

/* Composer scroll areas must not reserve a visible scrollbar gutter while expanding.
   (.custom-scrollbar здесь не нужен — он скрыт глобальным правилом.) */
:is(.chat-input-shell, .media-composer-shell) .media-composer-scroll-region {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

:is(.chat-input-shell, .media-composer-shell) .media-composer-scroll-region::-webkit-scrollbar {
    display: none;
}

.media-setting-card,
.media-param-model-card {
    border-radius: var(--radius-base);
    background: color-mix(in srgb, var(--bg-panel) 68%, var(--bg-elevated) 32%);
    box-shadow: var(--shadow-surface);
}

.media-param-model-card {
    display: inline-flex;
    align-items: center;
    gap: 0.32rem;
    width: auto;
    max-width: 100%;
    flex: 0 0 auto;
    align-self: center;
    padding: 0.28rem 0.42rem;
    min-height: 2.16rem;
    border: none;
    color: var(--text-main);
    text-align: left;
    white-space: nowrap;
    transition: background-color var(--transition), box-shadow var(--transition);
}

.media-param-model-card--toolbar {
    max-width: min(42%, 14rem);
}

@media (hover: hover) {
    .media-param-model-card:hover,
    .media-setting-card:hover {
        background-color: var(--bg-hover);
    }
}

.media-setting-card__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.5rem;
}

.media-setting-card__label {
    font-size: var(--text-2xs);
    line-height: 1.25;
    letter-spacing: 0.02em;
    font-weight: var(--font-weight-semibold);
    color: var(--text-subtle);
}

.media-param-model-card__icon {
    flex-shrink: 0;
}

.media-setting-card__value {
    font-size: var(--text-sm);
    line-height: 1.25;
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
}

.media-param-model-card__name {
    font-size: var(--text-xs);
    line-height: 1.2;
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    min-width: 0;
    max-width: 8rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

.media-setting-card__hint,
.generation-mode-btn__hint {
    font-size: var(--text-2xs);
    line-height: 1.2;
    color: var(--text-subtle);
    /* Подписи вроде «старт и финал» шире узкой пилюли — переносим до 2 строк
       вместо обрезки многоточием («старт и фи…»). */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}

.media-param-model-card__price,
.media-setting-card__meta {
    flex-shrink: 0;
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
}

.media-param-model-card__chevron {
    flex-shrink: 0;
    font-size: 0.82rem;
    color: var(--text-subtle);
}

.media-setting-card {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    gap: 0.16rem;
    min-height: 0;
    padding: 0.38rem 0.42rem;
    transition: background-color var(--transition), box-shadow var(--transition);
}

.media-params-grid__item.is-compact .media-setting-card__hint {
    display: none;
}

.media-params-grid__item.is-compact .media-setting-card__value,
.media-params-grid__item.is-compact .media-setting-card__meta {
    font-size: var(--text-xs);
}

.media-setting-card--select {
    display: flex;
    flex-direction: column;
    gap: 0.16rem;
    width: 100%;
    padding: 0.38rem 0.42rem;
    border: none;
    border-radius: var(--radius-base);
    background: transparent;
    color: inherit;
    text-align: left;
    cursor: pointer;
    transition: background-color var(--transition);
}

@media (hover: hover) {
    .media-setting-card--select:hover {
        background: var(--bg-hover);
    }
}

.media-setting-card--select.is-open {
    background: var(--bg-hover);
}

.media-setting-card--toggle {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 0.56rem;
    cursor: pointer;
}

.media-setting-card__toggle-copy {
    display: flex;
    flex-direction: column;
    gap: 0.08rem;
    flex: 1 1 auto;
}

.media-setting-card__value {
    padding-right: 1rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.media-setting-card__chevron {
    flex-shrink: 0;
    color: var(--text-subtle);
    font-size: 1rem;
    transition: transform 200ms var(--motion-ease-standard);
}

.media-setting-card--select.is-open .media-setting-card__chevron {
    transform: rotate(180deg);
}

.media-setting-card--select:focus-visible {
    outline: none;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary-500) 28%, transparent);
}

.media-setting-card__field {
    width: 100%;
    min-height: 1.9rem;
    padding: 0.36rem 0.46rem;
    border: none;
    border-radius: var(--radius-md);
    background: var(--bg-input);
    color: var(--text-main);
    font-size: var(--text-xs);
    line-height: 1.35;
    outline: none;
    transition: box-shadow var(--transition), background-color var(--transition);
}

.media-setting-card__field::placeholder {
    color: var(--text-subtle);
}

.media-setting-card__field:focus {
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary-500) 28%, transparent);
}

.media-setting-card__field--textarea {
    min-height: 3.9rem;
    resize: vertical;
}

.media-setting-card__switch {
    position: relative;
    flex-shrink: 0;
    width: 2rem;
    height: 1.15rem;
    border: none;
    border-radius: var(--radius-pill);
    background: var(--bg-raised);
    transition: background-color var(--transition), transform var(--transition-fast);
}

.media-setting-card__switch.is-active {
    background: var(--primary-500);
}

.media-setting-card__switch-handle {
    position: absolute;
    top: 0.12rem;
    left: 0.12rem;
    width: 0.9rem;
    height: 0.9rem;
    border-radius: var(--radius-pill);
    background: var(--text-inverse);
    box-shadow: var(--shadow-surface);
    transition: transform var(--transition-fast);
}

.media-setting-card__switch-handle.is-active {
    transform: translateX(0.82rem);
}

.media-setting-card__slider {
    width: 100%;
    accent-color: var(--primary-500);
}

.media-setting-card__stack {
    display: flex;
    flex-direction: column;
    gap: 0.24rem;
    min-width: 0;
}

.media-composer-preview-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    align-items: center;
}

.media-composer-preview-card {
    width: 3rem;
    height: 3rem;
}

.media-frame-strip {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    align-items: center;
    max-width: 100%;
    /* Родитель (.media-composer-top-stack) обрезает overflow, поэтому небольшой
       запас под подъём карточки на hover (translateY -6px) и её тень. */
    padding: 0.7rem 0.4rem 0.5rem;
}

.media-frame-tile {
    position: relative;
    flex: 0 0 auto;
    width: 5.2rem;
    min-width: 4.6rem;
}

/* Фон — сплошной серый токен (--bg-raised), hover светлее (--bg-raised-hover);
   без рамки. Аффорданс пустой плитки — «+» в углу. */
.media-frame-tile__action {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 4 / 5;
    border: none;
    border-radius: var(--radius-lg);
    background: var(--bg-raised);
    color: var(--text-main);
    overflow: hidden;
    cursor: pointer;
    box-shadow: var(--shadow-glass);
    transition: transform var(--motion-duration-base) var(--motion-ease-elastic),
                background-color var(--transition),
                box-shadow var(--transition);
}

.media-frame-tile__action.has-media::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-app) 8%, transparent) 35%, color-mix(in srgb, var(--bg-app) 64%, transparent));
}

@media (hover: hover) {
    /* На hover карточка приподнимается — эластичная кривая проекта;
       фон усиливается до --surface-strong (как у пилюль). */
    .media-frame-tile__action:hover {
        transform: translateY(-6px) scale(1.03);
        background: var(--bg-raised-hover);
        box-shadow: var(--shadow-dropdown);
    }
}

@media (prefers-reduced-motion: reduce) {
    .media-frame-tile__action { transition: none; }
}

/* Иерархия кадров: старт — основной вход (i2v), конец — опциональный таргет.
   Конец приглушён, но остаётся явной кликабельной зоной (на hover оживает). */
[data-media-frame-tile="end"] .media-frame-tile__empty {
    opacity: 0.6;
    transition: opacity var(--transition);
}

@media (hover: hover) {
    [data-media-frame-tile="end"] .media-frame-tile__action:hover .media-frame-tile__empty {
        opacity: 1;
    }
}

/* «Конец» заблокирован, пока нет стартового кадра: приглушён, клик не работает
   (tooltip объясняет почему). disabled-атрибут не используем — он глушит hover,
   а tooltip должен показываться. */
.media-frame-tile__action.is-locked {
    opacity: 0.45;
    cursor: not-allowed;
}

@media (hover: hover) {
    .media-frame-tile__action.is-locked:hover {
        transform: none;
        background: var(--bg-raised);
        box-shadow: var(--shadow-glass);
    }
    [data-media-frame-tile="end"] .media-frame-tile__action.is-locked:hover .media-frame-tile__empty {
        opacity: 0.6;
    }
}

.media-frame-tile__media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.media-frame-tile__upload {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, var(--bg-app) 42%, transparent);
}

/* Слой-обложка для пустого состояния: «+» сверху-слева, подпись снизу. */
.media-frame-tile__empty {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    color: var(--text-muted);
}

.media-frame-tile__plus {
    position: absolute;
    top: 0.3rem;
    left: 0.42rem;
    font-size: 1.4rem;
    line-height: 1;
}

.media-frame-tile__text {
    position: absolute;
    left: 0.46rem;
    right: 0.46rem;
    bottom: 0.42rem;
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    line-height: 1.15;
}

.media-frame-tile__badge {
    position: absolute;
    left: 0.46rem;
    bottom: 0.42rem;
    z-index: 1;
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--overlay-text);
    text-shadow: 0 1px 2px color-mix(in srgb, var(--bg-app) 70%, transparent);
}

.media-frame-tile__clear {
    position: absolute;
    top: -0.18rem;
    right: -0.18rem;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.45rem;
    height: 1.45rem;
    border: none;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--bg-elevated) 82%, var(--bg-app));
    color: var(--text-main);
    box-shadow: var(--shadow-surface);
    transition: background-color var(--transition);
}

@media (hover: hover) {
    .media-frame-tile__clear:hover {
        background: color-mix(in srgb, var(--bg-panel) 78%, var(--bg-elevated));
    }
}

/* Декоративный коннектор-своп между Старт и Конец (не кнопка, aria-hidden). */
.media-frame-strip__flow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: center;
    flex: 0 0 auto;
    z-index: 2;
    width: 1.7rem;
    height: 1.7rem;
    margin: 0 -0.2rem;
    border-radius: var(--radius-pill);
    background: var(--bg-elevated);
    color: var(--text-muted);
    box-shadow: var(--shadow-surface);
    font-size: 0.95rem;
}

@media (min-width: 768px) {
    /* Карточки кадров наполовину «выходят» за верхнюю кромку контейнера композера.
       Только desktop: на mobile .media-composer-scroll-region режет overflow. */
    .media-composer-top-stack {
        position: relative;
        z-index: 2;
        margin-top: -5.5rem;
        transition: margin-top 0.25s ease;
    }

    /* Когда в shell показан warning-баннер (NS ULTRA), он занимает место над
       фрейм-стрипом — отрицательный margin утащил бы карточки прямо на баннер.
       Двойной класс: оверрайд должен выигрывать у правила выше при равном каскаде. */
    .chat-input-main-shell.has-composer-warning .media-composer-top-stack {
        margin-top: 0;
    }

    /* Содержимое композера режет .composer-state-layer { overflow: hidden } (нужен
       для voice-анимации grid-rows). Снимаем клип ТОЧЕЧНО для медиа-слоя и только в
       обычном режиме (:not(.is-voice-active) → при voice клип возвращается базовым
       правилом, анимация цела). Именно `visible`, а не `clip`+`clip-margin`: последний
       лишь РИСУЕТ выступающую часть, но не пропускает к ней клики (✕ на торчащей
       карточке становится «мёртвым»). visible сохраняет интерактивность. */
    .composer-state-switch:not(.is-voice-active) > .media-composer-normal-layer {
        overflow: visible;
    }

    /* Тень и hover-подъём карточек резал .media-composer-top-stack (overflow:hidden от
       правила коллапса .composer-collapsible > *). В ОТКРЫТОМ состоянии снимаем клип —
       тень видна целиком; при закрытии is-open снимается, базовый overflow:hidden
       возвращается и анимация сворачивания (grid-rows) клипает как надо. */
    .composer-collapsible.is-open > .media-composer-top-stack {
        overflow: visible;
    }
}

@media (max-width: 767px) {
    .media-params-bar__meta {
        gap: 0.24rem;
    }

    .media-params-pill {
        min-height: 2.2rem;
        padding: 0.38rem 0.62rem;
        gap: 0.38rem;
        max-width: 9.5rem;
        font-size: var(--text-sm);
    }

    .media-params-pill__icon {
        font-size: 1.05rem;
    }

    .media-params-pill__icon.media-params-pill__icon--aspect-preview {
        width: 0.98rem;
        height: 0.98rem;
    }

    .media-params-bar__toggle {
        width: 2.2rem;
        height: 2.2rem;
    }

    .media-params-bar__toggle i {
        font-size: 1.05rem;
    }

    .media-composer-price {
        gap: 0.28rem;
    }

    .media-params-grid {
        gap: 0.28rem;
    }

    .media-params-grid__item,
    .media-params-grid__item.is-compact {
        flex-basis: calc(50% - 0.18rem);
        width: calc(50% - 0.18rem);
    }

    .media-params-grid__item.is-range,
    .media-params-grid__item.is-wide {
        flex-basis: 100%;
        width: 100%;
    }

    .media-composer-top-stack {
        gap: 0.28rem;
        margin-bottom: 0.36rem;
    }

    .media-param-model-card {
        max-width: calc(100% - 0.18rem);
        padding: 0.24rem 0.36rem;
        border-radius: var(--radius-lg);
    }

    .media-param-model-card--toolbar {
        max-width: 8.4rem;
    }

    .media-setting-card {
        padding: 0.34rem 0.38rem;
        border-radius: var(--radius-base);
    }

    .media-setting-card__field {
        min-height: 1.8rem;
        padding: 0.32rem 0.4rem;
    }

    .media-setting-card__field--textarea {
        min-height: 3.7rem;
    }

    .media-composer-preview-card {
        width: 2.75rem;
        height: 2.75rem;
    }

    .media-frame-strip {
        gap: 0.22rem;
    }

    .media-frame-tile {
        width: 3.9rem;
        min-width: 3.35rem;
    }

    .media-frame-tile__action {
        min-height: 3.45rem;
        padding: 0.34rem 0.24rem 0.28rem;
        border-radius: var(--radius-base);
    }

    .media-frame-tile__icon {
        font-size: 1.2rem;
    }

    .media-frame-tile__plus {
        font-size: 1rem;
    }

    .media-frame-tile__clear {
        width: 1.3rem;
        height: 1.3rem;
        top: -0.14rem;
        right: -0.14rem;
    }

    .media-frame-strip__flow {
        width: 0.72rem;
        font-size: 0.82rem;
    }
}

/* ── Media Composer Layout ──
   Плоская структура: на mobile — flex column (селектор сверху, shell снизу).
   На desktop ≥1100px — flex row, селектор слева от shell'а. align-items: stretch
   гарантирует, что высота селектора всегда совпадает с высотой shell'а. */
.media-composer {
    display: flex;
    flex-direction: column;
    gap: var(--gap-xs);
    width: 100%;
    position: relative;
    z-index: 1;
}

.media-composer-shell {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: var(--gap-xs);
    min-width: 0;
    flex: 1 1 auto;
}

/* Generic collapsible-секция внутри composer'а (chat и media):
   плавно разворачивается/сворачивается через grid-template-rows trick
   с эластичной кривой. Применяется к блокам, которые добавляются в DOM
   и иначе скачком увеличивают высоту поля (вложения, reply, frame strip и т.п.).
   Закрытое состояние выпадает из layout (display: none + allow-discrete),
   чтобы не оставлять паразитный gap во flex-родителе. */
.composer-collapsible {
    display: grid;
    grid-template-rows: 1fr;
    opacity: 1;
    pointer-events: auto;
    transition-property: display, grid-template-rows, opacity;
    transition-duration: var(--motion-duration-base), var(--motion-duration-base), var(--motion-duration-fast);
    transition-timing-function: var(--motion-ease-elastic), var(--motion-ease-elastic), var(--motion-ease-premium);
    transition-behavior: allow-discrete;
}
.composer-collapsible:not(.is-open) {
    display: none;
    grid-template-rows: 0fr;
    opacity: 0;
    pointer-events: none;
}
.composer-collapsible > * {
    min-height: 0;
    overflow: hidden;
}
@starting-style {
    .composer-collapsible.is-open {
        grid-template-rows: 0fr;
        opacity: 0;
    }
}

/* Пилы в ГОРИЗОНТАЛЬНОМ ряду params-row схлопываются ТОЛЬКО по ширине
   (grid-columns) и opacity. Высота ряда пилам не принадлежит ни в одном
   состоянии — ей владеет обёртка .chat-input-params-rowslot (см. layout-секцию
   композера): rows-анимация пилы в flex-ряду сжимала её вертикально при полной
   ширине, а пер-пильные фазовые задержки читались «лесенкой»/фризом.
   Отрицательный margin-right в закрытом состоянии компенсирует flex-gap ряда —
   display:none не даёт скачка и на ширину gap. Easing premium (не elastic):
   овершут по ширине на выходе читается как дрожь.
   Единый темп композера: геометрия — base/premium, прозрачность — fast/premium,
   НИКАКИХ transition-delay. display = base (allow-discrete из базового правила):
   узел покидает поток ровно в момент, когда ширина доехала до нуля. */
.chat-input-params-row > .composer-collapsible {
    grid-template-rows: 1fr;
    grid-template-columns: 1fr;
    transition-property: display, grid-template-columns, opacity, margin-right;
    transition-duration: var(--motion-duration-base), var(--motion-duration-base), var(--motion-duration-fast), var(--motion-duration-base);
    transition-timing-function: var(--motion-ease-premium);
}
.chat-input-params-row > .composer-collapsible:not(.is-open) {
    grid-template-rows: 1fr;   /* высоту не отдаём никогда — см. комментарий выше */
    grid-template-columns: 0fr;
    margin-right: calc(var(--params-row-gap) * -1);
}
.chat-input-params-row > .composer-collapsible > * {
    min-width: 0;
    white-space: nowrap;       /* без переноса лейбла на середине анимации (скачок высоты) */
    /* bg/shadow/color — как у базового .surface-chip (этот блок его перебивает). */
    transition: padding var(--motion-duration-base) var(--motion-ease-premium),
                background-color var(--transition), box-shadow var(--transition), color var(--transition);
}
/* Остаточная ширина схлопнутой пилы — собственные паддинги чипа (px-3):
   grid 0fr зажимает только трек, padding-box остаётся ~1.5rem, и в момент
   display:none соседние пилы прыгали влево на эту ширину. Зануляем паддинги
   по той же кривой — пила доезжает ровно до нулевой ширины. Только при
   открытой шторке (.has-params): при её закрытии пила в hold-open остаётся
   полноразмерной (см. правило ниже). */
.chat-input-state-stack.has-params .chat-input-params-row > .composer-collapsible:not(.is-open) > * {
    padding-left: 0;
    padding-right: 0;
}
@starting-style {
    .chat-input-params-row > .composer-collapsible.is-open {
        grid-template-columns: 0fr;
        margin-right: calc(var(--params-row-gap) * -1);
        opacity: 0;
    }
    /* Зеркало для входа: паддинги растут вместе с треком — без стартового 24px-попа. */
    .chat-input-state-stack.has-params .chat-input-params-row > .composer-collapsible.is-open > * {
        padding-left: 0;
        padding-right: 0;
    }
}

/* Инлайн width-collapse ВНЕ params-row (чип ассистента в контролс-баре):
   та же механика, что у пил ряда — постоянный узел, ширина+fade+padding,
   leave-анимация при снятии; высоту не трогаем (бар фиксированной высоты).
   Отрицательный margin-right закрытого состояния компенсирует gap-1 (0.25rem)
   flex-ряда контролов. */
.composer-collapsible--inline {
    display: grid;
    grid-template-columns: 1fr;
    min-width: 0;
    opacity: 1;
    pointer-events: auto;
    transition-property: display, grid-template-columns, opacity, margin-right;
    transition-duration: var(--motion-duration-base), var(--motion-duration-base), var(--motion-duration-fast), var(--motion-duration-base);
    transition-timing-function: var(--motion-ease-premium);
    transition-behavior: allow-discrete;
}
.composer-collapsible--inline > * {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    transition: padding var(--motion-duration-base) var(--motion-ease-premium);
}
.composer-collapsible--inline:not(.is-open) {
    display: none;
    grid-template-columns: 0fr;
    margin-right: -0.25rem;
    opacity: 0;
    pointer-events: none;
}
.composer-collapsible--inline:not(.is-open) > * {
    padding-left: 0;
    padding-right: 0;
}
@starting-style {
    .composer-collapsible--inline.is-open {
        grid-template-columns: 0fr;
        margin-right: -0.25rem;
        opacity: 0;
    }
    .composer-collapsible--inline.is-open > * {
        padding-left: 0;
        padding-right: 0;
    }
}

/* Шторка params закрывается (снята последняя пила → у стека ушёл .has-params):
   пилы внутри держим на полной ширине и непрозрачными — закрывающаяся шторка
   сама клипает их одним движением, без гонки двух схлопываний. display уходит
   в none по концу собственного transition (allow-discrete, base) — ровно когда
   шторка (тоже base) закрылась. */
.chat-input-state-stack:not(.has-params) .chat-input-params-row > .composer-collapsible:not(.is-open) {
    grid-template-columns: 1fr;
    margin-right: 0;
    opacity: 1;
}
@media (max-width: 767px) {
    /* Активный ассистент держит шторку открытой и без params — рядом с его
       чипом пилы схлопываются по ширине как обычно. */
    .chat-input-state-stack.has-mobile-assistant:not(.has-params) .chat-input-params-row > .composer-collapsible:not(.is-open) {
        grid-template-columns: 0fr;
        margin-right: calc(var(--params-row-gap) * -1);
        opacity: 0;
    }
    .chat-input-state-stack.has-mobile-assistant .chat-input-params-row > .composer-collapsible:not(.is-open) > * {
        padding-left: 0;
        padding-right: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .composer-collapsible,
    .chat-input-params-row > .composer-collapsible,
    .chat-input-params-row > .composer-collapsible > *,
    .composer-collapsible--inline,
    .composer-collapsible--inline > *,
    .chat-input-state-stack,
    .chat-input-state-stack::before,
    .chat-input-params-shell,
    .chat-input-params-rowslot,
    .chat-input-params-shell .ultra-banner { transition: none; }
}

/* Эластичная анимация padding-bottom композера при активации ассистента / multiline. */
.composer-input-stack {
    transition: padding var(--motion-duration-base) var(--motion-ease-elastic);
}

@media (prefers-reduced-motion: reduce) {
    .composer-input-stack { transition: none; }
}

@media (min-width: 1100px) {
    .media-composer.has-modes {
        flex-direction: row;
        align-items: stretch;
        gap: 0.42rem;
    }
}

.generation-mode-selector {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(5.3rem, max-content));
    gap: var(--gap-2xs);
    width: fit-content;
    max-width: 100%;
    padding: var(--gap-xs);
    /* Капсульный сегментбар (эталон): pill-трей + pill-сегменты, активный
       --surface-strong, концентричный зазор --gap-xs. Трей стеклянный
       (--chat-input-bg + блюр) — бар автономный на странице, не в стекле. */
    border-radius: var(--radius-pill);
    background: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    box-shadow: var(--shadow-glass);
}

@media (min-width: 1100px) {
    .media-composer.has-modes > .generation-mode-selector {
        flex: 0 0 5.15rem;
        width: 5.15rem;
        grid-template-columns: 1fr;
        grid-auto-rows: 1fr;
    }
}

.generation-mode-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.08rem;
    min-width: 0;
    min-height: 2rem;
    padding: 0.28rem 0.4rem;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text-muted);
    border: none;
    cursor: pointer;
    text-align: center;
    transition: background-color var(--transition), color var(--transition);
}

.generation-mode-btn__label {
    width: 100%;
    font-size: var(--text-xs);
    line-height: 1.25;
    font-weight: var(--font-weight-semibold);
    color: currentColor;
    text-transform: none;
    text-align: center;
}

.generation-mode-btn__hint {
    width: 100%;
    text-align: center;
}

@media (hover: hover) {
    .generation-mode-btn:hover {
        background: var(--bg-hover);
        color: var(--text-main);
    }
}
.generation-mode-btn.active {
    background: var(--surface-strong);
    color: var(--text-main);
}

@media (max-width: 767px) {
    .generation-mode-selector {
        grid-template-columns: 1fr 1fr;
        width: 100%;
    }

    .generation-mode-btn {
        min-height: 1.9rem;
        padding: 0.24rem 0.34rem;
    }
}

.icon-circle-primary {
    background-color: var(--primary-500);
    color: var(--primary-text);
    box-shadow: var(--shadow-icon);
    border-radius: var(--radius-pill);
}
.icon-chip-primary {
    background-color: var(--primary-20);
    color: var(--primary-500);
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--radius-pill);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.overlay-backdrop,
.payment-backdrop { background-color: var(--overlay-backdrop); }
.overlay-backdrop-soft { background-color: var(--overlay-backdrop-soft); }

/* Bottom Drawer (Шторка) */
.drawer-viewport {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    pointer-events: none;
}
@media (min-width: 640px) {
    .drawer-viewport {
        align-items: center;
        padding: var(--app-gutter-x);
    }
    :root { --drawer-max-h: 90vh; }
}

/* Drawer panels — max-height tied to a single token */
:is(.settings-panel, .model-modal, .payment-modal, .assistant-modal, .prompt-library-panel) {
    max-height: var(--drawer-max-h);
}
@media (min-width: 640px) {
    .model-modal { max-height: min(75vh, 680px); }
}
.drawer-handle {
    position: relative;
    width: 40px;
    height: 4px;
    background: var(--bg-raised);
    border-radius: var(--radius-pill);
    flex-shrink: 0;
    margin: 12px auto 0;
    cursor: grab;
}
.drawer-handle::before {
    content: '';
    position: absolute;
    inset: -10px -20px;
}
@media (min-width: 640px) {
    .drawer-handle { display: none; }
}

/* Swipe-to-dismiss: Only the drag handle should prevent vertical scroll by default.
   The rest of the drawer needs native vertical scrolling. */
@media (max-width: 639px) {
    .drawer-handle { touch-action: none; }
}

/* Safe-area bottom padding for mobile drawers */
@media (max-width: 639px) {
    :is(.settings-panel, .model-modal, .payment-modal, .assistant-modal, .prompt-library-panel, .composer-plus-sheet),
    .profile-settings-card {
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }
}

/* ══════════════════════════════════════════════
   COMPOSER PLUS SHEET — шторка кнопки «+»
   Mobile: full-width bottom-sheet (как .settings-panel).
   Desktop: floating panel рядом с триггером (inline-стиль из стора).
   ══════════════════════════════════════════════ */
.composer-plus-sheet-viewport {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    pointer-events: none;
}
@media (min-width: 640px) {
    .composer-plus-sheet-viewport {
        display: block;
    }
}

.composer-plus-sheet {
    /* Радиус и внутренний отступ панели — единый источник для концентрики
       вложенных элементов (трей плиток считает свой радиус от --sheet-radius
       минус --sheet-pad, не хардкодит числа). */
    /* One UI-style окно: крупный радиус + щедрый внутренний padding.
       Локальные алиасы (не глобальный --radius-lg) — пробуем только на этом
       шите, остальные окна проекта не затрагиваем. */
    --sheet-radius: var(--radius-xl);
    --sheet-pad: 0.5rem;
    width: 100%;
    max-height: var(--drawer-max-h, 90vh);
    display: flex;
    flex-direction: column;
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    border-radius: var(--sheet-radius) var(--sheet-radius) 0 0;
    box-shadow: var(--shadow-glass);
    /* Верх 0: на мобиле трей отступает от верхней кромки своим margin-top
       (= --sheet-pad), чтобы offset от угла панели был равномерным. */
    padding: 0 var(--sheet-pad) var(--sheet-pad);
    overflow: hidden;
}

@media (min-width: 640px) {
    .composer-plus-sheet {
        width: 20rem;
        max-height: min(70vh, 32rem);
        border-radius: var(--sheet-radius);
        padding: var(--sheet-pad);
        /* Скролл живёт на __list внутри __stage — panel сам ничего
           не прокручивает, иначе появятся вложенные скроллы. */
    }
}

.composer-plus-sheet__tiles {
    /* Сегмент-бар плавает внутри панели с воздухом по краям (One UI), НЕ
       прижат к кромкам: негативные margin вылезали бы за overflow:hidden
       у .stage/.slide и трей обрезался бы. Закреплён внизу панели (flex-shrink:0);
       боковой и нижний зазор задаёт padding панели (--sheet-pad, равномерно),
       сверху — отступ-разделитель от списка моделей.
       Слои полупрозрачные (стекло-в-стекле): и трей, и плитки берут --surface-soft,
       но плитки лежат ПОВЕРХ трея, и два полупрозрачных слоя складываются
       (≈11–12% против 6% в зазорах) — плитки сами читаются светлее без тёмного
       колодца. Тема-зависимо через --surface-tint, светлую тему отдельно не правим.
       Скругление — капсула: и трей, и плитки берут --radius-pill; равномерный
       зазор --tiles-pad делает их концентричными (каждый клампит радиус к своей
       полувысоте), пилюли echo'ят контейнер — сегмент-бар как у iOS / GPTunneL. */
    --tiles-pad: var(--gap-xs);
    display: flex;
    gap: var(--gap-2xs);
    margin-top: var(--gap-sm);
    flex-shrink: 0;
    padding: var(--tiles-pad);
    background-color: var(--surface-soft);
    border-radius: var(--radius-pill);
}

.composer-plus-sheet__tile {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    /* Компактный сегмент: глиф + подпись, плотные отступы (метрики таб-бара). */
    gap: 0.1875rem;
    padding: 0.375rem 0.25rem;
    background-color: var(--surface-soft);
    color: var(--text-main);
    /* Капсула; равномерный зазор --tiles-pad до трея делает пилюлю
       концентричной лотку (оба клампятся к своей полувысоте). */
    border-radius: var(--radius-pill);
    transition: background-color var(--transition), transform var(--transition);
}
@media (hover: hover) {
    .composer-plus-sheet__tile:hover { background-color: var(--surface-strong); }
}
.composer-plus-sheet__tile:active { transform: scale(0.97); }

.composer-plus-sheet__tile-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    color: var(--text-main);
}

.composer-plus-sheet__tile-label {
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    line-height: 1.1;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

/* ── Недоступная функция (замок): tile приглушён, в углу значок замка.
   Цвет/фон через токены — без новых цветов. ── */
.composer-plus-sheet__tile.is-locked {
    position: relative;
    opacity: 0.55;
}
.composer-plus-sheet__tile.is-locked .composer-plus-sheet__tile-icon,
.composer-plus-sheet__tile.is-locked .composer-plus-sheet__tile-label {
    color: var(--text-subtle);
}
.composer-plus-sheet__tile-lock {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    font-size: 0.875rem;
    color: var(--text-subtle);
}

.composer-plus-sheet__list {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    margin-top: 0.75rem;
    /* Скролл всегда здесь, а не на panel/stage — корректно работает и на
       мобильной bottom-sheet, и на desktop floating-панели. flex:1 + min-h:0
       позволяет списку сжаться до доступного пространства slide'а. */
    overflow-y: auto;
    overscroll-behavior: contain;
    flex: 1 1 auto;
    min-height: 0;
}
/* В root-слайде список теперь первый (плитки уехали вниз) — верхний зазор
   даёт padding панели, свой margin-top убираем. В sub-слайде список идёт
   под sub-header'ом, там margin-top нужен. */
.composer-plus-sheet__stage > .composer-plus-sheet__slide:first-child .composer-plus-sheet__list {
    margin-top: 0;
}

.composer-plus-sheet__item {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    width: 100%;
    padding: 0.375rem 0.625rem;
    border-radius: calc(var(--radius-lg) - 0.25rem);
    text-align: left;
    color: var(--text-main);
    transition: background-color var(--transition);
}
@media (hover: hover) {
    .composer-plus-sheet__item:hover { background-color: var(--bg-hover); }
}
.composer-plus-sheet__item.is-active { background-color: var(--bg-raised-75); }
[data-theme="light"] .composer-plus-sheet__item.is-active { background-color: var(--bg-raised); }

.composer-plus-sheet__item-icon {
    flex-shrink: 0;
    width: 2.25rem;
    height: 2.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background-color: var(--bg-raised-55);
    color: var(--text-main);
    font-size: 1.125rem;
}
/* Когда внутри иконки оригинальный brand-SVG модели — даём небольшой
   внутренний отступ, чтобы лого не упиралось в края кружка. */
.composer-plus-sheet__item-icon > .model-icon-content {
    width: 72%;
    height: 72%;
}
[data-theme="light"] .composer-plus-sheet__item-icon { background-color: var(--bg-input); }

.composer-plus-sheet__item-body {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
    flex: 1 1 auto;
}

.composer-plus-sheet__item-label {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    line-height: 1.2;
    color: var(--text-main);
}

.composer-plus-sheet__item-desc {
    font-size: var(--text-2xs);
    line-height: 1.25;
    color: var(--text-muted);
}

/* Вторая строка под лейблом: provider-текст + чипы-иконки возможностей.
   Чипы дают визуальные маркеры (референс, dynamic pricing, multi-input
   и т.п.) без накопления плейн-текста вроде «· ↻ референс». */
.composer-plus-sheet__item-sub {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    min-width: 0;
    flex-wrap: wrap;
    row-gap: 0.125rem;
}
.composer-plus-sheet__item-caps {
    display: inline-flex;
    align-items: center;
    gap: 0.1875rem;
}
.composer-plus-sheet__item-cap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.125rem;
    height: 1.125rem;
    border-radius: var(--radius-pill);
    background-color: var(--bg-raised-55);
    color: var(--text-muted);
    font-size: 0.75rem;
    transition: background-color var(--transition), color var(--transition);
}
.composer-plus-sheet__item.is-active .composer-plus-sheet__item-cap {
    color: var(--primary-500);
    background-color: color-mix(in srgb, var(--primary-500) 12%, transparent);
}
[data-theme="light"] .composer-plus-sheet__item-cap {
    background-color: var(--bg-input);
}

.composer-plus-sheet__item-check {
    flex-shrink: 0;
    color: var(--primary-500);
    font-size: 1rem;
}

/* Недоступная функция (замок) в списке: приглушаем, гасим hover, значок справа. */
.composer-plus-sheet__item.is-locked {
    opacity: 0.6;
    cursor: default;
}
.composer-plus-sheet__item.is-locked .composer-plus-sheet__item-label,
.composer-plus-sheet__item.is-locked .composer-plus-sheet__item-icon {
    color: var(--text-subtle);
}
@media (hover: hover) {
    .composer-plus-sheet__item.is-locked:hover { background-color: transparent; }
}
.composer-plus-sheet__item-lock {
    flex-shrink: 0;
    margin-left: auto;
    padding-left: 0.5rem;
    color: var(--text-subtle);
    font-size: 1rem;
}

/* Текст поповера-предупреждения (locked/forced функция). */
.composer-plus-sheet__note {
    /* Горизонтальный inset = padding заголовка (.dropdown-menu__title, 0.75rem),
       чтобы текст ноты и заголовок шли по одному левому краю. */
    margin: 0.25rem 0.75rem 0.125rem;
    max-width: 16rem;
    font-size: var(--text-2xs);
    line-height: 1.35;
    color: var(--text-muted);
}

/* Условия загрузки модели под tiles («1 файл, JPEG/PNG, до 10 МБ»). */
.composer-plus-sheet__caption {
    margin: 0.5rem 0.25rem 0;
    font-size: var(--text-2xs);
    line-height: 1.35;
    color: var(--text-muted);
    text-align: center;
}

/* Тонкая разделительная полоска внутри items (item.divider === true).
   Отделяет, например, «Настройки» от секции активных режимов. */
.composer-plus-sheet__divider {
    border: 0;
    height: 1px;
    margin: 0.375rem 0.5rem;
    background-color: var(--bg-raised-55);
}
[data-theme="light"] .composer-plus-sheet__divider {
    background-color: var(--bg-raised);
}

.composer-plus-sheet__item-meta {
    flex-shrink: 0;
    margin-left: auto;
    padding-left: 0.5rem;
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.composer-plus-sheet__item.is-active .composer-plus-sheet__item-meta {
    color: var(--primary-500);
}
.composer-plus-sheet__item.is-active .composer-plus-sheet__item-icon {
    background-color: color-mix(in srgb, var(--primary-500) 18%, transparent);
    color: var(--primary-500);
}

/* Chevron у строк с подменю */
.composer-plus-sheet__item-chev {
    flex-shrink: 0;
    margin-left: auto;
    padding-left: 0.25rem;
    color: var(--text-subtle);
    font-size: 1rem;
}
/* Если у строки уже есть meta, chevron идёт после, без margin-left:auto */
.composer-plus-sheet__item-meta + .composer-plus-sheet__item-chev {
    margin-left: 0.375rem;
    padding-left: 0;
}

/* ─── Stage с двумя слайдами (root ↔ sub) ──────────────────────
   Mobile push-view внутри стеклянной поверхности шторки.
   Оба слайда лежат в одной grid-ячейке → видны поверх друг друга
   только во время Alpine x-transition, идущий слайд анимируется. */
.composer-plus-sheet__stage {
    display: grid;
    grid-template-areas: "main";
    grid-template-rows: minmax(0, 1fr);
    overflow: hidden;
    flex: 1 1 auto;
    min-height: 0;
}
.composer-plus-sheet__slide {
    grid-area: main;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

/* Sub-header (back + title) */
.composer-plus-sheet__sub-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 0.25rem 0.5rem;
}
.composer-plus-sheet__back {
    width: 2rem;
    height: 2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    color: var(--text-muted);
    transition: background-color var(--transition), color var(--transition);
}
@media (hover: hover) {
    .composer-plus-sheet__back:hover {
        background-color: var(--bg-hover);
        color: var(--text-main);
    }
}
.composer-plus-sheet__sub-title {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Horizontal slide-анимации для push-view внутри stage.
   Используются как x-transition:enter/leave классы. */
@keyframes sheet-slide-in-right {
    from { opacity: 0; transform: translateX(8%); }
    to   { opacity: 1; transform: translateX(0); }
}
@keyframes sheet-slide-out-right {
    from { opacity: 1; transform: translateX(0); }
    to   { opacity: 0; transform: translateX(8%); }
}
@keyframes sheet-slide-in-left {
    from { opacity: 0; transform: translateX(-8%); }
    to   { opacity: 1; transform: translateX(0); }
}
@keyframes sheet-slide-out-left {
    from { opacity: 1; transform: translateX(0); }
    to   { opacity: 0; transform: translateX(-8%); }
}
.sheet-slide-from-right { animation: sheet-slide-in-right  var(--motion-duration-base) var(--motion-ease-premium) both; }
.sheet-slide-to-right   { animation: sheet-slide-out-right var(--motion-duration-fast) var(--motion-ease-exit)    both; }
.sheet-slide-from-left  { animation: sheet-slide-in-left   var(--motion-duration-base) var(--motion-ease-premium) both; }
.sheet-slide-to-left    { animation: sheet-slide-out-left  var(--motion-duration-fast) var(--motion-ease-exit)    both; }

/* ─── Desktop hover/click flyout — отдельная панель сбоку.
   Габариты как у dropdown'а, но со стеклянным фоном шторки. */
.composer-plus-sheet--flyout {
    position: fixed;
    width: 18rem;
    /* Высоту держим в пределах ~5-6 видимых элементов: иначе flyout
       с длинным списком (image-picker) при anchor'е у нижнего края
       viewport-а смещается вверх _fitPosition'ом и перекрывает родителя. */
    max-height: 20rem;
    padding: 0.3125rem;
    /* Скролл — на внутреннем __list, не на самом flyout, чтобы не было
       двух вложенных скролл-областей. */
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.composer-plus-sheet--flyout .composer-plus-sheet__list {
    margin-top: 0;
    gap: 0.125rem;
}
.composer-plus-sheet--flyout .composer-plus-sheet__item {
    padding: 0.4375rem 0.625rem;
    gap: 0.5rem;
}
.composer-plus-sheet--flyout .composer-plus-sheet__item-icon {
    width: 1.5rem;
    height: 1.5rem;
    font-size: var(--text-xs);
}
.composer-plus-sheet--flyout .composer-plus-sheet__item-label {
    font-size: var(--text-sm);
}
.composer-plus-sheet--flyout .composer-plus-sheet__item-desc {
    font-size: var(--text-2xs);
}
.composer-plus-sheet--flyout .composer-plus-sheet__item-meta {
    font-size: var(--text-xs);
    padding-left: 0.375rem;
}
.composer-plus-sheet--flyout .composer-plus-sheet__item-cap {
    width: 1rem;
    height: 1rem;
    font-size: 0.6875rem;
}
.composer-plus-sheet--flyout .composer-plus-sheet__item-sub {
    gap: 0.25rem;
}
@media (max-width: 639px) {
    /* На мобиле flyout не нужен — sub-view внутри панели заменяет его. */
    .composer-plus-sheet--flyout { display: none !important; }
}

/* Прячем индикатор прокрутки во всех скроллящихся областях шторки
   (тот же подход, что у .dropdown-menu). Скролл работает, бара не видно. */
:is(.composer-plus-sheet, .composer-plus-sheet--flyout, .composer-plus-sheet__list) {
    scrollbar-width: none;
    -ms-overflow-style: none;
}
:is(.composer-plus-sheet, .composer-plus-sheet--flyout, .composer-plus-sheet__list)::-webkit-scrollbar {
    display: none;
    width: 0;
    height: 0;
}

/* ══════════════════════════════════════════════
   УНИВЕРСАЛЬНЫЕ АНИМАЦИИ ШТОРОК / МОДАЛОВ
   Чтобы изменить анимацию ВСЕХ шторок — редактируй только здесь.
   Мобайл (< 640px) : слайд снизу вверх
   Десктоп (≥ 640px): scale + fade
   ══════════════════════════════════════════════ */
@media (max-width: 639px) {
    @keyframes drawer-in  { from { transform: translateY(100%); } to { transform: translateY(0);    } }
    @keyframes drawer-out { from { transform: translateY(0);    } to { transform: translateY(100%); } }
}
@media (min-width: 640px) {
    @keyframes drawer-in  { from { opacity: 0; transform: scale(0.95) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } }
    @keyframes drawer-out { from { opacity: 1; transform: scale(1) translateY(0);       } to { opacity: 0; transform: scale(0.95) translateY(8px); } }
}
@keyframes backdrop-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes backdrop-out { from { opacity: 1; } to { opacity: 0; } }

/* Используй x-transition:enter="drawer-enter"  x-transition:leave="drawer-leave" */
.drawer-enter   { animation: drawer-in   var(--motion-duration-drawer) var(--motion-ease-premium) both; }
.drawer-leave   { animation: drawer-out  var(--motion-duration-fast) var(--motion-ease-premium) both; }
/* Используй x-transition:enter="backdrop-enter" x-transition:leave="backdrop-leave" */
.backdrop-enter { animation: backdrop-in  var(--motion-duration-fast) var(--motion-ease-standard) both; }
.backdrop-leave { animation: backdrop-out var(--motion-duration-micro) var(--motion-ease-standard) both; }

/* Reusable elastic popup entrance (dropdowns, flyouts, popovers) */
@keyframes popup-in {
    from { opacity: 0; transform: scale(0.9); }
    to   { opacity: 1; transform: scale(1); }
}
.popup-enter { animation: popup-in var(--motion-duration-base) var(--motion-ease-elastic) both; }

@keyframes popup-retarget-in {
    from { transform: translateY(0.125rem) scale(0.985); }
    to   { transform: translateY(0) scale(1); }
}
.popup-retarget { animation: popup-retarget-in var(--motion-duration-fast) var(--motion-ease-standard) both; }

/* Fade enter/leave (lightboxes, fullscreen overlays) */
@keyframes fade-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-out { from { opacity: 1; } to { opacity: 0; } }
.fade-enter { animation: fade-in  var(--motion-duration-base) var(--motion-ease-standard) both; }
.fade-leave { animation: fade-out var(--motion-duration-fast) var(--motion-ease-standard) both; }

/* Step transition (payment wizard, multi-step flows) */
@keyframes step-in  { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes step-out { from { opacity: 1; transform: translateY(0);   } to { opacity: 0; transform: translateY(-3px); } }
.step-enter { animation: step-in  var(--motion-duration-drawer) var(--motion-ease-premium) both; }
.step-leave { animation: step-out var(--motion-duration-fast)   var(--motion-ease-exit)    both; }

/* Content slide-up (empty states, hero sections) */
@keyframes content-up-in  { from { opacity: 0; transform: translateY(1rem); } to { opacity: 1; transform: translateY(0); } }
@keyframes content-up-out { from { opacity: 1; transform: translateY(0);    } to { opacity: 0; transform: translateY(-1rem); } }
.content-up-enter { animation: content-up-in  var(--motion-duration-slow) var(--motion-ease-premium) both; }
.content-up-leave { animation: content-up-out var(--motion-duration-fast) var(--motion-ease-exit)    both; }

/* Stagger-in (sequential reveal for sidebar lists) */
@keyframes stagger-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}
.stagger-enter > .stagger-item,
.stagger-enter .stagger-item {
    animation: stagger-in var(--motion-duration-shell) var(--motion-ease-elastic) both;
}
.stagger-enter .stagger-item:nth-child(1)  { animation-delay: calc(0  * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(2)  { animation-delay: calc(1  * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(3)  { animation-delay: calc(2  * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(4)  { animation-delay: calc(3  * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(5)  { animation-delay: calc(4  * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(6)  { animation-delay: calc(5  * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(7)  { animation-delay: calc(6  * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(8)  { animation-delay: calc(7  * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(9)  { animation-delay: calc(8  * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(10) { animation-delay: calc(9  * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(11) { animation-delay: calc(10 * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(12) { animation-delay: calc(11 * var(--motion-stagger-step)); }
.stagger-enter .stagger-item:nth-child(n+13) { animation-delay: calc(11 * var(--motion-stagger-step)); }
@media (prefers-reduced-motion: reduce) {
    .stagger-enter > .stagger-item,
    .stagger-enter .stagger-item { animation: none; opacity: 1; }
}

/* ══════════════════════════════════════════════
   IN-APP PUSH NOTIFICATIONS (сверху)
   ══════════════════════════════════════════════ */
.notif-container {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: var(--z-fullscreen-modal);
    display: flex;
    flex-direction: column;
    align-items: center;
    pointer-events: none;
    padding: env(safe-area-inset-top, 0px) 12px 0;
    /* spacing between items via margin-bottom (animatable per-item) */
}

.notif-push {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    max-width: 420px;
    margin-bottom: 8px;
    padding: 14px 16px;
    background: var(--bg-elevated);
    border-radius: var(--radius-2xl);
    box-shadow: var(--shadow-glass);
    pointer-events: auto;
    cursor: pointer;
    text-decoration: none;
    color: var(--text-main);
    -webkit-user-select: none;
    user-select: none;
    overflow: hidden;
    box-sizing: border-box;
    /* entrance — starts off-screen */
    transform: translateY(-120%);
    opacity: 0;
    transition:
        transform      var(--motion-duration-slow) var(--motion-ease-premium),
        opacity        var(--motion-duration-base) var(--motion-ease-standard),
        height         var(--motion-duration-base) var(--motion-ease-premium),
        margin-bottom  var(--motion-duration-base) var(--motion-ease-premium),
        padding-top    var(--motion-duration-base) var(--motion-ease-premium),
        padding-bottom var(--motion-duration-base) var(--motion-ease-premium);
}

.notif-push-visible {
    transform: translateY(12px);
    opacity: 1;
}

.notif-push-hiding {
    transform: translateY(-120%);
    opacity: 0;
    margin-bottom: 0;
    padding-top: 0;
    padding-bottom: 0;
    pointer-events: none;
    /* height обнуляется инлайн-стилем из JS — после фиксации актуальной высоты */
}

.notif-push:active {
    transform: translateY(12px) scale(0.98);
}

.notif-push-icon {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-xl);
    background: var(--primary-500);
    color: var(--primary-text);
    font-size: var(--text-xl);
}

.notif-push-body {
    flex: 1;
    min-width: 0;
}

.notif-push-title {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    line-height: 1.3;
    color: var(--text-main);
}

.notif-push-text {
    font-size: var(--text-xs);
    color: var(--text-muted);
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.notif-push-arrow {
    flex-shrink: 0;
    color: var(--text-subtle);
    font-size: 1rem;
    opacity: .6;
}

/* Compact toast: текст-пилюля без иконки/шеврона, ужимается по контенту */
.notif-push--toast {
    width: auto;
    max-width: min(calc(100vw - 24px), 420px);
    padding: 10px 18px;
    gap: 0;
}

.notif-push--toast .notif-push-body {
    flex: 0 1 auto;
    text-align: center;
}

.notif-push--toast .notif-push-title {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
}

/* ══════════════════════════════════════════════ */

.overlay-scrim { background-color: var(--overlay-scrim); }
.overlay-icon { background-color: var(--surface-dim); color: var(--text-main); }
@media (hover: hover) {
    .overlay-icon:hover,
    .hover-text-danger:hover {
        color: var(--text-main);
    }
}
.dropdown-item-danger,
.text-danger {
    color: var(--text-main);
}
.upload-overlay { background-color: var(--overlay-backdrop-soft); }
.accent-glow { background-color: var(--primary-10); }
.text-success,
.icon-success { color: var(--text-main); }
.accent-gradient-text {
    background-image: linear-gradient(90deg, var(--primary-500), var(--accent-cool));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.accent-strip { background-color: var(--primary-20); }
.settings-gradient { background-image: linear-gradient(90deg, var(--accent-cool), var(--gradient-warm), var(--red-500)); }
.icon-contrast { background-color: var(--primary-text); }

.voice-recording-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    line-height: 1;
    font-weight: var(--font-weight-semibold);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    /* перелив (gradient + clip + анимация) — общий .text-shimmer-rule, см. ниже */
}

@media (max-width: 767px) {
    .voice-recording-title {
        font-size: var(--text-base);
    }
}

/* Model Selector */
.model-chip,
.modal-close-btn-bg,
.camera-icon-box,
.relight-preset-btn,
.relight-toggle-label.is-active,
.relight-color-custom {
    background-color: var(--bg-input);
}

.model-chip {
    color: var(--text-muted);
    border-radius: var(--radius-pill);
    padding: 0.375rem 0.75rem;
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    display: inline-flex;
    align-items: center;
    gap: var(--gap-xs);
    white-space: nowrap;
    flex-shrink: 0;
    transition: background-color var(--transition), color var(--transition), box-shadow var(--transition), filter var(--transition);
}
@media (hover: hover) {
    .model-chip:hover {
        background-color: var(--surface-active);
        box-shadow: var(--shadow-surface);
    }
}
.model-chip-active { background-color: var(--text-main); color: var(--text-inverse); }
.model-chip-icon {
    width: 0.875rem;
    height: 0.875rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.model-icon-content {
    display: block;
    width: 100%;
    height: 100%;
    color: currentColor;
}
.model-icon-content > svg,
.model-icon-content > span {
    display: block;
    width: 100%;
    height: 100%;
}
.model-icon-content > svg {
    fill: currentColor;
}

/* Price display (shared by flyout + push-view) */
.model-row-price-free {
    color: var(--text-subtle);
}
.model-row-price-dual {
    display: inline-flex;
    align-items: center;
    gap: 0.125rem;
}
.model-row-price-sep {
    opacity: 0.35;
}

/* Section Headers */
.model-section-header {
    display: flex;
    align-items: center;
    gap: var(--gap-xs);
    padding: 0.4375rem 0.5rem 0.3125rem;
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-bold);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.model-section-icon-popular { color: var(--accent-warm); }

/* Popular Model Card */
.model-popular-card {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    padding: 0.5rem;
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: background-color var(--transition), transform var(--motion-duration-micro) var(--motion-ease-standard);
}
@media (hover: hover) {
    .model-popular-card:hover { background-color: var(--bg-hover); }
}
.model-popular-card:active { transform: scale(0.99); }
.model-popular-card-active { background-color: var(--surface-active); }
/* Подложка логотипа модели — единый компонент карточек (popular + group).
   Единственный источник размера — --model-icon-size; padding выводится из
   него, поэтому глиф во всех карточках занимает одинаковую внутреннюю
   область. Круглая (квадрат + radius-pill), overflow:hidden обрезает по кругу. */
.model-icon-box {
    --model-icon-size: 2.5rem;
    width: var(--model-icon-size);
    height: var(--model-icon-size);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: calc(var(--model-icon-size) * 0.2);
    border-radius: var(--radius-pill);
    overflow: hidden;
    background-color: var(--bg-elevated);
    color: var(--text-main);
}
.model-popular-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}
.model-popular-name {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    min-width: 0;            /* чтобы имя-truncate могло сжиматься */
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    line-height: 1.2;
}
/* Бейдж не сжимается — сжимается (обрезается) только имя. */
.model-badge-new { flex-shrink: 0; }
.model-popular-check,
.model-popular-price {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    font-size: var(--text-lg);
}
.model-popular-price {
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
}

/* Info chips (resolution, duration, etc.).
   nowrap — свойства всегда в одну строку (карточка ровно 2 строки: имя +
   свойства). Если чипы не влезают, лишние плавно угасают у правого края
   (mask), а не обрезаются жёстко. Маска самонастраивается: когда чипы
   влезают, зона угасания приходится на пустоту и не видна. */
.model-info-chips {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.375rem;
    align-items: center;
    min-width: 0;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 0.75rem), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 0.75rem), transparent);
}
.model-info-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.1875rem;
    padding: 0.125rem 0.4375rem;
    background-color: var(--bg-input);
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
    line-height: 1.25;
    white-space: nowrap;
}
.model-info-chip .ti { font-size: var(--text-xs); }

/* Icon-only чип (capability marker: brain / vision / web / audio).
   Лёгкий inline-вид без pill-фона — иначе ряд из 3-4 capability'ев
   визуально перегружает строку модели. Чёрная пилюля под одиночной
   иконкой выглядит как «кнопка», а это просто маркер свойства. */
.model-info-chip--icon {
    padding: 0;
    background: transparent;
    color: var(--text-subtle);
    border-radius: 0;
}
.model-info-chip--icon .ti { font-size: var(--text-sm); }

/* NEW badge */
.model-badge-new {
    display: inline-flex;
    align-items: center;
    padding: 0.0625rem 0.4375rem;
    background-color: var(--primary-20);
    border-radius: var(--radius-pill);
    /* 10px — меньше любого token'а (--text-2xs = 11.2px), бэйджу хочется
       быть чуть мельче окружающего текста. Оставлено хардкодом сознательно. */
    font-size: 0.625rem;
    font-weight: var(--font-weight-bold);
    color: var(--primary-500);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    line-height: 1.4;
}

/* Group Card (All models section) */
.model-group-card-wrapper { position: relative; }
.model-group-card {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    padding: 0.5rem;
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: background-color var(--transition), transform var(--motion-duration-micro) var(--motion-ease-standard);
}
@media (hover: hover) {
    .model-group-card:hover {
        background-color: var(--bg-hover);
    }
}
.model-group-card:active { transform: scale(0.99); }
.model-group-card-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.0625rem;
}
.model-group-card-name {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
}
.model-group-card-meta {
    font-size: var(--text-xs);
    color: var(--text-subtle);
}
.model-group-card-chevron {
    flex-shrink: 0;
    color: var(--text-subtle);
    font-size: var(--text-lg);
    margin-left: auto;
    opacity: 0.5;
    transition: opacity var(--transition), transform var(--transition);
}
@media (hover: hover) {
    .model-group-card:hover .model-group-card-chevron {
        opacity: 1;
        transform: translateX(2px);
    }
}

/* Flyout Popover (desktop only, fixed-position portal outside modal) */
.model-flyout {
    position: fixed;
    width: 18rem;
    /* Дизайн-максимум 24rem, но не выше вьюпорта (−1rem на отступы сверху/снизу):
       длинный список групп скроллится внутри .model-flyout-scroll. Раньше этот
       клампинг считался в JS — теперь живёт в CSS, JS позицию не трогает. */
    max-height: min(24rem, calc(100vh - 1rem));
    overflow: hidden;
    padding: 0.25rem;
    border-radius: var(--radius-lg);
    z-index: calc(var(--z-modal) + 1);
    pointer-events: auto;
    display: flex;
    flex-direction: column;
}
.model-flyout-scroll {
    flex: 1;
    overflow-y: auto;
    min-height: 0;
}
@media (max-width: 639px) {
    .model-flyout { display: none !important; }
}

/* Stage внутри model-modal. Root-слайд остаётся в flex-потоке
   (его intrinsic-высота определяет высоту stage'а, а через неё —
   модалки), push-слайд абсолютно поверх него. Это решает две
   проблемы сразу: модалка корректно сайзится по контенту, а
   внутренний __scroll получает definite-высоту через flex-цепочку
   stage → slide → scroll, и overflow-y у него срабатывает. */
.model-modal__stage {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.model-modal__slide {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
/* Push-слайд — абсолютно поверх root'а. Root не прячется через
   display:none (иначе stage коллапсит до 0), а уезжает влево +
   opacity:0 через is-pushed. На десктопе push скрыт sm:hidden. */
.model-modal__slide--push {
    position: absolute;
    inset: 0;
}
.model-modal__slide--root {
    transition: transform var(--motion-duration-base) var(--motion-ease-premium),
                opacity var(--motion-duration-base) var(--motion-ease-premium);
}
.model-modal__slide--root.is-pushed {
    transform: translateX(-8%);
    opacity: 0;
    pointer-events: none;
}
.model-modal__scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    /* Резерв под плавающее меню категорий (absolute bottom-0, ~80px), чтобы
       последняя карточка в конце прокрутки не пряталась под ним. Задаём в CSS,
       а не Tailwind-утилитой: pb-24 нет в пред-собранном tailwind.css. */
    padding-bottom: 6rem;
}

/* Внутренние элементы push-слайда (header/back/icon/title). Bg-фон самой
   push-вьюхи нет: она живёт в общей стеклянной поверхности .model-modal
   через __slide--push, без отдельного --bg-panel-слоя поверх root'а. */
.model-modal__push-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    flex-shrink: 0;
}
/* Круглая стеклянная кнопка «назад» в детальных видах модалок (список моделей,
   коннекторы) — как у кнопки прокрутки чата (.scroll-to-bottom-btn):
   --shell-header-slot + chat-input-bg + glass-blur + shadow-glass. */
.model-modal__push-back,
.modal-header-back {
    width: var(--shell-header-slot);
    height: var(--shell-header-slot);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    box-shadow: var(--shadow-glass);
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    transition: background-color var(--transition), color var(--transition);
}
@media (hover: hover) {
    .model-modal__push-back:hover,
    .modal-header-back:hover {
        background-color: var(--bg-hover);
        color: var(--text-main);
    }
}
.model-modal__push-icon {
    width: 1.75rem;
    height: 1.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-main);
}
.model-modal__push-title {
    font-size: var(--text-base);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
}

.composer-model-selector {
    height: 2.5rem;
    padding-inline-start: 0.875rem;
    padding-inline-end: 1.125rem;
    gap: 0.5rem;
    font-size: var(--text-sm);
}

.composer-model-selector .model-chip-icon {
    width: 1.3125rem;
    height: 1.3125rem;
}

.composer-model-selector__name {
    min-width: 0;
    max-width: 12rem;
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    line-height: 1.1;
}

@media (max-width: 1099.98px) {
    .composer-model-selector {
        padding-inline-start: 0.75rem;
        padding-inline-end: 0.875rem;
        gap: 0.375rem;
    }

    .composer-model-selector .model-chip-icon {
        width: 1.1875rem;
        height: 1.1875rem;
    }

    .composer-model-selector__name {
        max-width: 10rem;
    }
}

/* Model Category Tabs */
.model-category-tabs {
    display: flex;
    align-items: stretch;
    padding: var(--gap-xs);
    gap: var(--gap-2xs);
    background-color: var(--bg-input);
    /* Капсульный сегментбар (эталон): pill-трей + pill-сегменты, активный
       --surface-strong. Трей — recessed --bg-input (бар внутри модалки). */
    border-radius: var(--radius-pill);
}
.model-category-tab {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    padding: 0.5rem 0.25rem;
    border-radius: var(--radius-pill);
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    text-decoration: none;
    transition: color var(--transition), background-color var(--transition);
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
}
.model-category-tab .ti { font-size: 1.25rem !important; }
@media (min-width: 640px) {
    .model-category-tab {
        gap: 0.3125rem;
        padding: 0.5rem 0.5rem;
        font-size: var(--text-xs);
    }
    .model-category-tab .ti { font-size: 1.375rem !important; }
}
@media (hover: hover) {
    .model-category-tab:not(.model-category-tab-active):hover {
        color: var(--text-main);
        background-color: var(--bg-hover);
    }
}
.model-category-tab-active {
    color: var(--text-main);
    background-color: var(--surface-strong);
}
.model-category-tab-disabled {
    opacity: 0.35;
    pointer-events: none;
    cursor: default;
}

/* Под-табы модалки (underline, без пузырька): «Нейросети / Инструменты» в разделе картинок.
   На всю ширину — каждый таб flex:1, текст по центру, подчёркивание под активным. */
.model-subtabs {
    display: flex;
    align-items: stretch;
    margin-bottom: var(--gap-sm);
    border-bottom: 1px solid var(--surface-soft);
}
.model-subtab {
    flex: 1;
    text-align: center;
    padding: 0.5rem 0.25rem;
    margin-bottom: -1px; /* активный бордер перекрывает нижнюю линию контейнера */
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--text-muted);
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    cursor: pointer;
    transition: color var(--transition), border-color var(--transition);
}
.model-subtab:hover {
    color: var(--text-main);
}
.model-subtab--active {
    color: var(--text-main);
    border-bottom-color: var(--text-main);
}

/* Payment Modal */
.payment-modal {
    background: var(--bg-panel);
    border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
    box-shadow: var(--shadow-modal);
}
@media (min-width: 640px) {
    .payment-modal {
        border-radius: var(--radius-2xl);
    }
}

/* Платёжный iframe Т-Кассы — cross-origin фрейм; SDK сам отчитывает
   высоту своего <iframe> через postMessage('resize'), поэтому ВЛАДЕЛЕЦ
   размера — SDK, мы только даём ширину и срезаем углы. min-height тут
   создаёт пустое пространство при коротких шагах формы (OTP/3-DS) и
   дёргает лейаут на мобайле при изменениях высоты — не задаём. */
.payment-iframe {
    width: 100%;
    border: 0;
    border-radius: var(--radius-lg);
    overflow: hidden;
}
@media (max-width: 639px) {
    /* На мобайле — шторка во весь экран минус safe-area, без скруглений. */
    .payment-modal { max-height: 94vh; }
    .payment-iframe { border-radius: 0; }
}
.payment-flow-hero {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.85rem 0.95rem;
    border-radius: var(--radius-lg);
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-elevated) 94%, var(--primary-10)) 0%, var(--bg-elevated) 100%);
    box-shadow: var(--shadow-surface);
    margin-bottom: 0.85rem;
}
.payment-flow-copy {
    flex: 1;
    min-width: 0;
}
.payment-flow-kicker,
.payment-outcome-eyebrow {
    font-size: var(--text-2xs);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.payment-flow-kicker {
    margin-bottom: 0.35rem;
}
.payment-flow-title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    line-height: 1;
    color: var(--text-main);
}
.payment-flow-caption {
    margin-top: 0.25rem;
    font-size: var(--text-sm);
    line-height: 1.5;
    color: var(--text-muted);
}
.payment-flow-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.45rem 0.75rem;
    border-radius: var(--radius-pill);
    background: var(--primary-10);
    color: var(--primary-500);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    white-space: nowrap;
}
.payment-amount-shell,
.payment-outcome-card,
.payment-inline-toggle,
.payment-method-card,
.payment-status-card {
    background: color-mix(in srgb, var(--bg-panel) 42%, var(--bg-elevated));
}

.payment-amount-shell,
.payment-inline-toggle,
.payment-method-card,
.payment-status-card {
    box-shadow: none;
}
.payment-amount-shell,
.payment-outcome-card {
    padding: 0.85rem;
    border-radius: var(--radius-xl);
}
.payment-amount-label {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.payment-amount-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 0.55rem;
}
.payment-amount-input {
    width: 7rem;
    font-family: var(--font-display);
    font-size: clamp(var(--text-3xl), 6vw, var(--text-4xl));
    font-weight: var(--font-weight-bold);
    color: var(--text-main);
}
.payment-quick-amounts {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.45rem;
    margin-top: 0.75rem;
}
.payment-quick-amount {
    padding: 0.48rem 0.8rem;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--bg-panel) 42%, var(--bg-elevated));
    color: var(--text-main);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    transition: background-color var(--transition), color var(--transition), transform var(--transition-fast);
}
@media (hover: hover) {
    .payment-quick-amount:hover {
        transform: translateY(-1px);
        background: var(--surface-strong);
    }
}
.payment-quick-amount.is-active {
    background: var(--primary-500);
    color: var(--text-inverse);
    box-shadow: var(--shadow-surface);
}
.payment-outcome-card {
    margin-top: 0.85rem;
}
.payment-outcome-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
    margin-top: 0.6rem;
}
.payment-outcome-item {
    padding: 0.72rem 0.78rem;
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--bg-elevated) 66%, transparent);
}
.payment-outcome-label {
    font-size: var(--text-2xs);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-bottom: 0.3rem;
}
.payment-outcome-value {
    font-size: var(--text-sm);
    line-height: 1.45;
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
}
.payment-inline-toggle {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    padding: 0.85rem;
    border-radius: var(--radius-lg);
    cursor: pointer;
}
.payment-method-card {
    border-radius: var(--radius-lg);
    transition: background-color var(--transition), box-shadow var(--transition), transform var(--transition-fast);
}
@media (hover: hover) {
    .payment-method-card:hover:not(:disabled) {
        background: var(--surface-strong);
        box-shadow: var(--shadow-surface);
    }
}
/* Идёт создание платежа: гасим карточку и убираем hover-эффект,
   курсор-прогресс сигналит, что запрос в работе. */
.payment-method-card:disabled {
    opacity: 0.55;
    cursor: progress;
    box-shadow: none;
}
/* Выбранный способ автосписания (bind_setup) и основная кнопка оплаты
   сохранённым способом «в один клик» — одинаковая primary-подсветка. */
.payment-method-card.is-active,
.payment-method-card-primary {
    background: color-mix(in srgb, var(--primary-10) 70%, var(--bg-elevated));
    box-shadow: inset 0 0 0 1px var(--primary);
}
.payment-status-card {
    padding: 1rem;
    border-radius: var(--radius-xl);
}
.payment-status-card-blocked {
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-elevated) 94%, var(--primary-10)) 0%, var(--bg-elevated) 100%);
}
.payment-state-icon {
    width: 3rem;
    height: 3rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--bg-raised) 86%, transparent);
}
.payment-note {
    font-size: var(--text-xs);
    color: var(--text-muted);
    line-height: 1.55;
    text-align: center;
}
@media (max-width: 640px) {
    .payment-flow-hero {
        flex-direction: column;
        border-radius: var(--radius-xl);
    }

    .payment-flow-badge {
        align-self: flex-start;
    }

    .payment-outcome-grid {
        grid-template-columns: 1fr;
    }

    .payment-amount-shell,
    .payment-status-card {
        border-radius: var(--radius-xl);
    }
}
/* === Автоплатежи: поля порога/суммы, привязка карты/СБП === */
.autopay-body {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    /* Те же внутренние отступы, что у .profile-info-row — контент не
       прилипает к краям карточки и выровнен с рядами выше. */
    padding: 0.85rem 1.25rem;
}
/* Ряд способа автосписания: инфо слева (вертикальный стек), «Настроить»
   справа. Квалифицируем .profile-info-row — иначе его flex-direction:column
   (объявлен ниже по файлу) перебил бы row. Управление — только в модале. */
.profile-info-row.autopay-method-row {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}
.autopay-method-info {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}
/* Компактная pill-кнопка (НЕ profile-secondary-btn: та на мобайле width:100%). */
.autopay-configure-btn {
    flex-shrink: 0;
    padding: 0.5rem 0.9rem;
    border-radius: var(--radius-pill);
    background-color: color-mix(in srgb, var(--bg-panel) 42%, var(--bg-elevated));
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    white-space: nowrap;
}
@media (hover: hover) {
    .autopay-configure-btn:hover { background-color: var(--bg-hover); }
}
/* Вложенный блок деталей опции «Автопополнение» (поля порога/суммы + сноски).
   Отступ сверху отделяет его от галочки/панели выше (раньше прилегал вплотную),
   лёгкий левый отступ показывает вложенность; ритм — едиными токенами. */
.autopay-fields-group {
    margin-top: var(--gap-sm);
    padding-left: var(--gap-sm);
    display: flex;
    flex-direction: column;
    gap: var(--gap-sm);
}
.autopay-fields {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gap-sm);
}
.autopay-field {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    min-width: 0;
}
.autopay-field-label {
    font-size: var(--text-2xs);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.autopay-input-wrap {
    position: relative;
    display: flex;
    align-items: center;
}
.autopay-input {
    width: 100%;
    min-width: 0;
    padding: 0.6rem 1.9rem 0.6rem 0.75rem; /* справа место под знак ₽ */
    background: var(--bg-input);
    color: var(--text-main);
    border: 1px solid color-mix(in srgb, var(--text-subtle) 24%, transparent);
    border-radius: var(--radius-lg);
    font-size: var(--text-base);
    font-weight: var(--font-weight-semibold);
    transition: border-color var(--transition), box-shadow var(--transition), opacity var(--transition);
}
.autopay-input:focus {
    outline: none;
    border-color: var(--primary-500);
    box-shadow: 0 0 0 3px var(--primary-10);
}
.autopay-input:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}
.autopay-input-suffix {
    position: absolute;
    right: 0.7rem;
    font-size: var(--text-sm);
    color: var(--text-subtle);
    pointer-events: none;
}
.autopay-actions {
    display: flex;
    gap: 0.6rem;
}
.autopay-actions .btn { flex: 1 1 0; }
@media (max-width: 480px) {
    .autopay-fields { grid-template-columns: 1fr; }
    .autopay-actions { flex-direction: column; }
}

/* Status Tokens */
.success-pill { color: var(--text-main); background-color: var(--surface-soft); }

/* Payment method icons */
/* Converts black SVG to neutral --text-muted color */
.payment-card-icon {
    filter: brightness(0) invert(0.65);
}

/* Base row-style items (dropdown entries) */
.dropdown-item {
    width: 100%;
    min-height: 2.375rem;
    padding: 0.4375rem 0.75rem;
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
    /* Концентрично панели (--radius-lg) минус её padding. */
    border-radius: calc(var(--radius-lg) - 0.25rem);
    transition: background-color var(--transition), color var(--transition), opacity var(--transition), filter var(--transition);
    text-align: left;
    color: var(--text-main);
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
}

.dropdown-item.is-selected {
    background-color: var(--bg-hover);
}

@media (hover: hover) {
    .dropdown-item:hover { background-color: var(--bg-hover); }
}

/* Индикатор подменю (drill-down): шеврон вправо у пунктов-категорий. */
.dropdown-item__chevron {
    margin-left: auto;
    opacity: 0.45;
    font-size: 0.95em;
}

.dropdown-menu .dropdown-item > i,
.dropdown-menu .dropdown-item > .dropdown-item-glyph,
.mention-item-icon {
    width: 1.75rem;
    height: 1.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    border-radius: var(--radius-pill);
    background-color: var(--bg-input);
    overflow: hidden;
    font-size: var(--text-sm);
}

.dropdown-menu .dropdown-item > i {
    color: var(--text-main);
}

/* Бренд-иконка коннектора (фирменный SVG) — в пилах, пунктах меню и «+»-листе.
   `.connector-glyph` (img) рендерится через x-html; контейнер задаёт размер бокса. */
.connector-glyph {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}
.connector-pill-glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    font-size: 1.125rem; /* размер Tabler-фоллбэка (text-lg) */
}
.dropdown-menu .dropdown-item > .dropdown-item-glyph > .connector-glyph {
    width: 70%;
    height: 70%;
}

.dropdown-menu .dropdown-item > i.dropdown-item__aspect-icon {
    position: relative;
    font-size: 0;
}

.dropdown-menu .dropdown-item > i.dropdown-item__aspect-icon::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--aspect-preview-width, 0.95rem);
    height: var(--aspect-preview-height, 0.95rem);
    transform: translate(-50%, -50%);
    border-radius: 0.18rem;
    box-shadow: inset 0 0 0 1.5px currentColor;
}

.dropdown-menu .dropdown-item-danger > i {
    background-color: var(--surface-soft);
    color: var(--text-main);
}
@media (hover: hover) {
    .hover-danger-blur:hover,
    .danger-blur { background-color: var(--surface-soft); }
}

/* Chat error retry banner */
.chat-error-banner {
    background-color: var(--surface-soft);
}

/* Layout helpers */
.app-edge-gutters { padding-inline: var(--app-gutter-x); }

.app-root {
    --shell-mobile-header-offset: 0px;
}

@media (max-width: 767.98px) {
    .app-root[data-page-key='chat'],
    .app-root[data-page-key='profile'],
    .app-root[data-page-key='prices'] {
        --shell-mobile-header-offset: calc(env(safe-area-inset-top, 0px) + 3.65rem);
    }

    .app-root[data-page-key='home'],
    .app-root[data-page-key='image'],
    .app-root[data-page-key='video'],
    .app-root[data-page-key='music'] {
        --shell-mobile-header-offset: calc(env(safe-area-inset-top, 0px) + 6.9rem);
    }

    .app-root[data-page-key='chats'],
    .app-root[data-page-key='workflows'],
    .app-root[data-page-key='transcription'] {
        --shell-mobile-header-offset: calc(env(safe-area-inset-top, 0px) + 6.9rem);
    }

    /* Открытый редактор сценариев: полный shell-хедер сменяется компактным
       баром (_mobile_wf_header) — оффсет как у chat/prices/profile. */
    .app-root[data-page-key='workflows']:has(.wf-sidebar--editor-open) {
        --shell-mobile-header-offset: calc(env(safe-area-inset-top, 0px) + 3.65rem);
    }

    /* Транскрипция: активный/сохранённый тред — компактный хедер (как chat).
       Стартовый composer без истории несёт data-mheader='shell' → дефолтный
       офсет полного shell-хедера (6.9rem) выше. */
    .app-root[data-page-key='transcription']:has(.transcribe-shell[data-mheader='thread']) {
        --shell-mobile-header-offset: calc(env(safe-area-inset-top, 0px) + 3.65rem);
    }
}

.app-with-overlay-header,
.generation-result-area {
    padding-top: var(--shell-mobile-header-offset);
}

.generation-result-area {
    scroll-padding-bottom: calc(var(--input-height, 0px) + 1rem);
}

.chat-view-switching {
    visibility: hidden;
}

.page-container {
    max-width: var(--layout-max-width);
    margin: 0 auto;
    padding: var(--layout-pad-y) var(--app-gutter-x);
}

.page-container--pricing {
    max-width: 82rem;
}

.hero-title {
    font-family: var(--font-display);
    font-weight: var(--font-weight-bold);
    margin-bottom: 1rem;
    font-size: var(--text-3xl);
    background-image: var(--heading-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
@media (min-width: 768px) {
    .hero-title { font-size: var(--text-4xl); }
}
.section-title { font-family: var(--font-display); font-weight: var(--font-weight-bold); color: var(--text-main); }
.section-subtitle { color: var(--text-muted); }

/* Sidebar shell */
.sidebar-shell {
    transition-property: transform, opacity, background-color, box-shadow;
    transition-duration: var(--motion-duration-base);
    transition-timing-function: var(--motion-ease-premium);
    will-change: transform;
    transform: translateZ(0);
    backface-visibility: hidden;
    overflow: hidden;
}

.sidebar-section-pad {
    padding-inline: 0.75rem;
}

.sidebar-item-pad {
    padding-inline: 0.75rem;
}

.sidebar-history-list {
    display: flex;
    flex-direction: column;
    gap: 0.0625rem;
}

.sidebar-generation-feed {
    gap: 1rem;
    padding-top: 0.75rem;
}

.sidebar-generation-feed.is-image {
    display: grid;
    grid-template-columns: repeat(var(--media-sidebar-grid-columns, 1), minmax(0, 1fr));
    column-gap: 0;
    gap: 0.75rem;
    align-items: start;
}

.sidebar-generation-feed__column {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    min-width: 0;
}

.sidebar-history-entry {
    padding-block: 0.125rem;
}

.sidebar-generation-entry {
    padding-block: 0;
    content-visibility: auto;
    contain-intrinsic-size: 17rem;
}

.sidebar-generation-card {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}

.app-root[data-page-category='image'] .sidebar-generation-entry {
    min-width: 0;
    contain-intrinsic-size: 15rem;
}

.app-root[data-page-category='image'] .sidebar-generation-card {
    gap: 0.5rem;
}

.sidebar-generation-preview {
    position: relative;
    width: 100%;
}

.sidebar-generation-preview-frame {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: var(--bg-elevated);
    border-radius: 0;
}

/* Скругление правых углов ленты генераций — чистый CSS (заменяет прежний
   JS-пересчёт borderRadius по скроллу, который оставлял углы квадратными до
   ручного скролла). Внешние углы «стопки карточек»: у самой верхней — top-right,
   у самой нижней — bottom-right; в image-сетке скругляется только последняя
   (правая) колонка. 2rem ≈ прежний R=32px. `:first/last-of-type` (а не -child),
   т.к. Alpine <template x-for> остаётся первым ребёнком-сиблингом. */
.sidebar-generation-feed:not(.is-image) > .sidebar-generation-entry:first-of-type .sidebar-generation-preview-frame {
    border-top-right-radius: 2rem;
}
.sidebar-generation-feed:not(.is-image) > .sidebar-generation-entry:last-of-type .sidebar-generation-preview-frame {
    border-bottom-right-radius: 2rem;
}
.sidebar-generation-feed.is-image > .sidebar-generation-feed__column:last-of-type > .sidebar-generation-entry:first-of-type .sidebar-generation-preview-frame {
    border-top-right-radius: 2rem;
}
.sidebar-generation-feed.is-image > .sidebar-generation-feed__column:last-of-type > .sidebar-generation-entry:last-of-type .sidebar-generation-preview-frame {
    border-bottom-right-radius: 2rem;
}

.sidebar-generation-media {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity var(--motion-duration-base) var(--motion-ease-standard);
}

.sidebar-generation-media.is-loaded {
    opacity: 1;
}

/* Шахматная подложка прозрачности — для фото «без фона» (gpt-image transparent,
   удаление фона). Квадраты собраны из поверхностных токенов, поэтому работают в
   обеих темах без хардкода цветов. Красится сам <img>: фон проступает только
   сквозь прозрачные пиксели. Класс вешается через window.isTransparentMedia(). */
.media-checkerboard {
    background-color: var(--bg-elevated);
    background-image:
        linear-gradient(45deg, var(--bg-raised) 25%, transparent 25%, transparent 75%, var(--bg-raised) 75%),
        linear-gradient(45deg, var(--bg-raised) 25%, transparent 25%, transparent 75%, var(--bg-raised) 75%);
    background-size: 1.25rem 1.25rem;
    background-position: 0 0, 0.625rem 0.625rem;
}

.sidebar-generation-preview-frame.is-placeholder {
    min-height: 9rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.sidebar-generation-status {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    color: var(--text-muted);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
}

.sidebar-generation-status.is-failed {
    color: var(--text-main);
}

.sidebar-generation-status.is-failed i {
    font-size: 1.125rem;
}

.sidebar-generation-count,
.sidebar-generation-delete {
    position: absolute;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}

.sidebar-generation-count {
    top: 0.625rem;
    left: 0.625rem;
    min-width: 1.875rem;
    height: 1.875rem;
    padding-inline: 0.5rem;
    background: color-mix(in srgb, var(--bg-panel) 82%, transparent);
    color: var(--text-main);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
}

.sidebar-generation-delete {
    top: 0.625rem;
    right: 0.625rem;
    width: 2rem;
    height: 2rem;
    background: color-mix(in srgb, var(--bg-panel) 78%, transparent);
    color: var(--text-muted);
    opacity: 0;
    pointer-events: none;
    transition:
        opacity var(--motion-duration-base) var(--motion-ease-standard),
        color var(--motion-duration-base) var(--motion-ease-standard),
        background-color var(--motion-duration-base) var(--motion-ease-standard),
        transform var(--motion-duration-base) var(--motion-ease-standard);
}

.sidebar-generation-meta {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}

.sidebar-generation-prompt {
    color: var(--text-main);
    font-size: var(--text-base);
    line-height: 1.3;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    line-clamp: 2;
    -webkit-line-clamp: 2;
    overflow: hidden;
}

.app-root[data-page-category='image'] .sidebar-generation-prompt {
    font-size: var(--text-sm);
    line-height: 1.25;
}

.sidebar-generation-subline {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    min-width: 0;
}

.sidebar-generation-model,
.sidebar-generation-date {
    font-size: var(--text-xs);
    line-height: 1.2;
}

.sidebar-generation-model {
    color: var(--text-muted);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sidebar-generation-date {
    color: var(--text-subtle);
    flex-shrink: 0;
}

.sidebar-generation-entry.is-active .sidebar-generation-prompt {
    color: var(--text-main);
}

@media (hover: hover) {
    .sidebar-generation-entry:hover .sidebar-generation-delete,
    .sidebar-generation-entry:focus-within .sidebar-generation-delete {
        opacity: 1;
        pointer-events: auto;
    }

    .sidebar-generation-delete:hover {
        color: var(--text-main);
        background: color-mix(in srgb, var(--bg-panel) 90%, transparent);
        transform: scale(1.04);
    }
}

@media (max-width: 767.98px) {
    .sidebar-generation-feed {
        gap: 1.125rem;
    }

    .sidebar-generation-prompt {
        font-size: var(--text-sm);
    }
}

@media (hover: none) {
    .sidebar-generation-delete {
        opacity: 1;
        pointer-events: auto;
    }
}

.sidebar-block + .sidebar-block {
    margin-top: 1rem;
}

.sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

/* Sidebar navigation items (section switcher) */
.sidebar-nav-item {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.5rem 0.625rem;
    border-radius: var(--radius-lg);
    color: var(--text-muted);
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    transition: background-color var(--transition), color var(--transition);
    cursor: pointer;
    text-decoration: none;
}
@media (hover: hover) {
    .sidebar-nav-item:hover { color: var(--text-main); }
}
.sidebar-nav-item.active { color: var(--text-main); font-weight: var(--font-weight-bold); }
.sidebar-nav-disabled { opacity: 0.4; pointer-events: none; cursor: default; }

.sidebar-nav-item > span {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: var(--font-weight-medium);
    letter-spacing: 0.01em;
}

/* Shared desktop shell rail */
.shell-rail {
    --shell-rail-width: 12rem;
    --shell-rail-collapsed-width: 3.75rem;
    --shell-rail-slot-size: 2.25rem;
    width: var(--shell-rail-width);
    background: linear-gradient(
        180deg,
        color-mix(in srgb, var(--bg-panel) 92%, black) 0%,
        color-mix(in srgb, var(--bg-app) 70%, var(--bg-panel)) 100%
    );
    z-index: 12;
    overflow: visible;
}

[data-theme="light"] .shell-rail {
    background: var(--chat-input-bg);
}

.shell-rail.is-collapsed {
    width: var(--shell-rail-collapsed-width);
}

.shell-rail__header {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 0.5rem;
    padding-top: 1rem;
    padding-bottom: 1rem;
}

.shell-rail.is-collapsed .shell-rail__header {
    justify-content: center;
    padding-bottom: 1rem;
}

.shell-rail__avatar {
    width: 1.85rem;
    height: 1.85rem;
    object-fit: cover;
    border-radius: var(--radius-pill);
    flex-shrink: 0;
}

.shell-rail__logo {
    width: var(--brand-logo-size);
    height: var(--brand-logo-size);
    flex: 0 0 auto;
    justify-content: center;
}

/* Свёрнутый рейл узкий (60px) — лого возвращаем к размеру слота навигации,
   чтобы он не вылезал за край и совпадал с иконками меню. */
.shell-rail.is-collapsed .shell-rail__logo {
    width: var(--shell-rail-slot-size);
    height: var(--shell-rail-slot-size);
}

.shell-rail__logo-icon {
    display: block;
    width: 100%;
    height: 100%;
    flex-shrink: 0;
}

.shell-rail .sidebar-section-pad {
    padding-inline: 0.75rem;
}

.shell-rail .sidebar-block + .sidebar-block {
    margin-top: 0.625rem;
}

.shell-rail__nav {
    gap: 0.0625rem;
}

.shell-rail .sidebar-nav-item,
.shell-rail .sidebar-nav-disabled,
.shell-rail__profile-trigger {
    flex: none;
    width: 100%;
    min-height: var(--shell-rail-slot-size);
    margin-inline: 0;
    padding: 0.125rem 0.4375rem;
    justify-content: flex-start;
    border-radius: var(--radius-lg);
}

.shell-rail .sidebar-nav-item > span,
.shell-rail .sidebar-nav-disabled > span,
.shell-rail__profile-copy {
    display: block;
    line-height: 1.05;
}

.shell-rail .sidebar-nav-item i,
.shell-rail .sidebar-nav-disabled i,
.shell-rail__profile-trigger i {
    font-size: 1rem;
}

.shell-rail.is-collapsed .sidebar-nav-item,
.shell-rail.is-collapsed .sidebar-nav-disabled,
.shell-rail.is-collapsed .shell-rail__profile-trigger {
    width: var(--shell-rail-slot-size);
    height: var(--shell-rail-slot-size);
    min-height: 0;
    margin-inline: auto;
    padding: 0;
    justify-content: center;
}

.shell-rail.is-collapsed .sidebar-nav-item > span,
.shell-rail.is-collapsed .sidebar-nav-disabled > span,
.shell-rail.is-collapsed .shell-rail__profile-copy {
    display: none;
}

.shell-rail .sidebar-nav-item.active,
.shell-rail__profile-trigger.active {
    color: var(--text-main);
    font-weight: var(--font-weight-bold);
    background-color: transparent;
    box-shadow: none;
}

.shell-rail__middle {
    display: flex;
    flex: 1;
    min-height: 0;
    flex-direction: column;
    padding-bottom: 0.375rem;
}

.shell-rail-chat-list {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.1875rem;
    overflow-y: auto;
    padding: 0.0625rem 0;
    scrollbar-width: none;
}

.shell-rail-chat-list::-webkit-scrollbar {
    display: none;
}

.shell-rail-chat-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--shell-rail-slot-size);
    height: var(--shell-rail-slot-size);
    border-radius: var(--radius-pill);
    background-color: transparent;
    color: var(--text-muted);
    cursor: pointer;
    flex-shrink: 0;
    overflow: hidden;
    transition: background-color var(--transition), color var(--transition);
}

.shell-rail-chat-icon svg {
    width: 1rem;
    height: 1rem;
}

.shell-rail__footer {
    margin-top: auto;
    padding-bottom: 1rem;
    display: flex;
    flex-direction: column;
}

.shell-rail__footer .sidebar-block + .sidebar-block {
    margin-top: 0.875rem;
}

.shell-rail__socials {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.shell-rail__social {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    flex: 0 0 auto;
    border: none;
    background: transparent;
    padding: 0;
    cursor: pointer;
    border-radius: 999px;
    transition: opacity var(--transition);
}

.shell-rail__social-icon {
    display: block;
    width: 100%;
    height: 100%;
    background-color: var(--icon-default);
    -webkit-mask: var(--social-icon-url) center / contain no-repeat;
    mask: var(--social-icon-url) center / contain no-repeat;
    transition: background-color var(--transition);
}

.shell-rail__social:hover .shell-rail__social-icon {
    background-color: var(--icon-hover);
}

.shell-rail.is-collapsed .shell-rail__socials {
    display: none;
}

.shell-rail__legal-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.15rem 0.7rem;
    font-size: 0.7rem;
    line-height: 1.25;
    color: var(--text-subtle);
}

.shell-rail__legal-link {
    color: inherit;
    text-decoration: none;
    transition: color var(--transition);
}

.shell-rail__legal-link:hover {
    color: var(--text-main);
}

.shell-rail__copyright {
    font-size: 0.65rem;
    line-height: 1.3;
    color: var(--text-subtle);
}

.shell-rail.is-collapsed .shell-rail__legal-links,
.shell-rail.is-collapsed .shell-rail__copyright,
.shell-rail.is-collapsed .shell-rail__footer .sidebar-divider {
    display: none;
}

.shell-rail__profile-trigger {
    gap: 0.375rem;
    align-items: center;
    min-width: 0;
    background-color: color-mix(in srgb, var(--bg-elevated) 94%, var(--bg-panel));
    box-shadow: 0 0.75rem 2rem color-mix(in srgb, var(--bg-app) 45%, transparent);
    transition: background-color var(--transition), color var(--transition), box-shadow var(--transition);
}

.shell-rail__profile-copy {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0;
    min-width: 0;
}

.shell-rail__profile-label {
    display: block;
    font-size: var(--text-sm);
    line-height: 1.05;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.shell-rail__profile-trigger.active {
    background-color: color-mix(in srgb, var(--bg-raised) 88%, var(--bg-elevated));
    box-shadow: 0 1rem 2.5rem color-mix(in srgb, var(--bg-app) 58%, transparent);
}

@media (hover: hover) {
    .shell-rail-chat-icon:hover {
        color: var(--text-main);
    }

    .shell-rail__profile-trigger:hover {
        color: var(--text-main);
    }
}

/* Sidebar divider */
.sidebar-divider {
    height: 1px;
    background-color: var(--surface-soft);
    margin: 0;
    flex-shrink: 0;
}

/* Sidebar as a full-height panel flush to the left edge, rounded on the right only.
   No margin-top needed: app-div already starts below the in-flow announcement banner. */
@media (min-width: 768px) {
    .sidebar-shell.sidebar-inset {
        margin: 0;
        height: 100%;
        border-radius: 0 var(--radius-2xl) var(--radius-2xl) 0;
        box-shadow: var(--shadow-glass);
        overflow: hidden;
    }

    .shell-rail.sidebar-inset {
        overflow: visible;
    }

    .shell-rail.sidebar-inset.shell-rail-has-panel {
        border-radius: 0;
        box-shadow: none;
        border-right: 1px solid var(--surface-soft);
    }
}

/* ══════════════════════════════════════════════════
   TELEGRAM-STYLE SIDEBAR (tg-*)
   Desktop: icon rail + history panel (side by side)
   Mobile: full-screen chat list
   ══════════════════════════════════════════════════ */

/* Container: flex row holding rail + panel */
.tg-sidebar {
    display: flex;
    flex-direction: row;
    height: 100%;
    flex-shrink: 0;
    z-index: 10;
    overflow: hidden;
}

/* Mobile: sidebar takes full width, is the "main" screen */
@media (max-width: 767.98px) {
    .tg-sidebar {
        width: 100%;
        flex-shrink: 1;
        min-width: 0;
    }

    /* Stack: list underneath, chat slides over it */
    .app-shell-body {
        position: relative;
        /* Both children are absolute — body needs explicit sizing */
        height: 100%;
        min-height: 0;
    }
    .tg-sidebar {
        position: absolute;
        inset: 0;
        z-index: 1;
    }
    .app-shell-body > .sidebar-page {
        position: absolute;
        inset: 0;
        z-index: 2;
    }

    /* Enable transition only after first paint (class added by JS) */
    .app-shell-body.mobile-nav-ready > .sidebar-page {
        transition: transform var(--motion-duration-base) var(--motion-ease-premium);
        will-change: transform;
    }

    /* List always stays in place */
    .tg-sidebar-mobile-hidden {
        visibility: hidden;
        pointer-events: none;
    }
    /* Chat hidden = off-screen right */
    .tg-content-hidden {
        transform: translateX(100%);
        pointer-events: none;
    }
}

/* Desktop: fixed-width sidebar */
@media (min-width: 768px) {
    .tg-sidebar {
        width: auto;
        overflow: visible;
    }
    .tg-sidebar-collapsed {
        width: auto;
    }
    /* Content area always visible on desktop */
    .tg-content-hidden {
        display: flex !important;
    }
}

@media (min-width: 768px) and (max-width: 1099.98px) {
    .app-shell-body {
        position: relative;
    }

    .shell-rail + .shell-tablet-overlay-panel {
        position: absolute !important;
        top: 0;
        bottom: 0;
        left: var(--shell-rail-width);
    }

    .shell-rail.is-collapsed + .shell-tablet-overlay-panel {
        left: var(--shell-rail-collapsed-width);
    }

    .shell-tablet-overlay-panel {
        width: var(--shell-secondary-panel-width);
        max-width: min(22rem, calc(100vw - var(--shell-rail-collapsed-width) - 1rem));
        z-index: var(--z-sidebar);
        opacity: 0;
        pointer-events: none;
        will-change: transform, opacity;
        transition:
            transform var(--motion-duration-base) var(--motion-ease-premium),
            opacity var(--motion-duration-fast) var(--motion-ease-standard);
    }

    .shell-tablet-overlay-panel--open {
        opacity: 1;
        pointer-events: auto;
    }

    .tg-sidebar.shell-tablet-overlay-panel {
        overflow: visible;
    }

    .tg-sidebar.shell-tablet-overlay-panel > .tg-panel {
        width: 100%;
    }
}

/* ── Shared secondary shell panels (chat history + media generations) ── */
.tg-panel,
.shell-secondary-panel {
    overflow: hidden;
    position: relative;
}

.shell-secondary-panel.sidebar-shell {
    background-color: transparent;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

/* Glass background on pseudo-element so panel doesn't create containing block for fixed children */
.tg-panel::before,
.shell-secondary-panel::before {
    content: '';
    position: absolute;
    inset: 0;
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    z-index: 0;
    border-radius: inherit;
}

.tg-panel > *,
.shell-secondary-panel > * {
    position: relative;
    z-index: 1;
}

@media (max-width: 767.98px) {
    .tg-panel {
        width: 100%;
    }
    /* Mobile: drop the panel glass-bg pseudo entirely — body already paints
       --bg-app, and the shell mobile header owns the top progressive blur. */
    .tg-panel::before,
    .shell-secondary-panel::before {
        content: none;
    }

    .tg-panel-header .tg-panel-blur-top {
        display: none;
    }

    .tg-panel-list {
        padding-top: var(--shell-mobile-header-offset);
    }
}

@media (min-width: 768px) {
    .tg-panel,
    .shell-secondary-panel {
        width: var(--shell-secondary-panel-width);
        flex: 0 0 var(--shell-secondary-panel-width);
        border-radius: 0 var(--radius-2xl) var(--radius-2xl) 0;
        box-shadow: var(--shadow-glass);
    }
}

.app-root[data-shell-kind='media'] {
    --media-sidebar-width: 18rem;
    --media-sidebar-grid-columns: 1;
}

.media-sidebar-resize-zone {
    display: none;
    position: relative;
    flex: 0 0 var(--media-sidebar-resize-gap);
    width: var(--media-sidebar-resize-gap);
    align-items: center;
    justify-content: center;
    cursor: ew-resize;
    z-index: calc(var(--z-sidebar) + 1);
}

.media-sidebar-resize-zone::before {
    content: '';
    width: 0.25rem;
    height: 3rem;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--bg-raised) 86%, transparent);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--bg-panel) 54%, transparent);
    transition:
        background-color var(--motion-duration-fast) var(--motion-ease-standard),
        box-shadow var(--motion-duration-fast) var(--motion-ease-standard);
}

@media (hover: hover) {
    .media-sidebar-resize-zone:hover::before {
        background: color-mix(in srgb, var(--primary-500) 30%, var(--bg-raised));
        box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary-500) 22%, transparent);
    }
}

.media-sidebar-resize-zone.is-active::before {
    background: color-mix(in srgb, var(--primary-500) 44%, var(--bg-raised));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary-500) 28%, transparent);
}

@media (min-width: 1100px) {
    .app-root[data-shell-kind='media'] {
        --shell-secondary-panel-width: var(--media-sidebar-width);
    }

    .media-sidebar-resize-zone {
        display: flex;
    }
}

/* Panel header & footer — sticky with progressive blur */
.tg-panel-header,
.tg-panel-footer {
    position: sticky;
    z-index: 20;
    flex-shrink: 0;
    background-color: transparent;
}
.tg-panel-header { top: 0; }
.tg-panel-footer {
    bottom: 0;
    padding-top: 2rem;
}

/* Progressive blur layers (reusable for top/bottom) */
.tg-panel-blur {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 0;
}

.tg-panel-blur-soft {
    position: absolute;
    inset: 0;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}
.tg-panel-blur-strong {
    position: absolute;
    inset: 0;
    -webkit-backdrop-filter: blur(var(--progressive-blur-4, 12px));
    backdrop-filter: blur(var(--progressive-blur-4, 12px));
}
.tg-panel-blur-tint {
    position: absolute;
    inset: 0;
}

/* Top blur: solid at top, fading downward */
.tg-panel-blur-top .tg-panel-blur-soft {
    -webkit-mask-image: var(--surface-fade-top-soft-mask);
    mask-image: var(--surface-fade-top-soft-mask);
}
.tg-panel-blur-top .tg-panel-blur-strong {
    -webkit-mask-image: var(--surface-fade-top-strong-mask);
    mask-image: var(--surface-fade-top-strong-mask);
}
.tg-panel-blur-top .tg-panel-blur-tint {
    background: var(--surface-fade-top-tint-gradient);
    opacity: var(--surface-fade-top-tint-opacity);
}

/* Bottom blur: solid at bottom, fading upward */
.tg-panel-blur-bottom .tg-panel-blur-soft {
    -webkit-mask-image: linear-gradient(to top, black 30%, transparent 100%);
    mask-image: linear-gradient(to top, black 30%, transparent 100%);
}
.tg-panel-blur-bottom .tg-panel-blur-strong {
    -webkit-mask-image: linear-gradient(to top, black 20%, transparent 65%);
    mask-image: linear-gradient(to top, black 20%, transparent 65%);
}
.tg-panel-blur-bottom .tg-panel-blur-tint {
    background: linear-gradient(to top, var(--surface-fade-top-tint-color) 20%, transparent 100%);
    opacity: 0.95;
}

/* Mobile panel is transparent over body --bg-app — fade into that token
   so the bottom gradient stays tonally aligned with the page background. */
@media (max-width: 767.98px) {
    .tg-panel-blur-bottom .tg-panel-blur-tint {
        background: linear-gradient(to top, var(--bg-app) 20%, transparent 100%);
    }
}

/* Search field */
.tg-search-field input {
    background-color: var(--bg-input);
    border: none;
    transition: background-color var(--transition), box-shadow var(--transition);
}
.tg-search-field input:focus {
    background-color: var(--bg-elevated);
    box-shadow: 0 0 0 2px var(--primary-20);
}

/* Chat rows */
.tg-chat-row {
    transition: background-color var(--transition);
}

.tg-chat-icon {
    width: 2.75rem;
    height: 2.75rem;
    padding: 0.5rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--bg-elevated);
    color: var(--text-muted);
    flex-shrink: 0;
    overflow: hidden;
}
.tg-chat-icon svg {
    width: 100%;
    height: 100%;
}

/* Show chat actions on hover (desktop) */
@media (hover: hover) and (min-width: 640px) {
    .tg-chat-row .chat-history-actions {
        opacity: 0;
        pointer-events: none;
        transition: opacity var(--transition-fast);
    }
    .tg-chat-row:hover .chat-history-actions,
    .tg-chat-row:focus-within .chat-history-actions {
        opacity: 1;
        pointer-events: auto;
    }
}

/* Scrollable chat list — hide scrollbar for clean look */
.tg-panel-list {
    scrollbar-width: none;
}
.tg-panel-list::-webkit-scrollbar {
    display: none;
}

/* ── Bottom Action Bar ── */
.tg-footer-bar {
    background-color: var(--bg-hover);
    border-radius: var(--radius-xl);
    padding: 0.375rem;
}

.tg-footer-new-chat {
    height: 2.75rem;
    padding-inline: 1rem;
    border-radius: var(--radius-lg);
    background-color: var(--primary-500);
    background-image: linear-gradient(135deg, var(--primary-600), var(--primary-500));
    color: var(--primary-text);
    border: none;
    cursor: pointer;
    transition: filter var(--transition), transform var(--transition);
    white-space: nowrap;
}
@media (hover: hover) {
    .tg-footer-new-chat:hover { filter: saturate(1.08) brightness(1.03); }
}
.tg-footer-new-chat:active { transform: scale(0.97); }

@media (max-width: 767.98px) {
    .tg-footer-bar {
        width: fit-content;
        max-width: 100%;
        margin-inline: auto;
    }

    .tg-footer-new-chat {
        flex: 0 1 auto;
        min-width: 0;
        gap: 0.5rem;
        padding-inline: 0.875rem;
    }
}

.tg-footer-icon-btn {
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--radius-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--bg-input);
    color: var(--text-muted);
    border: none;
    cursor: pointer;
    flex-shrink: 0;
    transition: background-color var(--transition), color var(--transition);
}
@media (hover: hover) {
    .tg-footer-icon-btn:hover {
        background-color: var(--bg-hover);
        color: var(--text-main);
    }
}
.tg-footer-icon-btn-active {
    background-color: var(--primary-20);
    color: var(--primary-500);
}

.chat-input-shell,
.shell-mobile-chat-header-btn,
.shell-desktop-header__toggle,
.shell-user-pill,
.shell-user-pill--standalone,
.shell-tabs {
    box-shadow: var(--shadow-glass);
    transform: translateZ(0);
    backface-visibility: hidden;
}

.system-modal-card {
    width: min(92vw, 22.5rem);
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1.125rem;
    transform: translateZ(0);
    backface-visibility: hidden;
}

.system-modal-body {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.system-modal-title {
    font-family: var(--font-display);
    font-size: clamp(1.15rem, 0.98rem + 0.6vw, 1.375rem);
    font-weight: var(--font-weight-semibold);
    line-height: 1.12;
    color: var(--text-main);
}
.system-modal-title.hidden,
.system-modal-message.hidden,
.system-modal-chips.hidden { display: none; }

.system-modal-message {
    color: var(--text-muted);
    font-size: var(--text-sm);
    line-height: 1.45;
    white-space: pre-wrap;
    max-width: 100%;
}

.system-modal-input {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--bg-raised);
    background: var(--bg-input);
    color: var(--text-main);
    font-size: var(--text-base);
    outline: none;
    transition: border-color var(--transition-fast);
}
.system-modal-input:focus {
    border-color: var(--primary);
}
.system-modal-input::placeholder {
    color: var(--text-subtle);
}

/* Кнопки — вертикальным стеком (primary сверху, отмена снизу), на всю ширину. */
.system-modal-actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.5rem;
}
.system-modal-actions .btn {
    width: 100%;
    justify-content: center;
}
/* «Тихая» кнопка — сливается с фоном карточки (без своего фона/обводки). */
.system-modal-actions .btn-modal-flat {
    background-color: transparent;
    color: var(--text-main);
}
@media (hover: hover) {
    .system-modal-actions .btn-modal-flat:hover {
        background-color: var(--bg-hover);
    }
}

/* Чипы для перечисления (напр. «модель не поддерживает: …»). */
.system-modal-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.system-modal-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.3rem 0.625rem;
    border-radius: var(--radius-pill);
    background-color: var(--bg-raised);
    color: var(--text-main);
    font-size: var(--text-sm);
    line-height: 1.1;
}
.system-modal-chip > i {
    font-size: 1.05rem;
    color: var(--text-muted);
}

@media (max-width: 640px) {
    .system-modal-card {
        width: min(92vw, 26rem);
        gap: 1rem;
        padding: 1rem;
    }
}

/* ── Idle Glow: animated border shimmer when input is empty ── */
@property --glow-angle {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: false;
}

@property --glow-opacity {
    syntax: '<number>';
    initial-value: 0.5;
    inherits: false;
}

.shell-idle-glow::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: conic-gradient(
        from var(--glow-angle),
        transparent 0%,
        transparent 25%,
        color-mix(in srgb, var(--primary-500) 40%, transparent) 35%,
        var(--primary-500) 45%,
        color-mix(in srgb, var(--primary-500) 80%, white) 50%,
        var(--primary-500) 55%,
        color-mix(in srgb, var(--primary-500) 40%, transparent) 65%,
        transparent 75%,
        transparent 100%
    );
    -webkit-mask:
        linear-gradient(#fff 0 0) content-box,
        linear-gradient(#fff 0 0);
    mask:
        linear-gradient(#fff 0 0) content-box,
        linear-gradient(#fff 0 0);
    -webkit-mask-composite: destination-out;
    mask-composite: exclude;
    pointer-events: none;
    z-index: 2;
    --glow-angle: 0deg;
    --glow-opacity: 0.5;
    opacity: var(--glow-opacity);
    animation: shell-glow-spin 4s linear infinite, shell-glow-pulse 3s ease-in-out infinite;
}

@keyframes shell-glow-spin {
    to { --glow-angle: 360deg; }
}

@keyframes shell-glow-pulse {
    0%, 100% { --glow-opacity: 0.4; }
    50% { --glow-opacity: 0.8; }
}

@media (prefers-reduced-motion: reduce) {
    .shell-idle-glow::before { animation: none; opacity: 0.3; }
}

@media (max-width: 640px) {
    .shell-idle-glow::before { clip-path: inset(0 0 1px 0); }
}

/* ── Temp Chat Dash: бегущий пунктир (marching ants) по периметру композера
   во временном чате. Заменяет idle-glow на пустом экране (см. биндинг в
   _composer_text.html). SVG-обводка со stroke-dasharray даёт ровные штрихи
   одинаковой длины по всему периметру — в отличие от conic-маски, которая на
   широкой пилюле «плыла» и не читалась как пунктир. Пунктир — фирменный знак
   temp-чата (ср. stroke-dasharray иконки в _temp_chat_icon.html). */
.temp-dash-frame {
    display: none;
    position: absolute;
    inset: 1px; /* стоит чуть внутри пилюли, как ring у idle-glow */
    /* <svg> — replaced-элемент: без явных размеров он откатывается к дефолтным
       300×150px и не тянется по inset. Поэтому размер задаём явно. */
    width: calc(100% - 2px);
    height: calc(100% - 2px);
    overflow: visible;
    pointer-events: none;
    z-index: 2;
}
.shell-temp-dash > .temp-dash-frame { display: block; }

.temp-dash-frame rect {
    fill: none;
    stroke: var(--text-muted);
    stroke-width: 1.5;
    stroke-dasharray: 5 6;
    stroke-linecap: round;
    animation: temp-dash-march 0.7s linear infinite;
}

/* Сдвиг на один цикл «штрих+пробел» (5+6) → штрихи плавно бегут по контуру. */
@keyframes temp-dash-march {
    to { stroke-dashoffset: -11; }
}

@media (prefers-reduced-motion: reduce) {
    .temp-dash-frame rect { animation: none; }
}

.chat-input-state-host {
    --chat-params-curtain-radius: calc(var(--radius-xl) - 0.25rem);
    --chat-params-curtain-bottom-radius: calc(var(--chat-params-curtain-radius) + 0.5rem);
    --chat-params-curtain-top-pad: 0.5rem;
    --chat-params-curtain-x-pad: 0.5rem;
    --chat-params-curtain-overlap: 0.625rem;
    --chat-params-curtain-bottom-pad: calc(var(--chat-params-curtain-top-pad) + var(--chat-params-curtain-overlap));
    display: grid;
    align-items: end;
    grid-template-columns: minmax(0, 1fr);
    position: relative;
    z-index: 1;
}

.chat-input-state-shell {
    min-height: var(--chat-input-shell-min-height);
}

/* Input zone: единый padding для всех дочерних элементов внутри формы.
   Absolute-позиционированные controls ссылаются на padding-box,
   поэтому inset: 0 автоматически совпадает с padding content'а. */
.chat-input-zone {
    padding: var(--composer-inset, 0.625rem); /* 10px */
    min-height: var(--chat-input-shell-min-height); /* 40px buttons + padding */
    border-radius: inherit;
}

/* Drag-n-drop файлов: подсветка зоны, пока над ней тянут файл
   (.is-drag-over ставит AttachmentsService на чат- и медиа-композере).
   В медиа подсвечиваем внутренний скруглённый pill, а не внешний
   flex-контейнер без радиуса. */
.chat-input-zone.is-drag-over,
.media-composer-shell.is-drag-over .chat-input-main-shell {
    box-shadow: inset 0 0 0 2px var(--primary-500);
    background-color: var(--primary-10);
}

.composer-state-switch {
    position: relative;
}

.composer-state-switch > .composer-state-layer {
    display: grid;
    grid-template-rows: 1fr;
    min-height: 0;
    width: 100%;
    min-width: 0;
    overflow: hidden;
    opacity: 1;
    transform: translate3d(0, 0, 0);
    transition:
        grid-template-rows var(--motion-duration-base) var(--motion-ease-premium),
        opacity var(--motion-duration-fast) var(--motion-ease-premium),
        transform var(--motion-duration-fast) var(--motion-ease-premium);
    will-change: opacity, transform;
}

.composer-state-layer__inner {
    min-height: 0;
    min-width: 0;
}

.composer-state-switch.is-voice-active > .composer-state-layer--normal,
.composer-state-switch:not(.is-voice-active) > .composer-state-layer--voice {
    grid-template-rows: 0fr;
    opacity: 0;
    transform: translate3d(0, 0.25rem, 0);
    pointer-events: none;
    z-index: 0;
}

.composer-state-switch.is-voice-active > .composer-state-layer--voice,
.composer-state-switch:not(.is-voice-active) > .composer-state-layer--normal {
    position: relative;
    grid-template-rows: 1fr;
    opacity: 1;
    transform: translate3d(0, 0, 0);
    pointer-events: auto;
    z-index: 1;
}

.chat-input-state-stack {
    display: flex;

    flex-direction: column;
    gap: 0;
    /* Перебивает .motion (там нет padding/border-radius): рост/схлопывание
       шторки params двигает верх стека синхронно с .chat-input-params-shell
       (base/premium — единый темп геометрии композера), иначе padding-top
       прыгает мгновенно. Остальные свойства — как в .motion. */
    transition: padding-top var(--motion-duration-base) var(--motion-ease-premium),
                border-radius var(--motion-duration-base) var(--motion-ease-premium),
                transform var(--motion-duration-base) var(--motion-ease-premium),
                opacity var(--motion-duration-base) var(--motion-ease-premium),
                background-color var(--motion-duration-base) var(--motion-ease-premium),
                box-shadow var(--motion-duration-base) var(--motion-ease-premium);
}

/* Тонировка шторки — на ::before с opacity-переходом: background-image
   (градиент) не интерполируется и при снятии .has-params исчезал скачком в
   первом же кадре, до схлопывания шторки. Базовое стекло (background-color +
   backdrop-filter) у стека есть всегда — из общего правила .chat-input-shell. */
.chat-input-state-stack::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-elevated) 88%, transparent), color-mix(in srgb, var(--bg-input) 84%, transparent));
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--motion-duration-fast) var(--motion-ease-premium);
}

[data-theme="light"] .chat-input-state-stack::before {
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-raised) 94%, transparent), color-mix(in srgb, var(--bg-elevated) 88%, transparent));
}

.chat-input-state-stack.has-params {
    padding-top: var(--chat-params-curtain-top-pad);
    border-radius: var(--chat-params-curtain-radius) var(--chat-params-curtain-radius) var(--chat-params-curtain-bottom-radius) var(--chat-params-curtain-bottom-radius);
    transform: translateZ(0);
    backface-visibility: hidden;
}

.chat-input-state-stack.has-params::before {
    opacity: 1;
}

.chat-input-params-shell {
    min-width: 0;
    position: relative;
    z-index: 0;
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    padding: 0;
    margin-bottom: 0;
    pointer-events: none;
    transition: grid-template-rows var(--motion-duration-base) var(--motion-ease-premium),
                opacity var(--motion-duration-fast) var(--motion-ease-premium),
                padding var(--motion-duration-base) var(--motion-ease-premium),
                margin-bottom var(--motion-duration-base) var(--motion-ease-premium);
}

.chat-input-state-stack.has-params .chat-input-params-shell {
    grid-template-rows: 1fr;
    opacity: 1;
    padding: 0 var(--chat-params-curtain-x-pad) var(--chat-params-curtain-bottom-pad);
    margin-bottom: calc(var(--chat-params-curtain-overlap) * -1);
    pointer-events: auto;
}

/* Inner wrapper — единственный grid-child shell'а. Объединяет row+banner
   в одну схлопывающуюся единицу: при закрытии шторки grid-rows 0fr зажимает
   всё содержимое (включая баннер). Padding/margin остаются на shell, чтобы
   inner не давал ненулевого min-content в close state. */
.chat-input-params-inner {
    min-height: 0;
    overflow: hidden;
}

.chat-input-assistants-host {
    width: 100%;
    min-width: 0;
    margin-bottom: 0.625rem;
    max-height: 8rem;
    opacity: 1;
    overflow: hidden;
    transition:
        max-height var(--motion-duration-base) var(--motion-ease-premium),
        margin-bottom var(--motion-duration-base) var(--motion-ease-premium),
        opacity var(--motion-duration-base) var(--motion-ease-premium);
}

.chat-input-assistants-host.is-voice-hidden {
    max-height: 0;
    margin-bottom: 0;
    opacity: 0;
    pointer-events: none;
}

.chat-input-assistants-strip {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 0;
    min-width: 0;
    /* верт. padding нужен под бейдж .chat-input-assistant-dot__status,
       который висит на bottom: -1px и иначе клиппится overflow-y */
    padding: 0.25rem 0;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
}

.chat-input-assistants-strip::-webkit-scrollbar {
    display: none;
}

.chat-input-assistant-create {
    order: 1;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.6875rem;
    height: 2.875rem;
    min-height: 0;
    min-width: max-content;
    max-width: 100%;
    padding: 0.25rem 1rem 0.25rem 0.25rem;
    border: none;
    border-radius: var(--radius-pill);
    background: linear-gradient(
        180deg,
        color-mix(in srgb, var(--primary-10) 68%, var(--bg-raised)) 0%,
        color-mix(in srgb, var(--primary-10) 30%, var(--bg-panel)) 100%
    );
    color: var(--text-main);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary-500) 14%, transparent);
    transition:
        transform var(--motion-duration-fast) var(--motion-ease-premium),
        background var(--motion-duration-fast) var(--motion-ease-standard),
        box-shadow var(--motion-duration-fast) var(--motion-ease-standard);
}

.chat-input-assistant-create__icon {
    position: relative;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: calc(2.875rem - 0.5rem);
    height: calc(2.875rem - 0.5rem);
    border: none;
    border-radius: 50%;
    background: color-mix(in srgb, var(--bg-raised) 84%, transparent);
    color: var(--text-main);
}

.chat-input-assistant-create__icon .ti {
    font-size: 1.375rem;
}

.chat-input-assistant-create__label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: var(--text-sm);
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
}

.chat-input-assistant-dot {
    order: 3;
    position: relative;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.875rem;
    height: 2.875rem;
    border: none;
    border-radius: 50%;
    background: color-mix(in srgb, var(--bg-raised) 84%, transparent);
    color: var(--text-main);
    box-shadow: var(--shadow-surface);
    transition:
        background var(--motion-duration-fast) var(--motion-ease-standard),
        box-shadow var(--motion-duration-fast) var(--motion-ease-standard);
}

.chat-input-assistant-dot .ti {
    font-size: 1.375rem;
}

.chat-input-assistant-dot__avatar {
    width: calc(100% - 2px) !important;
    height: calc(100% - 2px) !important;
    object-fit: cover;
    border: none;
    border-radius: 50%;
    display: block;
    box-sizing: border-box;
    box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--text-main) 22%, transparent) !important;
}

.chat-input-assistant-dot__fallback {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    line-height: 1;
}

.chat-input-assistant-dot__status {
    position: absolute;
    right: -0.0625rem;
    bottom: -0.0625rem;
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--primary-500);
    color: var(--primary-text);
    box-shadow: 0 0 0 2px var(--bg-elevated);
}

.chat-input-assistant-dot.is-active {
    background: linear-gradient(
        180deg,
        color-mix(in srgb, var(--primary-10) 72%, var(--bg-raised)) 0%,
        color-mix(in srgb, var(--primary-10) 34%, var(--bg-panel)) 100%
    );
    box-shadow:
        0 10px 24px -18px color-mix(in srgb, var(--primary-500) 36%, transparent);
}

.chat-input-assistant-dot-create {
    color: color-mix(in srgb, var(--primary-600) 74%, var(--text-main));
}

.chat-input-assistant-dot-all {
    order: 2;
    color: var(--text-muted);
}

@media (hover: hover) {
    .chat-input-assistant-create:hover {
        background: linear-gradient(
            180deg,
            color-mix(in srgb, var(--primary-10) 82%, var(--bg-raised)) 0%,
            color-mix(in srgb, var(--primary-10) 40%, var(--bg-panel)) 100%
        );
    }

    .chat-input-assistant-dot:hover {
        background: color-mix(in srgb, var(--bg-panel) 92%, transparent);
    }

    .chat-input-assistant-dot.is-active:hover {
        background: linear-gradient(
            180deg,
            color-mix(in srgb, var(--primary-10) 84%, var(--bg-raised)) 0%,
            color-mix(in srgb, var(--primary-10) 44%, var(--bg-panel)) 100%
        );
    }
}

/* Чип ассистента: mobile-вариант — пила в params-row, desktop — width-collapse
   узел в контролс-баре. Прячем ОБЁРТКУ-collapsible, а не кнопку: скрытая кнопка
   внутри видимой grid-обёртки оставляла бы ghost-слот в flex-gap ряда. */
@media (min-width: 768px) {
    .chat-input-params-row > .composer-collapsible.assistant-pill-mobile { display: none; }
}
@media (max-width: 767px) {
    .composer-collapsible--inline.assistant-pill-desktop { display: none; }
    .chat-input-state-stack.has-mobile-assistant {
        padding-top: var(--chat-params-curtain-top-pad);
        border-radius: var(--chat-params-curtain-radius) var(--chat-params-curtain-radius) var(--chat-params-curtain-bottom-radius) var(--chat-params-curtain-bottom-radius);
        transform: translateZ(0);
        backface-visibility: hidden;
    }
    /* Плёнка шторки — общий ::before стека (см. desktop-вариант выше). */
    .chat-input-state-stack.has-mobile-assistant::before {
        opacity: 1;
    }
    .chat-input-state-stack.has-mobile-assistant .chat-input-params-shell {
        grid-template-rows: 1fr;
        opacity: 1;
        padding: 0 var(--chat-params-curtain-x-pad) var(--chat-params-curtain-bottom-pad);
        margin-bottom: calc(var(--chat-params-curtain-overlap) * -1);
        pointer-events: auto;
    }
}

/* Единственный владелец ВЫСОТЫ ряда пил. Пилы анимируют только ширину
   (см. .chat-input-params-row > .composer-collapsible), а вертикальное место
   под ряд выдаёт/забирает этот slot: ряд без видимых чипов схлопывается, когда
   шторку держит открытой что-то ещё (ultra-banner / ассистент на мобиле).
   При закрытии самой шторки slot держится открытым — клипает шторка, одним
   движением. Темп — base/premium, как у всей геометрии композера. */
.chat-input-params-rowslot {
    display: grid;
    grid-template-rows: 1fr;
    transition: grid-template-rows var(--motion-duration-base) var(--motion-ease-premium);
}
.chat-input-state-stack.has-params:not(.has-active-chips) .chat-input-params-rowslot {
    grid-template-rows: 0fr;
}

.chat-input-params-row {
    /* Токен gap: его же (с минусом) использует margin-компенсация схлопнутой
       пилы (.composer-collapsible:not(.is-open)) — менять только здесь. */
    --params-row-gap: 0.5rem;
    display: flex;
    flex-wrap: wrap;
    gap: var(--params-row-gap);
    min-height: 0;
    overflow: hidden;
}

.chat-input-params-shell .surface-chip {
    background: var(--surface-active);
    box-shadow: none;
    /* Единая высота пил ряда (py-1.5 + крестик 24px = 36px): у пил без
       крестика (forced-thinking) контент ниже, и ряд проседал скачком,
       когда такая пила оставалась последней. */
    min-height: 2.25rem;
}

/* Зазор между chips и баннером — только если в ряду есть ВИДИМЫЕ чипы
   (hasComposerChips: пилы режимов; чип ассистента считается только на мобиле —
   на десктопе он в нижнем контролс-баре, и зазор давал пустой «резерв» над
   баннером). Темп = base/premium — зазор уезжает синхронно со схлопыванием
   .chat-input-params-rowslot, баннер движется одним движением, без фаз. */
.chat-input-params-shell .ultra-banner {
    transition: margin-top var(--motion-duration-base) var(--motion-ease-premium);
}
.chat-input-state-stack.has-active-chips .ultra-banner {
    margin-top: 0.5rem;
}

@media (hover: hover) {
    .chat-input-params-shell .surface-chip:hover {
        background: var(--surface-strong);
    }
}

.chat-input-params-shell .surface-chip.assistant-chip,
.surface-chip.assistant-chip {
    background: linear-gradient(
        180deg,
        color-mix(in srgb, var(--primary-10) 68%, var(--bg-raised)) 0%,
        color-mix(in srgb, var(--primary-10) 30%, var(--bg-panel)) 100%
    );
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary-500) 14%, transparent);
}

/* Лидирующий аватар-слот в пиле ассистента: круглый контейнер для иконки
   или буквы-фоллбэка (первая буква имени), как у верхних дотов ассистентов.
   Размер задаётся утилитами (w-7/h-7 desktop, w-6/h-6 mobile). */
.assistant-chip__glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    border-radius: 50%;
    background: color-mix(in srgb, var(--bg-raised) 84%, transparent);
    color: var(--text-main);
    font-weight: var(--font-weight-semibold);
    line-height: 1;
}

@media (hover: hover) {
    .chat-input-params-shell .surface-chip.assistant-chip:hover,
    .surface-chip.assistant-chip:hover {
        background: linear-gradient(
            180deg,
            color-mix(in srgb, var(--primary-10) 82%, var(--bg-raised)) 0%,
            color-mix(in srgb, var(--primary-10) 40%, var(--bg-panel)) 100%
        );
    }
}

.media-composer-warning-slot {
    padding: 0.5rem 0.5rem 0;
}

@media (max-width: 767px) {
    .chat-input-state-host {
        --chat-params-curtain-radius: calc(var(--radius-lg) - 0.125rem);
        --chat-params-curtain-bottom-radius: calc(var(--chat-params-curtain-radius) + 0.25rem);
        --chat-params-curtain-top-pad: 0.4375rem;
        --chat-params-curtain-x-pad: 0.4375rem;
        --chat-params-curtain-overlap: 0.5rem;
        --chat-params-curtain-bottom-pad: calc(var(--chat-params-curtain-top-pad) + var(--chat-params-curtain-overlap));
    }

    .chat-input-params-row {
        flex-wrap: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
        scrollbar-width: none;
        /* Горизонтальный скролл пил режется не жёсткой прямой у края контейнера,
           а мягко растворяется — это «уважает» скругление окна композера. Затухание
           видно только при переполнении: когда пилы помещаются, у правого края
           пусто и маска ни на что не влияет. */
        -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 1.5rem), transparent 100%);
        mask-image: linear-gradient(to right, #000 calc(100% - 1.5rem), transparent 100%);
    }

    .chat-input-params-row::-webkit-scrollbar {
        display: none;
    }

    .chat-input-assistant-dot {
        width: 2.75rem;
        height: 2.75rem;
    }

    .chat-input-assistant-create {
        flex: 0 0 auto;
        height: 2.75rem;
        min-height: 0;
        min-width: max-content;
        padding: 0.25rem 0.875rem 0.25rem 0.25rem;
    }

    .chat-input-assistant-create__icon {
        width: calc(2.75rem - 0.5rem);
        height: calc(2.75rem - 0.5rem);
    }

    /* Реальные флекс-элементы скролл-ряда — обёртки .composer-collapsible
       (чип внутри них) и прямой чип ассистента. Без 0 0 auto на обёртках
       пилюли сжимаются/переносят текст вместо горизонтального скролла. */
    .chat-input-params-shell .surface-chip,
    .chat-input-params-row > .composer-collapsible {
        flex: 0 0 auto;
    }
}

/* Ghost-кнопки в стеклянном инпуте (категория B) — полупрозрачные; tint делает их
   тема-зависимыми сам, поэтому отдельный [data-theme="light"]-дубль больше не нужен. */
.chat-input-shell .btn.btn-ghost {
    background-color: var(--surface-active);
}

@media (hover: hover) {
    .chat-input-shell .btn.btn-ghost:hover {
        background-color: var(--surface-strong);
    }
}

/* Enhance prompt button */
.enhance-btn {
    color: var(--text-muted);
    transition: color var(--transition-fast),
                background-color var(--transition-fast);
}

@media (hover: hover) {
    .enhance-btn:hover {
        color: var(--primary-500);
    }
}

.enhance-btn-active {
    color: var(--primary-500);
}

/* Modal Card */
.modal-card,
.system-modal-card {
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    box-shadow: var(--shadow-glass);
}

.modal-card {
    max-height: var(--drawer-max-h);
    border-radius: var(--radius-2xl);
    position: relative;
    width: 100%;
    max-width: 500px;
    transform: scale(0.96);
    transition: transform var(--transition-slow), opacity var(--transition), box-shadow var(--transition);
}

@media (max-width: 640px) {
    .modal-card { width: 95% !important; padding: 1.5rem !important; }
    .auth-social-icon { width: 3.5rem; height: 3.5rem; }
}

/* --- Chat Elements --- */

/* Пузырёк юзера — полупрозрачный токен БЕЗ backdrop-filter: лежит над плоским фоном чата,
   блюр там почти ничего не давал, но стоил перфа при скролле множества сообщений. */
.chat-bubble-user {
    background-color: var(--chat-input-bg);
    color: var(--text-main);
    border-radius: var(--chat-radius-xl);
    border-bottom-right-radius: var(--radius-chat-tail);
    font-size: var(--text-base);
    box-shadow: var(--shadow-glass);
}

/* User Bubble Markdown Reset */
.chat-bubble-user p { margin: 0; }
.chat-bubble-user > *:first-child { margin-top: 0; }
.chat-bubble-user > *:last-child { margin-bottom: 0; }

.chat-bubble-ai {
    background-color: transparent;
    color: var(--text-main);
    padding-left: 0;
    font-size: var(--text-base);
}

/* Вложения в сообщении — компактная сетка миниатюр снаружи пузырька.
   Пользовательские (user) — мини-квадраты; AI-сгенерированные (.is-large) — крупнее,
   в естественной пропорции с ограничением по высоте. */
.chat-msg-attachment-thumb {
    width: 6.5rem;
    height: 6.5rem;
    max-width: 100%;
    object-fit: cover;
    display: block;
}

@media (min-width: 768px) {
    .chat-msg-attachment-thumb {
        width: 7.5rem;
        height: 7.5rem;
    }
}

.chat-msg-attachments.is-large .chat-msg-attachment-thumb {
    width: auto;
    height: auto;
    max-height: 20rem;
    max-width: 100%;
    object-fit: contain;
}

@media (min-width: 768px) {
    .chat-msg-attachments.is-large .chat-msg-attachment-thumb {
        max-height: 24rem;
    }
}

.chat-msg-attachment-doc {
    max-width: 16rem;
}

/* Streaming cursor — blinking caret at end of AI response */
@keyframes cursor-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0; }
}

.is-streaming .markdown-render > :last-child::after,
.is-streaming .markdown-render:empty::after {
    content: '';
    display: inline-block;
    width: 2.5px;
    height: 1.1em;
    background: var(--primary);
    vertical-align: text-bottom;
    border-radius: 1px;
    margin-left: 1px;
    animation: cursor-blink 0.8s steps(2) infinite;
}

/* ========================================
   5. MARKDOWN CONTENT
   ======================================== */
.markdown-content { 
    line-height: 1.75;
    color: var(--text-main);
    overflow-wrap: anywhere;
    word-break: break-word;
}

.markdown-table-wrap {
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    margin: 0.75rem 0;
    border-radius: var(--radius-md);
}

/* Фавиконка сайта перед текстом ссылки (вставляется в link_open, markdown.js).
   Размер в em — масштабируется со шрифтом ссылки. */
.md-link-favicon {
    display: inline-block;
    width: 1em;
    height: 1em;
    margin-right: 0.3em;
    vertical-align: -0.15em;
    border-radius: 0.2em;
    object-fit: contain;
}

.markdown-content table {
    width: max-content;
    min-width: 100%;
    border-collapse: collapse;
    table-layout: auto;
    font-size: var(--text-base);
}

.markdown-content th,
.markdown-content td {
    padding: 0.55rem 0.75rem;
    text-align: left;
    vertical-align: top;
    overflow-wrap: normal;
    word-break: normal;
    hyphens: none;
}

.markdown-content th {
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    background-color: var(--bg-input);
}

.markdown-content tr:nth-child(even) td {
    background-color: var(--bg-input-45);
}

.markdown-content .katex-display {
    overflow-x: auto;
    overflow-y: hidden;
    padding: 0.125rem 0;
}

/* 1. Normalize spacing for common block elements */
.markdown-content p, .markdown-content ul, .markdown-content ol, 
.markdown-content blockquote, .markdown-content pre {
    margin-top: 0.75rem;
    margin-bottom: 0.75rem;
}

/* 2. Kill outer margins to fit bubble padding perfectly */
.markdown-content > :first-child { margin-top: 0 !important; }
.markdown-content > :last-child { margin-bottom: 0 !important; }

/* If markdown is injected into a wrapper element (e.g. x-html), normalize its first/last block margins too */
.markdown-content .markdown-render > :first-child { margin-top: 0 !important; }
.markdown-content .markdown-render > :last-child { margin-bottom: 0 !important; }

/* Headings */
.markdown-content h1, 
.markdown-content h2, 
.markdown-content h3 { 
    color: var(--text-main);
    margin-top: 1.5rem;
    margin-bottom: 0.5rem;
    font-weight: var(--font-weight-bold);
    line-height: 1.3;
}
.markdown-content h1 {
    background-image: var(--heading-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    padding-bottom: 0.5rem;
    font-size: var(--text-2xl);
}
.markdown-content h2 { 
    font-size: var(--text-xl);
}
.markdown-content h3 { 
    font-size: var(--text-lg);
}
.markdown-content a {
    color: var(--primary-500);
    background: var(--surface-accent);
    padding: 0.125rem 0.375rem;
    border-radius: var(--radius-sm);
    text-decoration: none;
    /* подложка корректно переносится на новую строку */
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
}
.markdown-content ul,
.markdown-content ol {
    padding-left: 1.5rem;
}
.markdown-content ul { list-style-type: disc; }
.markdown-content ol { list-style-type: decimal; }
.markdown-content blockquote { 
    position: relative;
    background-color: var(--bg-input);
    border-radius: var(--chat-radius-xl);
    padding: 0.75rem 1rem 0.75rem 1.25rem;
    margin: 1rem 0;
    overflow: hidden; /* To clip content to rounded corners */
}

.markdown-content hr {
    border: 0;
    height: 1px;
    background-color: var(--bg-raised);
    margin: 1.1rem 0;
}

[data-theme="light"] .markdown-content hr {
    background-color: var(--text-main-18);
}

/* Prevent long code/lines from widening the whole chat layout */
.markdown-content pre {
    max-width: 100%;
    overflow-x: auto;
    min-width: 0;
}

.markdown-content blockquote pre {
    max-width: 100%;
}

/* Rounded colored bar on the left */
.markdown-content blockquote::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: linear-gradient(180deg, var(--text-main), var(--text-muted));
    opacity: 1;
}

/* Inline Code */
.markdown-content code {
    background: var(--surface-accent);
    color: var(--primary-500);
    padding: 0.125rem 0.375rem;
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: var(--text-sm);
}
.markdown-content pre code {
    background: transparent; padding: 0; color: inherit;
}

/* Think Block (Chain of thought) */
.think-accordion {
    background: var(--bg-input); 
    border-radius: var(--radius-md); 
    margin-bottom: 1rem; 
    overflow: hidden;
}
.think-summary { 
    padding: 0.75rem; 
    cursor: pointer; 
    color: var(--text-muted); 
    font-size: var(--text-sm);
}
@media (hover: hover) {
    .think-summary:hover { background: var(--bg-hover); }
}
.think-content { 
    padding: 1rem; 
    color: var(--text-muted); 
    font-size: var(--text-sm);
}

.think-mode-shell {
    width: 100%;
    border-radius: var(--chat-radius);
    overflow: hidden;
    background-color: var(--chat-input-bg);
    box-shadow: var(--shadow-glass);
}

.think-mode-header {
    min-height: 2.25rem;
    background-color: transparent;
}

.think-mode-content {
    background-color: transparent;
}

/* Таймлайн этапов размышления: вертикальная линия с точками слева. */
.think-timeline {
    padding: 0.625rem 0.875rem 0.75rem;
}

.think-step {
    position: relative;
    padding-left: 1.25rem;
    padding-bottom: 0.875rem;
}

.think-step:last-child {
    padding-bottom: 0;
}

/* Соединительная линия — за точкой, до следующего этапа. */
.think-step::before {
    content: "";
    position: absolute;
    left: 0.28rem;
    top: 0.35rem;
    height: 100%;
    width: 1.5px;
    background: color-mix(in srgb, var(--text-subtle) 35%, transparent);
}

.think-step:last-child::before {
    display: none;
}

.think-step__dot {
    position: absolute;
    left: 0;
    top: 0.25rem;
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 50%;
    background: color-mix(in srgb, var(--text-subtle) 50%, transparent);
    /* кольцо цветом фона «гасит» линию под точкой */
    box-shadow: 0 0 0 3px var(--chat-input-bg);
}

/* Активный этап — тот, что пишется прямо сейчас. */
.think-step--active .think-step__dot {
    background: var(--primary-500);
    box-shadow: 0 0 0 3px var(--chat-input-bg), 0 0 0 5px var(--primary-20);
}

.think-step__title {
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    margin-bottom: 0.125rem;
}

.think-step__text {
    font-size: var(--text-xs);
    font-family: var(--font-mono);
    color: var(--text-muted);
    white-space: pre-wrap;
    line-height: 1.5;
}

/* Лента ответа ассистента: хронологические сегменты reasoning | action | text.
   Согласована с .think-step (таймлайн размышлений) по визуальному языку. */
.agent-flow {
    display: flex;
    flex-direction: column;
}

/* Текстовый сегмент — markdown; отступ между соседними блоками. */
.agent-flow__text:not(:first-child) {
    margin-top: 0.25rem;
}

/* Медиа- и post-сегменты — заметнее текста, дышат сверху в ленте. */
.agent-flow__media,
.agent-flow__post {
    margin-top: 0.5rem;
}

/* ── Карточка-черновик поста в Telegram (.tg-draft) ──────────────────────
   Нейтральный «модный» вид в духе Telegram: скруглённый пузырёк, тонкая
   акцентная полоса слева, шапка с аватаром-логотипом. Только токены. */
.tg-draft {
    position: relative;
    padding: 0.875rem 0.875rem 0.875rem 1.125rem;
    background-color: var(--bg-elevated);
    border-radius: 16px;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text-main) 8%, transparent);
    transition: var(--transition);
}
.tg-draft.is-busy {
    opacity: 0.6;
    pointer-events: none;
}
/* Акцентная полоса слева — фирменный лайм. */
.tg-draft__bar {
    position: absolute;
    left: 0.5rem;
    top: 0.875rem;
    bottom: 0.875rem;
    width: 3px;
    border-radius: var(--radius-pill);
    background-color: var(--primary-500);
}

.tg-draft__head {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin-bottom: 0.75rem;
}
.tg-draft__avatar {
    flex: 0 0 auto;
    width: 1.75rem;
    height: 1.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background-color: color-mix(in srgb, var(--text-main) 7%, transparent);
}
.tg-draft__avatar img {
    width: 1.05rem;
    height: 1.05rem;
    object-fit: contain;
}
.tg-draft__head-text {
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}
.tg-draft__title {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text-main);
}
.tg-draft__channel {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.75rem;
    color: var(--text-muted);
}
.tg-draft__channel i { font-size: 0.75rem; }

/* Медиа поста — превью-плитки. */
.tg-draft__media {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}
.tg-draft__thumb {
    position: relative;
    width: 4rem;
    height: 4rem;
    border-radius: 12px;
    overflow: hidden;
    background-color: var(--bg-raised);
}
.tg-draft__thumb img,
.tg-draft__thumb-file {
    width: 100%;
    height: 100%;
    cursor: pointer;
}
.tg-draft__thumb img { object-fit: cover; }
.tg-draft__thumb-file {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    font-size: 1.25rem;
}
.tg-draft__thumb-load {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--overlay-pill-bg-soft);
}
.tg-draft__thumb-x {
    position: absolute;
    top: 0.25rem;
    right: 0.25rem;
    width: 1.25rem;
    height: 1.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background-color: var(--overlay-pill-bg);
    color: var(--overlay-text);
    font-size: 0.7rem;
}
.tg-draft__thumb-x:hover { background-color: var(--overlay-pill-bg-strong); }
/* Плитка добавления фото — пунктирная, в духе «+» композера. */
.tg-draft__add {
    width: 4rem;
    height: 4rem;
    border-radius: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    font-size: 1.25rem;
    background-color: transparent;
    box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--text-main) 14%, transparent);
    transition: var(--transition);
}
.tg-draft__add:hover {
    color: var(--text-main);
    box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--primary-500) 55%, transparent);
}

/* Текст черновика / правки. */
.tg-draft__text {
    padding: 0.5rem 0.75rem;
    font-size: 0.875rem;
    resize: none;
    margin-bottom: 0.625rem;
}
.tg-draft__published-text {
    font-size: 0.875rem;
    color: var(--text-main);
    white-space: pre-wrap;
    word-break: break-word;
    margin-bottom: 0.625rem;
}
.tg-draft__hint {
    display: flex;
    align-items: flex-start;
    gap: 0.375rem;
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-bottom: 0.625rem;
}
.tg-draft__hint i { margin-top: 0.05rem; flex: 0 0 auto; }

/* Ряд действий. */
.tg-draft__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}
.tg-draft__btn {
    height: 2.25rem;
    padding-left: 1rem;
    padding-right: 1rem;
    font-size: 0.875rem;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}
.btn-ghost.tg-draft__btn { font-weight: 500; }
.tg-draft__chip {
    height: 2.25rem;
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0 0.75rem;
    font-size: 0.875rem;
}

/* Удалённый пост — компактная нейтральная плашка. */
.tg-draft--gone {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.875rem;
    font-size: 0.8125rem;
    color: var(--text-muted);
    background-color: var(--bg-elevated);
    border-radius: 12px;
    box-shadow: none;
}

/* Превью-миниатюра в выпадайке «Из чата» (composerPlusSheet item iconHtml). */
.tg-pick-thumb {
    width: 1.5rem;
    height: 1.5rem;
    border-radius: var(--radius-sm);
    object-fit: cover;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background-color: var(--bg-raised);
    color: var(--text-muted);
}
.tg-pick-thumb--file { font-size: 0.875rem; }

/* Reasoning-сегмент — компактный сворачиваемый блок. */
.agent-flow__reasoning {
    margin: 0.375rem 0;
}

.agent-flow__reasoning-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.125rem 0;
    background: none;
    border: none;
    cursor: pointer;
    font-size: var(--text-xs);
    color: var(--text-muted);
}

.agent-flow__reasoning-toggle:hover {
    color: var(--text-main);
}

.agent-flow__reasoning-tokens {
    color: var(--text-subtle);
}

/* Контейнер раскрытого reasoning — лишь обёртка для таймлайна .think-step.
   Без pre-wrap/font-mono: за вид этапов отвечают сам таймлайн и .think-step__text
   (иначе pre-wrap превращает отступы разметки в пустые вертикальные зазоры). */
.agent-flow__reasoning-body {
    margin-top: 0.25rem;
}

/* ── Унифицированный статус-лейбл ленты: размышления / действия / поиск ──
   Один шрифт во всех состояниях (sm, semibold). Активный — перелив (.is-active,
   см. общий shimmer-rule ниже); завершённый — тот же шрифт, просто серый. Без
   иконок-маркеров: активность показывают перелив лейбла и крутящееся лого. */
.agent-status {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-subtle);
}

/* Action-сегмент: статус-лейбл + краткая сводка (домены поиска и т.п.). */
.agent-step {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin: 0.375rem 0;
    line-height: 1.5;
}

.agent-step__summary {
    font-size: var(--text-xs);
    color: var(--text-subtle);
}

/* Краткий итог завершённого шага («Готово» / «найдено N» / «Ошибка»). Нейтральный,
   без красного/зелёного (см. --red-500 у токенов). Отделён точкой от детали/лейбла. */
.agent-step__result {
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
}
.agent-step__result::before {
    content: "·";
    margin-right: 0.5rem;
    color: var(--text-subtle);
}

/* Переливающийся текст в серых тонах — ОБЩИЙ механизм: надпись «Говорите…»
   (.voice-recording-title), активный статус ленты и баланс в шапке во время
   фонового обновления (.is-refreshing). Градиент/токены/keyframe — одни. */
.voice-recording-title,
.agent-status.is-active,
.shell-user-pill__balance.is-refreshing {
    background-image: linear-gradient(
        90deg,
        var(--text-subtle) 0%,
        var(--text-muted) 35%,
        color-mix(in srgb, var(--text-muted) 55%, white) 50%,
        var(--text-muted) 65%,
        var(--text-subtle) 100%
    );
    background-size: 200% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    animation: chat-input-gradient-flow 3.4s linear infinite;
}

/* ========================================
   6. CODE BLOCKS
   ======================================== */
.code-block-wrapper {
    border-radius: var(--chat-radius-xl); 
    margin: 0.5rem 0; 
    overflow: hidden; 
     position: relative;
    box-shadow: var(--shadow-code);
    display: flex;
    flex-direction: column;
    max-width: 100%;
    min-width: 0;
}

.code-block-wrapper pre {
    margin: 0; 
    padding: 0.75rem 1rem 0.25rem 1rem; 
    overflow-x: auto;
    background: transparent; 
    box-shadow: none; 
    border-radius: 0;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

.code-block-wrapper pre::-webkit-scrollbar { height: 8px; }
.code-block-wrapper pre::-webkit-scrollbar-thumb { background: var(--bg-hover); border-radius: var(--radius-chat-tail); }
.code-block-wrapper code { 
    font-family: var(--font-mono); 
    font-size: var(--text-xs);
    line-height: 1.5; 
}

/* Media-composer dynamic spacer (chat composer in normal flow doesn't need it). */
.input-spacer {
    height: var(--input-height, 0px);
    transition: height var(--motion-duration-fast) var(--motion-ease-standard);
}

/* ── Chat page layout ──
   Единая flex-колонка чата. Активное состояние: composer — absolute-overlay
   с glass-fade поверх скролл-области; сообщения скроллятся под ним, последнее
   сообщение помещается выше композера через padding-bottom = --composer-height.
   Пустое состояние: composer в нормальном flow, родитель центрирует/прижимает
   его, #chat-container скрыт через x-show.

   Один источник правды по высоте композера — CSS-переменная --composer-height,
   которую ResizeObserver в scroll.js пишет на .chat-page при каждом изменении
   габаритов dock'а (цитата, multiline, params). Никакого Alpine state, никаких
   магических констант. */
.chat-page {
    min-width: 0;
    position: relative;
    --composer-height: 0px;
}

.chat-page > #chat-container {
    flex: 1 1 auto;
    /* Скрываем родной scrollbar — overflow остаётся, скроллится колесом/тачем/
       пробелом, но visual-индикатор не нужен (есть кнопка «вниз» как у ChatGPT). */
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.chat-page > #chat-container::-webkit-scrollbar {
    width: 0;
    height: 0;
}

/* Entrance-анимация для новых сообщений: чуть всплывают и проявляются.
   Alpine x-for с :key="msg.id" пере-использует существующие элементы,
   поэтому анимация играет только на свежесмонтированных msg-узлах
   (отправка, приём, гидрация истории при открытии чата). */
@keyframes chat-message-enter {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
}

[data-msg-id] {
    animation: chat-message-enter var(--motion-duration-base) var(--motion-ease-premium);
}

@media (prefers-reduced-motion: reduce) {
    [data-msg-id] {
        animation: none;
    }
}

.chat-page.is-empty {
    /* Резервируем место под mobile overlay header — в empty контейнер скрыт,
       и без этого composer налезал бы на header. На desktop var == 0. */
    padding-top: var(--shell-mobile-header-offset);
}

.chat-page.is-empty > #chat-container {
    display: none;
}

/* Активное состояние: composer overlay'ит сообщения. Dock — пустая
   позиционная обёртка без визуальных эффектов: ни фона, ни тени, ни blur.
   Всё видимое стекло живёт внутри pill'а (.chat-input-shell). Прозрачная
   зона dock'а пропускает wheel/touch к scroll-области позади; форма внутри
   получает .pointer-events-auto. */
.chat-page:not(.is-empty) > .chat-composer-dock {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 5;
    pointer-events: none;
}

.chat-page:not(.is-empty) > #chat-container {
    padding-bottom: var(--composer-height);
}

/* Композер базовый: padding'и сохраняются и для empty (in-flow), и для
   active (absolute overlay). Высота снимается ResizeObserver'ом по факту. */
.chat-composer-dock {
    padding-top: 1rem;
    padding-bottom: 0;
}

@media (min-width: 768px) {
    .chat-composer-dock {
        padding-bottom: var(--app-frame-inset-desktop);
    }
}

@media (max-width: 767px) {
    .chat-composer-dock {
        padding-bottom: env(safe-area-inset-bottom);
    }

    /* Композер на mobile прижимается к экрану «без полей» */
    .chat-composer-dock.app-edge-gutters {
        padding-inline: 0;
    }

    .chat-composer-dock > .max-w-3xl {
        max-width: 100%;
        padding-inline: 0;
    }
}

/* Empty-state композер: desktop — центрирован с воздухом снизу, mobile —
   прижат к нижнему краю поверх safe-area. */
@media (min-width: 768px) {
    .chat-page.is-empty {
        justify-content: center;
    }

    .chat-page.is-empty > .chat-composer-dock {
        padding-bottom: 5rem;
    }
}

@media (max-width: 767px) {
    .chat-page.is-empty {
        justify-content: flex-end;
    }

    .chat-mobile-sheet {
        background-color: transparent;
        border-radius: 0;
        box-shadow: none;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        padding-bottom: env(safe-area-inset-bottom);
    }

    .chat-mobile-sheet.app-edge-gutters {
        padding-inline: 0;
    }

    .chat-mobile-sheet > .max-w-3xl {
        max-width: 100%;
        padding-inline: 0;
    }

    /* Media composer on mobile: cap overall height, allow scroll-region to scroll
       while dock-region (textarea + bottom row) stays pinned at the bottom.
       Without this, expanding "Все параметры" would push the dock out of view. */
    .media-mobile-composer-sheet .chat-input-main-shell {
        max-height: 75dvh;
    }

    .media-mobile-composer-sheet .chat-input-zone {
        min-height: 0;
        flex: 1 1 auto;
    }

    .media-mobile-composer-sheet .media-composer-normal-layer {
        flex: 1 1 auto;
        min-height: 0;
    }

    .media-mobile-composer-sheet .media-composer-scroll-region {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    /* Скруглённая нижняя кромка композера на mobile (sheet-look) для чата и media */
    :is(.chat-composer-dock, .chat-mobile-sheet)
    :is(.chat-input-main-shell).shape-pill,
    :is(.chat-composer-dock, .chat-mobile-sheet)
    :is(.chat-input-main-shell).shape {
        border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    }
}

/* Chat input docking: avoid Tailwind bottom-* conflicts by using a semantic class.
   Используется только media composer (`_composer_media.html` — absolute-режим). */

.chat-input-docked {
    bottom: 0;
}

@media (min-width: 768px) {
    .chat-input-docked {
        bottom: var(--app-frame-inset-desktop);
    }
}

/* Scroll-to-bottom FAB */
.scroll-to-bottom-btn {
    position: absolute;
    /* Справа по композеру (правый край inputArea), а не по центру, с небольшим
       отступом от края. */
    right: 0.5rem;
    bottom: calc(100% + 0.5rem);
    z-index: 1;
    /* Размер и стекло — как у кнопок временного чата (.shell-mobile-chat-header-btn):
       --shell-header-slot + chat-input-bg + glass-blur + shadow-glass. */
    width: var(--shell-header-slot);
    height: var(--shell-header-slot);
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    color: var(--text-muted);
    cursor: pointer;
    box-shadow: var(--shadow-glass);
    transition: color var(--transition-fast),
                background var(--transition-fast),
                box-shadow var(--transition-fast);
}

@media (hover: hover) {
    .scroll-to-bottom-btn:hover {
        color: var(--text-main);
        background: var(--bg-raised);
        box-shadow: var(--shadow-icon);
    }
}

.slider-thumb {
    left: var(--slider-pos, 0%);
    transform: translate(-50%, -50%);
}

/* Force transparent background for HLJS to respect our glass panel */
.code-block-wrapper .hljs {
    background: transparent !important;
}

/* Preview Area */
.code-block-preview { 
    padding: 1rem; 
    background: var(--bg-panel); 
    color: var(--text-main); 
    min-height: 120px; 
    max-width: 100%;
}
.code-block-preview iframe { width: 100%; border: none; height: 100%; min-height: 300px; }

/* Footer (Integrated look) */
.code-block-footer {
    display: flex;
    justify-content: space-between; 
    align-items: center; 
    padding: 0.5rem 1rem 0.75rem 1rem;
    background: transparent; 
    margin-top: 0;
    font-family: var(--font-sans);
}

/* Language Label (Left side) */
.footer-lang { 
    font-size: var(--text-xs);
    font-weight: var(--font-weight-bold); 
    color: var(--text-muted); 
    text-transform: lowercase;
}

/* Actions (Right side) */
.footer-actions { 
    display: flex; 
    align-items: center; 
    gap: 0.625rem; 
}

/* Copy Button */
.footer-btn {
    background: transparent; color: var(--text-muted); cursor: pointer; padding: 0.25rem;
    transition: background-color var(--transition), color var(--transition), filter var(--transition); display: flex; align-items: center; justify-content: center;
    border-radius: var(--radius-md);
}
@media (hover: hover) {
    .footer-btn:hover { color: var(--text-main); background: var(--bg-hover); }
}
.footer-btn svg { width: 18px; height: 18px; }

/* Quote-button работает только в полноценном чате (нужен chatApp.startReply
   под #app-shell-root). На статичных страницах вроде shared-чата приложения
   нет — скрываем кнопку, чтобы клик не выглядел как баг (no-op). */
body:not(:has(#app-shell-root)) .quote-btn,
body:not(:has(#app-shell-root)) .attachment-quote-btn,
body:not(:has(#app-shell-root)) .selection-quote-bar { display: none !important; }

/* Кнопка «Цитировать» поверх image/video-вложений в сообщениях. Стеклянное
   оформление, чтобы читалось поверх любого фона. На touch-устройствах
   (`hover: none`) видна всегда; на десктопе появляется только при hover'е
   на контейнер группы, чтобы не загромождать. */
.attachment-quote-btn {
    background: var(--overlay-pill-bg);
    color: var(--overlay-text);
    backdrop-filter: blur(8px); /* блюрит медиа под собой, не стеклянный родитель — ОК */
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid color-mix(in srgb, var(--overlay-text) 12%, transparent);
    cursor: pointer;
    opacity: 1;
}
@media (hover: hover) {
    .attachment-quote-btn { opacity: 0; }
    .group\/att:hover .attachment-quote-btn,
    .attachment-quote-btn:focus-visible { opacity: 1; }
    .attachment-quote-btn:hover { background: var(--overlay-pill-bg-strong); }
}
.attachment-quote-btn:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* Плавающий бар «Цитировать выделенное» над текстовым выделением в чате. */
.selection-quote-bar {
    pointer-events: auto;
    animation: selection-quote-fade-in 120ms ease-out;
}
@keyframes selection-quote-fade-in {
    from { opacity: 0; transform: translateY(2px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* View Toggle (Pill Style) */
.view-toggle {
    display: flex;
    align-items: center;
    /* Капсульный сегментбар (эталон): pill-трей + pill-сегменты, активный
       --surface-strong. Трей — recessed --bg-input. */
    gap: var(--gap-2xs);
    padding: var(--gap-xs);
    background: var(--bg-input);
    border-radius: var(--radius-pill);
}

.toggle-option { 
    background: transparent; 
    color: var(--text-muted); 
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold); 
    padding: 0.35rem 0.85rem; 
    border-radius: var(--radius-pill);
    cursor: pointer; 
    transition: color var(--transition), background-color var(--transition), box-shadow var(--transition), filter var(--transition); 
}

@media (hover: hover) {
    .toggle-option:hover:not(.active) {
        color: var(--text-main);
        background: var(--bg-hover);
    }
}

.toggle-option.active {
    background-color: var(--surface-strong);
    color: var(--text-main);
}
/* Utility: Remove spinners from number inputs */
.input-no-spinners::-webkit-outer-spin-button,
.input-no-spinners::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.input-no-spinners {
    -moz-appearance: textfield;
    appearance: textfield;
}

@media (prefers-reduced-motion: reduce) {
    html:focus-within {
        scroll-behavior: auto;
    }

    .motion,
    .btn,
    .sidebar-shell,
    .service-card,
    .surface-chip,
    .model-chip,
    .dropdown-item,
    .overlay-icon,
    .toggle-option,
    .footer-btn,
    .loading-spinner,
    .modal-card,
    .input-spacer {
        animation: none !important;
        transition: none !important;
        transform: none !important;
    }
}

/* Sidebar: history fades at top and bottom while scrolling */
.sidebar-history-fade {
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, black 1.5rem, black calc(100% - 1.5rem), transparent 100%);
    mask-image: linear-gradient(to bottom, transparent 0, black 1.5rem, black calc(100% - 1.5rem), transparent 100%);
}

/* ─── Custom Tooltips (floating, rendered via JS) ─── */
.app-tooltip {
    position: fixed;
    padding: 4px 10px;
    background: var(--bg-elevated);
    color: var(--text-main);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
    line-height: 1.4;
    white-space: nowrap;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-glass);
    pointer-events: none;
    visibility: hidden;
    opacity: 0;
    transform: scale(0.96);
    transition: opacity var(--motion-duration-micro) var(--motion-ease-standard), transform var(--motion-duration-micro) var(--motion-ease-standard), visibility 0s linear var(--motion-duration-micro);
    z-index: 99999;
}
.app-tooltip.visible {
    visibility: visible;
    opacity: 1;
    transform: scale(1);
    transition-delay: 0s;
}

@media (hover: none), (pointer: coarse) {
    .app-tooltip {
        display: none !important;
    }

    .hover-reveal-actions,
    .hover-reveal-action {
        opacity: 1 !important;
        pointer-events: auto !important;
    }

    .hover-delete-overlay {
        opacity: 1 !important;
        align-items: flex-start;
        justify-content: flex-end;
        padding: 0.25rem;
        background: linear-gradient(180deg, var(--overlay-backdrop-soft) 0%, transparent 58%);
    }

    .hover-delete-overlay .overlay-icon {
        box-shadow: var(--shadow-surface);
    }

    .hover-reveal-overlay {
        opacity: 1 !important;
        background: linear-gradient(
            180deg,
            color-mix(in srgb, var(--overlay-scrim) 88%, transparent) 0%,
            transparent 36%,
            color-mix(in srgb, var(--overlay-backdrop) 92%, transparent) 100%
        );
    }
}

/* === Camera Cube === */

/* Scene wrapper — sets perspective */
.cube-perspective {
    width: 200px;
    height: 200px;
    perspective: 700px;
}

/* The rotating box */
.cube-body {
    position: relative;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transition: transform var(--transition-fast);
    cursor: grab;
}
.cube-body:active { cursor: grabbing; }

/* Each face */
.cube-face {
    position: absolute;
    inset: 0;
    background: var(--overlay-backdrop-soft);
    -webkit-backdrop-filter: blur(var(--progressive-blur-2));
    backdrop-filter: blur(var(--progressive-blur-2));
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
}

/* Transforms — half of 200px = 100px */
.cube-face--front  { transform: translateZ(100px); }
.cube-face--back   { transform: rotateY(180deg) translateZ(100px); }
.cube-face--left   { transform: rotateY(-90deg) translateZ(100px); }
.cube-face--right  { transform: rotateY(90deg)  translateZ(100px); }
.cube-face--top    { transform: rotateX(90deg)  translateZ(100px); }
.cube-face--bottom { transform: rotateX(-90deg) translateZ(100px); }

/* Face label pill */
.cube-face-label {
    background: var(--bg-panel);
    color: var(--text-main);
    padding: 2px 10px;
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-bold);
    letter-spacing: 0.06em;
    line-height: 1.6;
}

/* Controls card */
.cube-controls-card {
    background: var(--bg-panel);
    border-radius: var(--radius-xl);
    padding: 20px 22px 16px;
    width: 100%;
    max-width: 380px;
    box-shadow: var(--shadow-modal);
}

/* Slider track */
.cube-slider-track {
    position: relative;
    width: 100%;
    height: 32px;
    background: var(--bg-input);
    border-radius: var(--radius-pill);
}

/* Native input — invisible but interactive */
.cube-slider-input {
    -webkit-appearance: none;
    appearance: none;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    background: transparent;
    cursor: pointer;
    z-index: 2;
    opacity: 0;
}
.cube-slider-input::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 28px;
    height: 28px;
}
.cube-slider-input::-moz-range-thumb {
    appearance: none;
    width: 28px;
    height: 28px;
    border: none;
    background: transparent;
}

/* Visual thumb — positioned via Alpine :style */
.cube-slider-thumb {
    position: absolute;
    top: 50%;
    transform: translate(-50%, -50%);
    height: 26px;
    min-width: 42px;
    padding: 0 10px;
    background: var(--bg-elevated);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-surface);
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    z-index: 1;
    transition: left var(--transition-fast);
}
.cube-slider-thumb span {
    font-size: var(--text-xs);
    font-weight: var(--font-weight-bold);
    color: var(--text-main);
    white-space: nowrap;
}

/* === Generation Gallery — pure CSS columns masonry === */
.gen-gallery {
    columns: 1;
    column-gap: 0.75rem;
}
@media (min-width: 640px) {
    .gen-gallery { columns: 2; }
}
@media (min-width: 1024px) {
    .gen-gallery { columns: 3; }
}

.gen-gallery-item {
    break-inside: avoid;
    margin-bottom: 0.75rem;
    cursor: pointer;
    scroll-margin-bottom: calc(var(--input-height, 0px) + 1rem);
    transition: box-shadow var(--transition);
}
@media (hover: hover) {
    .gen-gallery-item:hover {
        box-shadow: var(--shadow-glass);
    }
}

/* Frame — clips media + overlay + badge together.
   aspect-ratio set inline from gen data → frame is sized
   before media loads, so no layout shift. */
.gen-gallery-frame {
    position: relative;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--bg-elevated);
}

/* Media inside gallery — fills frame, fades in on load */
.gen-gallery-media {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: 0;
    transition: opacity var(--motion-duration-base) var(--motion-ease-standard);
}
.gen-gallery-media.is-loaded {
    opacity: 1;
}

/* Error state for failed media (gallery + sidebar) */
.gen-gallery-media.is-error,
.sidebar-generation-media.is-error {
    opacity: 1;
    object-fit: none;
    background: var(--bg-elevated);
}
.gen-gallery-media.is-error::after,
.sidebar-generation-media.is-error::after {
    content: '⚠';
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    color: var(--text-muted);
}

/* === Unified Media Viewer (fullscreen) === */

.media-viewer {
    position: fixed;
    inset: 0;
    z-index: var(--z-fullscreen-modal);
    background: var(--bg-app);
    color: var(--text-main);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* Все слои контента — поверх сплошного фона .media-viewer (--bg-app) */
.media-viewer__header,
.media-viewer__canvas,
.media-viewer__prompt,
.media-viewer__pills,
.media-viewer__toolbar {
    position: relative;
    z-index: 1;
}

/* Логотип бренда — левый верхний угол (декоративный, поверх контента).
   Само тело — .brand-logo (CSS-маска), цвет берётся из color ниже. */
.media-viewer__logo {
    position: absolute;
    /* центр по вертикали совпадает с кнопкой закрытия (40px) в шапке */
    top: calc(10px + env(safe-area-inset-top));
    left: 16px;
    z-index: 2;
    width: var(--brand-logo-size);
    height: var(--brand-logo-size);
    color: var(--text-main);
    pointer-events: none;
}

/* Шапка */
.media-viewer__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: calc(14px + env(safe-area-inset-top)) 16px 8px;
    flex-shrink: 0;
}
.media-viewer__meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1;
    text-align: center;
    padding-left: 40px;   /* визуальный баланс с кнопкой закрытия справа */
}
.media-viewer__title { font-size: 0.9375rem; font-weight: 600; color: var(--text-main); }
.media-viewer__date  { font-size: 0.75rem; color: var(--text-subtle); }

.media-viewer__close {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--bg-elevated);
    color: var(--text-main);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    transition: background var(--transition-fast), transform var(--transition-fast);
}
.media-viewer__close:hover  { background: var(--bg-raised); transform: scale(1.05); }
.media-viewer__close:active { transform: scale(0.96); }

/* Канвас (медиа по центру) */
.media-viewer__canvas {
    position: relative;
    flex: 1;
    min-height: 0;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 8px 16px;
}
.media-viewer__media {
    display: block;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    transition: transform var(--transition-fast);
    transform-origin: center center;
}
/* Пока новое медиа не декодировано — держим его скрытым (на его месте свечение
   генерации / спиннер из .media-viewer__loading; старого размытого фона-дубля
   картинки больше нет). Убирает «прыжок» reflow при листании. Через :class
   (не :style) — display:none от x-show не перебивается. */
.media-viewer__media.is-loading { opacity: 0; }
/* Смена контента в галерее: keyframe-фейд (а не opacity-transition) — играет
   полную длительность даже когда соседнее медиа предзагружено и появляется
   мгновенно (иначе loaded щёлкает false→true и перехода не видно). Запуск —
   _playSwap() на @load/@loadeddata; длительность по motion-токену --transition. */
@keyframes media-viewer-swap {
    /* --swap-dir: +1 (next) старт справа, -1 (prev) слева, 0 — чистый фейд/pop.
       --swap-scale: <1 при завершении генерации (фото «выскакивает» из центра),
       1 при листании. transform только на время анимации (без fill-mode) — после
       возвращается к инлайну (зум/пан) и не конфликтует с ним. */
    from { opacity: 0; transform: translateX(calc(var(--swap-dir, 0) * 2.5rem)) scale(var(--swap-scale, 1)); }
    to { opacity: 1; transform: translateX(0) scale(1); }
}
.media-viewer__media.is-swapping {
    animation: media-viewer-swap var(--transition);
    animation-timing-function: var(--swap-ease, var(--motion-ease-standard));
}
/* Изображение управляется жестами (Pointer Events): отдаём ему весь тач,
   запрещаем нативный drag/выделение, отключаем transition во время жеста. */
.media-viewer__image {
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
    -webkit-user-drag: none;
}
.media-viewer__image.is-grabbing { transition: none; }

.media-viewer__audio { width: 100%; max-width: 32rem; }
.media-viewer__iframe {
    width: 100%;
    height: 70vh;
    max-width: 64rem;
    border-radius: var(--radius-lg);
    background: var(--bg-elevated);
}

.media-viewer__fallback {
    max-width: 28rem;
    margin: 0 auto;
    text-align: center;
    color: var(--text-main);
}
.media-viewer__fallback-icon {
    width: 3.5rem;
    height: 3.5rem;
    border-radius: var(--radius-lg);
    background: var(--bg-elevated);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 1rem;
    font-size: 1.5rem;
    color: var(--text-muted);
}

.media-viewer__state-card {
    width: min(100%, 520px);
    background: var(--bg-elevated);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: 24px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
}

/* Индикатор «медиа не готово» в просмотре. Два состояния внутри: наблюдаемая
   генерация — открытое свечение «Генерирую…» (как в чате); загрузка готового
   кадра — спиннер. Появление отложено enter-переходом (mv-loading-enter): на
   быстрых/кэш-кадрах при листании оверлей снимается раньше, чем дойдёт до
   видимости, поэтому ничего не мелькает. Завершение генерации → leave-переход
   плавно растворяет свечение. */
.media-viewer__loading {
    /* Оверлей по центру канваса (а не flex-сосед медиа — иначе спиннер встаёт
       СБОКУ от грузящегося <img> в row-флексе). Спиннер крутится ровно там, где
       появится фото, и фото заменяет его на месте. pointer-events:none — клики
       проходят к канвасу (закрытие по фону). */
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.85rem;
    pointer-events: none;
    color: var(--overlay-text);
}

/* Появление/растворение оверлея (Alpine x-transition). Enter с задержкой —
   кэш-кадры при листании не успевают проявиться → нет мелька. Leave-фейд —
   свечение растворяется только если успело стать видимым (с 0 уйдёт в 0
   незаметно). */
.mv-loading-enter       { transition: opacity 140ms ease-out 140ms; }
.mv-loading-enter-start { opacity: 0; }
.mv-loading-enter-end   { opacity: 1; }
.mv-loading-leave       { transition: opacity 240ms ease-out; }
.mv-loading-leave-start { opacity: 1; }
.mv-loading-leave-end   { opacity: 0; }

/* Тёмный оверлей → светлый спиннер независимо от темы (токены спиннера завязаны
   на --text-main, который в светлой теме тёмный и был бы невидим на чёрном). */
.media-viewer__loading .loading-spinner {
    --spinner-size: 2.5rem;
    --spinner-thickness: 0.28rem;
    --spinner-track: color-mix(in srgb, var(--overlay-text) 20%, transparent);
    --spinner-mid:   color-mix(in srgb, var(--overlay-text) 45%, transparent);
    --spinner-head:  color-mix(in srgb, var(--overlay-text) 85%, transparent);
}
/* Открытое свечение генерации во всю область канваса (без рамки-карточки) —
   тот же приём, что у .gen-loading--chat: прозрачный фон + видимый overflow +
   эллиптическая маска (граница контейнера не видна). Спецификация (0,2,0)
   перебивает базовый .gen-loading независимо от порядка в файле. */
.media-viewer__loading .gen-loading {
    /* Размер как в чате (≈544×136), НЕ во весь канвас — переливы при этом сохранены.
       Полноэкранный glow + переливы (chat-input-gradient-flow двигает
       background-position → перерастеривание blur(56px) каждый кадр) ронял вьюер до
       ~5–20 fps; на чатовом размере та же анимация держит ~60 fps (замерено).
       Анимацию НЕ переопределяем — наследуется база .gen-loading::before (переливы +
       дыхание). Маленький центрированный glow до краёв канваса не достаёт, поэтому
       обрезки overflow:hidden родителя нет. (Компонент общий — .gen-loading из чата.) */
    width: min(62vw, 34rem);
    height: auto;
    min-height: 8.5rem;
    background: transparent;
    overflow: visible;
}
.gen-loading--chat::before,
.media-viewer__loading .gen-loading::before {
    /* Эллипс с радиусом в % от ::before-бокса. Фон не рисуется за пределами бокса,
       поэтому фейд маски обязан догаснуть ДО его края, иначе свечение срезается
       прямой границей: условие — радиус × стоп-прозрачности ≤ 0.5 (центр→край).
       По вертикали 0.62×0.80≈0.50 — гаснет ровно у края (мягко). По горизонтали
       прежние 72% давали 0.72×0.80≈0.58 > 0.5 → бока обрезались на широком боксе
       вьюера (≈544×136); 60% возвращает 0.60×0.80=0.48 ≤ 0.5 → бока мягкие. */
    -webkit-mask-image: radial-gradient(ellipse 60% 62% at 50% 50%, #000 20%, transparent 80%);
            mask-image: radial-gradient(ellipse 60% 62% at 50% 50%, #000 20%, transparent 80%);
}
.media-viewer__loading .gen-loading::before { inset: -45% -16%; }

/* Multi-result пейджер */
.media-viewer__pager {
    position: absolute;
    bottom: 16px;
    left: 50%;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 4px 6px;
    border-radius: var(--radius-pill);
    background: var(--overlay-pill-bg);
    color: var(--overlay-text);
    font-size: 0.75rem;
    font-weight: 500;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    z-index: 2;
}
.media-viewer__pager-btn {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: inherit;
    font-size: 1rem;
    transition: background var(--transition-fast);
}
.media-viewer__pager-btn:hover:not(:disabled) { background: var(--overlay-control-bg); }
.media-viewer__pager-btn:disabled             { opacity: 0.4; cursor: not-allowed; }
.media-viewer__pager-count { min-width: 48px; text-align: center; }

/* Стрелки навигации по коллекции */
.media-viewer__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--overlay-pill-bg-soft);
    color: var(--overlay-text);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    z-index: 2;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    transition: background var(--transition-fast), transform var(--transition-fast);
}
.media-viewer__nav:hover  { background: var(--overlay-pill-bg-strong); transform: translateY(-50%) scale(1.05); }
.media-viewer__nav--prev  { left: 12px; }
.media-viewer__nav--next  { right: 12px; }

/* Промпт (усечён до 2 строк) */
.media-viewer__prompt {
    flex-shrink: 0;
    display: flex;
    gap: 8px;
    align-items: baseline;
    padding: 8px 16px 0;
    max-width: 56rem;
    width: 100%;
    margin: 0 auto;
    font-size: 0.8125rem;
    line-height: 1.5;
}
.media-viewer__prompt-label { flex-shrink: 0; font-weight: 600; color: var(--text-main); }
.media-viewer__prompt-text {
    flex: 1;
    min-width: 0;
    color: var(--text-muted);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Pills */
.media-viewer__pills {
    flex-shrink: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    padding: 8px 16px 0;
}
.media-viewer__pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 11px;
    border-radius: var(--radius-pill);
    background: var(--bg-raised);
    color: var(--text-main);
    font-size: 0.6875rem;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
}

/* Тулбар действий (снизу) */
.media-viewer__toolbar {
    flex-shrink: 0;
    display: flex;
    justify-content: center;
    padding: 14px 16px calc(14px + env(safe-area-inset-bottom));
}
/* Контейнер-трей под кнопками (эталон): капсула + --surface-soft, хватает
   ширину по содержимому и центрируется в футере. Кнопки внутри тоже
   --surface-soft — слои складываются, пилюли читаются светлее трея. */
.media-viewer__tools {
    display: flex;
    /* Не переносим в 2 ряда: при нехватке ширины кнопки скроллятся по
       горизонтали внутри трея. safe center — центрируем, когда влезает, но
       при переполнении прижимаем к началу (иначе левые кнопки не докрутить).
       Скроллбар скрыт (как у прочих скролл-зон проекта). */
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    align-items: center;
    justify-content: safe center;
    gap: 8px;
    max-width: 100%;
    padding: var(--gap-xs);
    background: var(--surface-soft);
    border-radius: var(--radius-pill);
}
.media-viewer__tools::-webkit-scrollbar { display: none; }
.media-viewer__tool {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    min-width: 64px;
    flex-shrink: 0;
    padding: 8px 12px;
    /* Эталон: капсула + --surface-soft, ховер --surface-strong — как плитки
       «+»-меню и табы модалки выбора моделей (нейтрально, без акцента). */
    border-radius: var(--radius-pill);
    background: var(--surface-soft);
    color: var(--text-main);
    font-size: var(--text-2xs);
    line-height: 1.1;
    transition: background var(--transition-fast), transform var(--transition-fast);
}
.media-viewer__tool i        { font-size: 1.25rem; color: var(--text-main); }
.media-viewer__tool:hover    { background: var(--surface-strong); transform: translateY(-1px); }
.media-viewer__tool:active   { transform: translateY(0); }
.media-viewer__tool--danger:hover i { color: var(--danger); }

@media (max-width: 1023.98px) {
    .media-viewer__nav { display: none; }
}

/* === Media Empty State (Landing) === */
.media-empty-state {
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.media-empty-state::-webkit-scrollbar { display: none; }

/* === Relight Sphere === */

/* Preset buttons grid */
.relight-preset-btn {
    padding: 8px 0;
    border-radius: var(--radius-md);
    color: var(--text-main);
    font-size: var(--text-sm);
    font-weight: var(--font-weight-medium);
    text-align: center;
    transition: background var(--transition), color var(--transition);
    cursor: pointer;
}
@media (hover: hover) {
    .relight-preset-btn:hover {
        background: var(--bg-raised);
    }
}
.relight-preset-btn.is-active {
    background: var(--bg-elevated);
    box-shadow: 0 0 0 1px var(--primary-500);
    color: var(--primary-500);
}

/* Arrow nudge buttons */
.relight-arrow-btn {
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-subtle);
    font-size: var(--text-sm);
    border-radius: var(--radius-sm);
    transition: color var(--transition), background var(--transition);
    cursor: pointer;
}
@media (hover: hover) {
    .relight-arrow-btn:hover {
        color: var(--text-main);
        background: var(--bg-input);
    }
}

/* Sphere container */
.relight-sphere {
    position: relative;
    width: 200px;
    height: 200px;
    border-radius: var(--radius-pill);
    cursor: grab;
    -webkit-user-select: none;
    user-select: none;
}
.relight-sphere:active { cursor: grabbing; }

/* Wireframe overlay */
.relight-sphere-wireframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    color: var(--text-muted);
    pointer-events: none;
}

/* Centered thumbnail inside sphere */
.relight-sphere-thumb {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 64px;
    height: 64px;
    border-radius: var(--radius-sm);
    overflow: hidden;
    box-shadow: var(--shadow-surface);
    pointer-events: none;
}

/* Light direction indicator */
.relight-light-dot {
    position: absolute;
    width: 14px;
    height: 14px;
    border-radius: var(--radius-pill);
    background: var(--primary-500);
    box-shadow: 0 0 12px color-mix(in srgb, var(--primary-500) 60%, transparent);
    transform: translate(-50%, -50%);
    pointer-events: none;
    transition: left var(--transition-fast),
                top var(--transition-fast);
}

/* SVG cone beam overlay */
.relight-cone-svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 3;
}

/* Spotlight fixture icon */
.relight-spotlight {
    position: absolute;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    transform: translate(-50%, -50%) rotate(var(--spot-rotate, 0deg));
    pointer-events: none;
    z-index: 4;
    color: var(--text-main);
    font-size: var(--text-xl);
    filter: drop-shadow(0 0 6px var(--glow-spotlight));
    transition: left var(--transition-fast),
                top var(--transition-fast);
}

/* Soft/Hard toggle labels */
.relight-toggle-label {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-subtle);
    cursor: pointer;
    padding: 4px 12px;
    border-radius: var(--radius-md);
    transition: color var(--transition), background var(--transition);
}
@media (hover: hover) {
    .relight-toggle-label:hover {
        color: var(--text-main);
    }
}
.relight-toggle-label.is-active {
    color: var(--text-main);
}

/* Color swatches */
.relight-color-swatch {
    width: 28px;
    height: 28px;
    border-radius: var(--radius-pill);
    background: var(--swatch-color, var(--bg-input));
    cursor: pointer;
    transition: box-shadow var(--transition), transform var(--transition);
    flex-shrink: 0;
}
@media (hover: hover) {
    .relight-color-swatch:hover {
        transform: scale(1.12);
    }
}
.relight-color-swatch.is-active {
    box-shadow: 0 0 0 2px var(--bg-panel), 0 0 0 4px var(--text-main);
}
.relight-color-custom {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
}

/* ========================================
   PROFILE PAGE
   ======================================== */

/* ── Layout ── */
.profile-page {
    max-width: 680px;
    margin: 0 auto;
    padding: 1.5rem 1rem 4rem;
}

@media (min-width: 1180px) {
    .profile-page {
        max-width: 56rem;
    }
    /* Десктоп: шапка чуть крупнее, аватар/кнопки растут синхронно. */
    .profile-header {
        --profile-avatar-size: 4rem;
        gap: 1.25rem;
    }
    .profile-name { font-size: var(--text-2xl); }
    .profile-id { font-size: var(--text-sm); }
    .profile-settings-btn { font-size: var(--text-xl); }
}

/* ── Header ── */
.profile-header {
    /* Единый размер: аватар и круглые кнопки-иконки равны ему. */
    --profile-avatar-size: 3.5rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
}
.profile-header-left {
    display: flex;
    align-items: center;
    gap: 1rem;
    min-width: 0;
}
.profile-avatar {
    width: var(--profile-avatar-size);
    height: var(--profile-avatar-size);
    border-radius: var(--radius-pill);
    object-fit: cover;
    flex-shrink: 0;
    background: var(--bg-raised);
}
.profile-name {
    font-size: var(--text-xl);
    font-weight: var(--font-weight-bold);
    color: var(--text-main);
    line-height: 1.2;
}
.profile-id {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: var(--text-xs);
    color: var(--text-subtle);
    margin-top: 0.2rem;
    cursor: default;
}
.profile-id-copy {
    color: var(--text-subtle);
    cursor: pointer;
    padding: 0.1rem;
    border-radius: var(--radius-sm);
    transition: color var(--transition);
    line-height: 1;
}
@media (hover: hover) {
    .profile-id-copy:hover { color: var(--text-muted); }
}

/* ── Settings button (gear icon) ── */
.profile-settings-btn {
    width: var(--profile-avatar-size);
    height: var(--profile-avatar-size);
    border-radius: var(--radius-pill);
    background: var(--bg-raised);
    border: none;
    color: var(--text-muted);
    font-size: var(--text-lg);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: background var(--transition), color var(--transition);
}
@media (hover: hover) {
    .profile-settings-btn:hover {
        background: var(--bg-hover);
        color: var(--text-main);
    }
}

/* ── Settings modal overlay (шторка) ── */
.profile-settings-overlay {
    position: fixed;
    inset: 0;
    background-color: var(--overlay-backdrop);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    z-index: var(--z-modal);
}
@media (min-width: 640px) {
    .profile-settings-overlay {
        align-items: center;
        padding: 1rem;
    }
}
.profile-settings-card {
    background: var(--bg-panel);
    border-radius: var(--radius-3xl) var(--radius-3xl) 0 0;
    box-shadow: var(--shadow-modal);
    width: 100%;
    max-width: 100%;
    padding: 0 1.5rem 1.5rem;
    padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
}
@media (min-width: 640px) {
    .profile-settings-card {
        border-radius: var(--radius-2xl);
        max-width: 420px;
        padding: 1.5rem;
    }
}

.profile-settings-field {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-bottom: 1rem;
}
.profile-settings-label {
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.profile-settings-field .input-field {
    color: var(--text-main);
}

/* ── Balance card ── */
.profile-balance-card {
    margin-bottom: 1.25rem;
}
.profile-balance-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.65fr) minmax(18rem, 0.95fr);
    gap: 0.85rem;
    align-items: stretch;
}
.profile-balance-eyebrow-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}
.profile-balance-eyebrow {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.profile-status-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.32rem 0.65rem;
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
    background: var(--bg-raised);
    color: var(--text-muted);
}
.profile-status-pill.is-active {
    background: var(--primary-10);
    color: var(--primary-500);
}
.profile-status-pill.is-inactive {
    background: var(--bg-raised);
    color: var(--text-muted);
}
.profile-balance-summary-card,
.profile-balance-wallet-card {
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-surface);
    padding: 1.1rem 1.2rem;
}
.profile-balance-summary-card {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-elevated) 96%, var(--primary-10)) 0%, color-mix(in srgb, var(--bg-elevated) 88%, var(--bg-panel)) 100%);
}
.profile-balance-summary-main {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}
.profile-balance-plan-name {
    font-size: clamp(2rem, 5vw, 4.25rem);
    font-weight: var(--font-weight-bold);
    letter-spacing: -0.04em;
    line-height: 0.95;
    color: var(--text-main);
    text-wrap: balance;
    max-width: 10ch;
}
.profile-balance-amount {
    font-size: clamp(2.2rem, 4vw, 3.8rem);
    font-weight: var(--font-weight-bold);
    color: var(--text-main);
    line-height: 0.96;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}
@media (min-width: 768px) {
    .profile-balance-plan-name,
    .profile-balance-amount {
        font-family: var(--font-display);
    }
}
.profile-balance-caption {
    font-size: var(--text-sm);
    line-height: 1.5;
    color: var(--text-muted);
    max-width: 36rem;
}
.profile-balance-summary-meta {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.65rem;
    margin-top: auto;
}
.profile-balance-meta-item {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.8rem 0.9rem;
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--bg-panel) 24%, var(--bg-elevated));
}
.profile-balance-meta-item.is-benefit {
    background: linear-gradient(180deg, color-mix(in srgb, var(--primary-10) 44%, var(--bg-elevated)) 0%, color-mix(in srgb, var(--bg-panel) 24%, var(--bg-elevated)) 100%);
}
.profile-balance-meta-label {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.profile-balance-meta-value {
    font-size: var(--text-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    line-height: 1.2;
}
.profile-balance-meta-note {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    line-height: 1.4;
}
.profile-balance-wallet-card {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    background: color-mix(in srgb, var(--bg-panel) 30%, var(--bg-elevated));
}
.profile-balance-wallet-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}
.profile-balance-wallet-label {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.profile-balance-wallet-icon {
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--primary-10) 42%, var(--bg-raised));
    color: var(--primary-icon);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--text-lg);
    flex-shrink: 0;
}
.profile-balance-wallet-main {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.profile-balance-wallet-note {
    font-size: var(--text-sm);
    color: var(--text-muted);
}
.profile-balance-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: stretch;
    margin-top: auto;
}
.profile-topup-btn {
    padding: 0.6rem 1rem;
    font-size: var(--text-sm);
    font-weight: var(--font-weight-bold);
    border-radius: var(--radius-pill);
    white-space: nowrap;
    flex-shrink: 0;
    text-transform: none;
    letter-spacing: 0;
    min-width: 0;
    flex: 1 1 10rem;
}
.profile-secondary-btn {
    border-radius: var(--radius-pill);
    background-color: color-mix(in srgb, var(--bg-panel) 42%, var(--bg-elevated));
    box-shadow: none;
}
@media (hover: hover) {
    .profile-secondary-btn:hover {
        background-color: var(--bg-hover);
        box-shadow: none;
    }
}
/* Накладывающиеся бейджи способов оплаты внутри кнопки «Пополнить».
   Кольцо — цветом фона ghost-кнопки, чтобы кружки «вырезались». */
.topup-pay-stack {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}
.topup-pay-ic {
    position: relative;
    width: 1.35rem;
    height: 1.35rem;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border-radius: var(--radius-pill);
    background: var(--bg-elevated);
    /* Кольцо — под цвет кнопки-носителя (surface-raised), чтобы
       наложенные кружки аккуратно «вырезались» друг из друга. */
    box-shadow: 0 0 0 2px var(--bg-raised);
}
/* Второй кружок (СБП) — спереди и лишь слегка перекрывает карту,
   чтобы ни один логотип не «грязнился» сильным срезом. */
.topup-pay-ic + .topup-pay-ic {
    margin-left: -0.32rem;
    z-index: 1;
}
.topup-pay-ic img {
    width: 58%;
    height: 58%;
    object-fit: contain;
    display: block;
}
.profile-balance-lock-note {
    margin-top: 0.75rem;
    font-size: var(--text-xs);
    line-height: 1.5;
    color: var(--text-muted);
}

/* ── Balance card · режим без тарифа ──
   По умолчанию — стопка (контейнер профиля до 1180px узкий, ~680px,
   две колонки там жмутся). Две зоны включаются на ≥1180px, ровно
   когда .profile-page расширяется до 56rem. Брейкпоинты совпадают. */
.profile-balance-wallet {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
    align-items: stretch;
    padding: 1.25rem;
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-surface);
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--bg-elevated) 92%, var(--primary-10)) 0%,
        color-mix(in srgb, var(--bg-elevated) 86%, var(--bg-panel)) 100%);
}
.profile-balance-wallet__main {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 0.55rem;
    padding: 0.25rem 0;
    min-width: 0;
}
.profile-balance-wallet__amount {
    font-size: clamp(2.4rem, 4.4vw, 3.4rem);
    font-weight: var(--font-weight-bold);
    color: var(--text-main);
    line-height: 1;
    letter-spacing: -0.03em;
    max-width: 100%;
}
@media (min-width: 768px) {
    .profile-balance-wallet__amount { font-family: var(--font-display); }
}
.profile-balance-wallet__note {
    font-size: var(--text-sm);
    color: var(--text-muted);
}
.profile-balance-wallet__panel {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.8rem;
    padding: 1rem 1.1rem;
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--bg-panel) 55%, var(--bg-elevated));
}
.profile-balance-wallet__offer {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
}
.profile-balance-wallet__offer-icon {
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-lg);
    background: var(--primary-10);
    color: var(--primary-icon);
    font-size: var(--text-lg);
}
.profile-balance-wallet__offer-body {
    min-width: 0;
}
.profile-balance-wallet__offer-title {
    font-size: var(--text-base);
    font-weight: var(--font-weight-bold);
    color: var(--text-main);
    line-height: 1.25;
}
.profile-balance-wallet__offer-text {
    margin: 0.25rem 0 0;
    font-size: var(--text-sm);
    line-height: 1.45;
    color: var(--text-muted);
}
.profile-balance-wallet__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.55rem;
}
.profile-balance-wallet__actions .profile-topup-btn {
    flex: 1 1 9rem;
    width: auto;
}
/* Вторичная кнопка не должна сливаться с панелью: поднимаем её на
   surface-raised, тогда рядом с lime-primary она читается как кнопка. */
.profile-balance-wallet__actions .profile-secondary-btn {
    background-color: var(--bg-raised);
}
@media (hover: hover) {
    .profile-balance-wallet__actions .profile-secondary-btn:hover {
        background-color: var(--bg-raised);
        filter: brightness(1.18);
    }
}

/* Десктоп: контейнер профиля = 56rem, места хватает на две зоны.
   Левая колонка — по контенту (баланс), правая панель забирает всё
   оставшееся место (1fr), поэтому растягивается до края, без пустоты. */
@media (min-width: 1180px) {
    .profile-balance-wallet {
        grid-template-columns: max-content minmax(0, 1fr);
        gap: 1.5rem;
        padding: 1.35rem;
    }
    .profile-balance-wallet__main {
        align-items: flex-start;
        text-align: left;
        padding: 0.35rem 0.4rem;
    }
}

@media (max-width: 1120px) {
    .profile-balance-layout {
        grid-template-columns: 1fr;
    }

    .profile-balance-plan-name {
        max-width: 100%;
    }
}

@media (max-width: 720px) {
    .profile-balance-summary-meta {
        grid-template-columns: 1fr;
    }
}
/* ── Tabs ── */
.profile-tabs,
.shell-tabs {
    display: flex;
    gap: 0.3rem;
    padding: 0.3rem;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-x;
    overscroll-behavior-x: contain;
    scroll-behavior: smooth;
    border-radius: var(--radius-pill);
}

.profile-tabs {
    background: var(--bg-elevated);
    margin: 1rem 0;
}

.profile-tabs::-webkit-scrollbar,
.shell-tabs::-webkit-scrollbar { display: none; }

.shell-tabs {
    margin: 0;
}

.profile-tab,
.shell-tab {
    flex-shrink: 0;
    border-radius: var(--radius-pill);
    font-weight: var(--font-weight-medium);
    color: var(--text-subtle);
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
    border: none;
    background: transparent;
    white-space: nowrap;
}
/* Профильные табы = тот же размер/стиль, что и основное меню (.shell-tab),
   и сохраняются такими на десктопе (не ужимаются). */
.profile-tab,
.shell-tab {
    padding: 0.58rem 1.12rem;
    font-size: var(--text-lg);
    text-decoration: none;
}
@media (hover: hover) {
    .profile-tab:hover,
    .shell-tab:hover { color: var(--text-muted); }
}
.profile-tab.is-active,
.shell-tab.is-active {
    background: var(--bg-raised);
    color: var(--text-main);
}

.shell-tab.is-disabled {
    opacity: 0.35;
    pointer-events: none;
}

/* ── Shell Mobile Header ── */
.shell-mobile-header-host {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: var(--z-backdrop);
    overflow: hidden;
    padding-block-start: calc(env(safe-area-inset-top, 0px) + 0.55rem);
    padding-block-end: 0.5rem;
    padding-inline: var(--shell-mobile-gutter);
    --surface-fade-top-soft-mask: linear-gradient(to bottom, black 0, black 28%, transparent 100%);
    --surface-fade-top-strong-mask: linear-gradient(to bottom, black 0, black 18%, transparent 62%);
    --surface-fade-top-tint-gradient: linear-gradient(
        180deg,
        color-mix(in srgb, var(--bg-app) 92%, transparent) 0%,
        color-mix(in srgb, var(--bg-elevated) 58%, transparent) 46%,
        transparent 100%
    );
    --surface-fade-top-tint-opacity: 1;
    background: transparent;
    pointer-events: none;
}

.shell-mobile-header-host::before,
.shell-mobile-header-host::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 0;
}

.shell-mobile-header-host::before {
    -webkit-backdrop-filter: blur(var(--progressive-blur-2));
    backdrop-filter: blur(var(--progressive-blur-2));
    -webkit-mask-image: var(--surface-fade-top-soft-mask);
    mask-image: var(--surface-fade-top-soft-mask);
}

.shell-mobile-header-host::after {
    background: var(--surface-fade-top-tint-gradient);
    opacity: var(--surface-fade-top-tint-opacity);
    -webkit-backdrop-filter: blur(var(--progressive-blur-4));
    backdrop-filter: blur(var(--progressive-blur-4));
    -webkit-mask-image: var(--surface-fade-top-strong-mask);
    mask-image: var(--surface-fade-top-strong-mask);
}

.shell-mobile-header-host + .app-shell-body {
    position: relative;
    z-index: 0;
}

.shell-mobile-header-host > * {
    position: relative;
    z-index: 1;
    pointer-events: auto;
}

.shell-mobile-header,
.shell-mobile-chat-header,
.shell-mobile-page-header {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.shell-mobile-header-top,
.shell-mobile-chat-header-bar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.shell-mobile-chat-header-bar--draft {
    padding-top: 0.45rem;
}

.shell-mobile-header-top {
    justify-content: space-between;
}

.shell-mobile-header-brand {
    /* Логотип мобильной шапки привязан к высоте пилюли профиля
       (--shell-header-slot) — равны и зависимы: меняешь слот → меняются оба.
       --brand-logo-size здесь НЕ используем (он общий для рейла/вьюера/signin). */
    width: var(--shell-header-slot);
    height: var(--shell-header-slot);
    min-width: var(--shell-header-slot);
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    color: var(--text-main);
}

.shell-mobile-header-logo-icon {
    display: block;
    width: 100%;
    height: 100%;
    flex-shrink: 0;
}

.shell-mobile-chat-header-btn {
    width: var(--shell-header-slot);
    height: var(--shell-header-slot);
    border-radius: 999px;
    color: var(--text-main);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    border: none;
    flex-shrink: 0;
    cursor: pointer;
}

.shell-mobile-chat-header-btn-active {
    background: var(--primary-20);
    color: var(--primary-500);
}

.shell-mobile-chat-header-copy {
    min-width: 0;
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.08rem;
}

.shell-mobile-chat-header-eyebrow {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.shell-mobile-chat-header-title {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--text-sm);
    color: var(--text-main);
    font-weight: var(--font-weight-semibold);
}

.shell-mobile-chat-header-actions {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-shrink: 0;
}

@media (max-width: 767.98px) {
    .sidebar-top-offset {
        top: var(--shell-mobile-header-offset);
        height: calc(100% - var(--shell-mobile-header-offset));
    }
}

/* ── Desktop shell header: floats over content (transparent), pills are clickable ── */
.shell-desktop-header {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 20;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.6rem 0.85rem;
    background: transparent;
    pointer-events: none;
}

.shell-desktop-header__left,
.shell-desktop-header__right {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
    pointer-events: auto;
}

.shell-desktop-header__toggle {
    width: var(--shell-header-slot);
    height: var(--shell-header-slot);
    border-radius: 999px;
    color: var(--text-muted);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    cursor: pointer;
    transition: background-color var(--transition), color var(--transition);
}

/* Shared user pill: balance + avatar in one rounded container.
   Размер пилюли задаётся через --shell-header-slot, всё внутри derived от него:
   balance растягивается по высоте, profile — quadratic через aspect-ratio,
   avatar полностью заполняет profile. Никаких явных размеров на детях.
   Внутренний padding даёт аватару визуальный inset от каёмки пилюли — чтобы
   круп аватар-картинки не казался «упёртым» в curve cap'а пилюли. */
.shell-user-pill {
    display: inline-flex;
    align-items: stretch;
    gap: 0;
    height: var(--shell-header-slot);
    padding: 0.25rem;
    border-radius: 999px;
    overflow: hidden;
    border: none;
    -webkit-appearance: none;
    appearance: none;
    font: inherit;
    color: inherit;
    cursor: pointer;
    transition: background-color var(--transition);
}

.shell-user-pill__balance {
    display: inline-flex;
    align-items: center;
    padding: 0 0.4rem 0 0.75rem;
    color: var(--text-main);
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    text-decoration: none;
    white-space: nowrap;
    flex-shrink: 0;
    background: transparent;
    transition: color var(--transition);
}

.shell-user-pill__profile {
    position: relative;
    flex: 0 0 auto;
    /* Явная ширина: Safari не выводит её из aspect-ratio, когда высота
       приходит через align-items: stretch — без width аватар коллапсится
       в полоску, и balance визуально наезжает. */
    width: calc(var(--shell-header-slot) - 0.5rem);
    aspect-ratio: 1;
    border-radius: 50%;
    overflow: hidden;
    background: transparent;
    text-decoration: none;
    border: none;
    cursor: pointer;
    transition: background-color var(--transition);
}

.shell-user-pill--standalone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: var(--shell-header-slot);
    width: var(--shell-header-slot);
    color: var(--text-main);
}

.shell-user-pill__avatar {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
}

@media (hover: hover) {
    .shell-desktop-header__toggle:hover {
        background: var(--bg-raised);
        color: var(--text-main);
    }

    .shell-user-pill:hover {
        background: var(--bg-raised);
    }
}

/* ── Unpoly progress bar ── */
.up-progress-bar {
    background-color: var(--primary-500);
}

/* ── Shell enter animation (CSS class-driven, no VT API) ── */
@keyframes shell-content-enter {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}
/* Анимация входа вешается на [data-shell-enter] (контент-области), а не на
   весь main — иначе transform/opacity на предке гасит backdrop-filter
   докнутого стеклянного композера на всё время анимации. Fallback на main
   остаётся для страниц без стеклянного композера (home/profile/prices). */
.app-shell-body main.shell-enter,
.tg-panel.shell-enter,
[data-shell-enter].shell-enter {
    animation: shell-content-enter var(--motion-duration-shell) var(--motion-ease-elastic);
}
@media (prefers-reduced-motion: reduce) {
    .app-shell-body main.shell-enter,
    .tg-panel.shell-enter,
    [data-shell-enter].shell-enter {
        animation-duration: 0s !important;
    }
}

/* ── Tab panels ── */
.profile-panel { display: none; }
.profile-panel.is-active { display: block; }

/* ── Info block (Общее) ── */
.profile-info-card,
.profile-sessions-card,
.profile-history-card,
.profile-referral-card {
    background: var(--bg-elevated);
    box-shadow: var(--shadow-surface);
    border-radius: var(--radius-lg);
}

.profile-info-card,
.profile-history-card,
.profile-referral-card {
    margin-bottom: 1rem;
}

.profile-info-card,
.profile-sessions-card,
.profile-history-card {
    overflow: hidden;
}
.profile-info-row {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.85rem 1.25rem;
    box-shadow: inset 0 -1px 0 var(--bg-raised);
}
.profile-info-row:last-child { box-shadow: none; }
.profile-info-label {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.profile-info-value {
    font-size: var(--text-sm);
    color: var(--text-main);
    word-break: break-all;
}

/* ── Section heading inside panel ── */
.profile-section-title {
    font-size: var(--text-base);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    margin-bottom: 0.75rem;
}

/* ── Sessions ── */
.profile-session-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 1.25rem;
    box-shadow: inset 0 -1px 0 var(--bg-raised);
    transition: background var(--transition);
}
.profile-session-row:last-child { box-shadow: none; }
@media (hover: hover) {
    .profile-session-row:hover { background: var(--bg-hover); }
}
.profile-session-device {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-main);
}
.profile-session-meta {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    margin-top: 0.15rem;
    display: flex;
    gap: var(--gap-sm);
    flex-wrap: wrap;
}
.profile-session-current {
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    background: var(--surface-soft);
    padding: 0.15rem 0.5rem;
    border-radius: var(--radius-pill);
}
.profile-session-end-btn {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    box-shadow: 0 0 0 1px var(--bg-raised-hover);
    border: none;
    border-radius: var(--radius-pill);
    padding: 0.25rem 0.65rem;
    background: transparent;
    cursor: pointer;
    white-space: nowrap;
    transition: color var(--transition), box-shadow var(--transition), background var(--transition);
    flex-shrink: 0;
}
@media (hover: hover) {
    .profile-session-end-btn:hover {
        color: var(--text-main);
        box-shadow: 0 0 0 1px var(--text-subtle);
        background: var(--surface-soft);
    }
}

/* ── Analytics chart ── */
.profile-analytics-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1rem;
}
.profile-month-nav {
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
}
.profile-month-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: var(--radius-sm);
    box-shadow: 0 0 0 1px var(--bg-raised-hover);
    border: none;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    text-decoration: none;
    transition: background var(--transition), color var(--transition);
    font-size: var(--text-sm);
}
@media (hover: hover) {
    .profile-month-btn:hover { background: var(--bg-raised); color: var(--text-main); }
}
.profile-month-btn.is-disabled {
    opacity: 0.3;
    pointer-events: none;
}
.profile-month-label {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-main);
    min-width: 7rem;
    text-align: center;
}

.profile-chart-card {
    background: var(--bg-elevated);
    box-shadow: var(--shadow-surface);
    border-radius: var(--radius-lg);
    padding: 1.25rem 1.25rem 0.75rem;
    margin-bottom: 1rem;
}
.profile-chart-bars {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 80px;
}
.profile-chart-bar-wrap {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    height: 100%;
    justify-content: flex-end;
}
.profile-chart-bar {
    width: 100%;
    height: var(--bar-h, 2px);
    min-height: 2px;
    border-radius: 2px 2px 0 0;
    background: var(--primary-500);
    opacity: 0.7;
    transition: opacity var(--transition);
}
@media (hover: hover) {
    .profile-chart-bar:hover { opacity: 1; }
}
.profile-chart-bar.is-zero {
    background: var(--bg-raised);
    opacity: 1;
    min-height: 3px;
}
.profile-chart-footer {
    display: flex;
    justify-content: space-between;
    margin-top: 0.4rem;
    font-size: var(--text-2xs);
    color: var(--text-subtle);
}
.profile-analytics-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--gap-sm);
    padding: 2rem 1rem;
    color: var(--text-subtle);
    font-size: var(--text-sm);
}
.profile-empty-icon {
    font-size: 2rem;
    opacity: 0.4;
}

/* ── History list ── */
.profile-history-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1.25rem;
    box-shadow: inset 0 -1px 0 var(--bg-raised);
    gap: 0.75rem;
}
.profile-history-item:last-child { box-shadow: none; }
.profile-history-left {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}
.profile-history-top {
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
    flex-wrap: wrap;
}
.profile-history-type {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-main);
}
.profile-history-model-chip {
    font-size: var(--text-2xs);
    padding: 0.1rem 0.5rem;
    border-radius: var(--radius-pill);
    background: var(--bg-raised);
    color: var(--text-subtle);
    white-space: nowrap;
    max-width: 160px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.profile-history-meta {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: var(--text-xs);
    color: var(--text-subtle);
}
.profile-history-meta-item {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}
.profile-history-amount {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    white-space: nowrap;
    flex-shrink: 0;
}
.profile-history-amount.is-expense { color: var(--text-main); }
.profile-history-amount.is-income { color: var(--text-main); }

/* ── Referral panel ── */
.profile-referral-card {
    padding: 1.25rem 1.5rem;
}
.profile-ref-link-row {
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
    background: var(--bg-raised);
    border-radius: var(--radius-md);
    padding: 0.5rem 0.75rem;
    margin-top: 0.5rem;
    overflow: hidden;
}
.profile-ref-link-text {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--text-xs);
    color: var(--text-subtle);
}
.profile-ref-copy-btn {
    flex-shrink: 0;
    font-size: var(--text-xs);
    padding: 0.25rem 0.65rem;
    border-radius: var(--radius-pill);
    background: var(--primary-10);
    color: var(--primary-500);
    border: none;
    cursor: pointer;
    transition: background var(--transition);
    white-space: nowrap;
}
@media (hover: hover) {
    .profile-ref-copy-btn:hover { background: var(--primary-20); }
}
.profile-ref-stat {
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
    font-size: var(--text-sm);
    color: var(--text-muted);
    margin-top: 1rem;
}
.profile-ref-stat strong { color: var(--text-main); }

/* ── Pager ── */
.profile-pager {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem;
    box-shadow: inset 0 1px 0 var(--bg-raised);
}
.profile-pager-text {
    font-size: var(--text-xs);
    color: var(--text-subtle);
}

/* ── Danger zone ── */
/* ── Styles tab: Theme & Accent picker ── */
.profile-theme-row {
    display: flex;
    gap: 0.25rem;
    padding: 0.25rem;
    background: var(--bg-elevated);
    border-radius: var(--radius-pill);
}
.profile-theme-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.6rem;
    border-radius: var(--radius-pill);
    border: none;
    background: transparent;
    color: var(--text-subtle);
    font-size: var(--text-sm);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
}
@media (hover: hover) {
    .profile-theme-btn:hover { color: var(--text-muted); }
}
.profile-theme-btn.is-active {
    background: var(--bg-raised);
    color: var(--text-main);
}
.profile-accent-row {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
}
.profile-accent-swatch {
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--radius-pill);
    background-color: var(--swatch);
    border: none;
    cursor: pointer;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform var(--transition), box-shadow var(--transition);
}
@media (hover: hover) {
    .profile-accent-swatch:hover { transform: scale(1.1); }
}
.profile-accent-swatch.is-active {
    box-shadow: 0 0 0 2px var(--bg-app), 0 0 0 4px var(--swatch);
}
.profile-accent-check {
    color: var(--primary-text);
    font-size: 1rem;
    line-height: 1;
}

/* ══════════════════════════════════════════════
   PROMPT LIBRARY MODAL (Assistants / Presets)
   ══════════════════════════════════════════════ */
/* Sidebar */
.prompt-library-sidebar {
    border-right: 1px solid var(--surface-soft);
}
.prompt-library-tag {
    border-radius: var(--radius-lg);
    color: var(--text-muted);
    transition: background var(--transition), color var(--transition);
    cursor: pointer;
}
@media (hover: hover) {
    .prompt-library-tag:hover {
        background: var(--bg-elevated);
        color: var(--text-main);
    }
}
.prompt-library-tag-active {
    background: var(--primary-500/10);
    color: var(--primary-500);
}

/* Cards (chat assistants) */
.prompt-library-card {
    border-radius: var(--radius-lg);
    transition: background var(--transition);
    cursor: pointer;
}
@media (hover: hover) {
    .prompt-library-card:hover {
        background: var(--bg-elevated);
    }
}
.prompt-library-card-active {
    background: var(--primary-10);
}

/* Preset grid (media) */
.preset-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
}
@media (min-width: 640px) {
    .preset-grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 14px;
    }
}
.preset-card {
    position: relative;
    aspect-ratio: 3/4;
    border-radius: var(--radius-xl);
    overflow: hidden;
    cursor: pointer;
    transition: transform var(--transition-fast), box-shadow var(--transition-fast);
    background: var(--bg-elevated);
}
@media (hover: hover) {
    .preset-card:hover {
        box-shadow: 0 8px 24px rgba(0,0,0,0.25);
    }
}
.preset-card-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.preset-card-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
}
.preset-card-name {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 28px 14px 14px;
    background: linear-gradient(to top, var(--overlay-pill-bg-strong) 0%, transparent 100%);
    color: var(--overlay-text);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: var(--text-lg);
    line-height: 1.2;
    text-align: left;
}
.preset-card-selected {
    box-shadow: 0 0 0 3px var(--primary-500);
}
.preset-card-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--overlay-pill-bg);
    color: var(--overlay-text);
    display: flex;
    align-items: center;
    justify-content: center;
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
}
.preset-card-create {
    border: 2px dashed var(--surface-soft);
    background: transparent;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    opacity: 0.7;
    transition: opacity var(--transition-fast), border-color var(--transition-fast);
}
@media (hover: hover) {
    .preset-card-create:hover {
        opacity: 1;
        border-color: var(--primary-500);
        transform: none;
        box-shadow: none;
    }
}

/* ── Utility: mono text ── */
.profile-mono {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
}

/* ── Referral hint ── */
.profile-ref-hint {
    font-size: var(--text-sm);
    color: var(--text-muted);
}

/* ── Analytics header title resets margin ── */
.profile-analytics-header .profile-section-title {
    margin: 0;
}

/* ── History meta icons ── */
.profile-history-meta-item i {
    font-size: var(--text-2xs);
}

/* ── Промокод: минималистичный центрированный ввод (крупный текст + кнопка) ── */
.profile-panel--promo.is-active {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 50vh;
}
.promo-claim {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.75rem;
    width: 100%;
}
.promo-claim__input {
    width: 100%;
    border: none;
    background: transparent;
    text-align: center;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(2rem, 7vw, 4rem);
    line-height: 1.1;
    color: var(--text-main);
    padding: 0;
}
.promo-claim__input::placeholder { color: var(--text-muted); opacity: 1; }
.promo-claim__input:focus { outline: none; }
/* Кнопка всегда в потоке (резервирует место) — при вводе блок не «прыгает»;
   до ввода просто скрыта по прозрачности. */
.promo-claim__btn { transition: opacity var(--transition); }
.promo-claim__btn.is-empty { opacity: 0; pointer-events: none; }

/* ── Mobile ── */
@media (max-width: 480px) {
    .profile-page { padding: 1rem 0.75rem 4rem; }
    .profile-tabs,
    .shell-tabs { gap: 0.2rem; padding: 0.24rem; }
    .profile-tab,
    .shell-tab { padding: 0.52rem 0.98rem; font-size: var(--text-base); }
    .profile-header { gap: 0.75rem; }
    .profile-balance-layout { gap: 0.75rem; }
    .profile-balance-summary-card,
    .profile-balance-wallet-card { padding: 1rem; }
    .profile-balance-wallet { padding: 1.15rem 1rem; }
    .profile-balance-wallet__panel { padding: 1rem; }
    .profile-balance-wallet__actions .profile-topup-btn { flex: 1 1 100%; width: 100%; }
    .profile-topup-btn { width: 100%; }
    .profile-secondary-btn { width: 100%; }
    .profile-balance-plan-name { font-size: clamp(2.2rem, 13vw, 3.5rem); }
    .profile-balance-amount { font-size: clamp(2.15rem, 12vw, 3.2rem); }
    :root { --shell-mobile-gutter: 0.625rem; }
    .shell-mobile-header-host {
        padding-block-start: calc(env(safe-area-inset-top, 0px) + 0.45rem);
        padding-block-end: 0.45rem;
    }
}

/* ══════════════════════════════════════════════════════════════
    PRICES PAGE — pricing-focused layout
    ══════════════════════════════════════════════════════════════ */
.subscription-showcase,
.subscription-reference-layout,
.subscription-plan-grid {
    display: grid;
    gap: 0.6rem;
}

.subscription-showcase-main,
.subscription-account-card,
.subscription-plan-card,
.prices-calculator-card,
.subscription-reference-card,
.prices-group-card,
.subscription-faq-item {
    position: relative;
    overflow: hidden;
}

.subscription-showcase {
    grid-template-columns: 1fr;
}

.subscription-showcase-main {
    padding: clamp(0.9rem, 1.5vw, 1.15rem);
    border-radius: var(--radius-2xl);
    background:
        radial-gradient(circle at top right, color-mix(in srgb, var(--primary-500) 14%, transparent) 0%, transparent 34%),
        linear-gradient(180deg, color-mix(in srgb, var(--bg-elevated) 97%, var(--primary-10)) 0%, color-mix(in srgb, var(--bg-elevated) 100%, var(--bg-panel)) 100%);
    box-shadow: 0 22px 46px -40px color-mix(in srgb, var(--primary-500) 28%, transparent), var(--shadow-surface);
}

.subscription-showcase-main::before {
    content: "";
    position: absolute;
    inset: auto -10% -30% 45%;
    height: 16rem;
    background: radial-gradient(circle, color-mix(in srgb, var(--primary-500) 16%, transparent) 0%, transparent 70%);
}

.subscription-showcase-head,
.subscription-section-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.55rem;
}

.subscription-showcase-kicker,
.subscription-section-kicker,
.subscription-reference-card__eyebrow,
.subscription-account-card__eyebrow,
.subscription-path-card__eyebrow {
    display: inline-flex;
    align-items: center;
    font-size: var(--text-2xs);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-subtle);
}

.subscription-status-pill,
.subscription-account-card__pill,
.subscription-plan-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    padding: 0.28rem 0.58rem;
    border-radius: var(--radius-pill);
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    white-space: nowrap;
}

.subscription-status-pill.is-active,
.subscription-account-card__pill.is-active,
.subscription-plan-badge.is-recommended {
    background: var(--primary-500);
    color: var(--text-inverse);
}

.subscription-status-pill.is-free,
.subscription-account-card__pill.is-free,
.subscription-plan-badge.is-free {
    background: var(--primary-10);
    color: var(--primary-500);
}

.subscription-status-pill.is-inactive,
.subscription-account-card__pill.is-inactive {
    background: color-mix(in srgb, var(--bg-panel) 46%, var(--bg-elevated));
    color: var(--text-muted);
}

.subscription-plan-badge.is-current {
    background: var(--surface-soft);
    color: var(--text-main);
}

.subscription-showcase-title {
    position: relative;
    z-index: 1;
    max-width: 9ch;
    margin-top: 0.55rem;
    font-family: var(--font-display);
    font-size: clamp(2.2rem, 4.8vw, 3.9rem);
    line-height: 0.94;
    color: var(--text-main);
}

.subscription-showcase-copy {
    position: relative;
    z-index: 1;
    max-width: 34rem;
    margin-top: 0.55rem;
    font-size: var(--text-sm);
    line-height: 1.55;
    color: color-mix(in srgb, var(--text-muted) 92%, var(--text-main));
}

.subscription-path-grid {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
    margin-top: 0.85rem;
}

.subscription-path-card {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    min-height: 13.75rem;
    padding: 0.8rem;
    border-radius: var(--radius-xl);
    background: color-mix(in srgb, var(--bg-panel) 46%, var(--bg-elevated));
    box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text-main) 4%, transparent);
}

.subscription-path-card.is-primary {
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-elevated) 92%, var(--primary-14)) 0%, color-mix(in srgb, var(--bg-elevated) 98%, var(--primary-10)) 100%);
    box-shadow: 0 20px 40px -36px color-mix(in srgb, var(--primary-500) 24%, transparent), inset 0 1px 0 color-mix(in srgb, var(--text-main) 4%, transparent);
}

.subscription-path-card__title {
    font-family: var(--font-display);
    font-size: clamp(var(--text-xl), 2.8vw, var(--text-2xl));
    line-height: 0.98;
    color: var(--text-main);
}

.subscription-path-card__copy {
    font-size: var(--text-sm);
    line-height: 1.55;
    color: var(--text-muted);
}

.subscription-path-card__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: auto;
}

.subscription-path-card__chip,
.subscription-plan-offer-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.28rem 0.58rem;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--bg-panel) 40%, var(--bg-elevated));
    color: var(--text-main);
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-semibold);
}

.subscription-path-card__action {
    align-self: flex-start;
    margin-top: 0.45rem;
}

.subscription-showcase-side {
    display: grid;
    gap: 0.6rem;
}

.subscription-account-card,
.subscription-plan-card,
.prices-calculator-card,
.subscription-reference-card,
.prices-group-card,
.subscription-faq-item {
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-elevated) 97%, var(--primary-10)) 0%, var(--bg-elevated) 100%);
    box-shadow: 0 18px 36px -34px color-mix(in srgb, var(--text-main) 20%, transparent), var(--shadow-surface);
}

.subscription-account-card,
.subscription-plan-card,
.prices-calculator-card,
.subscription-reference-card {
    padding: 0.8rem;
    border-radius: var(--radius-xl);
}

.subscription-account-card h2 {
    font-family: var(--font-display);
    font-size: clamp(var(--text-2xl), 4vw, var(--text-3xl));
    line-height: 0.95;
    color: var(--text-main);
}

.subscription-account-card__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.45rem;
    margin-top: 0.65rem;
}

.subscription-account-card__metric {
    padding: 0.55rem 0.65rem;
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--bg-panel) 36%, transparent);
}

.subscription-account-card__metric span {
    display: block;
    margin-bottom: 0.35rem;
    font-size: var(--text-2xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-subtle);
}

.subscription-account-card__metric strong {
    font-size: var(--text-sm);
    color: var(--text-main);
    line-height: 1.4;
}

.subscription-account-card__note,
.subscription-plan-copy,
.subscription-plan-footnote,
.subscription-reference-card__header p,
.subscription-reference-point span,
.subscription-section-copy,
.subscription-faq-content {
    font-size: var(--text-xs);
    line-height: 1.55;
    color: var(--text-muted);
}

.subscription-account-card__note {
    margin-top: 0.6rem;
}

.subscription-reference-card__header h3 {
    margin-top: 0.35rem;
    color: var(--text-main);
    font-family: var(--font-display);
    font-size: clamp(var(--text-lg), 2.4vw, var(--text-xl));
    line-height: 1.05;
    margin-bottom: 0.35rem;
}

.subscription-section-head {
    margin-bottom: 0.7rem;
}

.subscription-section-title {
    font-family: var(--font-display);
    font-weight: var(--font-weight-bold);
    color: var(--text-main);
}

.subscription-section-head--plans {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    text-align: center;
    margin-bottom: 0.85rem;
}

.subscription-section-title--plans {
    font-size: clamp(2.35rem, 5.8vw, 4.8rem);
    line-height: 0.92;
    letter-spacing: -0.045em;
    text-transform: uppercase;
    max-width: none;
}

.subscription-section-copy {
    max-width: 32rem;
}

.subscription-section-copy--plans {
    max-width: 42rem;
    margin: 0 auto;
    font-size: var(--text-base);
    line-height: 1.5;
}

.subscription-period-shell {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.7rem;
    margin-top: 0.75rem;
    padding: 0.65rem 0.75rem;
    border-radius: var(--radius-xl);
    background: color-mix(in srgb, var(--bg-panel) 36%, var(--bg-elevated));
    box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text-main) 4%, transparent);
}

.subscription-period-shell--plans {
    width: 100%;
    max-width: 31rem;
    margin: 0 auto 1rem;
    padding: 0;
    justify-content: center;
    background: transparent;
    box-shadow: none;
}

.subscription-period-toolbar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.7rem;
    flex-direction: column;
    width: 100%;
}

.subscription-period-switcher {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding-left: 2.2rem;
}

.subscription-period-toggle {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gap-2xs);
    padding: var(--gap-xs);
    /* Капсульный сегментбар (эталон): pill-трей + pill-сегменты, активный
       --surface-strong. Трей — recessed --bg-input на сплошной странице. */
    border-radius: var(--radius-pill);
    background: var(--bg-input);
    min-width: min(100%, 25rem);
}

.subscription-period-toggle__btn {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 10rem;
    padding: 0.95rem 1.55rem;
    border: 0;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text-muted);
    font-size: clamp(1.15rem, 1.5vw, 1.7rem);
    font-weight: var(--font-weight-bold);
    letter-spacing: -0.03em;
    white-space: nowrap;
    transition: background-color var(--transition), color var(--transition), transform var(--transition-fast), box-shadow var(--transition);
}

@media (hover: hover) {
    .subscription-period-toggle__btn:hover {
        transform: translateY(-1px);
    }
}

.subscription-period-toggle__btn.is-active {
    background: var(--surface-strong);
    color: var(--text-main);
}

.subscription-period-discount {
    position: absolute;
    left: 0;
    top: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 5.75rem;
    padding: 0.7rem 0.95rem;
    border-radius: calc(var(--radius-lg) - 0.5rem);
    background: var(--primary-500);
    color: var(--text-inverse);
    font-size: clamp(1rem, 1.2vw, 1.2rem);
    font-weight: var(--font-weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    transform: translate(-10%, -52%) rotate(-13deg);
    box-shadow: 0 18px 28px -20px color-mix(in srgb, var(--primary-500) 70%, transparent);
}

.subscription-plan-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}

.subscription-plan-card {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    position: relative;
    overflow: hidden;
}

.subscription-plan-card.is-featured {
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-elevated) 88%, var(--primary-18)) 0%, color-mix(in srgb, var(--bg-elevated) 94%, var(--primary-10)) 56%, color-mix(in srgb, var(--bg-elevated) 98%, var(--primary-10)) 100%);
    box-shadow: 0 28px 58px -42px color-mix(in srgb, var(--primary-500) 38%, transparent), var(--shadow-surface);
    transform: translateY(-0.16rem);
}

.subscription-plan-card.is-featured .subscription-plan-kicker {
    color: color-mix(in srgb, var(--primary-600) 72%, var(--text-main));
}

.subscription-plan-card.is-featured .subscription-plan-slider {
    background: linear-gradient(180deg, color-mix(in srgb, var(--primary-10) 58%, var(--bg-panel)) 0%, color-mix(in srgb, var(--bg-panel) 30%, var(--bg-elevated)) 100%);
    box-shadow: inset 0 1px 0 color-mix(in srgb, white 10%, transparent), 0 20px 38px -34px color-mix(in srgb, var(--primary-500) 34%, transparent);
}

.subscription-plan-card.is-featured .subscription-plan-slider__value {
    color: color-mix(in srgb, var(--primary-600) 68%, var(--text-main));
}

.subscription-plan-card.is-featured .subscription-plan-slider__mark.is-active {
    color: color-mix(in srgb, var(--primary-600) 82%, var(--text-main));
}

.subscription-plan-card.is-current {
    box-shadow: 0 18px 40px -34px color-mix(in srgb, var(--text-main) 20%, transparent), var(--shadow-surface);
}

.subscription-plan-card.is-free {
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-elevated) 98%, var(--bg-panel)) 0%, var(--bg-elevated) 100%);
}

.subscription-plan-badges {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.35rem;
}

.subscription-plan-kicker {
    margin-bottom: 0.2rem;
    font-size: var(--text-2xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-subtle);
}

.subscription-plan-title {
    font-family: var(--font-display);
    font-size: clamp(var(--text-lg), 2.3vw, var(--text-xl));
    line-height: 1;
    color: var(--text-main);
}

.subscription-plan-price {
    font-family: var(--font-display);
    font-size: clamp(var(--text-2xl), 3.2vw, var(--text-4xl));
    line-height: 0.94;
    color: var(--text-main);
}

.subscription-plan-price-line {
    display: flex;
    align-items: flex-end;
    gap: 0.65rem;
    flex-wrap: wrap;
}

.subscription-plan-price-current {
    display: inline-flex;
    align-items: baseline;
    gap: 0.35rem;
}

.subscription-plan-price-current span,
.subscription-plan-price > span {
    display: inline-block;
    margin-top: 0;
    font-family: var(--font-sans);
    font-size: var(--text-xs);
    color: var(--text-muted);
}

.subscription-plan-price-old {
    display: inline-block;
    font-family: var(--font-sans);
    font-size: clamp(var(--text-lg), 1.8vw, var(--text-2xl));
    font-weight: var(--font-weight-medium);
    line-height: 1;
    color: var(--text-subtle);
    text-decoration: line-through;
    text-decoration-thickness: 0.08em;
    text-decoration-color: color-mix(in srgb, var(--text-subtle) 72%, transparent);
}

.subscription-plan-slider {
    display: grid;
    gap: 0.65rem;
    padding: 0.75rem;
    border-radius: var(--radius-lg);
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-panel) 32%, var(--bg-elevated)) 0%, color-mix(in srgb, var(--bg-panel) 18%, transparent) 100%);
    box-shadow: inset 0 1px 0 color-mix(in srgb, white 4%, transparent);
}

.subscription-plan-slider__top {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 0.65rem;
}

.subscription-plan-slider__eyebrow {
    display: inline-flex;
    align-items: center;
    font-size: var(--text-2xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-subtle);
}

.subscription-plan-slider__hint {
    margin-top: 0.18rem;
    font-size: var(--text-xs);
    line-height: 1.45;
    color: var(--text-muted);
    max-width: 18rem;
}

.subscription-plan-slider__value {
    font-family: var(--font-display);
    font-size: clamp(var(--text-xl), 2.4vw, var(--text-2xl));
    line-height: 1;
    color: var(--text-main);
    text-align: right;
    white-space: nowrap;
}

.subscription-plan-slider__value span {
    font-family: var(--font-sans);
    font-size: var(--text-xs);
    color: var(--text-muted);
}

.subscription-plan-slider__input {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 0.45rem;
    border-radius: var(--radius-pill);
    outline: 0;
    background: linear-gradient(90deg, var(--primary-500) 0%, var(--primary-500) var(--slider-fill, 0%), color-mix(in srgb, var(--bg-raised) 88%, white 6%) var(--slider-fill, 0%), color-mix(in srgb, var(--bg-raised) 88%, white 6%) 100%);
}

.subscription-plan-slider__input::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 1.2rem;
    height: 1.2rem;
    border: 0;
    border-radius: 50%;
    background: var(--text-main);
    box-shadow: 0 10px 18px -12px color-mix(in srgb, black 80%, transparent);
    cursor: pointer;
}

.subscription-plan-slider__input::-moz-range-thumb {
    width: 1.2rem;
    height: 1.2rem;
    border: 0;
    border-radius: 50%;
    background: var(--text-main);
    box-shadow: 0 10px 18px -12px color-mix(in srgb, black 80%, transparent);
    cursor: pointer;
}

.subscription-plan-slider__input::-moz-range-track {
    height: 0.45rem;
    border-radius: var(--radius-pill);
    background: transparent;
}

.subscription-plan-slider__marks {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0.25rem;
}

.subscription-plan-slider__mark {
    border: 0;
    padding: 0;
    background: transparent;
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-subtle);
    text-align: center;
    cursor: pointer;
    transition: color var(--transition-fast), transform var(--transition-fast);
}

@media (hover: hover) {
    .subscription-plan-slider__mark:hover,
    .subscription-plan-slider__mark.is-active {
        color: var(--text-main);
    }
}

@media (hover: hover) {
    .subscription-plan-slider__mark:hover {
        transform: translateY(-1px);
    }
}

.subscription-plan-offer-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: -0.05rem;
}

.subscription-plan-rate-note {
    font-size: var(--text-xs);
    line-height: 1.45;
    color: var(--text-muted);
}

.subscription-plan-offer-chip {
    background: var(--primary-10);
    color: var(--primary-500);
}

.subscription-plan-metrics,
.subscription-reference-points {
    display: grid;
    gap: 0.45rem;
}

.subscription-plan-metrics {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.subscription-plan-metric,
.subscription-reference-point {
    padding: 0.6rem 0.7rem;
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--bg-panel) 34%, transparent);
}

.subscription-plan-metric {
    display: block;
    gap: 0;
    font-size: var(--text-2xs);
    color: var(--text-muted);
}

.subscription-plan-metric span {
    display: block;
    margin-bottom: 0.18rem;
}

.subscription-plan-metric strong,
.subscription-reference-point strong {
    color: var(--text-main);
    font-weight: var(--font-weight-semibold);
    font-size: var(--text-sm);
}

.subscription-plan-features {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.45rem;
}

.subscription-plan-features li {
    display: flex;
    align-items: flex-start;
    gap: 0.45rem;
    font-size: var(--text-xs);
    line-height: 1.35;
    color: var(--text-muted);
}

.subscription-plan-features i {
    margin-top: 0.05rem;
    color: var(--primary-500);
}

.subscription-reference-layout {
    grid-template-columns: 1fr;
}

.prices-calculator-card,
.subscription-reference-card {
    border-radius: var(--radius-xl);
}

.subscription-reference-card__header {
    margin-bottom: 0.8rem;
}

.prices-calc-inner {
    background: color-mix(in srgb, var(--bg-panel) 42%, var(--bg-raised));
    border-radius: var(--radius-lg);
    padding: 0.85rem;
}

.prices-calculator-card {
    margin-bottom: 0;
}

.subscription-models-stack {
    display: grid;
    gap: 0.5rem;
}

.subscription-faq-section {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.subscription-faq-header {
    max-width: 48rem;
}

.subscription-faq-list {
    display: grid;
    gap: 0.5rem;
}

.subscription-faq-summary {
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    padding: 0.8rem 0.9rem;
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
}

.subscription-faq-summary::-webkit-details-marker {
    display: none;
}

@media (hover: hover) {
    .subscription-faq-summary:hover {
        background: var(--bg-hover);
    }
}

.subscription-faq-question {
    font-size: var(--text-base);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    line-height: 1.35;
}

.subscription-faq-toggle {
    width: 2rem;
    height: 2rem;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--bg-panel) 38%, var(--bg-elevated));
    color: var(--text-main);
}

.subscription-faq-icon-minus {
    display: none;
}

.subscription-faq-item[open] .subscription-faq-toggle {
    background: var(--primary-10);
    color: var(--primary-500);
}

.subscription-faq-item[open] .subscription-faq-summary {
    background: color-mix(in srgb, var(--bg-panel) 18%, var(--bg-elevated));
}

.subscription-faq-item[open] .subscription-faq-icon-plus {
    display: none;
}

.subscription-faq-item[open] .subscription-faq-icon-minus {
    display: inline-block;
}

.subscription-faq-content {
    padding: 0 0.9rem 0.85rem;
}

.subscription-faq-content p + p {
    margin-top: 0.6rem;
}

.prices-group-card {
    border-radius: var(--radius-xl);
}

.prices-group-header {
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
    padding: 0.7rem 0.95rem;
    background: color-mix(in srgb, var(--bg-panel) 40%, transparent);
}

.prices-group-header h2 {
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.07em;
}

@media (min-width: 980px) {
    .subscription-showcase {
        grid-template-columns: minmax(18rem, 0.82fr) minmax(0, 1.2fr);
    }

    .subscription-showcase-side {
        order: 1;
    }

    .subscription-showcase-main {
        order: 2;
    }

    .subscription-reference-layout {
        grid-template-columns: minmax(0, 1.15fr) minmax(18rem, 0.85fr);
    }
}

@media (min-width: 1280px) {
    .subscription-plan-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

@media (max-width: 760px) {
    .subscription-path-grid {
        grid-template-columns: 1fr;
    }

    .subscription-period-shell {
        flex-direction: column;
        align-items: flex-start;
    }

    .subscription-period-shell--plans {
        align-items: stretch;
        padding: 0;
    }

    .subscription-period-toolbar {
        align-items: center;
        gap: 0.65rem;
    }

    .subscription-period-switcher {
        width: min(100%, 24rem);
        padding: 1.25rem 0 0;
    }

    .subscription-period-toggle {
        width: 100%;
        min-width: 0;
    }

    .subscription-period-discount {
        left: 50%;
        top: 0;
        transform: translate(-50%, -8%) rotate(-10deg);
    }

    .subscription-section-head,
    .subscription-showcase-head,
    .subscription-account-card__top,
    .subscription-plan-top {
        flex-direction: column;
        align-items: flex-start;
    }

    .subscription-section-head--plans {
        align-items: center;
    }

    .subscription-plan-badges {
        justify-content: flex-start;
    }

    .subscription-section-copy--plans {
        font-size: var(--text-sm);
    }
}

@media (max-width: 640px) {
    .subscription-showcase-main,
    .subscription-account-card,
    .subscription-path-card,
    .subscription-plan-card,
    .prices-calculator-card,
    .subscription-reference-card,
    .prices-group-card,
    .subscription-faq-item {
        border-radius: var(--radius-lg);
    }

    .subscription-account-card,
    .subscription-path-card,
    .subscription-plan-card,
    .prices-calculator-card,
    .subscription-reference-card,
    .subscription-showcase-main {
        padding: 0.95rem;
    }

    .subscription-showcase-title {
        max-width: none;
        font-size: clamp(var(--text-3xl), 12vw, var(--text-5xl));
    }

    .subscription-section-title--plans {
        font-size: clamp(2rem, 12vw, 3.25rem);
    }

    .subscription-period-switcher {
        width: 100%;
    }

    .subscription-period-toggle__btn {
        min-width: 0;
        padding: 0.9rem 1rem;
        font-size: clamp(1rem, 4vw, 1.25rem);
    }

    .subscription-period-discount {
        min-width: 5rem;
        padding: 0.6rem 0.8rem;
        font-size: 0.95rem;
    }

    .subscription-plan-slider {
        padding: 0.7rem;
    }

    .subscription-plan-slider__top {
        flex-direction: column;
        align-items: flex-start;
    }

    .subscription-plan-slider__value {
        text-align: left;
    }

    .subscription-account-card__grid {
        grid-template-columns: 1fr;
    }

    .subscription-plan-metrics {
        grid-template-columns: 1fr;
    }

    .subscription-path-card {
        min-height: auto;
    }

    .subscription-path-card__action {
        align-self: stretch;
    }

    .subscription-faq-summary {
        padding: 0.9rem;
        gap: 0.75rem;
    }

    .subscription-faq-question {
        font-size: var(--text-base);
    }

    .subscription-faq-toggle {
        width: 2.15rem;
        height: 2.15rem;
    }

    .subscription-faq-content {
        padding: 0 0.9rem 0.9rem;
    }
}
.prices-group-icon {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
    overflow: hidden;
    color: var(--text-subtle);
}
.prices-group-icon svg {
    display: block;
    width: 100%;
    height: 100%;
}

/* ── Column headers ── */
.prices-thead th {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: var(--font-weight-medium);
    padding: 0.45rem 1.25rem;
    box-shadow: inset 0 -1px 0 var(--bg-raised);
}
.prices-thead th:not(:first-child) { text-align: right; white-space: nowrap; }

/* ── Data rows — identical to .profile-history-item ── */
.prices-table-row {
    box-shadow: inset 0 -1px 0 var(--bg-raised);
    transition: background var(--transition);
}
.prices-table-row:last-child { box-shadow: none; }
@media (hover: hover) {
    .prices-table-row:hover { background: var(--bg-hover); }
}
.prices-table-row td {
    padding: 0.75rem 1.25rem;
    font-size: var(--text-sm);
    color: var(--text-main);
}
.prices-table-row td:not(:first-child) { text-align: right; white-space: nowrap; }

/* ========================================
   ASSISTANTS PAGE
   ======================================== */

/* ── Card ── */
.assistant-card {
    background: var(--surface-soft);
    border-radius: var(--radius-lg);
    padding: 1rem;
    cursor: pointer;
    transition: background var(--transition), box-shadow var(--transition);
}
@media (hover: hover) {
    .assistant-card:hover {
        background: var(--surface-active);
        box-shadow: var(--shadow-icon);
    }
}

/* ── Handle badge (static) ── */
.handle-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.45rem;
    border-radius: var(--radius-sm);
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-medium);
    color: var(--text-subtle);
    background: var(--bg-raised);
    white-space: nowrap;
    line-height: 1.3;
}

/* ── Icon circle ── */
.assistant-icon {
    width: 3.5rem;
    height: 3.5rem;
    border-radius: var(--radius-pill);
    background: var(--bg-elevated);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

/* ── Tag piills ── */
.assistant-tag {
    display: inline-flex;
    align-items: center;
    padding: 0.125rem 0.5rem;
    border-radius: var(--radius-pill);
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
    background: var(--bg-raised);
}

/* ── Capability badge (иконка + подпись встроенных режимов) ── */
.assistant-cap-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.125rem 0.4375rem;
    border-radius: var(--radius-pill);
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
    background: var(--bg-raised);
    white-space: nowrap;
    line-height: 1.25;
}
.assistant-cap-badge .ti {
    font-size: var(--text-xs);
}

/* ── Mention Dropdown ── */
.mention-dropdown {
    max-height: none;
    overflow: visible;
    padding: 0.25rem;
}

.mention-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    padding: 1rem 0.75rem;
    color: var(--text-muted);
    text-align: center;
}
.mention-empty-icon {
    font-size: 1.75rem;
    line-height: 1;
    opacity: 0.7;
}
.mention-empty-text {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-medium);
}

/* ========================================
   MODAL UTILITY CLASSES (relight, camera-angle, etc.)
   ======================================== */
.modal-fullscreen-bg {
    background: var(--bg-app);
    z-index: var(--z-dialog-above-overlay);
}

.modal-blurred-backdrop {
    opacity: 0.15;
}

.camera-modal-backdrop {
    opacity: 0.4;
}

.modal-image-rounded {
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-modal);
}

/* ── Modal header (unified) ── */
.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
}

.modal-header-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
}

.modal-header-close {
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: var(--text-lg);
    line-height: 1;
    transition: background var(--transition), color var(--transition);
}
@media (hover: hover) {
    .modal-header-close:hover {
        background: var(--bg-hover);
        color: var(--text-main);
    }
}

.modal-icon-xl {
    font-size: var(--text-xl);
    color: var(--text-main);
}

.modal-title-xl {
    font-family: var(--font-display);
    color: var(--text-main);
    font-weight: var(--font-weight-bold);
    font-size: var(--text-xl);
}

.modal-close-btn-bg {
    color: var(--text-muted);
}
@media (hover: hover) {
    .modal-close-btn-bg:hover {
        background: var(--bg-raised);
    }
}

.modal-icon-sm {
    font-size: var(--text-sm);
}

.modal-icon-xs {
    font-size: var(--text-xs);
}

.modal-icon-lg {
    font-size: var(--text-lg);
}

.modal-label-subtle {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    font-weight: var(--font-weight-medium);
}

.modal-hint-subtle {
    font-size: var(--text-xs);
    color: var(--text-subtle);
}

.modal-hint-sm {
    font-size: var(--text-sm);
    color: var(--text-subtle);
}

/* Camera Angle Modal */
.camera-icon-box {
    border-radius: var(--radius-md);
}

.camera-subtitle {
    color: var(--text-subtle);
    font-size: var(--text-xs);
    margin-top: 2px;
}

.camera-no-select {
    -webkit-user-select: none;
    user-select: none;
}

.camera-slider-label {
    font-size: var(--text-xs);
    color: var(--text-muted);
    font-weight: var(--font-weight-medium);
    letter-spacing: 0.04em;
}

/* Textarea field-sizing */
.field-sizing-content {
    field-sizing: content;
}

/* ===== TILE — переиспользуемая навигационная плитка =====
   Не привязана к главной: задумана для раскатки по проекту. Простая
   скруглённая форма, hairline-кольцо инсетом (без border — нет сдвига layout),
   ambient-засветка угла и иконка в круге со свечением акцента.
   Все цвета — токены: data-accent перекрашивает кольцо/свечение сам. */
.tile {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.7rem;
    padding: 1.25rem 1rem;
    background: var(--bg-elevated);
    border-radius: var(--radius-xl);
    box-shadow: inset 0 0 0 1px var(--text-main-5);
    color: var(--text-main);
    text-decoration: none;
    text-align: center;
    overflow: hidden;
    transition: transform var(--transition-fast);
}

/* Ambient-засветка верхнего угла (как у featured-тарифа, но инсетом). */
.tile::before {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(110% 85% at 82% -12%, var(--primary-10), transparent 58%);
}

.tile__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.4rem;
    height: 3.4rem;
    border-radius: var(--radius-pill);
    font-size: 1.5rem;
    color: var(--primary-icon);
    background: color-mix(in srgb, var(--primary-500) 7%, transparent);
    box-shadow: var(--ring-accent-soft), var(--glow-accent-soft);
    transition: box-shadow var(--transition);
}

.tile__label {
    font-family: var(--font-display);
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: 0.07em;
}

.tile__sublabel {
    font-size: var(--text-xs);
    color: var(--text-subtle);
    line-height: 1.3;
}

.tile__badge {
    position: absolute;
    top: 0.65rem;
    right: 0.65rem;
    padding: 0.15rem 0.45rem;
    border-radius: var(--radius-pill);
    background: var(--primary-500);
    color: var(--primary-text);
    font-size: 0.625rem;
    font-weight: var(--font-weight-bold);
    letter-spacing: 0.04em;
}

/* Квадратная плитка-инструмент (сетка 2x2 / 4x1). */
.tile--quick {
    aspect-ratio: 1 / 0.92;
}

@media (min-width: 768px) {
    .tile--quick {
        aspect-ratio: 1.15 / 1;
    }
    .tile--quick .tile__icon {
        width: 3.8rem;
        height: 3.8rem;
    }
}

@media (hover: hover) {
    .tile:hover {
        transform: translateY(-3px);
        color: var(--text-main);
    }
    .tile:hover .tile__icon {
        box-shadow: var(--ring-accent-strong), var(--glow-accent-strong);
    }
}

/* Тач-фидбек: лёгкое сжатие вместо hover-лифта. */
.tile:active {
    transform: scale(0.97);
    transition-duration: var(--motion-duration-micro);
}

/* ===== HOME HERO & QUICK ACCESS ===== */

.home-scroll {
    display: flex;
    flex-direction: column;
}

/* ── Хореография скролла главной ──
   homeShell._handleScroll пишет на .app-root одну переменную --home-progress
   (0→1 за 240px). Все эффекты — зависимые сегменты ОДНОГО прогресса,
   разложенные clamp()'ами:
     --hm            0–80px   морф мобильной шапки (меню+аватар в один ряд);
     --hero-out      0–190px  фейд контента hero (копия, CTA, дотсы);
     --sheet-densify 96–240px уплотнение растушёвки шторки.
   Фото hero растворяется по полному ходу прогресса (см. .home-hero__stage). */
.app-root[data-page-key='home'] {
    --home-progress: 0;
    --hm: clamp(0, calc(var(--home-progress) * 3), 1);
    --hero-out: clamp(0, calc(var(--home-progress) * 1.25), 1);
    --sheet-densify: clamp(0, calc((var(--home-progress) - 0.4) / 0.6), 1);
    /* Геометрия шва hero↔шторка: насколько шторка наезжает на hero и высота
       растушёвки над её краем. Дотсы/CTA hero позиционируются от этих же
       значений — выше плотной части растушёвки. */
    --home-sheet-overlap: 1.75rem;
    --home-feather-h: 4.5rem;
}

/* Видео-hero запинен сверху (top:0, z:0), а «шторка» (.home-sheet) наезжает
   на него при скролле — эффект VK Музыки без хаков. */
.home-hero {
    position: sticky;
    top: 0;
    z-index: 0;
    flex-shrink: 0;
    width: 100%;
    height: clamp(320px, 50vh, 520px);
    overflow: hidden;
    isolation: isolate;
    /* Цвет приложения: в него растворяется фото при скролле (и в него же
       уходит растушёвка шторки) — бесшовно в обеих темах. */
    background-color: var(--bg-app);
}

@media (min-width: 768px) {
    .home-hero {
        height: clamp(360px, 54vh, 600px);
    }
}

/* Mobile: hero полноширинный и уходит под плавающую шапку-оверлей
   (.shell-mobile-header-host). Профиль + табы фростед-стеклом лежат поверх
   видео, как в VK Музыке. */
@media (max-width: 767.98px) {
    /* VK-стиль: профиль и табы лежат ПОВЕРХ видео-арта. Фростед-подложка шапки
       (::after, тинт под цвет фона) проявляется по мере морфа (--hm), а у
       самого верха прозрачна — арт виден насквозь. Легибельность контролов
       сверху обеспечивает собственный scrim hero. */
    .app-root[data-page-key='home'] .shell-mobile-header-host::after {
        opacity: var(--hm, 0);
    }
}

.home-hero__stage {
    position: absolute;
    inset: 0;
    /* Без параллакса: фото просто растворяется в фон по ходу прокрутки. */
    opacity: calc(1 - var(--home-progress, 0));
}

.home-hero__slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 600ms var(--motion-ease-standard);
    pointer-events: none;
}

.home-hero__slide.is-active {
    opacity: 1;
    pointer-events: auto;
}

.home-hero__media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Anchor the visible window toward the upper third of the source so that
       the subject (typically framed near source center) renders lower in the
       hero — clear of the menu/scrim at the top. Same value on every breakpoint
       so the framing is identical on desktop and mobile. */
    object-position: center 25%;
    display: block;
}

.home-hero__scrim {
    position: absolute;
    inset: 0;
    background:
        linear-gradient(180deg, transparent 36%, var(--overlay-pill-bg-strong) 100%),
        linear-gradient(180deg, var(--overlay-pill-bg-soft) 0%, transparent 34%);
    pointer-events: none;
}

/* padding-bottom держит копию ВЫШЕ растушёвки шторки (зона тумана —
   нижние ~6.25rem hero: overlap 1.75 + feather 4.5);
   padding-right (мобайл) — клиренс под круглую CTA на строке заголовка. */
.home-hero__content {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    padding: 1.25rem 4.75rem 4.5rem 1.25rem;
    opacity: calc(1 - var(--hero-out, 0));
    transition: opacity 200ms linear;
    pointer-events: none;
}

@media (min-width: 768px) {
    .home-hero__content {
        padding: 2rem 6.5rem 5rem 2.25rem;
    }
}

.home-hero__copy {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: inherit;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.65rem;
    max-width: 34rem;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 500ms var(--motion-ease-standard), transform 500ms var(--motion-ease-standard);
    pointer-events: none;
}

.home-hero__copy.is-active {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.home-hero__eyebrow {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--primary-500);
    font-weight: var(--font-weight-semibold);
    /* Overlay-контекст: тень для легибельности лайма над фото. */
    text-shadow: 0 1px 8px rgba(0, 0, 0, 0.45);
}

.home-hero__title {
    font-size: clamp(2.1rem, 5.5vw, 3.4rem);
    font-weight: 700;
    line-height: 1.04;
    letter-spacing: -0.01em;
    text-wrap: balance;
    color: var(--overlay-text);
    margin: 0;
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
}

/* Круглая стрелка-CTA — аффорданс кликабельного баннера (как на референсе):
   стеклянный круг с лаймовым кольцом-свечением на строке заголовка. Верх не
   трогаем — там шапка. bottom — от геометрии шва, выше плотной растушёвки.
   Сам переход — tap-nav по всему hero. */
.home-hero__cta {
    position: absolute;
    right: var(--shell-mobile-gutter, 0.75rem);
    /* Центр стрелки — на строке заголовка, выше зоны растушёвки. */
    bottom: calc(var(--home-sheet-overlap, 1.75rem) + 2.4rem);
    z-index: 3;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.25rem;
    height: 3.25rem;
    border-radius: var(--radius-pill);
    font-size: 1.35rem;
    color: var(--primary-500);
    background: var(--overlay-control-bg);
    -webkit-backdrop-filter: blur(var(--blur-lg));
    backdrop-filter: blur(var(--blur-lg));
    box-shadow: var(--ring-accent-strong), var(--glow-accent-soft);
    /* Затухает вместе с контентом hero при скролле (сегмент --hero-out). */
    opacity: calc(1 - var(--hero-out, 0));
    pointer-events: auto;
    transition: background-color var(--transition), color var(--transition),
                box-shadow var(--transition), opacity 200ms linear;
}

@media (hover: hover) {
    .home-hero__cta:hover {
        background: var(--primary-500);
        color: var(--primary-text);
        box-shadow: var(--ring-accent-strong), var(--glow-accent-strong);
    }
}

@media (min-width: 768px) {
    .home-hero__cta {
        right: 2.25rem;
        bottom: calc(var(--home-sheet-overlap, 1.75rem) + 2.9rem);
    }
}

/* Дотсы — между заголовком и швом, выше плотной части растушёвки;
   затухают вместе с hero. */
.home-hero__dots {
    position: absolute;
    left: 0;
    right: 0;
    bottom: calc(var(--home-sheet-overlap, 1.75rem) + 1.6rem);
    display: flex;
    justify-content: center;
    gap: 0.4rem;
    padding: 0 1rem;
    z-index: 2;
    opacity: calc(1 - var(--hero-out, 0));
    transition: opacity 200ms linear;
}

.home-hero__dot {
    width: 22px;
    height: 3px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--overlay-text) 40%, transparent);
    transition: width 300ms var(--motion-ease-standard), background-color 300ms var(--motion-ease-standard);
    cursor: pointer;
    border: none;
    padding: 0;
}

.home-hero__dot.is-active {
    width: 34px;
    background: var(--primary-500);
}

/* ── «Шторка»: лист наезжает на видео; край — растушёвка (::before/::after),
   а не жёсткое скругление с тенью. ── */
.home-sheet {
    position: relative;
    z-index: 1;
    flex-shrink: 0;
    margin-top: calc(-1 * var(--home-sheet-overlap, 1.75rem));
    padding: 1.25rem 0 2.5rem;
    background: var(--bg-app);
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

/* Растушёвка края: полоса над листом едет вместе со шторкой поверх фото.
   Намеренно ЧИСТЫЙ градиент без backdrop-blur — как на референсе, и контролы
   hero в зоне шва (дотсы, CTA) остаются чёткими; blur здесь к тому же дорог
   при скролле. Сглаженные остановки (~smoothstep) убирают видимую «ступень». */
.home-sheet::before {
    content: '';
    position: absolute;
    top: calc(-1 * var(--home-feather-h, 4.5rem));
    left: 0;
    right: 0;
    height: var(--home-feather-h, 4.5rem);
    pointer-events: none;
    background: linear-gradient(to bottom,
        transparent 0%,
        color-mix(in srgb, var(--bg-app) 12%, transparent) 22%,
        color-mix(in srgb, var(--bg-app) 38%, transparent) 46%,
        color-mix(in srgb, var(--bg-app) 72%, transparent) 70%,
        var(--bg-app) 100%);
}

/* Уплотнитель растушёвки: к концу прокрутки (сегмент --sheet-densify) край
   становится плотнее — фото под краем гасится раньше. Только opacity. */
.home-sheet::after {
    content: '';
    position: absolute;
    top: calc(-1 * var(--home-feather-h, 4.5rem));
    left: 0;
    right: 0;
    height: var(--home-feather-h, 4.5rem);
    pointer-events: none;
    background: linear-gradient(to bottom, transparent 0%, var(--bg-app) 70%);
    opacity: var(--sheet-densify, 0);
}

/* ── Секция ── */
.home-section {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.home-section__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding-inline: var(--app-gutter-x);
}

/* Заголовки секций — uppercase-кикеры в языке плиток (.tile__label). */
.home-section__title {
    font-size: var(--text-base);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-main);
    margin: 0;
}

.home-section__more {
    flex-shrink: 0;
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    text-decoration: none;
    transition: color var(--transition-fast);
}

.home-section__more:hover {
    color: var(--primary-500);
}

/* Горизонтальный ряд со snap; боковые отступы = gutter (скроллбар скрыт через
   утилиту .custom-scrollbar в разметке). */
.home-section__rail {
    display: flex;
    gap: 0.75rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--app-gutter-x);
    padding-inline: var(--app-gutter-x);
    padding-bottom: 0.25rem;
}

.home-section__rail > * {
    scroll-snap-align: start;
    flex: 0 0 auto;
}

/* ── Карточка «Продолжить» ── */
.home-continue-card {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    width: 15rem;
    padding: 0.95rem 1.05rem;
    background: var(--bg-elevated);
    border-radius: var(--radius-xl);
    box-shadow: inset 0 0 0 1px var(--text-main-5);
    color: var(--text-main);
    text-decoration: none;
    transition: transform var(--transition-fast), background-color var(--transition-fast);
}

.home-continue-card:hover {
    transform: translateY(-2px);
    background: var(--bg-raised);
}

/* Шапка: иконка модели + имя + capability-чипы («модель и её параметры»). */
.home-continue-card__head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.home-continue-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    flex-shrink: 0;
    border-radius: var(--radius-pill);
    background: var(--surface-soft);
    box-shadow: var(--ring-accent-soft);
    color: var(--primary-icon);
    font-size: 1.1rem;
}

.home-continue-card__logo {
    display: block;
    width: 1.1rem;
    height: 1.1rem;
}

.home-continue-card__model {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: var(--font-weight-semibold);
    font-size: var(--text-xs);
    color: var(--text-main);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.home-continue-card__chips {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    flex-shrink: 0;
}

.home-continue-card__chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: var(--radius-pill);
    background: var(--surface-soft);
    color: var(--text-muted);
    font-size: 0.8rem;
}

.home-continue-card__title {
    font-weight: var(--font-weight-semibold);
    font-size: var(--text-sm);
    color: var(--text-main);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.home-continue-card__preview {
    font-size: var(--text-xs);
    color: var(--text-muted);
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ── Карточка ассистента ── */
.home-assistant-card {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    width: 13.5rem;
    padding: 1rem 1.1rem 1.15rem;
    background: var(--bg-elevated);
    border-radius: var(--radius-xl);
    box-shadow: inset 0 0 0 1px var(--text-main-5);
    color: var(--text-main);
    text-decoration: none;
    transition: transform var(--transition-fast), background-color var(--transition-fast);
}

.home-assistant-card:hover {
    transform: translateY(-2px);
    background: var(--bg-raised);
}

.home-assistant-card__avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--radius-pill);
    overflow: hidden;
    background: var(--surface-soft);
    box-shadow: var(--ring-accent-soft);
    color: var(--primary-text);
    font-size: 1.35rem;
}

.home-assistant-card__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.home-assistant-card__name {
    font-weight: var(--font-weight-semibold);
    font-size: var(--text-sm);
    color: var(--text-main);
}

.home-assistant-card__desc {
    font-size: var(--text-xs);
    color: var(--text-muted);
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ── Галерея сгенерированных материалов (masonry) ──
   Зеркалит раскладку .sidebar-generation-feed.is-image: grid из N flex-колонок,
   число колонок (--home-gallery-columns) homeShell считает по ширине. Высоту
   плитки задаёт inline aspect-ratio из params генерации. */
.home-gallery {
    display: grid;
    grid-template-columns: repeat(var(--home-gallery-columns, 2), minmax(0, 1fr));
    gap: 0.1875rem;
    align-items: start;
    /* Скругление — на контейнере: overflow:hidden клипует крайние фото по внешним
       углам, а сами фото — без скруглений (минимальный зазор между ними). Gutter —
       через margin, чтобы контейнер обнимал фото вплотную (иначе радиус не режет). */
    margin-inline: var(--app-gutter-x);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

/* Бесконечная лента: невидимый sentinel ловит низ галереи, спиннер — на время
   догрузки следующей страницы (homeShell._loadMoreGallery). */
.home-gallery__sentinel {
    height: 1px;
}

.home-gallery__loading {
    display: flex;
    justify-content: center;
    padding: 1rem 0;
    color: var(--text-muted);
}

.home-gallery__spinner {
    font-size: 1.25rem;
    animation: loading-spinner-rotate 0.9s linear infinite;
}

.home-gallery__column {
    display: flex;
    flex-direction: column;
    gap: 0.1875rem;
    min-width: 0;
}

.home-gallery-card {
    position: relative;
    width: 100%;
    padding: 0;
    border: none;
    /* Скругления нет — их даёт контейнер .home-gallery (overflow:hidden) только по
       крайним фото. transform-hover убран: на плотной сетке с клипом контейнера он
       перекрывал соседей и обрезался по краю. Ховер — мягкая яркость. */
    border-radius: 0;
    overflow: hidden;
    background: var(--bg-elevated);
    cursor: pointer;
    transition: filter var(--transition-fast);
}

@media (hover: hover) {
    .home-gallery-card:hover {
        filter: brightness(1.08);
    }
}

.home-gallery-card__media {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.home-gallery-card__badge {
    position: absolute;
    bottom: 0.4rem;
    right: 0.4rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: var(--radius-pill);
    background: var(--overlay-pill-bg);
    color: var(--overlay-text);
    font-size: 0.8rem;
}

/* ── Инструменты: сетка плиток (.tile--quick) ── */
.home-tools {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.85rem;
    padding-inline: var(--app-gutter-x);
}

@media (min-width: 768px) {
    .home-tools {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* ── Морф мобильной шапки на главной (scroll-linked, сегмент --hm 0→1).
   Финал — ОДИН консистентный ряд: меню-пилюля слева + кружок-аватар справа
   той же высоты. Хореография: табы поднимаются на строку брэнда (по центру
   пилюли профиля) и подбирают правый край, освобождая место аватару; брэнд
   растворяется ПОД приехавшим меню (табы выше по z); у пилюли профиля
   схлопывается баланс (остаётся только картинка) и она подрастает до высоты
   меню (transform scale). Шапка — absolute-оверлей: морф не трогает layout
   страницы (внутренние max-width/margin пересчитывают только сам оверлей). */
@media (max-width: 767.98px) {
    /* Высота меню-пилюли (= padding табов + строка text-lg при lh 1.5) и
       коэффициент подроста пилюли профиля (tabs-h / 2.6rem - 1). */
    .app-root[data-page-key='home'] {
        --shell-tabs-h: 3.45rem;
        --shell-pill-grow: 0.33;
    }

    /* В свёрнутом состоянии опускаем ряд «меню + профиль» ниже от верхнего края —
       больше воздуха сверху. Растёт по ходу морфа (--hm); добавка к общему
       padding'у хоста сдвигает И табы, И пилюлю одинаково (выравнивание не рвём). */
    .app-root[data-page-key='home'] .shell-mobile-header-host {
        padding-block-start: calc(env(safe-area-inset-top, 0px) + 0.55rem + var(--hm, 0) * 0.4rem);
    }

    /* Брэнд тает в первые ~60% хода и уходит под меню (без z — табы выше). */
    .app-root[data-page-key='home'] .shell-mobile-header-brand {
        opacity: calc(1 - clamp(0, calc(var(--hm, 0) * 1.6), 1));
        transform: scale(calc(1 - var(--hm, 0) * 0.15));
        transform-origin: left center;
    }
    .app-root[data-page-key='home'].is-home-collapsed .shell-mobile-header-brand {
        pointer-events: none;
    }

    /* Табы: вверх до ОДНОЙ высоты с пилюлей профиля. Сдвиг считается по геометрии,
       а не магической константой: центр табов совмещаем с центром пилюли. Верхний
       ряд высотой --shell-header-slot (бренд = пилюля), его центр на slot/2 от верха;
       табы лежат ниже на (slot + gap 0.55rem), их центр — ещё на tabs-h/2 ниже.
       Итого подъём = slot/2 + 0.55rem + tabs-h/2 → ряд встаёт ровно (без отрыва
       пилюли от верха при упёртых в край табах). Поджатие справа — аватар в ряд. */
    .app-root[data-page-key='home'] .shell-mobile-header .shell-tabs {
        position: relative;
        z-index: 1;
        transform: translateY(calc(var(--hm, 0) * (var(--shell-header-slot) / 2 + 0.55rem + var(--shell-tabs-h) / 2) * -1));
        margin-right: calc(var(--hm, 0) * (var(--shell-tabs-h) + 0.5rem));
    }

    .app-root[data-page-key='home'] .shell-mobile-header-top {
        position: relative;
        pointer-events: none;   /* прозрачный ряд не должен глушить тапы по табам */
    }
    .app-root[data-page-key='home'] .shell-mobile-header-top > * {
        pointer-events: auto;
    }

    /* Пилюля профиля: стекло в обоих состояниях (над hero-артом и над тинтом
       свёрнутой шапки, тема флипает сама); к концу морфа подрастает до высоты
       меню — финальный ряд одной высоты. */
    .app-root[data-page-key='home'] .shell-mobile-header-top :is(.shell-user-pill, .shell-user-pill--standalone) {
        position: relative;
        z-index: 2;
        background: var(--chat-input-bg);
        -webkit-backdrop-filter: blur(var(--blur-lg));
        backdrop-filter: blur(var(--blur-lg));
        transform: scale(calc(1 + var(--hm, 0) * var(--shell-pill-grow)));
        transform-origin: right center;
    }

    /* Баланс схлопывается — от профиля остаётся только аватар (пилюля → круг;
       overflow: hidden у пилюли прячет текст по ходу). Старт — от натуральной
       ширины текста (--pill-balance-w меряет homeShell._measurePillBalance),
       поэтому контейнер худеет линейно с первого пикселя хода, а не в конце. */
    .app-root[data-page-key='home'] .shell-user-pill__balance {
        max-width: calc((1 - var(--hm, 0)) * var(--pill-balance-w, 9rem));
        padding-left: calc((1 - var(--hm, 0)) * 0.75rem);
        padding-right: calc((1 - var(--hm, 0)) * 0.4rem);
        opacity: calc(1 - clamp(0, calc(var(--hm, 0) * 1.8), 1));
    }
}

/* Узкие экраны: табы компактнее (см. медиа 480 у .shell-tab) — пересчёт цели. */
@media (max-width: 480px) {
    .app-root[data-page-key='home'] {
        --shell-tabs-h: 3.02rem;
        --shell-pill-grow: 0.16;
    }
}

/* ── Entry-каскад главной: секции шторки и плитки поднимаются волной.
   --enter-i проставлен в разметке (плитки 1–4, секции 2–4); backwards-fill
   держит отложенные элементы невидимыми до старта. При Unpoly-навигации main
   пересоздаётся — каскад честно повторяется. Догружаемые карточки галереи
   не затрагивает (анимируются только корни секций и плитки). */
@keyframes home-rise {
    from {
        opacity: 0;
        transform: translateY(14px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

.home-sheet > .home-section,
.home-tools .tile {
    animation: home-rise var(--motion-duration-slow) var(--motion-ease-premium) backwards;
    animation-delay: calc(var(--enter-i, 0) * var(--motion-stagger-step) * 2);
}

@media (prefers-reduced-motion: reduce) {
    .home-sheet > .home-section,
    .home-tools .tile {
        animation: none;
    }

    .home-hero__stage,
    .home-hero__slide,
    .home-hero__copy,
    .home-hero__content,
    .home-hero__dots,
    .home-hero__cta,
    .tile,
    .home-continue-card,
    .home-assistant-card,
    .home-gallery-card {
        transition: none !important;
    }
}

/* Voice recording glow.
   Sized to stay within the composer's horizontal footprint: <main> has
   `overflow: hidden` (required for sticky composer + messages scroll
   container), which would clip any lateral overflow against the rail /
   history sidebar edge. Vertical inset is generous because that direction
   is not clipped by an ancestor at the bottom. The 52px blur softens the
   sides naturally without needing to reach past the composer. */
.chat-input-state-host::before,
.media-composer-shell::before,
.gen-loading::before {
    content: '';
    position: absolute;
    inset: -10rem 0 -4.5rem;
    border-radius: 38% 62% 54% 46% / 42% 34% 66% 58%;
    background-image:
        conic-gradient(from 132deg at 48% 58%,
            transparent 0deg,
            color-mix(in srgb, var(--primary-500) 48%, transparent) 38deg,
            transparent 88deg,
            color-mix(in srgb, var(--accent-cool) 32%, transparent) 148deg,
            transparent 212deg,
            color-mix(in srgb, var(--primary-600) 42%, transparent) 286deg,
            transparent 360deg),
        radial-gradient(ellipse 68% 22% at 18% 54%,
            color-mix(in srgb, var(--primary-500) 50%, transparent) 0%,
            transparent 72%),
        radial-gradient(ellipse 58% 20% at 78% 46%,
            color-mix(in srgb, var(--accent-cool) 32%, transparent) 0%,
            transparent 70%),
        linear-gradient(104deg,
            transparent 12%,
            color-mix(in srgb, var(--primary-500) 30%, transparent) 32%,
            transparent 48%,
            color-mix(in srgb, var(--gradient-warm) 22%, transparent) 62%,
            color-mix(in srgb, var(--accent-cool) 26%, transparent) 76%,
            transparent 92%);
    background-size: 170% 160%, 122% 112%, 130% 116%, 180% 140%;
    background-position: 0% 52%, 7% 58%, 92% 42%, 100% 48%;
    filter: blur(52px) saturate(1.15);
    opacity: 0;
    pointer-events: none;
    transform: translate3d(0, 0.85rem, 0) scale(0.96) rotate(-2deg);
    transform-origin: 50% 100%;
    transition: opacity var(--motion-duration-shell) var(--motion-ease-standard);
    contain: paint;
    z-index: 0;
}

.chat-input-state-host.is-recording::before,
.media-composer-shell.is-recording::before {
    opacity: calc(0.55 + 0.45 * var(--voice-level, 0));
    transform: translate3d(0, 0.85rem, 0)
               scale(calc(0.96 + 0.06 * var(--voice-level, 0)))
               rotate(-2deg);
    filter: blur(calc(52px - 12px * var(--voice-level, 0))) saturate(calc(1.15 + 0.25 * var(--voice-level, 0)));
    transition: opacity 90ms linear, transform 120ms linear, filter 120ms linear;
    animation: chat-input-gradient-flow 9s ease-in-out infinite;
}

@keyframes chat-input-gradient-flow {
    0%   { background-position: 0% 52%, 7% 58%, 92% 42%, 100% 48%; }
    50%  { background-position: 100% 48%, 93% 42%, 8% 58%, 0% 52%; }
    100% { background-position: 0% 52%, 7% 58%, 92% 42%, 100% 48%; }
}

@media (prefers-reduced-motion: reduce) {
    .chat-input-state-host.is-recording::before,
    .media-composer-shell.is-recording::before,
    .gen-loading::before {
        animation: none;
    }

    .gen-loading--chat .gen-loading__media {
        transition: opacity 0.15s linear;
        transform: none;
        filter: none;
    }

    .composer-state-switch > .composer-state-layer {
        transition: none;
    }

    .voice-recording-title {
        animation: none;
    }
}

/* ════════════════════════════════════════════════════════════════
   GENERATION LOADING — переливающийся плейсхолдер ожидания генерации.
   Переиспользует рецепт градиента voice-recording и chat-input-gradient-flow.
   ════════════════════════════════════════════════════════════════ */
.gen-loading {
    position: relative;
    width: 100%;
    min-height: 9rem;            /* запас, когда aspect-ratio не задан (чат) */
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;            /* клипуем размытый ::before внутри скруглений */
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--bg-elevated) 55%, transparent);
    isolation: isolate;
}

/* Мягкое свечение (always-on; voice реагирует на --voice-level, тут — медленное
   «дыхание» яркости вместо реакции на громкость). Низкая непрозрачность +
   большое размытие дают лёгкий, воздушный эффект как при записи голоса. */
.gen-loading::before {
    inset: -25% -12%;
    border-radius: 0;
    opacity: 0.45;
    filter: blur(56px) saturate(1.05);
    transform: none;
    animation: chat-input-gradient-flow 9s ease-in-out infinite,
               gen-loading-breathe 3.6s ease-in-out infinite;
}

@keyframes gen-loading-breathe {
    0%, 100% { opacity: 0.34; }
    50%      { opacity: 0.58; }
}

.gen-loading__label {            /* + класс .voice-recording-title в разметке */
    position: relative;
    z-index: 1;
    text-align: center;
    padding: 0 1rem;
}

/* Модификатор: плитка боковой галереи — квадратные углы как у фреймов; высоту
   задаёт aspect-кадр (для completed), а для processing — правило .is-placeholder. */
.gen-loading--thumb { border-radius: 0; min-height: 0; }
.gen-loading--thumb .gen-loading__label { font-size: var(--text-xs); white-space: normal; }

/* Модификатор: крошечная плитка нижней ленты — только перелив, без текста. */
.gen-loading--bare {
    min-height: 0;
    height: 100%;
    border-radius: inherit;
}
.gen-loading--bare::before { filter: blur(16px) saturate(1.05); }

/* ── Reveal: результат проявляется поверх свечения ──
   Свечение остаётся фоном кадра, медиа фейдится поверх по факту загрузки
   (@load / @loadeddata добавляет .is-loaded на контейнер). Нет пустого бокса. */
.gen-loading__media {
    position: relative;
    z-index: 1;
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 70vh;
    border-radius: inherit;
    opacity: 0;
    transition: opacity 0.55s var(--motion-ease-standard);
}
.gen-loading.is-loaded .gen-loading__media { opacity: 1; }

/* Свечение гаснет, когда медиа загрузилось (transition берётся из общего рецепта). */
.gen-loading.is-loaded::before { opacity: 0; animation: none; }

/* Чат: без рамки/поверхности — только свечение и надпись на фоне; фото резко
   проявляется, трансформируясь из свечения (масштаб + уход размытия). */
.gen-loading--chat {
    background: transparent;
    overflow: visible;       /* свечение свободно растекается в чат, без рамки контейнера */
}
/* Свечение выходит за пределы полосы и мягко угасает к краям (эллиптическая
   маска вынесена в общий рецепт с просмотром, см. .media-viewer__loading),
   поэтому прямоугольной границы контейнера не видно. */
.gen-loading--chat::before {
    inset: -45% -15%;
}
.gen-loading--chat .gen-loading__media {
    transform: scale(0.94);
    filter: blur(10px);
    transition: opacity 0.22s ease-out,
                transform 0.32s cubic-bezier(0.2, 0.85, 0.25, 1.1),
                filter 0.32s ease-out;
}
.gen-loading--chat.is-loaded .gen-loading__media {
    transform: scale(1);
    filter: blur(0);
}
/* После загрузки контейнер сжимается ровно по фото (слева), без пустых полей —
   бокс = картинка, кнопки садятся в её угол. */
.gen-loading--chat.is-loaded {
    display: inline-block;
    min-height: 0;
    vertical-align: top;
}

/* ════════════════════════════════════════════════════════════════
   LEGAL PAGES (/policy, /privacy)
   ════════════════════════════════════════════════════════════════ */
.legal-page {
    position: relative;
    z-index: 1;
    flex: 1 1 0%;
    min-height: 0;
    width: 100%;
    background: var(--bg-app);
    color: var(--text-main);
    overflow-y: auto;
}

.legal-page__header {
    display: flex;
    align-items: center;
    padding: 1rem 2.5rem;
    background: transparent;
}

.legal-page__brand {
    display: inline-flex;
    align-items: center;
    color: var(--text-main);
    text-decoration: none;
    transition: color var(--transition);
}

.legal-page__brand:hover {
    color: var(--primary-500);
}

.legal-page__brand-icon {
    width: var(--brand-logo-size);
    height: var(--brand-logo-size);
    display: block;
}

.legal-page__article {
    width: 100%;
    padding: 2rem 2.5rem 6rem;
    line-height: 1.65;
    font-size: 0.95rem;
}

.legal-page__article h1 {
    font-family: var(--font-display);
    font-size: 1.75rem;
    line-height: 1.25;
    font-weight: var(--font-weight-bold);
    margin-bottom: 0.5rem;
}

.legal-page__article h2 {
    font-family: var(--font-display);
    font-size: 1.25rem;
    line-height: 1.3;
    font-weight: var(--font-weight-bold);
    margin: 2.25rem 0 1rem;
    color: var(--text-main);
}

.legal-page__article p {
    margin: 0 0 0.65rem;
    color: var(--text-secondary);
}

.legal-page__article p b,
.legal-page__article p strong {
    color: var(--text-main);
    font-weight: var(--font-weight-semibold);
}

.legal-page__article a {
    color: var(--primary-500);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.legal-page__article a:hover {
    color: var(--text-main);
}

.legal-page__meta {
    color: var(--text-subtle);
    font-size: 0.8125rem;
    margin-bottom: 2rem !important;
}

@media (max-width: 640px) {
    .legal-page__header {
        padding: 0.85rem 1.25rem;
    }
    .legal-page__article {
        padding: 1.5rem 1.25rem 5rem;
        font-size: 0.9rem;
    }
    .legal-page__article h1 {
        font-size: 1.45rem;
    }
    .legal-page__article h2 {
        font-size: 1.1rem;
    }
}

/* ════════════════════════════════════════════════════════════════
   COOKIE CONSENT BANNER
   ════════════════════════════════════════════════════════════════ */
.cookie-banner {
    position: fixed;
    left: 50%;
    bottom: 1rem;
    transform: translate(-50%, calc(100% + 2rem));
    width: min(36rem, calc(100vw - 1.5rem));
    z-index: 9999;
    color: var(--text-main);
    border: 1px solid var(--surface-soft);
    transition: transform 0.3s var(--motion-ease-premium, ease-out);
}

.cookie-banner--visible {
    transform: translate(-50%, 0);
}

.cookie-banner__inner {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.85rem 1rem;
    flex-wrap: wrap;
}

.cookie-banner__text {
    flex: 1 1 16rem;
    margin: 0;
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--text-secondary);
}

.cookie-banner__link {
    color: var(--primary-500);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.cookie-banner__accept {
    flex: 0 0 auto;
    padding: 0.55rem 1.1rem;
    border-radius: 999px;
    border: none;
    background: var(--text-main);
    color: var(--bg-app);
    font-size: 0.85rem;
    font-weight: var(--font-weight-semibold);
    cursor: pointer;
    transition: opacity var(--transition);
}

.cookie-banner__accept:hover {
    opacity: 0.85;
}

@media (max-width: 480px) {
    .cookie-banner__inner {
        padding: 0.75rem 0.85rem;
    }
    .cookie-banner__accept {
        flex: 1 0 100%;
    }
}

/* PWA splash overlay (markup всегда в DOM, см. _app_splash.html) — здесь
   только дефолтный off-state. Все активные стили живут в pwa.css, который
   подключается условно через media="(display-mode: standalone), ...". */
.app-splash {
    display: none;
}

/* ════════════════════════════════════════════════════════════════
   СЦЕНАРИИ (/workflows) — нод-редактор.
   Канвас — vendored Drawflow (css/vendor/drawflow.min.css задаёт только
   механику/геометрию), здесь его темизация токенами ядра + layout страницы.
   ════════════════════════════════════════════════════════════════ */

/* ── Сайдбар-список (анатомия и поверхности — как строки истории чатов) ── */
.wf-side-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.625rem 0.75rem;
    border-radius: var(--radius-xl);
    background: var(--bg-hover);
    cursor: pointer;
    transition: background-color var(--transition);
}

@media (hover: hover) {
    .wf-side-item:hover {
        background: var(--bg-input);
    }
}

.wf-side-item.is-active {
    background: var(--bg-input);
}

/* Мобайл: списки историй (чаты/транскрипция/сценарии) — полноэкранный экран без
   сплит-вида. Активный элемент НЕ подсвечиваем: иначе после открытия и возврата
   «назад» прошлый пункт остаётся гореть как активный. На десктопе подсветка нужна
   (виден сплит), поэтому правило только под мобильным брейкпоинтом. */
@media (max-width: 767.98px) {
    .tg-chat-row.bg-bg-input { background-color: var(--bg-hover); }
    .wf-side-item.is-active { background: transparent; }
}

.wf-side-item__icon {
    width: 2.75rem;
    height: 2.75rem;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--bg-elevated);
    color: var(--text-muted);
}

.wf-side-item__body {
    min-width: 0;
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.wf-side-item__name {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-main);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wf-side-item__meta {
    font-size: var(--text-xs);
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Индикатор автозапуска: точка primary, выключен — прозрачная. */
.wf-side-item__dot {
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    flex-shrink: 0;
    background: transparent;
}

.wf-side-item__dot.is-on {
    background: var(--primary-500);
}

.wf-side-item__menu {
    opacity: 0;
    transition: opacity var(--transition);
}

.wf-side-item:hover .wf-side-item__menu,
.wf-side-item.is-active .wf-side-item__menu {
    opacity: 1;
}

@media (hover: none) {
    .wf-side-item__menu {
        opacity: 1;
    }
}

.wf-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex-shrink: 0;
    padding: 0.15rem 0.6rem;
    border-radius: var(--radius-pill);
    background: var(--surface-soft);
    color: var(--text-muted);
    font-size: var(--text-2xs);
    white-space: nowrap;
}

/* Бейдж статуса прогона в строке тулбара — глассовый, в высоту кластеров.
   Должен идти ДО --active: у запущенного рана primary-заливка поверх гласса. */
.wf-badge--float {
    height: 2.75rem;
    padding-inline: 0.9rem;
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    box-shadow: var(--shadow-glass);
}

.wf-badge--active {
    background: var(--primary-14);
    color: var(--primary-icon);
}

/* ── Layout редактора: канвас = фон страницы, всё управление — overlay ── */
.wf-editor {
    position: relative;
    flex: 1;
    min-height: 0;
}

/* Канвас без обёртки-контейнера: точечная сетка прямо на фоне страницы,
   под глассовыми панелями сайдбаров; тулбар и панели плавают поверх. */
.wf-canvas-host {
    position: absolute;
    inset: 0;
    background-image: radial-gradient(var(--surface-soft) 1px, transparent 1px);
    background-size: 22px 22px;
}

/* Тулбар-оверлей: глассовые кластеры в одну линию с кнопкой «Нод» внутри канваса.
   pointer-events только на кластерах — пустые зоны строки не перехватывают канвас. */
.wf-topbar {
    position: absolute;
    top: 0.75rem;
    left: 0.75rem;
    right: 0.75rem;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    pointer-events: none;
}

.wf-topbar > * {
    pointer-events: auto;
}

/* Desktop: по углам absolute-оверлей shell-desktop-header (слева шеврон панели,
   справа пилюля профиля) — выравниваемся по его строке и не заезжаем под пилюли. */
@media (min-width: 768px) {
    .wf-topbar {
        top: 0.6rem;
        left: 4rem;
        right: 13rem;
    }
}

.wf-top-group {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem;
    border-radius: var(--radius-pill);
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    box-shadow: var(--shadow-glass);
}

/* Кнопки внутри глассового кластера — прозрачные круги (рецепт shell-desktop-header__toggle). */
.wf-top-group .btn-ghost {
    background-color: transparent;
    border-radius: var(--radius-pill);
}

@media (hover: hover) {
    .wf-top-group .btn-ghost:hover {
        background-color: var(--surface-soft);
    }
}

.wf-top-group .btn-ghost:disabled {
    background-color: transparent;
}

/* Зум-кластер канваса — глассовая пилюля в правом нижнем углу
   (на мобилке поднята над кнопкой «Запустить»). */
.wf-zoom {
    position: absolute;
    right: 0.75rem;
    bottom: 0.75rem;
    z-index: 10;
}

@media (max-width: 767.98px) {
    .wf-zoom {
        bottom: calc(env(safe-area-inset-bottom, 0px) + 4.4rem);
    }
}

/* AI-ассистент: плавающая панель-промпт у нижнего края канваса (по центру),
   глассовый стиль как у .wf-panel. */
.wf-assistant {
    position: absolute;
    left: 50%;
    bottom: 0.75rem;
    transform: translateX(-50%);
    z-index: 12;
    width: min(34rem, calc(100% - 1.5rem));
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.85rem 1rem;
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    box-shadow: var(--shadow-glass);
    border-radius: var(--radius-lg);
}

.wf-assistant__head {
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

.wf-assistant__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

/* Чип-контрол связи: шестерёнка ПОСТОЯННО видна в середине каждой линии
   (живёт внутри precanvas — пан/зум отслеживает его transform). */
.wf-edge-chip {
    position: absolute;
    transform: translate(-50%, -50%);
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.65rem;
    height: 1.65rem;
    border-radius: var(--radius-md);
    background: var(--bg-elevated);
    box-shadow: var(--shadow-icon);
    color: var(--text-subtle);
    font-size: 0.85rem;
    cursor: pointer;
    transition: color var(--transition), box-shadow var(--transition);
}

.wf-edge-chip:hover {
    color: var(--primary-icon);
    box-shadow: var(--shadow-surface);
}

/* Штрих-кривая сцепки при перетаскивании нода («отпусти — соединю»):
   форма как у связей Drawflow, бегущий пунктир. */
.wf-snap-line {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 9;
    display: none;
    overflow: visible;
}

.wf-snap-line path {
    fill: none;
    stroke: var(--primary-500);
    stroke-width: 2.5px;
    stroke-dasharray: 7 6;
    stroke-linecap: round;
    opacity: 0.85;
    animation: wf-snap-dash 0.5s linear infinite;
}

@keyframes wf-snap-dash {
    to { stroke-dashoffset: -13; }
}

/* Кнопка вставки переменной у шаблонизируемых полей панели нода. */
.wf-field__label--row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.wf-var-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: var(--radius-md);
    color: var(--text-subtle);
    transition: color var(--transition), background-color var(--transition);
}

.wf-var-btn:hover {
    color: var(--text-main);
    background: var(--surface-soft);
}

/* Секретный URL вебхука в панели параметров. */
.wf-webhook-url {
    display: block;
    padding: 0.5rem 0.75rem;
    border-radius: var(--radius-md);
    background: var(--surface-soft);
    font-size: var(--text-2xs);
    color: var(--text-muted);
    word-break: break-all;
}

/* Точка несохранённых изменений на кнопке «Сохранить». */
.wf-dirty-dot {
    position: absolute;
    top: 0.3rem;
    right: 0.3rem;
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background: var(--primary-500);
}

/* Кнопка добавления нода — глассовая пилюля в строке тулбара, меню — ctxMenu. */
.wf-canvas-add {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    height: 2.75rem;
    padding-inline: 1rem;
    border-radius: var(--radius-pill);
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    box-shadow: var(--shadow-glass);
    color: var(--text-main);
    transition: background-color var(--transition);
}

@media (hover: hover) {
    .wf-canvas-add:hover {
        background-color: var(--surface-strong);
    }
}

.wf-canvas-add i {
    color: var(--primary-icon);
}

.wf-settings__title {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    margin-bottom: 0.5rem;
}

.wf-settings__subtitle {
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    margin: 0.75rem 0 0.4rem;
}

.wf-field {
    display: block;
    margin-bottom: 0.75rem;
}

/* Чекбокс-поле: контрол и лейбл в одну строку. */
.wf-field--row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
}

.wf-field--row .wf-field__label {
    margin-bottom: 0;
}

.wf-field__label {
    display: block;
    font-size: var(--text-xs);
    color: var(--text-muted);
    margin-bottom: 0.3rem;
}

.wf-field__help {
    display: block;
    font-size: var(--text-2xs);
    color: var(--text-subtle);
    margin-top: 0.3rem;
}

/* Триггер-кнопка дропдауна (поля-селекты панели настроек) — поверх .input-field. */
.wf-select {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.wf-select__icon {
    width: 1.15rem;
    height: 1.15rem;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.wf-select__icon svg {
    width: 100%;
    height: 100%;
}

.wf-select__label {
    min-width: 0;
    flex: 1;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wf-hint {
    margin-top: 0.75rem;
    padding: 0.6rem 0.75rem;
    border-radius: var(--radius-md);
    background: var(--surface-soft);
    font-size: var(--text-2xs);
    color: var(--text-muted);
    line-height: 1.5;
    word-break: break-word;
}

.wf-hint--warn {
    background: var(--primary-10);
    color: var(--text-main);
}

.wf-hint__title {
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    margin-bottom: 0.2rem;
}

.wf-hint code {
    background: var(--bg-input);
    border-radius: var(--radius-sm);
    padding: 0 0.25rem;
}

/* ── Единая overlay-панель (настройки нода / параметры сценария / история):
   плавающая глассовая карточка поверх канваса (рецепт dropdown-panel). ── */
.wf-panel {
    position: absolute;
    top: 4rem;
    right: 0.75rem;
    bottom: 0.75rem;
    width: min(22rem, calc(100% - 1.5rem));
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    box-shadow: var(--shadow-glass);
    border-radius: var(--radius-lg);
    display: flex;
    flex-direction: column;
    z-index: 20;
}

.wf-panel__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem 0.25rem;
    flex-shrink: 0;
}

.wf-panel__head .wf-settings__title {
    margin-bottom: 0;
}

.wf-panel__body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 0.5rem 1rem 1rem;
}

/* Обёртка полей панели: fieldset, чтобы :disabled (read-only мобилка) нативно
   гасил все вложенные контролы. Сбрасываем юзер-агент стили. */
.wf-panel-fields {
    border: none;
    margin: 0;
    padding: 0;
    min-width: 0;
}

.wf-run-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.5rem 0.4rem;
    border-radius: var(--radius-md);
    text-align: left;
}

.wf-run-row:hover {
    background: var(--surface-soft);
}

/* Статусы — нейтральная палитра ядра (без красного/зелёного): активное —
   primary, остальное — поверхности; см. комментарий у --red-500. */
.wf-run-row__status {
    font-size: var(--text-2xs);
    padding: 0.1rem 0.5rem;
    border-radius: var(--radius-pill);
    background: var(--surface-soft);
    color: var(--text-muted);
    white-space: nowrap;
}

.wf-status--running { background: var(--primary-14); color: var(--primary-icon); }
.wf-status--succeeded { background: var(--surface-active); color: var(--text-main); }
.wf-status--failed { background: var(--text-main-6); color: var(--text-main); }

.wf-step {
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--surface-soft);
}

.wf-step__output {
    font-size: var(--text-2xs);
    color: var(--text-muted);
    margin-top: 0.25rem;
    white-space: pre-wrap;
    word-break: break-word;
}

/* Превью медиа-результата шага в истории запусков */
.wf-step__media {
    display: block;
    max-width: 100%;
    max-height: 220px;
    border-radius: var(--radius-base);
    margin-top: 0.35rem;
}

.wf-spin {
    animation: wf-spin 0.9s linear infinite;
}

@keyframes wf-spin {
    to { transform: rotate(360deg); }
}

/* ── Темизация Drawflow токенами ядра (без бордеров — заливка + тень,
   состояния — кольца box-shadow) ── */
.wf-canvas-host .drawflow .drawflow-node {
    background: var(--bg-elevated);
    border: none;
    border-radius: var(--radius-base);
    color: var(--text-main);
    width: 200px;
    min-height: 0;
    padding: 0;
    box-shadow: var(--shadow-surface);
    transition: box-shadow var(--motion-duration-fast) var(--motion-ease-standard);
}

.wf-canvas-host .drawflow .drawflow-node.selected {
    background: var(--bg-elevated);
    box-shadow: 0 0 0 2px var(--primary-500), var(--shadow-surface);
}

.wf-canvas-host .drawflow .drawflow-node .input,
.wf-canvas-host .drawflow .drawflow-node .output {
    width: 12px;
    height: 12px;
    background: var(--text-subtle);
    border: none;
    transition: background-color var(--transition);
}

.wf-canvas-host .drawflow .drawflow-node .input {
    left: -7px;
}

.wf-canvas-host .drawflow .drawflow-node .output {
    right: -7px;
}

/* Типизированные порты (advisory): цвет по типу данных потока. Связи НЕ
   блокируются — это лишь визуальная подсказка. text-порты остаются дефолтным
   --text-subtle (см. .input/.output выше); audio опущен — media-нод воркфлоу
   отдаёт только image/video. Правила стоят ДО :hover, чтобы наведение
   по-прежнему подсвечивало порт. */
.wf-canvas-host .drawflow .drawflow-node.wf-out-image .output { background: var(--accent-cool); }
.wf-canvas-host .drawflow .drawflow-node.wf-out-video .output { background: var(--accent-warm); }
.wf-canvas-host .drawflow .drawflow-node.wf-out-mixed .output { background: var(--primary-500); }
.wf-canvas-host .drawflow .drawflow-node.wf-in-mixed .input { background: var(--primary-500); }

.wf-canvas-host .drawflow .drawflow-node .input:hover,
.wf-canvas-host .drawflow .drawflow-node .output:hover {
    background: var(--primary-500);
}

/* Подписи веток фильтра у выходных портов («Да» сверху, «Нет» снизу) */
.wf-canvas-host .drawflow .drawflow-node.wf-kind-filter .output::after {
    position: absolute;
    left: calc(100% + 4px);
    top: 50%;
    transform: translateY(-50%);
    font-size: var(--text-2xs);
    color: var(--text-subtle);
    pointer-events: none;
}

.wf-canvas-host .drawflow .drawflow-node.wf-kind-filter .output_1::after {
    content: 'Да';
}

.wf-canvas-host .drawflow .drawflow-node.wf-kind-filter .output_2::after {
    content: 'Нет';
}

.wf-canvas-host .drawflow .connection .main-path {
    stroke: var(--text-subtle);
    stroke-width: 2.5px;
}

.wf-canvas-host .drawflow .connection .main-path:hover,
.wf-canvas-host .drawflow .connection .main-path.selected {
    stroke: var(--primary-500);
}

.wf-canvas-host .drawflow-delete {
    background: var(--bg-raised);
    border: none;
    box-shadow: var(--shadow-icon);
    color: var(--text-main);
    line-height: 30px;
}

/* Содержимое нода (наш html внутри drawflow_content_node) */
.wf-node {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.65rem 0.75rem;
}

.wf-node__icon {
    width: 2rem;
    height: 2rem;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-md);
    background: var(--surface-soft);
    color: var(--primary-icon);
    font-size: 1.05rem;
}

/* Фирменная иконка группы модели внутри нода (svg из каталога). */
.wf-node__icon svg {
    width: 1.15rem;
    height: 1.15rem;
}

.wf-kind-trigger .wf-node__icon {
    background: var(--primary-14);
}

.wf-node__text {
    min-width: 0;
    flex: 1;
}

.wf-node__title {
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Чипы на лице ноды: модель + ключевые параметры (разрешение/соотношение/
   длительность, размышления/поиск и т.п.) — как в нод-канвасе референса. */
.wf-node__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-top: 0.15rem;
}

.wf-node__chip {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    max-width: 100%;
    padding: 0.05rem 0.35rem;
    border-radius: var(--radius-sm);
    background: var(--surface-soft);
    color: var(--text-subtle);
    font-size: var(--text-2xs);
    line-height: 1.5;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wf-node__chip i {
    font-size: 0.85em;
    flex-shrink: 0;
}

.wf-node__state {
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    flex-shrink: 0;
    background: transparent;
    transition: background var(--motion-duration-fast) var(--motion-ease-standard);
}

/* Статусы прогона на нодах (классы вешает workflowsApp.applyNodeStatus) */
.wf-canvas-host .drawflow-node.wf-node-running {
    box-shadow: 0 0 0 3px var(--primary-14), var(--shadow-surface);
}

.wf-canvas-host .drawflow-node.wf-node-running .wf-node__state {
    background: var(--primary-500);
    animation: wf-pulse 1s var(--motion-ease-standard) infinite;
}

.wf-canvas-host .drawflow-node.wf-node-done .wf-node__state {
    background: var(--primary-500);
}

.wf-canvas-host .drawflow-node.wf-node-failed {
    box-shadow: 0 0 0 2px var(--text-main-18), var(--shadow-surface);
}

.wf-canvas-host .drawflow-node.wf-node-failed .wf-node__state {
    background: var(--text-subtle);
}

.wf-canvas-host .drawflow-node.wf-node-skipped {
    opacity: 0.45;
}

@keyframes wf-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

/* ── Живые ноды (ai_text/media): инлайн-промпт + ▶ + результат на карточке ── */
.wf-canvas-host .drawflow .drawflow-node:has(.wf-node--live) {
    width: 264px;
}

.wf-node--live {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.6rem 0.65rem;
}

.wf-node--live .wf-node__head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.wf-node--live .wf-node__title {
    flex: 1;
    min-width: 0;
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wf-node__live-result {
    min-height: 3.25rem;
    max-height: 12rem;
    overflow-y: auto;
    border-radius: var(--radius-md);
    background: var(--surface-soft);
    padding: 0.5rem 0.55rem;
}

.wf-node__live-ph {
    color: var(--text-subtle);
    font-size: var(--text-2xs);
    text-align: center;
    padding: 0.5rem 0;
}

.wf-node__live-text {
    width: 100%;
    color: var(--text-main);
    font-size: var(--text-2xs);
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
}

.wf-node__live-media {
    display: block;
    margin: 0 auto;
    max-width: 100%;
    max-height: 11rem;
    object-fit: contain;
    border-radius: var(--radius-sm);
}

.wf-node__live-row {
    display: flex;
    align-items: flex-end;
    gap: 0.4rem;
}

.wf-node__live-prompt {
    flex: 1;
    min-width: 0;
    resize: none;
    border: none;
    outline: none;
    border-radius: var(--radius-md);
    padding: 0.45rem 0.55rem;
    background: var(--surface-soft);
    color: var(--text-main);
    font-size: var(--text-2xs);
    line-height: 1.45;
    font-family: inherit;
}

.wf-node__live-prompt::placeholder { color: var(--text-muted); }

.wf-node__live-run {
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-md);
    background: var(--primary-14);
    color: var(--primary-icon);
    transition: background var(--transition), color var(--transition);
}

@media (hover: hover) {
    .wf-node__live-run:hover { background: var(--primary-500); color: var(--primary-text); }
}

.wf-node__live-model {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    align-self: flex-start;
    max-width: 100%;
    height: 1.75rem;
    padding: 0 0.55rem;
    border-radius: var(--radius-pill);
    background: var(--surface-soft);
    color: var(--text-subtle);
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-semibold);
    transition: background var(--transition), color var(--transition);
}

.wf-node__live-model span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

@media (hover: hover) {
    .wf-node__live-model:hover { background: var(--surface-strong); color: var(--text-main); }
}

/* Нижняя строка живой карточки: модель + чипы управляемых параметров модели. */
.wf-node__live-params {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
}

.wf-node__live-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    max-width: 100%;
    height: 1.75rem;
    padding: 0 0.5rem;
    border-radius: var(--radius-pill);
    background: var(--surface-soft);
    color: var(--text-subtle);
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-semibold);
    white-space: nowrap;
    transition: background var(--transition), color var(--transition);
}

.wf-node__live-chip > span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wf-node__live-chip > i { font-size: 0.85em; opacity: 0.7; }

.wf-node__live-chip.is-on {
    background: var(--primary-14);
    color: var(--primary-icon);
}

@media (hover: hover) {
    .wf-node__live-chip:hover { background: var(--surface-strong); color: var(--text-main); }
    .wf-node__live-chip.is-on:hover { background: var(--primary-500); color: var(--primary-text); }
}

.wf-node__live-model .wf-node__live-bolt { color: var(--primary-icon); }
.wf-node__live-model > .ti-chevron-down { font-size: 0.85em; opacity: 0.6; }

/* Иконки действий нода — прижаты вправо, проявляются при наведении/выборе нода. */
.wf-node__live-actions {
    display: flex;
    align-items: center;
    gap: 0.1rem;
    margin-left: auto;
    opacity: 0;
    transition: opacity var(--transition);
}

.drawflow-node:hover .wf-node__live-actions,
.drawflow-node.selected .wf-node__live-actions { opacity: 1; }

.wf-node__live-act {
    flex-shrink: 0;
    width: 1.6rem;
    height: 1.6rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    color: var(--text-subtle);
    transition: background var(--transition), color var(--transition);
}

@media (hover: hover) {
    .wf-node__live-act:hover { background: var(--surface-strong); color: var(--text-main); }
    .wf-node__live-act--danger:hover { background: var(--danger-bg, var(--surface-strong)); color: var(--danger); }
}

/* ── Канвас-ноды ввода: Текст / Файл / Заметка ── */
.wf-canvas-host .drawflow .drawflow-node:has(.wf-node--input),
.wf-canvas-host .drawflow .drawflow-node:has(.wf-node--note) {
    width: 230px;
}

.wf-node--input {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.6rem 0.65rem;
}

.wf-node--input .wf-node__head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.wf-node--input .wf-node__title {
    flex: 1;
    min-width: 0;
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-main);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wf-node__input-text,
.wf-node__note-text {
    width: 100%;
    resize: none;
    border: none;
    outline: none;
    border-radius: var(--radius-md);
    padding: 0.45rem 0.55rem;
    background: var(--surface-soft);
    color: var(--text-main);
    font-size: var(--text-2xs);
    line-height: 1.45;
    font-family: inherit;
}

.wf-node__input-text::placeholder,
.wf-node__note-text::placeholder { color: var(--text-muted); }

/* Заметка — стикер: только поле, без шапки/портов, мягкий акцент. */
.wf-node--note { padding: 0.4rem; }
.wf-node__note-text {
    background: var(--primary-14);
    min-height: 4rem;
}

/* Файл — превью загруженного медиа или кнопка загрузки. */
.wf-node__file {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.wf-node__file-upload {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    min-height: 3.5rem;
    border-radius: var(--radius-md);
    border: 1px dashed var(--border-soft, var(--surface-strong));
    background: var(--surface-soft);
    color: var(--text-subtle);
    font-size: var(--text-2xs);
    font-weight: var(--font-weight-semibold);
    transition: background var(--transition), color var(--transition);
}

.wf-node__file-media {
    display: block;
    width: 100%;
    max-height: 9rem;
    object-fit: contain;
    border-radius: var(--radius-sm);
    background: var(--surface-soft);
}

.wf-node__file-audio { width: 100%; }

.wf-node__file-replace {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    max-width: 100%;
    padding: 0.25rem 0.4rem;
    border-radius: var(--radius-pill);
    background: var(--surface-soft);
    color: var(--text-subtle);
    font-size: var(--text-2xs);
}

.wf-node__file-replace span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

@media (hover: hover) {
    .wf-node__file-upload:hover { background: var(--surface-strong); color: var(--text-main); }
    .wf-node__file-replace:hover { background: var(--surface-strong); color: var(--text-main); }
}

@media (max-width: 767.98px) {
    /* Сайдбар-список на мобилке — полноэкранный (как список чатов);
       отступ под мобильный хедер даёт tg-panel-list. */
    .wf-sidebar {
        width: 100%;
        flex: 1 1 auto;
        border-radius: 0;
        box-shadow: none;
    }

    /* Открытый редактор — единственный экран: список прячется (на десктопе
       сайдбар остаётся видимым, как история чатов). Двойной класс обязателен:
       tailwind.css в каскаде ПОЗЖЕ styles.css, и одноклассовый селектор
       проигрывает его `.flex` — сайдбар оставался поверх редактора. */
    .wf-sidebar.wf-sidebar--editor-open {
        display: none;
    }

    /* Нет сценариев: пустой сайдбар-список прячется, контент показывает
       стартовый экран-герой создания (зеркало стартовой страницы чата). */
    .wf-sidebar.wf-sidebar--empty-hidden {
        display: none;
    }

    /* Пока открыт список (сайдбар во весь экран) — колонка контента спрятана
       (зеркало tg-content-hidden у чатов; сайдбар идёт в DOM перед колонкой).
       Исключение — пустой список: тогда показываем экран-герой в контенте. */
    .wf-sidebar:not(.wf-sidebar--editor-open):not(.wf-sidebar--empty-hidden) ~ .sidebar-page {
        display: none;
    }

    /* Мобильный тулбар = бейдж статуса + «Запустить» по центру снизу (зона
       большого пальца); назад/действия живут в компактном хедере. */
    .wf-topbar {
        top: auto;
        bottom: calc(env(safe-area-inset-bottom, 0px) + 0.85rem);
        justify-content: center;
    }

    /* Панель — нижняя шторка под компактным хедером. */
    .wf-panel {
        top: auto;
        left: 0.5rem;
        right: 0.5rem;
        bottom: 0.5rem;
        width: auto;
        max-height: calc(100dvh - var(--shell-mobile-header-offset) - 1.5rem);
    }
}

/* ===== Транскрипция (/transcription) ===== */

/* Композер — absolute-overlay поверх ленты (как чат/медиа): лента скроллится
   ПОД ним, а не обрезается у его верха. Высоту пишет ResizeObserver
   (transcriptionApp) в --composer-height; лента резервирует её снизу.
   Обёртка прозрачна и pointer-events:none — wheel/touch проходят к ленте позади;
   видимые контролы (пилюли + поле) получают pointer-events:auto. */
.transcribe-content { --composer-height: 0px; }
.transcribe-thread-scroll { padding-bottom: var(--composer-height); }
.transcribe-composer-wrap {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 5;
    pointer-events: none;
}
.transcribe-composer-wrap > * { pointer-events: auto; }

/* Сегмент-пилюли выбора модели (в композере чата) */
.transcribe-models {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    padding: 0.25rem;
    /* Стекло как у нижнего композера (.chat-input-shell) — лента скроллится
       под контейнером пилюль, поэтому фон полупрозрачный с блюром, не сплошной. */
    background-color: var(--chat-input-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    border-radius: var(--radius-pill);
}
.transcribe-model {
    padding: 0.5rem 1.1rem;
    border: none;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text-muted);
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    cursor: pointer;
    transition: background-color var(--transition), color var(--transition);
}
@media (hover: hover) {
    .transcribe-model:hover { color: var(--text-main); }
}
.transcribe-model.is-active {
    background: var(--surface-strong);
    color: var(--text-main);
}

/* Компактные пилюли модели в чат-композере */
.transcribe-models--sm { padding: 0.18rem; }
.transcribe-models--sm .transcribe-model {
    padding: 0.32rem 0.8rem;
    font-size: var(--text-xs);
}

/* ── Сайдбар истории тредов ── каркас/ширина/скругление/стекло стандартные
   (shell-secondary-panel + sidebar-inset, вынесен ВНЕ <main> как остальные
   сайдбары); внутренняя раскладка — Tailwind-классы на <aside>. */
.transcribe-shell { position: relative; }
.transcribe-sidebar__list {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    /* padding-top включает offset мобильного shell-хедера (на десктопе offset = 0).
       Свой shorthand-padding иначе затирал бы .app-with-overlay-header. */
    padding: calc(var(--shell-mobile-header-offset, 0px) + 0.75rem) 0.5rem 0.75rem;
}
.transcribe-sidebar__footer {
    flex-shrink: 0;
    padding: 0.75rem;
}
.transcribe-sidebar__del {
    background: none;
    border: none;
    cursor: pointer;
    transition: color var(--transition), background-color var(--transition);
}
@media (hover: hover) {
    .transcribe-sidebar__del:hover {
        color: var(--text-main);
        background: var(--surface-soft);
    }
}

/* Мобайл: полноэкранный список ⇄ тред переключаются display-toggle'ом (как у
   сценариев). Сайдбар вынесен ВНЕ <main>, перед колонкой контента (.sidebar-page):
   в режиме списка скрыт контент, в режиме треда скрыт сайдбар. */
@media (max-width: 767.98px) {
    .transcribe-sidebar {
        width: 100%;
        flex: 1 1 auto;
        border-radius: 0;
        box-shadow: none;
    }
    .transcribe-sidebar.transcribe-sidebar--thread-open { display: none; }
    .transcribe-sidebar:not(.transcribe-sidebar--thread-open) ~ .sidebar-page { display: none; }
}

/* Аудио-плеер в пузыре записи */
.transcribe-audio {
    display: block;
    width: clamp(12rem, 60vw, 17rem);
    height: 2.5rem;
}

/* Прикреплённое вложение в композере (ждёт отправки) — без обёртки-контейнера */
.transcribe-staged {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.transcribe-staged .transcribe-audio {
    width: clamp(10rem, 50vw, 15rem);
}
/* Видео — в нативных пропорциях (без letterbox), только ограничено по габаритам */
.transcribe-staged-video {
    flex: 0 1 auto;
    width: auto;
    height: auto;
    max-width: min(15rem, 60vw);
    max-height: 12rem;
    border-radius: var(--radius-base);
}
.transcribe-msg-video {
    display: block;
    width: auto;
    height: auto;
    max-width: min(20rem, 70vw);
    max-height: 16rem;
    border-radius: var(--radius-base);
}

/* Плавное разворачивание прикреплённого вложения (grid-трюк, как в композере) */
.transcribe-collapse {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--motion-duration-base) var(--motion-ease-premium);
}
.transcribe-collapse.is-open {
    grid-template-rows: 1fr;
}
.transcribe-collapse__inner {
    overflow: hidden;
    min-height: 0;
}

/* Пилюля стоимости рядом с кнопкой отправки */
.transcribe-cost-pill {
    flex-shrink: 0;
    padding: 0.25rem 0.7rem;
    border-radius: var(--radius-pill);
    background: var(--surface-strong);
    color: var(--text-main);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    white-space: nowrap;
}
.transcribe-staged__del {
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    border-radius: var(--radius-md);
    transition: color var(--transition), background-color var(--transition);
}
@media (hover: hover) {
    .transcribe-staged__del:hover {
        color: var(--text-main);
        background: var(--surface-strong);
    }
}

/* Текст распознанного сообщения */
.transcribe-msg-text {
    white-space: pre-wrap;
    word-break: break-word;
    font-size: var(--text-sm);
    line-height: 1.6;
    color: var(--text-main);
}
