    :root {
      /* Obsidian & Luxury Tech palette */
      --bg-base: #050811;
      --bg-mid: #0b1120;
      --bg-deep: #10172a;
      --bg-gradient: linear-gradient(160deg, var(--bg-base) 0%, var(--bg-mid) 55%, var(--bg-deep) 100%);
      --card-bg: rgba(16, 23, 42, 0.78);
      --card-border: rgba(255, 255, 255, 0.08);
      /* Алиас из docs/DESIGN_SYSTEM.md: в admin.css он есть, здесь его не
         было — и `border: 1px solid var(--glass-border)` на кнопках ответа
         молча становился нулевым. Кнопка действия («Записаться на просмотр»)
         выглядела голым текстом посреди ленты. */
      --glass-border: rgba(255, 255, 255, 0.08);
      --panel-bg: rgba(16, 23, 42, 0.78);
      --panel-border: rgba(255, 255, 255, 0.08);
      --accent-gradient-primary: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #d946ef 100%);
      --accent-gradient-emerald: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
      --accent-gradient-gold: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
      /* Канонические имена — те же, что в admin.css и docs/DESIGN_SYSTEM.md.
         --accent-blue и --accent-amber оставлены алиасами: на них свёрстана
         половина виджета, переименование сломало бы её без всякой пользы. */
      --accent-indigo: #6366f1;
      --accent-gold: #f59e0b;
      /* Осветлённое золото для ТЕКСТА на обсидиане: чистый --accent-gold
         на тёмном фоне не добирает контраста в мелком кегле. */
      --accent-gold-soft: #fbbf24;
      /* Затемнённое золото для ТЕКСТА на жемчужном фоне: --accent-gold там
         не добирает контраста ровно так же, как чистое золото на обсидиане.
         Значение — второй стоп --accent-gradient-gold, а не новый цвет. */
      --accent-gold-deep: #d97706;
      --accent-blue: var(--accent-indigo);
      --accent-purple: #8b5cf6;
      --accent-cyan: #06b6d4;
      --accent-emerald: #10b981;
      --accent-teal: #06b6d4;
      --accent-amber: var(--accent-gold);
      --accent-rose: #f43f5e;
      --text-main: #fafafa;
      --text-body: #cbd5e1;
      --text-muted: #808ea3;
      --user-msg-bg: var(--accent-gradient-primary);
      --bot-msg-bg: rgba(16, 23, 42, 0.75);
      --gradient-indigo-cyan: var(--accent-gradient-primary);
      --gradient-emerald-teal: var(--accent-gradient-emerald);
      --font-display: 'Outfit', system-ui, sans-serif;
      --font-body: 'Plus Jakarta Sans', -apple-system, sans-serif;
      --radius-sm: 8px;
      --radius-md: 12px;
      --radius-lg: 16px;
      --radius-pill: 999px;
      --blur-glass: blur(16px);
      --blur-modal-deep: blur(20px);
      --shadow-glow-indigo: 0 8px 30px rgba(99, 102, 241, 0.35);
      --shadow-glow-emerald: 0 8px 30px rgba(16, 185, 129, 0.3);
      --shadow-glow-gold: 0 8px 30px rgba(245, 158, 11, 0.3);
      --shadow-card: 0 10px 30px rgba(0, 0, 0, 0.45);
    }

    * { box-sizing: border-box; margin: 0; padding: 0; font-family: var(--font-body); }

    html, body {
      overflow-x: hidden;
      max-width: 100vw;
      scrollbar-width: thin;
      scrollbar-color: rgba(255, 255, 255, 0.16) transparent;
    }

    /* Custom Dark Scrollbars */
    ::-webkit-scrollbar {
      width: 6px;
      height: 6px;
    }
    ::-webkit-scrollbar-track {
      background: transparent;
    }
    ::-webkit-scrollbar-thumb {
      background: rgba(255, 255, 255, 0.16);
      border-radius: 999px;
    }
    ::-webkit-scrollbar-thumb:hover {
      background: rgba(255, 255, 255, 0.3);
    }

    @media (prefers-reduced-motion: reduce) {
      *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
    }

    body {
      background: var(--bg-gradient);
      color: var(--text-body);
      height: 100vh;
      display: flex;
      flex-direction: column;
      overflow: hidden;
      position: relative;
    }

    /* Background Mesh Glow */
    body::before {
      content: '';
      position: fixed;
      top: 0; left: 50%;
      transform: translateX(-50%);
      width: 1000px; height: 400px;
      background: radial-gradient(ellipse at top, rgba(99, 102, 241, 0.12), transparent 70%);
      pointer-events: none;
      z-index: 0;
    }

    header, .dialog-stage-track, .app-container {
      position: relative;
      z-index: 1;
    }

    h1, h3, h4, .brand-title h1 { font-family: var(--font-display); }

    /* Header */
    header {
      background: rgba(11, 17, 32, 0.94);
      backdrop-filter: var(--blur-glass);
      border-bottom: 1px solid rgba(255, 255, 255, 0.08);
      padding: 14px 24px;
      display: flex;
      align-items: center;
      justify-content: space-between;
    }

    .brand {
      display: flex;
      align-items: center;
      gap: 12px;
    }

    .drawer-toggle {
      display: none;
      background: rgba(255, 255, 255, 0.06);
      border: 1px solid var(--panel-border);
      color: var(--text-main);
      width: 36px;
      height: 36px;
      border-radius: var(--radius-sm);
      font-size: 16px;
      cursor: pointer;
    }

    .brand-logo {
      width: 40px;
      height: 40px;
      background: var(--gradient-indigo-cyan);
      border-radius: var(--radius-md);
      display: flex;
      align-items: center;
      justify-content: center;
      font-weight: 800;
      font-family: var(--font-display);
      font-size: 20px;
      box-shadow: var(--shadow-glow-indigo);
    }

    .brand-title h1 { font-size: 18px; font-weight: 700; background: var(--gradient-indigo-cyan); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
    .brand-title p { font-size: 12px; color: var(--text-muted); }

    .header-actions {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
      gap: 8px;
    }

    .badge {
      background: rgba(16, 185, 129, 0.15);
      color: var(--accent-emerald);
      border: 1px solid rgba(16, 185, 129, 0.3);
      padding: 5px 12px;
      border-radius: var(--radius-pill);
      font-size: 12px;
      font-weight: 600;
      display: flex;
      align-items: center;
      gap: 6px;
    }

    .badge-dot {
      width: 8px;
      height: 8px;
      background: var(--accent-emerald);
      border-radius: 50%;
      box-shadow: 0 0 8px var(--accent-emerald);
      animation: pulseGlow 2.4s infinite;
    }

    @keyframes pulseGlow {
      0%, 100% { opacity: 1; transform: scale(1); }
      50% { opacity: 0.5; transform: scale(1.3); }
    }

    .doc-link {
      color: var(--accent-blue);
      text-decoration: none;
      font-size: 13px;
      font-weight: 600;
      padding: 6px 12px;
      border-radius: var(--radius-sm);
      background: rgba(99, 102, 241, 0.1);
      transition: all 0.2s;
    }
    .doc-link:hover { background: rgba(99, 102, 241, 0.25); }
    .icon-link {
      display: inline-flex;
      align-items: center;
      gap: 6px;
    }

    /* Sidebar Section Titles */
    .sidebar-section-title {
      font-size: 10px;
      font-weight: 800;
      text-transform: uppercase;
      letter-spacing: 0.8px;
      color: var(--accent-cyan);
      margin-top: 4px;
      padding-bottom: 2px;
    }

    /* Dialog Graph Stage Indicator */
    .dialog-stage-track {
      display: flex;
      align-items: center;
      gap: 4px;
      padding: 8px 24px;
      background: rgba(11, 17, 32, 0.94);
      border-bottom: 1px solid var(--panel-border);
      overflow-x: auto;
      -webkit-overflow-scrolling: touch;
      scrollbar-width: none;
      white-space: nowrap;
    }
    .dialog-stage-track::-webkit-scrollbar { display: none; }

    .stage-node {
      display: flex;
      align-items: center;
      gap: 6px;
      font-size: 11px;
      font-weight: 600;
      color: var(--text-muted);
      white-space: nowrap;
      padding: 4px 10px;
      border-radius: var(--radius-pill);
      transition: all 0.3s ease;
    }

    .stage-node::after {
      content: '›';
      margin-left: 8px;
      color: var(--panel-border);
    }
    .stage-node:last-child::after { content: ''; }

    .stage-dot {
      width: 6px;
      height: 6px;
      border-radius: 50%;
      background: var(--panel-border);
    }

    .stage-node.active {
      color: var(--text-main);
      background: var(--gradient-indigo-cyan);
      box-shadow: var(--shadow-glow-indigo);
    }
    .stage-node.active .stage-dot { background: white; }

    .stage-node.done {
      color: var(--accent-emerald);
    }
    .stage-node.done .stage-dot { background: var(--accent-emerald); }

    /* Layout */
    .app-container {
      display: flex;
      flex: 1;
      overflow: hidden;
    }

    /* Sidebar controls */
    .sidebar {
      width: 350px;
      min-width: 300px;
      max-width: 350px;
      box-sizing: border-box;
      background: var(--panel-bg);
      border-right: 1px solid var(--panel-border);
      padding: 16px;
      display: flex;
      flex-direction: column;
      gap: 14px;
      backdrop-filter: var(--blur-glass);
      overflow-y: auto;
    }

    .control-group {
      display: flex;
      flex-direction: column;
      gap: 6px;
      width: 100%;
      box-sizing: border-box;
    }

    .control-group label {
      font-size: 11px;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.5px;
      color: var(--text-muted);
    }

    .input-field, .select-field {
      background: rgba(15, 23, 42, 0.6);
      border: 1px solid var(--panel-border);
      color: var(--text-main);
      padding: 10px 12px;
      border-radius: var(--radius-sm);
      font-size: 13px;
      outline: none;
      transition: border 0.2s;
    }
    .input-field:focus, .select-field:focus {
      border-color: var(--accent-blue);
    }
    .input-field:focus-visible, .select-field:focus-visible, .btn:focus-visible, .preset-btn:focus-visible,
    .chip:focus-visible, .calc-slider:focus-visible {
      outline: 2px solid var(--accent-cyan);
      outline-offset: 2px;
    }

    .btn {
      background: var(--gradient-indigo-cyan);
      color: white;
      border: none;
      padding: 10px 16px;
      border-radius: var(--radius-sm);
      font-size: 13px;
      font-weight: 600;
      cursor: pointer;
      transition: opacity 0.2s, transform 0.1s;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 8px;
    }
    .btn:hover { opacity: 0.9; }
    .btn:active { transform: scale(0.98); }

    .btn-secondary {
      background: rgba(255, 255, 255, 0.05);
      border: 1px solid var(--panel-border);
      color: var(--text-main);
    }
    .btn-secondary:hover { background: rgba(255, 255, 255, 0.1); }

    .icon-btn {
      padding: 8px !important;
      display: inline-flex;
      align-items: center;
      justify-content: center;
    }
    .theme-icon {
      font-size: 14px;
      line-height: 1;
      transition: transform 0.3s ease;
      display: inline-block;
    }

    /* Presets */
    /* В окно списка обязаны попадать ШЕСТЬ кнопок без прокрутки: раньше
       max-height 170px вмещал ровно четыре, и половина фраз пряталась за
       скроллом ещё до того, как человек понимал, что список длиннее.
       Высоту считаем из размера строки, а не подбираем на глаз, — правка
       кегля или отступов больше не ломает счёт. Список остаётся
       прокручиваемым: фраз в нём больше шести. */
    .presets-list {
      --preset-row-h: 32px;
      --preset-gap: 6px;
      display: flex;
      flex-direction: column;
      gap: var(--preset-gap);
      max-height: calc(var(--preset-row-h) * 6 + var(--preset-gap) * 5);
      overflow-y: auto;
      padding-right: 4px;
    }

    .presets-list::-webkit-scrollbar {
      width: 5px;
    }
    .presets-list::-webkit-scrollbar-track {
      background: rgba(0, 0, 0, 0.2);
      border-radius: 4px;
    }
    .presets-list::-webkit-scrollbar-thumb {
      background: rgba(139, 92, 246, 0.35);
      border-radius: 4px;
    }
    .presets-list::-webkit-scrollbar-thumb:hover {
      background: rgba(139, 92, 246, 0.6);
    }

    /* Кегль и отступы ужаты ровно настолько, чтобы строка укладывалась в
       --preset-row-h. Текст при этом не режем и не прячем многоточием:
       подписи подобраны короткими, длинная просто перенесётся на вторую
       строку и раздвинет кнопку. */
    .preset-btn {
      background: rgba(15, 23, 42, 0.5);
      border: 1px solid var(--panel-border);
      color: var(--text-main);
      padding: 6px 10px;
      border-radius: var(--radius-sm);
      font-size: 11.5px;
      text-align: left;
      cursor: pointer;
      transition: all 0.2s;
      line-height: 1.35;
      min-height: var(--preset-row-h, 32px);
      flex-shrink: 0;
    }
    .preset-btn:hover {
      border-color: var(--accent-blue);
      background: rgba(99, 102, 241, 0.15);
    }

    /* ------------------------------------------------------------------
       Витрина для сотрудника кабинета: блок выключенного модуля
       ------------------------------------------------------------------
       Владелец платформы сам выключает модули и открывает чат, чтобы
       посмотреть, как всё устроено, — прятать от него ровно то, чем он
       управляет, бессмысленно. Поэтому вошедшему в кабинет блок не гасится,
       а помечается: пунктир + подпись «покупатель этого не видит». Текст
       подписи приходит из data-feature-note, поэтому одна и та же пара
       правил обслуживает и большие панели, и чипсы.
       Покупателю (без токена кабинета) класс не ставится вовсе — блок
       остаётся скрытым, как и был. */
    .feature-off-preview {
      border-style: dashed !important;
      border-color: rgba(245, 158, 11, 0.5) !important;
      opacity: 0.85;
    }
    .feature-off-preview:hover { opacity: 1; }

    .feature-off-preview::before {
      content: '🔒 ' attr(data-feature-note);
      display: block;
      margin-bottom: 6px;
      padding: 3px 7px;
      border-radius: var(--radius-sm);
      background: rgba(245, 158, 11, 0.12);
      border: 1px solid rgba(245, 158, 11, 0.3);
      color: var(--accent-gold-soft);
      font-family: var(--font-body);
      font-size: 10px;
      font-weight: 700;
      line-height: 1.35;
      letter-spacing: 0.2px;
      text-align: left;
      white-space: normal;
    }

    /* Чипс и кнопка-фраза — узкие элементы в один ряд текста: там подпись
       идёт слева от названия, а не отдельной плашкой сверху. */
    .chip.feature-off-preview::before,
    .preset-btn.feature-off-preview::before {
      display: inline-block;
      margin: 0 6px 0 0;
      padding: 1px 5px;
      font-size: 9px;
      vertical-align: middle;
    }
    .chip.feature-off-preview { white-space: normal; }

    /* .btn — flex-строка, и плашка встала бы рядом с подписью, деля кнопку
       пополам. В режиме показа разворачиваем кнопку в колонку: сначала
       пометка, под ней сама подпись. */
    .btn.feature-off-preview {
      flex-direction: column;
      align-items: stretch;
      gap: 0;
    }
    /* Золотая кнопка-CTA: полупрозрачное золото на золотом же градиенте
       читается плохо, поэтому под пометкой — тёмная подложка. Она же
       выручает и в светлой теме, где кнопка остаётся золотой. */
    .mortgage-app-cta.feature-off-preview::before {
      background: rgba(0, 0, 0, 0.35);
      border-color: rgba(0, 0, 0, 0.2);
      color: var(--accent-gold-soft);
    }

    /* Кнопка-фразa: только замок, объяснение — в подсказке (title). Подпись
       словами разгоняла строку на две, и в окно списка переставали
       помещаться шесть фраз — ровно то, из-за чего окно и переделывали. */
    .preset-btn.feature-off-preview::before {
      content: '🔒';
      padding: 0 3px;
      background: none;
      border: none;
    }

    /* Mortgage Calculator Widget */
    .calc-widget {
      background: rgba(245, 158, 11, 0.05);
      border: 1px solid rgba(245, 158, 11, 0.18);
      border-radius: var(--radius-md);
      padding: 12px;
      gap: 10px;
    }

    .calc-row {
      display: flex;
      flex-direction: column;
      gap: 4px;
    }

    .calc-row-label {
      display: flex;
      justify-content: space-between;
      font-size: 12px;
      color: var(--text-main);
    }

    .calc-row-label strong {
      color: var(--accent-gold-soft);
      font-family: var(--font-display);
    }

    .calc-slider {
      -webkit-appearance: none;
      appearance: none;
      width: 100%;
      height: 5px;
      border-radius: var(--radius-pill);
      background: linear-gradient(90deg, rgba(16, 185, 129, 0.5), rgba(245, 158, 11, 0.5));
      outline: none;
      cursor: pointer;
    }
    .calc-slider::-webkit-slider-thumb {
      -webkit-appearance: none;
      appearance: none;
      width: 16px;
      height: 16px;
      border-radius: 50%;
      background: var(--accent-gradient-gold);
      box-shadow: var(--shadow-glow-gold);
      cursor: pointer;
      border: 2px solid rgba(255,255,255,0.85);
    }
    .calc-slider::-moz-range-thumb {
      width: 16px;
      height: 16px;
      border-radius: 50%;
      background: var(--accent-gradient-gold);
      box-shadow: var(--shadow-glow-gold);
      cursor: pointer;
      border: 2px solid rgba(255,255,255,0.85);
    }

    .calc-result {
      display: flex;
      justify-content: space-between;
      align-items: center;
      background: rgba(15, 23, 42, 0.6);
      border-radius: var(--radius-sm);
      padding: 10px 12px;
      margin-top: 4px;
      font-size: 12px;
      color: var(--text-muted);
    }
    .calc-result strong {
      font-family: var(--font-display);
      font-size: 16px;
      min-width: 140px;
      display: inline-block;
      text-align: right;
      background: var(--accent-gradient-gold);
      -webkit-background-clip: text;
      background-clip: text;
      -webkit-text-fill-color: transparent;
    }
    .calc-result-secondary {
      margin-top: 2px;
      background: transparent;
      padding: 0 12px;
    }
    /* Копирование расчёта: второстепенное действие рядом с главным CTA
       «Оформить предзаявку», поэтому без заливки — только рамка и текст. */
    .calc-copy-btn {
      width: 100%;
      margin-top: 8px;
      padding: 9px 12px;
      font-size: 12px;
      border-radius: var(--radius-sm);
      transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
    }
    .calc-copy-btn:hover {
      border-color: color-mix(in srgb, var(--accent-gold) 45%, transparent);
      color: var(--accent-gold);
    }
    .calc-copy-btn:active { transform: scale(0.97); }
    .calc-copy-btn.is-copied {
      border-color: color-mix(in srgb, var(--accent-emerald) 45%, transparent);
      background: color-mix(in srgb, var(--accent-emerald) 12%, transparent);
      color: var(--accent-emerald);
    }

    .calc-result-secondary strong {
      font-size: 13px;
      min-width: 140px;
      display: inline-block;
      text-align: right;
      color: var(--accent-emerald);
      -webkit-text-fill-color: unset;
      background: none;
    }

    /* Main Chat Area */
    .chat-main {
      flex: 1;
      display: flex;
      flex-direction: column;
      background: rgba(15, 23, 42, 0.4);
      min-width: 0;
    }

    .messages-container {
      flex: 1;
      padding: 24px;
      padding-bottom: 28px;
      overflow-y: auto;
      scroll-behavior: smooth;
      display: flex;
      flex-direction: column;
      gap: 0;
    }

    .message-row {
      display: flex;
      gap: 10px;
      max-width: 68%;
      width: fit-content;
      margin-bottom: 12px;
      animation: fadeInUp 0.35s ease;
    }

    @keyframes fadeInUp {
      from { opacity: 0; transform: translateY(8px); }
      to { opacity: 1; transform: translateY(0); }
    }

    .message-row.user {
      align-self: flex-end;
      flex-direction: row-reverse;
      margin-left: auto;
    }

    .message-row.bot {
      align-self: flex-start;
      margin-right: auto;
    }

    .avatar {
      width: 34px;
      height: 34px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 13px;
      font-weight: 700;
      font-family: var(--font-display);
      flex-shrink: 0;
      position: relative;
    }

    /* Тот же баг, что у .message-row.user .bubble чуть ниже (найден
       владельцем 23.08.2026): .avatar не задаёт color, «Вы» наследовал
       приглушённый var(--text-body) на цветном фоне --accent-blue. */
    .avatar.user { background: var(--accent-blue); color: #fff; }
    .avatar.bot { background: var(--gradient-indigo-cyan); box-shadow: var(--shadow-glow-indigo); }
    .avatar.bot::after {
      content: '';
      position: absolute;
      bottom: -1px;
      right: -1px;
      width: 9px;
      height: 9px;
      border-radius: 50%;
      background: var(--accent-emerald);
      border: 2px solid var(--bg-deep);
      box-shadow: 0 0 6px var(--accent-emerald);
      animation: pulseGlow 2.4s infinite;
    }

    /* Реплика живого менеджера (Human-in-the-Loop Handover): клиент должен сразу
       видеть, что с ним говорит человек, а не бот — отсюда своя аватарка,
       янтарный акцент пузыря и подпись с именем менеджера. */
    .avatar.manager {
      background: var(--accent-gradient-gold);
      box-shadow: 0 0 10px rgba(245, 158, 11, 0.45);
    }
    .avatar.manager::after { display: none; }

    .bubble.manager-bubble {
      background: rgba(245, 158, 11, 0.12);
      border: 1px solid rgba(245, 158, 11, 0.35);
    }

    .meta-chip.manager-chip {
      background: rgba(245, 158, 11, 0.18);
      color: var(--accent-gold-soft);
      border: 1px solid rgba(245, 158, 11, 0.3);
    }

    .handover-notice {
      align-self: center;
      margin: 4px auto;
      padding: 6px 12px;
      border-radius: 12px;
      font-size: 12px;
      text-align: center;
      color: var(--accent-gold-soft);
      background: rgba(245, 158, 11, 0.12);
      border: 1px solid rgba(245, 158, 11, 0.28);
    }

    /* Copy-to-clipboard button on bot messages */
    .copy-btn {
      background: none;
      border: none;
      color: var(--text-muted);
      cursor: pointer;
      font-size: 10px;
      padding: 2px 4px;
      border-radius: 4px;
      transition: color 0.2s, background 0.2s;
    }
    .copy-btn:hover { color: var(--text-main); background: rgba(255,255,255,0.08); }

    /* Text-to-Speech button on bot messages */
    .speak-btn {
      background: none;
      border: none;
      color: var(--text-muted);
      cursor: pointer;
      font-size: 10px;
      padding: 2px 4px;
      border-radius: 4px;
      white-space: nowrap;
      transition: color 0.2s, background 0.2s;
    }
    .speak-btn:hover { color: var(--text-main); background: rgba(255,255,255,0.08); }
    .speak-btn.speaking {
      color: var(--accent-cyan);
      background: rgba(6, 182, 212, 0.14);
      animation: pulseGlowSoft 1.6s ease-in-out infinite;
    }

    @keyframes pulseGlowSoft {
      0%, 100% { opacity: 1; }
      50% { opacity: 0.55; }
    }

    /* Language Switcher + Finish Consultation toolbar */
    .chat-toolbar {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-between;
      gap: 8px;
      padding: 0 24px 8px 24px;
    }

    .lang-switch {
      display: flex;
      flex-wrap: wrap;
      gap: 6px;
    }

    .lang-chip {
      background: rgba(255, 255, 255, 0.05);
      border: 1px solid var(--panel-border);
      color: var(--text-body);
      padding: 5px 12px;
      border-radius: var(--radius-pill);
      font-family: var(--font-body);
      font-size: 12px;
      font-weight: 600;
      cursor: pointer;
      white-space: nowrap;
      transition: all 0.2s ease;
    }
    .lang-chip:hover {
      color: var(--text-main);
      border-color: var(--accent-blue);
      transform: translateY(-1px);
    }
    /* Явный выбор клиента — сплошная заливка фирменным градиентом */
    .lang-chip.active {
      background: var(--accent-gradient-primary);
      border-color: transparent;
      color: #fff;
      box-shadow: var(--shadow-glow-indigo);
    }
    /* Автодетекция — мягкая подсветка: это подсказка, а не выбор клиента */
    .lang-chip.detected {
      border-color: var(--accent-cyan);
      color: var(--accent-cyan);
      background: rgba(6, 182, 212, 0.12);
    }

    .finish-btn {
      font-size: 12px;
      padding: 6px 12px;
      white-space: nowrap;
    }

    /* CSAT Rating Widget */
    .csat-panel {
      margin: 0 24px 10px 24px;
      padding: 14px 16px;
      background: var(--card-bg, rgba(16, 23, 42, 0.78));
      border: 1px solid var(--panel-border);
      border-radius: var(--radius-md);
      box-shadow: var(--shadow-card);
      animation: fadeInUp 0.35s ease;
    }
    .csat-panel[hidden] { display: none; }

    .csat-head {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 8px;
    }
    .csat-title {
      font-family: var(--font-display);
      font-size: 13.5px;
      font-weight: 700;
      color: var(--text-main);
    }
    .csat-close {
      background: none;
      border: none;
      color: var(--text-muted);
      font-size: 15px;
      line-height: 1;
      cursor: pointer;
      padding: 2px 6px;
      border-radius: 4px;
    }
    .csat-close:hover { color: var(--text-main); background: rgba(255,255,255,0.08); }

    .csat-stars {
      display: flex;
      gap: 4px;
      margin: 8px 0 4px 0;
    }
    .csat-star {
      background: none;
      border: none;
      cursor: pointer;
      font-size: 26px;
      line-height: 1;
      padding: 0 2px;
      color: var(--text-muted);
      opacity: 0.45;
      transition: color 0.15s ease, transform 0.15s ease, opacity 0.15s ease;
    }
    .csat-star:hover { transform: scale(1.12); opacity: 1; color: var(--accent-amber); }
    .csat-star.filled {
      color: var(--accent-amber);
      opacity: 1;
      text-shadow: 0 0 12px rgba(245, 158, 11, 0.45);
    }
    .csat-star:focus-visible { outline: 2px solid var(--accent-cyan); border-radius: 4px; }

    .csat-hint {
      font-size: 11.5px;
      color: var(--text-muted);
      margin-bottom: 8px;
    }

    .csat-comment {
      width: 100%;
      background: rgba(30, 41, 59, 0.7);
      border: 1px solid var(--panel-border);
      border-radius: var(--radius-sm);
      color: var(--text-main);
      font-family: var(--font-body);
      font-size: 12.5px;
      padding: 8px 10px;
      resize: vertical;
      outline: none;
      max-height: 120px;
    }
    .csat-comment:focus { border-color: var(--accent-blue); }

    .csat-actions {
      display: flex;
      justify-content: flex-end;
      gap: 8px;
      margin-top: 8px;
    }
    .csat-actions .btn { font-size: 12px; padding: 7px 14px; }
    .csat-actions .btn:disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; }

    /* Voice input (Web Speech API) */
    .mic-btn {
      position: relative;
      min-height: 48px;
      padding: 0 14px;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 6px;
    }
    .mic-btn:disabled,
    .mic-btn.unsupported {
      opacity: 0.4;
      cursor: not-allowed;
      transform: none;
    }
    .mic-btn .mic-icon { font-size: 16px; line-height: 1; }
    .mic-btn.recording {
      border-color: var(--accent-rose);
      color: var(--accent-rose);
      background: rgba(244, 63, 94, 0.12);
    }

    /* Анимация звуковой волны — видна только во время записи */
    .mic-wave {
      display: none;
      align-items: flex-end;
      gap: 2px;
      height: 16px;
    }
    .mic-btn.recording .mic-wave { display: flex; }
    .mic-wave i {
      display: block;
      width: 2.5px;
      height: 4px;
      border-radius: var(--radius-pill);
      background: var(--accent-rose);
      animation: micWave 0.9s ease-in-out infinite;
    }
    .mic-wave i:nth-child(2) { animation-delay: 0.12s; }
    .mic-wave i:nth-child(3) { animation-delay: 0.24s; }
    .mic-wave i:nth-child(4) { animation-delay: 0.36s; }
    .mic-wave i:nth-child(5) { animation-delay: 0.48s; }

    @keyframes micWave {
      0%, 100% { height: 4px; opacity: 0.55; }
      50% { height: 16px; opacity: 1; }
    }

    /* ── Статус голосового ввода ──────────────────────────────────────────────
       Строка живёт над полем ввода и меняет цвет по смыслу состояния:
       индиго — идёт запись, циан — распознаём, изумруд — текст в поле,
       янтарь — распознать не удалось, роза — доступ к микрофону закрыт.
       Цвет несёт смысл не один: рядом всегда есть текст, поэтому состояние
       читается и в монохроме. */
    .voice-status {
      display: flex;
      align-items: center;
      gap: 8px;
      margin: 0 24px 8px 24px;
      padding: 8px 12px;
      border-radius: var(--radius-md);
      border: 1px solid var(--panel-border);
      background: var(--panel-bg);
      color: var(--text-body);
      font-size: 12.5px;
      line-height: 1.35;
      animation: voiceStatusIn 0.24s ease;
    }
    .voice-status[hidden] { display: none; }

    .voice-status-dot {
      flex: 0 0 auto;
      width: 8px;
      height: 8px;
      border-radius: var(--radius-pill);
      background: var(--text-muted);
      transition: background 0.2s ease, box-shadow 0.2s ease;
    }
    .voice-status-text { min-width: 0; }

    .voice-status.is-listening {
      border-color: color-mix(in srgb, var(--accent-indigo) 38%, transparent);
      background: color-mix(in srgb, var(--accent-indigo) 10%, var(--panel-bg));
    }
    .voice-status.is-listening .voice-status-dot {
      background: var(--accent-indigo);
      animation: voicePulse 1.6s ease-in-out infinite;
    }

    .voice-status.is-processing {
      border-color: color-mix(in srgb, var(--accent-cyan) 38%, transparent);
      background: color-mix(in srgb, var(--accent-cyan) 10%, var(--panel-bg));
    }
    .voice-status.is-processing .voice-status-dot {
      background: var(--accent-cyan);
      animation: voicePulse 1s ease-in-out infinite;
    }

    .voice-status.is-done {
      border-color: color-mix(in srgb, var(--accent-emerald) 38%, transparent);
      background: color-mix(in srgb, var(--accent-emerald) 10%, var(--panel-bg));
      color: var(--text-main);
    }
    .voice-status.is-done .voice-status-dot { background: var(--accent-emerald); }

    .voice-status.is-failed {
      border-color: color-mix(in srgb, var(--accent-gold) 38%, transparent);
      background: color-mix(in srgb, var(--accent-gold) 10%, var(--panel-bg));
    }
    .voice-status.is-failed .voice-status-dot { background: var(--accent-gold); }

    .voice-status.is-error {
      border-color: color-mix(in srgb, var(--accent-rose) 38%, transparent);
      background: color-mix(in srgb, var(--accent-rose) 10%, var(--panel-bg));
    }
    .voice-status.is-error .voice-status-dot { background: var(--accent-rose); }

    @keyframes voiceStatusIn {
      from { opacity: 0; transform: translateY(4px); }
      to { opacity: 1; transform: translateY(0); }
    }
    @keyframes voicePulse {
      0%, 100% { transform: scale(1); opacity: 0.75; }
      50% { transform: scale(1.35); opacity: 1; }
    }

    /* Prompt Action Chips */
    .chips-row {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      padding: 0 24px 10px 24px;
    }
    .chip {
      background: rgba(255, 255, 255, 0.05);
      border: 1px solid var(--panel-border);
      color: var(--text-main);
      padding: 7px 14px;
      border-radius: var(--radius-pill);
      font-size: 12px;
      font-weight: 500;
      cursor: pointer;
      transition: all 0.2s ease;
      white-space: nowrap;
    }
    .chip:hover {
      background: var(--gradient-indigo-cyan);
      border-color: transparent;
      transform: translateY(-1px);
    }

    /* Property Comparison Matrix */
    .comparison-matrix-title {
      font-family: var(--font-display);
      font-weight: 700;
      font-size: 13.5px;
      /* Отступ сверху держит ЗАГОЛОВОК, а не пустая строка перед ним: пустые
         переносы вокруг блока рендер теперь убирает (formatBotText). */
      margin: 12px 0 8px 0;
      color: var(--text-main);
    }
    .bubble-text > .comparison-matrix-title:first-child { margin-top: 0; }

    /* Пункт перечисления в ответе бота: маркер рисует CSS, дефис из текста
       убран разбором. Отступ слева выравнивает вторую строку пункта по первой,
       а не под маркер. */
    .bubble-li {
      position: relative;
      padding-left: 14px;
      margin: 2px 0;
    }
    .bubble-li::before {
      content: '';
      position: absolute;
      left: 3px;
      top: 0.62em;
      width: 4px;
      height: 4px;
      border-radius: var(--radius-pill);
      background: var(--accent-indigo);
    }
    .comparison-matrix-table {
      width: 100%;
      border-collapse: collapse;
      margin: 6px 0 10px 0;
      font-size: 12px;
      background: rgba(15, 23, 42, 0.4);
      border-radius: var(--radius-sm);
      overflow: hidden;
    }
    .comparison-matrix-table th {
      background: rgba(99, 102, 241, 0.18);
      color: var(--text-main);
      padding: 8px 10px;
      text-align: left;
      font-weight: 700;
      white-space: nowrap;
    }
    .comparison-matrix-table td {
      padding: 8px 10px;
      border-top: 1px solid var(--panel-border);
      color: var(--text-body);
    }
    .comparison-matrix-table td.rowlabel {
      color: var(--text-muted);
      font-weight: 600;
      white-space: nowrap;
    }
    .comparison-matrix-table td.winner-cell {
      color: var(--accent-emerald);
      font-weight: 700;
    }

    /* Колонка «пузырь + мета»: мета вынесена из пузыря, поэтому ширину пузыря
       задает только текст сообщения, а не строка чипсов с токенами и стоимостью. */
    .bubble-stack {
      display: flex;
      flex-direction: column;
      min-width: 0;
      max-width: 100%;
      align-items: flex-start;
    }
    .message-row.user .bubble-stack {
      align-items: flex-end;
    }

    .bubble {
      padding: 8px 12px;
      border-radius: 14px;
      font-size: 13.5px;
      line-height: 1.5;
      word-break: break-word;
      width: fit-content;
      max-width: 100%;
    }

    /* pre-wrap живет на тексте, а НЕ на пузыре: иначе переносы строк и отступы
       HTML-шаблона превращаются в реальные пустые строки внутри пузыря. */
    .bubble-text {
      white-space: pre-wrap;
    }

    /* Уплотнение: обнуляем нижние отступы последних элементов внутри пузыря */
    .bubble p:last-child,
    .bubble-text > *:last-child {
      margin-bottom: 0 !important;
    }

    .message-row.user .bubble {
      background: var(--user-msg-bg);
      /* Владелец увидел плохой контраст (23.08.2026): .bubble сам по себе
         цвет текста не задаёт, наследуется приглушённый var(--text-body) —
         рассчитан на тёмный фон .bot-msg-bg (почти чёрный), а не на яркий
         градиент индиго→фиолетовый→маджента этого пузыря. Белый — тот же
         приём, что у большинства чат-интерфейсов на цветном пузыре
         отправителя, и работает в обеих темах: light-тема ниже по файлу
         переопределяет только --bot-msg-bg, --user-msg-bg (и сам градиент)
         у неё общий с тёмной. */
      color: #fff;
      border-bottom-right-radius: 2px;
      box-shadow: 0 6px 18px rgba(139, 92, 246, 0.3);
    }

    .message-row.bot .bubble {
      background: var(--bot-msg-bg);
      backdrop-filter: var(--blur-glass);
      border: 1px solid rgba(139, 92, 246, 0.18);
      border-bottom-left-radius: 2px;
      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
    }

    /* Мета-строка живет ПОД пузырем и не влияет на его ширину */
    .bubble-meta {
      display: flex;
      flex-wrap: wrap;
      gap: 3px 5px;
      align-items: center;
      justify-content: flex-start;
      font-size: 10.5px;
      line-height: 1.35;
      color: var(--text-muted);
      margin: 3px 2px 0 2px;
      max-width: 100%;
    }
    .message-row.user .bubble-meta {
      justify-content: flex-end;
    }

    .meta-chip {
      background: rgba(0, 0, 0, 0.25);
      padding: 2px 6px;
      border-radius: 4px;
      font-size: 10px;
      white-space: nowrap;
      color: var(--text-muted);
    }

    /* Служебные чипсы (режим, Judge, активные теги): цвета из токенов, а не
       из захардкоженных HEX, иначе светлая тема их не переопределит. */
    .meta-chip-depth {
      background: color-mix(in srgb, var(--accent-blue) 20%, transparent);
      color: var(--accent-blue);
      border: 1px solid color-mix(in srgb, var(--accent-blue) 35%, transparent);
    }

    .meta-chip-judge {
      background: color-mix(in srgb, var(--accent-emerald) 16%, transparent);
      color: var(--accent-emerald);
      border: 1px solid color-mix(in srgb, var(--accent-emerald) 30%, transparent);
    }

    .meta-chip-tag {
      background: color-mix(in srgb, var(--accent-cyan) 16%, transparent);
      color: var(--accent-cyan);
      border: 1px solid color-mix(in srgb, var(--accent-cyan) 30%, transparent);
    }

    /* Блоки со служебными данными (data-demo-only) на этой демо-площадке видны
       всегда. Правило оставлено на случай, когда их прячут атрибутом hidden:
       у .control-group и строк аналитики свой display, и без !important
       hidden не сработал бы. */
    [data-demo-only][hidden] { display: none !important; }

    /* Блоки внутренней кухни платформы (data-platform-only) скрыты В РАЗМЕТКЕ и
       раскрываются только после подтверждения is_platform_admin сервером.
       Правило с !important обязательно: у .control-group собственный display,
       и голый атрибут hidden его бы не перекрыл — блок мигнул бы владельцу
       застройщика на каждой загрузке страницы. */
    [data-platform-only][hidden] { display: none !important; }

    /* Input Bar */
    .input-bar {
      padding: 16px 24px;
      background: rgba(15, 23, 42, 0.85);
      border-top: 1px solid var(--panel-border);
      display: flex;
      gap: 12px;
      align-items: flex-end;
    }

    .chat-textarea {
      flex: 1;
      background: rgba(30, 41, 59, 0.7);
      border: 1px solid var(--panel-border);
      border-radius: var(--radius-md);
      color: var(--text-main);
      padding: 12px 16px;
      font-size: 14px;
      outline: none;
      resize: none;
      max-height: 120px;
      min-height: 48px;
    }
    .chat-textarea:focus { border-color: var(--accent-blue); }

    /* Memory Panel (Right) */
    .memory-panel {
      width: 320px;
      background: var(--panel-bg);
      border-left: 1px solid var(--panel-border);
      padding: 20px;
      display: flex;
      flex-direction: column;
      gap: 16px;
      backdrop-filter: var(--blur-glass);
      overflow-y: auto;
    }

    .memory-card {
      background: rgba(15, 23, 42, 0.65);
      border: 1px solid var(--panel-border);
      border-radius: var(--radius-md);
      padding: 14px;
      display: flex;
      flex-direction: column;
      gap: 8px;
      transition: border-color 0.2s, box-shadow 0.2s;
    }
    .memory-card:hover {
      border-color: rgba(99, 102, 241, 0.35);
      box-shadow: var(--shadow-card);
    }

    .memory-card h4 {
      font-size: 12px;
      text-transform: uppercase;
      letter-spacing: 0.5px;
      color: var(--accent-cyan);
      display: flex;
      align-items: center;
      justify-content: space-between;
    }

    .fact-tag {
      background: rgba(99, 102, 241, 0.15);
      color: var(--text-main);
      padding: 8px 12px;
      border-radius: var(--radius-sm);
      font-size: 12px;
      border-left: 3px solid var(--accent-blue);
      margin-bottom: 6px;
      line-height: 1.4;
    }

    .lead-badge {
      background: rgba(245, 158, 11, 0.15);
      border: 1px solid rgba(245, 158, 11, 0.3);
      color: var(--accent-amber);
      padding: 8px 12px;
      border-radius: var(--radius-sm);
      font-size: 12px;
      margin-top: 4px;
      line-height: 1.4;
    }

    /* Typing indicator */
    .typing-dots {
      display: inline-flex;
      gap: 4px;
    }
    .typing-dots span {
      width: 6px;
      height: 6px;
      background: var(--text-muted);
      border-radius: 50%;
      animation: blink 1.4s infinite both;
    }
    .typing-dots span:nth-child(2) { animation-delay: 0.2s; }
    .typing-dots span:nth-child(3) { animation-delay: 0.4s; }
    @keyframes blink { 0%, 80%, 100% { opacity: 0.2; } 40% { opacity: 1; } }

    /* Skeleton loading */
    .skeleton {
      background: linear-gradient(90deg, rgba(255,255,255,0.04) 25%, rgba(255,255,255,0.09) 37%, rgba(255,255,255,0.04) 63%);
      background-size: 400% 100%;
      animation: shimmer 1.4s ease infinite;
      border-radius: var(--radius-sm);
    }
    @keyframes shimmer {
      0% { background-position: 100% 50%; }
      100% { background-position: 0 50%; }
    }

    /* Interactive 3D Tour & Media Buttons */
    .btn-3d-tour {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      background: var(--gradient-indigo-cyan);
      color: white;
      border: 1px solid rgba(192, 132, 252, 0.4);
      padding: 7px 16px;
      border-radius: var(--radius-sm);
      font-size: 12.5px;
      font-weight: 600;
      cursor: pointer;
      margin: 8px 0 4px 0;
      box-shadow: var(--shadow-glow-indigo);
      transition: all 0.2s ease;
      /* Длинная подпись тура переносится внутри пузыря, а не распирает его */
      max-width: 100%;
      white-space: normal;
      text-align: left;
      overflow-wrap: anywhere;
    }
    .btn-3d-tour:hover {
      transform: translateY(-1px);
      box-shadow: 0 6px 20px rgba(99, 102, 241, 0.55);
    }
    .btn-3d-tour:active {
      transform: translateY(0);
      box-shadow: var(--shadow-glow-indigo);
    }

    .btn-plan {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      background: rgba(34, 211, 238, 0.15);
      color: var(--accent-cyan);
      border: 1px solid rgba(34, 211, 238, 0.3);
      padding: 6px 12px;
      border-radius: var(--radius-sm);
      font-size: 12px;
      font-weight: 600;
      cursor: pointer;
      margin: 6px 6px 6px 0;
      transition: all 0.2s;
      max-width: 100%;
      white-space: normal;
      text-align: left;
      overflow-wrap: anywhere;
    }
    .btn-plan:hover {
      background: rgba(34, 211, 238, 0.3);
    }
    .btn-plan:active {
      background: rgba(34, 211, 238, 0.38);
    }
    /* Тот же элемент бывает ссылкой (PDF, готовое КП): открывается вкладкой,
       а не встроенным просмотрщиком, — но выглядеть обязан так же. */
    a.btn-plan {
      text-decoration: none;
    }
    a.btn-plan:hover {
      color: var(--accent-cyan);
    }
    .btn-plan:focus-visible,
    .btn-3d-tour:focus-visible {
      outline: 2px solid var(--accent-indigo);
      outline-offset: 2px;
    }
    /* Готовое коммерческое предложение — деньги и результат подбора, отсюда
       изумрудная линия, а не общая бирюза материалов. Кнопка лежит ПОД пузырём,
       рядом со временем реплики. */
    .offer-doc-btn {
      align-self: flex-start;
      background: rgba(16, 185, 129, 0.14);
      color: var(--accent-emerald);
      border-color: rgba(16, 185, 129, 0.32);
      margin: 8px 0 2px;
    }
    .offer-doc-btn:hover {
      background: rgba(16, 185, 129, 0.26);
      color: var(--accent-emerald);
    }

    /* Ссылка в тексте реплики: цвет — токен темы, а не HEX (#60a5fa терялся
       на белом фоне светлой темы), длинный адрес переносится внутри пузыря. */
    .bubble-link {
      color: var(--accent-cyan);
      text-decoration: underline;
      overflow-wrap: anywhere;
    }

    /* ── Кнопки ответа под последней репликой бота (#replyButtonsRow) ──────
       Ряд живёт В ЛЕНТЕ, а не над полем ввода: он отвечает на то, что клиент
       только что прочитал, и обязан уезжать вверх вместе с этой репликой.
       Отступ слева 44px = ширина аватара (34px) + gap строки сообщения (10px):
       кнопки встают ровно под пузырём бота, а не под его аватаром. */
    .reply-buttons {
      display: flex;
      flex-direction: column;
      align-items: stretch;
      gap: 8px;
      margin: 0 0 14px 44px;
      max-width: min(520px, 68%);
      animation: fadeInUp 0.35s ease;
    }
    .reply-buttons-hint {
      font-family: var(--font-display);
      font-size: 10.5px;
      font-weight: 600;
      letter-spacing: 0.6px;
      text-transform: uppercase;
      color: var(--text-muted);
    }
    .reply-btn {
      display: block;
      width: 100%;
      text-align: left;
      padding: 11px 14px;
      border-radius: var(--radius-md);
      border: 1px solid var(--glass-border);
      background: var(--card-bg);
      color: var(--text-body);
      font-family: var(--font-body);
      font-size: 13px;
      font-weight: 600;
      line-height: 1.35;
      cursor: pointer;
      transition: all 0.2s ease;
      /* Подпись вида «2К, 62 м², 5 этаж — 9,4 млн ₽» обязана переноситься:
         обрезанная подпись выбора квартиры — это выбор вслепую. */
      white-space: normal;
      overflow-wrap: anywhere;
    }
    .reply-btn:hover {
      transform: translateY(-2px);
      border-color: var(--accent-indigo);
      color: var(--text-main);
      box-shadow: var(--shadow-card);
    }
    .reply-btn:active { transform: scale(0.985); }
    .reply-btn:focus-visible {
      outline: 2px solid var(--accent-indigo);
      outline-offset: 2px;
    }
    /* Выбор конкретной квартиры — главное действие хода (Level 0 каскада),
       отсюда фирменный градиент; ипотека, КП и менеджер остаются вторичными. */
    .reply-btn-unit {
      background: var(--accent-gradient-primary);
      border-color: rgba(192, 132, 252, 0.4);
      color: #fff;
      box-shadow: var(--shadow-glow-indigo);
    }
    .reply-btn-unit:hover {
      color: #fff;
      box-shadow: 0 10px 28px rgba(99, 102, 241, 0.5);
    }
    @media (max-width: 768px) {
      /* На телефоне пузырь занимает почти всю ширину — кнопки идут следом,
         с тем же отступом под аватар. 44px по высоте — минимальная цель
         пальца, ниже начинаются промахи. */
      .reply-buttons { max-width: calc(100% - 44px); }
      .reply-btn { padding: 13px 14px; min-height: 44px; font-size: 13.5px; }
    }

    /* Toast Notifications */
    .toast-stack {
      position: fixed;
      bottom: 20px;
      right: 20px;
      display: flex;
      flex-direction: column;
      gap: 10px;
      z-index: 5000;
    }
    .toast {
      background: rgba(15, 23, 42, 0.95);
      border: 1px solid var(--panel-border);
      border-left: 3px solid var(--accent-blue);
      color: var(--text-main);
      padding: 12px 16px;
      border-radius: var(--radius-sm);
      font-size: 13px;
      box-shadow: var(--shadow-card);
      min-width: 240px;
      animation: toastIn 0.25s ease;
      backdrop-filter: var(--blur-glass);
    }
    .toast.success { border-left-color: var(--accent-emerald); }
    .toast.error { border-left-color: var(--accent-rose); }
    .toast.info { border-left-color: var(--accent-cyan); }
    @keyframes toastIn {
      from { opacity: 0; transform: translateX(20px); }
      to { opacity: 1; transform: translateX(0); }
    }

    /* ============================================================
       Предзаявка на ипотеку — кнопка входа и модальная форма
       ============================================================ */
    .mortgage-app-cta {
      width: 100%;
      margin-top: 10px;
      background: var(--accent-gradient-gold);
      box-shadow: var(--shadow-glow-gold);
      font-size: 12.5px;
    }

    /* Приём заявок выключен застройщиком: расчёт остался, анкеты нет. На месте
       кнопки — обычный лид «связаться с менеджером», без сбора данных для банка.
       Блок не кричит: это не ошибка и не отказ, а другой порядок работы. */
    .calc-manager-fallback {
      margin-top: 10px;
      padding: 10px 12px;
      border-radius: var(--radius-md);
      border: 1px solid var(--panel-border);
      background: rgba(99, 102, 241, 0.08);
    }
    .calc-manager-note {
      margin: 0 0 8px 0;
      font-size: 11.5px;
      line-height: 1.5;
      color: var(--text-muted);
    }
    .calc-manager-fallback .mortgage-app-cta { margin-top: 0; }

    /* Пояснение в модалке, открытой ради отзыва согласия при выключенном приёме. */
    .mortgage-lead-off { color: var(--text-muted); }

    /* Чипс-действие отличаем от чипсов-подсказок: он не отправляет сообщение,
       а открывает форму, и цвет должен об этом предупреждать. */
    .chip.chip-action {
      border-color: rgba(245, 158, 11, 0.45);
      color: var(--accent-amber);
    }
    .chip.chip-action:hover {
      background: rgba(245, 158, 11, 0.14);
      border-color: var(--accent-amber);
    }

    .mortgage-modal {
      position: fixed;
      inset: 0;
      z-index: 3100;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 24px;
      background: rgba(2, 4, 10, 0.78);
      backdrop-filter: var(--blur-modal-deep);
    }
    /* hidden побеждает display:flex только с явным правилом — иначе форма
       остаётся видимой при закрытой модалке. */
    .mortgage-modal[hidden] { display: none; }

    .mortgage-dialog {
      width: 720px;
      max-width: 100%;
      max-height: 92vh;
      display: flex;
      flex-direction: column;
      background: var(--card-bg);
      border: 1px solid var(--card-border);
      border-radius: var(--radius-lg);
      box-shadow: var(--shadow-card);
      backdrop-filter: var(--blur-glass);
      overflow: hidden;
      animation: mortgageDialogIn 0.22s ease;
    }
    @keyframes mortgageDialogIn {
      from { opacity: 0; transform: translateY(12px) scale(0.985); }
      to { opacity: 1; transform: translateY(0) scale(1); }
    }

    .mortgage-dialog-head {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      padding: 16px 20px;
      border-bottom: 1px solid var(--panel-border);
      background: rgba(255, 255, 255, 0.03);
    }
    .mortgage-dialog-head h3 {
      margin: 0;
      font-family: var(--font-display);
      font-size: 16px;
      font-weight: 700;
      color: var(--text-main);
    }
    .mortgage-dialog-close {
      background: none;
      border: none;
      color: var(--text-muted);
      font-size: 20px;
      line-height: 1;
      cursor: pointer;
      padding: 4px 8px;
      border-radius: var(--radius-sm);
      transition: all 0.2s ease;
    }
    .mortgage-dialog-close:hover { color: var(--text-main); background: rgba(255, 255, 255, 0.08); }
    .mortgage-dialog-close:focus-visible { outline: 2px solid var(--accent-cyan); outline-offset: 2px; }

    .mortgage-dialog-body {
      padding: 18px 20px 22px 20px;
      overflow-y: auto;
    }

    .mortgage-lead {
      font-size: 12.5px;
      line-height: 1.5;
      color: var(--text-body);
      margin-bottom: 14px;
    }

    .mortgage-grid {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 12px;
    }
    .mortgage-grid .field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
    .mortgage-grid .field-wide { grid-column: 1 / -1; }
    .mortgage-grid label {
      font-size: 11px;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.4px;
      color: var(--text-muted);
    }
    .field-hint { font-size: 11px; color: var(--text-muted); line-height: 1.4; }
    /* Подсказка под полем в сайдбаре: селектор канала теперь односоставной,
       и пояснение «почему только web» должно читаться, но не спорить по весу
       с самим полем — отсюда приглушённый цвет и отступ в 6px. */
    .control-group .field-hint { margin: 6px 0 0; }

    /* Читаемое поле «Модель ИИ»: не инпут, а два факта с сервера.
       Раньше здесь стоял readonly-input с зашитым именем модели — он выглядел
       редактируемым и врал. Панель наследует геометрию .input-field (тот же
       радиус, та же рамка, тот же фон), поэтому в колонке сайдбара она стоит
       в общем ритме с соседними полями. */
    .model-readout {
      display: flex;
      flex-direction: column;
      gap: 6px;
      padding: 9px 12px;
      background: rgba(15, 23, 42, 0.6);
      border: 1px solid var(--panel-border);
      border-radius: var(--radius-sm);
    }
    .model-readout-row {
      display: flex;
      align-items: baseline;
      justify-content: space-between;
      gap: 10px;
      min-width: 0;
    }
    .model-readout-key {
      font-size: 10.5px;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.4px;
      color: var(--text-muted);
      white-space: nowrap;
    }
    /* Имя модели — технический идентификатор (gemini-3.1-flash-lite), поэтому
       моноширинный набор и перенос по любому символу: в 260px сайдбара длинное
       имя иначе распирает колонку. */
    .model-readout-value {
      font-family: ui-monospace, 'SFMono-Regular', monospace;
      font-size: 12px;
      font-weight: 500;
      color: var(--text-main);
      text-align: right;
      overflow-wrap: anywhere;
      min-width: 0;
      transition: color 0.2s ease;
    }
    /* Пока ответа нет — прочерк приглушён и мерцает скелетоном: видно, что это
       состояние загрузки, а не настоящее значение. */
    .model-readout.is-loading .model-readout-value {
      color: var(--text-muted);
      background: linear-gradient(90deg, rgba(255,255,255,0.04) 25%, rgba(255,255,255,0.09) 37%, rgba(255,255,255,0.04) 63%);
      background-size: 400% 100%;
      animation: shimmer 1.4s ease infinite;
      border-radius: var(--radius-sm);
      padding: 0 8px;
    }
    /* Ручка недоступна: прочерк остаётся, но без мерцания — ждать нечего. */
    .model-readout.is-unknown .model-readout-value { color: var(--text-muted); }
    [data-theme="light"] .model-readout { background: rgba(241, 245, 249, 0.8); }
    [data-theme="light"] .model-readout.is-loading .model-readout-value {
      background: linear-gradient(90deg, rgba(15,23,42,0.05) 25%, rgba(15,23,42,0.1) 37%, rgba(15,23,42,0.05) 63%);
      background-size: 400% 100%;
    }
    @media (max-width: 480px) {
      .model-readout-value { font-size: 11.5px; }
    }

    .checkbox-row {
      display: flex;
      align-items: flex-start;
      gap: 10px;
      cursor: pointer;
      text-transform: none !important;
      letter-spacing: normal !important;
      font-size: 12.5px !important;
      font-weight: 500 !important;
      line-height: 1.45;
      color: var(--text-body) !important;
    }
    .checkbox-row input[type="checkbox"] {
      width: 18px;
      height: 18px;
      flex: 0 0 18px;
      margin-top: 1px;
      accent-color: var(--accent-purple);
      cursor: pointer;
    }
    .checkbox-row input[type="checkbox"]:focus-visible { outline: 2px solid var(--accent-cyan); outline-offset: 2px; }

    .consent-box {
      margin-top: 16px;
      padding: 14px;
      border: 1px solid rgba(139, 92, 246, 0.35);
      border-radius: var(--radius-md);
      background: rgba(139, 92, 246, 0.07);
      display: flex;
      flex-direction: column;
      gap: 10px;
    }
    .consent-box legend {
      padding: 0 6px;
      font-family: var(--font-display);
      font-size: 12px;
      font-weight: 700;
      color: var(--text-main);
    }
    .consent-hint { font-size: 11.5px; line-height: 1.45; }
    .consent-hint-ok { color: var(--accent-emerald); }
    .consent-hint-warn { color: var(--accent-amber); }
    /* Блокирующее состояние: без согласия на ПДн анкета не сохранится вовсе. */
    .consent-hint-error { color: var(--accent-rose); font-weight: 600; }

    .mortgage-actions {
      display: flex;
      justify-content: flex-end;
      gap: 10px;
      margin-top: 18px;
    }
    .mortgage-actions .btn { min-width: 150px; }

    .btn-spinner {
      width: 14px;
      height: 14px;
      border-radius: 50%;
      border: 2px solid rgba(255, 255, 255, 0.35);
      border-top-color: #fff;
      animation: btnSpin 0.7s linear infinite;
    }
    .btn-spinner[hidden] { display: none; }
    @keyframes btnSpin { to { transform: rotate(360deg); } }

    /* Спиннер внутри второстепенной кнопки (кнопки документов по подбору):
       белая обводка там теряется на светлой теме, поэтому берём цвет текста. */
    .btn-secondary .btn-spinner {
      display: inline-block;
      vertical-align: -2px;
      margin-right: 4px;
      border-color: rgba(127, 127, 127, 0.3);
      border-top-color: currentColor;
    }

    .mortgage-result { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; }
    .mortgage-result:empty { margin-top: 0; }

    .notice {
      padding: 12px 14px;
      border-radius: var(--radius-md);
      border-left: 3px solid var(--text-muted);
      background: rgba(255, 255, 255, 0.04);
      font-size: 12.5px;
      line-height: 1.5;
      color: var(--text-body);
    }
    .notice strong { color: var(--text-main); display: block; margin-bottom: 4px; }
    .notice p { margin: 4px 0 0 0; }
    .notice ul { margin: 6px 0 0 18px; display: flex; flex-direction: column; gap: 4px; }
    .notice-fineprint { color: var(--text-muted); font-size: 11.5px; }
    .notice-ok { border-left-color: var(--accent-emerald); background: rgba(16, 185, 129, 0.09); }
    .notice-warn { border-left-color: var(--accent-amber); background: rgba(245, 158, 11, 0.09); }
    .notice-error { border-left-color: var(--accent-rose); background: rgba(244, 63, 94, 0.09); }
    .notice-neutral { border-left-color: var(--accent-cyan); background: rgba(6, 182, 212, 0.08); }

    .result-card {
      padding: 12px 14px;
      border: 1px solid var(--panel-border);
      border-radius: var(--radius-md);
      background: rgba(255, 255, 255, 0.03);
    }
    .result-title {
      font-family: var(--font-display);
      font-size: 12px;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.5px;
      color: var(--text-muted);
      margin-bottom: 8px;
    }
    .result-row {
      display: flex;
      justify-content: space-between;
      gap: 12px;
      font-size: 12.5px;
      padding: 4px 0;
      border-bottom: 1px solid rgba(255, 255, 255, 0.04);
    }
    .result-row:last-of-type { border-bottom: none; }
    .result-row strong { color: var(--text-main); }
    .result-id { margin-top: 8px; font-size: 11px; color: var(--text-muted); }

    .consent-badges { display: flex; flex-wrap: wrap; gap: 6px; }
    .consent-badge {
      font-size: 11px;
      padding: 4px 9px;
      border-radius: var(--radius-pill);
      border: 1px solid var(--panel-border);
      background: rgba(255, 255, 255, 0.05);
      color: var(--text-body);
    }
    .consent-badge.ok { color: var(--accent-emerald); border-color: rgba(16, 185, 129, 0.35); background: rgba(16, 185, 129, 0.12); }
    .consent-badge.pending { color: var(--accent-amber); border-color: rgba(245, 158, 11, 0.35); background: rgba(245, 158, 11, 0.12); }

    /* --- Отзыв согласия на обработку ПДн (ФЗ-152 ст. 9 ч. 2) ---------------
       Право клиента, а не деструктивное действие в интерфейсе: rose-акцент
       только в контуре и подписи, без заливки-«опасности». */
    .consent-ledger {
      display: flex;
      flex-direction: column;
      gap: 10px;
      margin: 0 0 18px 0;
    }
    .consent-ledger[hidden] { display: none; }
    .consent-ledger-title {
      font-size: 12px;
      font-weight: 600;
      letter-spacing: 0.04em;
      text-transform: uppercase;
      color: var(--text-muted);
    }
    .ledger-item {
      border: 1px solid var(--panel-border);
      border-left: 3px solid var(--accent-rose);
      border-radius: var(--radius-md, 10px);
      background: rgba(244, 63, 94, 0.06);
      padding: 12px 14px;
      display: flex;
      flex-direction: column;
      gap: 8px;
      transition: all 0.2s ease;
    }
    .ledger-item-revoked {
      border-left-color: var(--accent-emerald);
      background: rgba(16, 185, 129, 0.07);
    }
    .ledger-item-head {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-between;
      gap: 6px;
    }
    .ledger-badge {
      font-size: 11px;
      font-weight: 600;
      padding: 3px 9px;
      border-radius: var(--radius-pill);
      border: 1px solid var(--panel-border);
    }
    .ledger-badge.active { color: var(--accent-rose); border-color: rgba(244, 63, 94, 0.35); }
    .ledger-badge.revoked { color: var(--accent-emerald); border-color: rgba(16, 185, 129, 0.35); }
    .ledger-when { font-size: 11px; color: var(--text-muted); }
    .ledger-text { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--text-body); }

    .btn-revoke {
      align-self: flex-start;
      background: transparent;
      border: 1px solid rgba(244, 63, 94, 0.45);
      color: var(--accent-rose);
      font-size: 12.5px;
      display: inline-flex;
      align-items: center;
      gap: 8px;
      transition: all 0.2s ease;
    }
    .btn-revoke:hover:not(:disabled) {
      background: rgba(244, 63, 94, 0.14);
      border-color: var(--accent-rose);
      transform: translateY(-1px);
    }
    .btn-revoke:active:not(:disabled) { transform: translateY(0); }
    .btn-revoke:disabled { opacity: 0.6; cursor: progress; }
    .btn-revoke:focus-visible { outline: 2px solid var(--accent-rose); outline-offset: 2px; }
    .revoke-notice .btn-revoke { margin-top: 8px; }
    .revoke-done {
      margin: 8px 0 0 0;
      font-size: 12.5px;
      font-weight: 600;
      color: var(--accent-emerald);
    }

    .chip-revoke {
      border-color: rgba(244, 63, 94, 0.4);
      color: var(--accent-rose);
    }
    .chip-revoke:hover { background: rgba(244, 63, 94, 0.12); border-color: var(--accent-rose); }
    .chip-revoke[hidden] { display: none; }

    [data-theme="light"] .ledger-item { background: rgba(244, 63, 94, 0.08); }
    [data-theme="light"] .ledger-item-revoked { background: rgba(16, 185, 129, 0.1); }
    [data-theme="light"] .ledger-badge.active { color: #be123c; }
    [data-theme="light"] .ledger-badge.revoked { color: #047857; }
    [data-theme="light"] .btn-revoke { color: #be123c; }
    [data-theme="light"] .revoke-done { color: #047857; }

    /* Responsive */
    @media (max-width: 1440px) {
      .memory-panel { width: 280px; }
    }

    @media (max-width: 1023px) {
      .drawer-toggle { display: inline-flex; align-items: center; justify-content: center; }
      .memory-panel { display: none; }
      .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 900;
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        box-shadow: 0 0 40px rgba(0,0,0,0.5);
      }
      .sidebar.open { transform: translateX(0); }
    }

    @media (max-width: 767px) {
      .brand-title p { display: none; }
      .header-actions .doc-link:not(:last-child) { display: none; }
      .message-row { max-width: 88%; }
      .dialog-stage-track { padding: 6px 12px; }
      .stage-node { font-size: 10px; padding: 3px 8px; }
      .chips-row { padding: 0 12px 8px 12px; }
      .chip { font-size: 11px; padding: 6px 10px; }
      .chat-toolbar { padding: 0 12px 8px 12px; }
      .csat-panel { margin: 0 12px 8px 12px; }
      /* Одна левая граница у ленты, чипсов, тулбара и статуса записи */
      .voice-status { margin: 0 12px 8px 12px; }
      /* Отзыв согласия на узком экране: заголовок и дата в столбик,
         кнопка — во всю ширину, чтобы попадать пальцем. */
      .ledger-item { padding: 10px 12px; }
      .ledger-item-head { flex-direction: column; align-items: flex-start; gap: 4px; }
      .btn-revoke { width: 100%; justify-content: center; }
    }

    /* Мобильный экран: тулбар в две строки, кнопка микрофона — компактный квадрат */
    @media (max-width: 480px) {
      .chat-toolbar {
        flex-direction: column;
        align-items: stretch;
        gap: 6px;
      }
      .lang-switch { justify-content: space-between; }
      .lang-chip { flex: 1; text-align: center; padding: 6px 8px; font-size: 11.5px; }
      .finish-btn { width: 100%; font-size: 11.5px; }

      .input-bar { padding: 10px 12px; gap: 8px; }
      .chat-textarea { font-size: 13px; padding: 10px 12px; }
      .mic-btn { padding: 0 10px; min-width: 44px; }
      .mic-btn .mic-icon { font-size: 18px; }
      /* Волну на узком экране прячем — иконка микрофона и цвет уже сигналят запись */
      .mic-btn.recording .mic-wave { display: none; }

      /* Статус голосового ввода прижимается к тем же полям, что и панель ввода,
         иначе на 360px он выпадает из общей сетки на 12px. */
      .voice-status {
        margin: 0 12px 6px 12px;
        padding: 7px 10px;
        font-size: 12px;
      }
      .calc-copy-btn { padding: 10px 12px; }

      .csat-panel { padding: 12px; }

      /* Анкета на телефоне — лист во весь экран: две колонки полей на 480px
         превращаются в нечитаемые огрызки. */
      .mortgage-modal { padding: 0; align-items: flex-end; }
      .mortgage-dialog {
        width: 100%;
        max-height: 100vh;
        height: 100%;
        border-radius: 0;
        border-left: none;
        border-right: none;
      }
      .mortgage-grid { grid-template-columns: 1fr; }
      .mortgage-dialog-body { padding: 14px 14px 20px 14px; }
      .mortgage-actions { flex-direction: column-reverse; }
      .mortgage-actions .btn { width: 100%; }
      /* 16px — порог, ниже которого iOS зумит страницу при фокусе поля. */
      .mortgage-grid .input-field,
      .mortgage-grid .select-field { font-size: 16px; }
      .csat-star { font-size: 30px; }
      .csat-stars { justify-content: space-between; }
      /* Две кнопки в столбик, «Отправить» — сверху под большим пальцем:
         отказ от оценки не должен оказаться первым в порядке нажатия. */
      .csat-actions { flex-direction: column-reverse; }
      .csat-actions .btn { width: 100%; }
      .speak-btn, .copy-btn { font-size: 10.5px; }
    }

    @media (max-width: 600px) {
      .toast-stack {
        left: 16px;
        right: 16px;
        bottom: 16px;
        width: auto;
      }
      .toast { min-width: 0; width: 100%; }
    }

    /* ============================================================
       Light Theme — Premium Pearl ([data-theme="light"])
       ============================================================ */
    [data-theme="light"] {
      --bg-base: #f8fafc;
      --bg-mid: #f1f5f9;
      --bg-deep: #e2e8f0;
      --card-bg: rgba(255, 255, 255, 0.88);
      --card-border: rgba(0, 0, 0, 0.08);
      --glass-border: rgba(0, 0, 0, 0.08);
      --panel-bg: rgba(255, 255, 255, 0.85);
      --panel-border: rgba(0, 0, 0, 0.08);
      --bot-msg-bg: rgba(241, 245, 249, 0.92);
      --text-main: #0f172a;
      --text-body: #334155;
      --text-muted: #64748b;
      --shadow-card: 0 4px 20px rgba(0, 0, 0, 0.06);
    }

    html[data-theme="light"],
    [data-theme="light"] body {
      scrollbar-color: rgba(15, 23, 42, 0.18) transparent;
    }
    [data-theme="light"] ::-webkit-scrollbar-thumb {
      background: rgba(15, 23, 42, 0.18);
    }
    [data-theme="light"] ::-webkit-scrollbar-thumb:hover {
      background: rgba(15, 23, 42, 0.32);
    }

    [data-theme="light"] header,
    [data-theme="light"] .dialog-stage-track,
    [data-theme="light"] .input-bar {
      background: rgba(255, 255, 255, 0.85);
    }
    [data-theme="light"] .btn-secondary {
      background: rgba(226, 232, 240, 0.7);
      color: var(--text-main);
    }
    [data-theme="light"] .input-field,
    [data-theme="light"] .select-field,
    [data-theme="light"] .preset-btn,
    [data-theme="light"] .calc-result {
      background: rgba(241, 245, 249, 0.8);
    }
    /* Пометка «модуль выключен» на жемчужном фоне: светлое золото на нём
       нечитаемо, берём затемнённый оттенок того же токена. */
    [data-theme="light"] .feature-off-preview::before {
      color: var(--accent-gold-deep);
      background: rgba(245, 158, 11, 0.14);
    }
    /* Исключение: у золотой кнопки подложка тёмная в обеих темах, поэтому
       текст на ней остаётся светлым. */
    [data-theme="light"] .mortgage-app-cta.feature-off-preview::before {
      color: var(--accent-gold-soft);
      background: rgba(0, 0, 0, 0.35);
    }
    [data-theme="light"] .chat-textarea,
    [data-theme="light"] .csat-comment {
      background: #ffffff;
    }
    [data-theme="light"] .lang-chip {
      background: rgba(15, 23, 42, 0.05);
      color: var(--text-body);
    }
    [data-theme="light"] .lang-chip.active { color: #fff; }
    [data-theme="light"] .lang-chip.detected {
      background: rgba(6, 182, 212, 0.14);
      color: #0e7490;
    }
    [data-theme="light"] .csat-panel {
      background: rgba(255, 255, 255, 0.92);
    }
    [data-theme="light"] .csat-close:hover,
    [data-theme="light"] .copy-btn:hover,
    [data-theme="light"] .speak-btn:hover {
      background: rgba(15, 23, 42, 0.08);
    }
    [data-theme="light"] .csat-star { color: #94a3b8; }
    [data-theme="light"] .csat-star.filled,
    [data-theme="light"] .csat-star:hover { color: #d97706; }
    [data-theme="light"] .chat-main {
      background: rgba(248, 250, 252, 0.6);
    }
    [data-theme="light"] .memory-card {
      background: rgba(255, 255, 255, 0.75);
    }
    [data-theme="light"] .toast {
      background: rgba(255, 255, 255, 0.97);
      color: var(--text-main);
    }
    [data-theme="light"] .meta-chip {
      background: rgba(15, 23, 42, 0.08);
      color: var(--text-body);
    }
    /* Таблица сравнения лотов приходит в пузыре бота и в кабинете, и в окне
       виджета. Её подложка была зашита тёмным сланцем: на жемчужном фоне
       получалось тёмное пятно, по которому шёл тёмный же текст --text-body. */
    [data-theme="light"] .comparison-matrix-table {
      background: rgba(255, 255, 255, 0.9);
    }
    [data-theme="light"] .comparison-matrix-table th {
      background: rgba(99, 102, 241, 0.12);
    }
    /* Скелетоны — блик БЕЛЫМ по тёмному. На светлой теме мерцания не видно
       вовсе: место загрузки выглядело просто пустым. Разворачиваем блик в
       обратную сторону — тень по жемчужному. */
    /* Только .skeleton: мерцание прочерка модели (.model-readout) и её подложка
       описаны ВЫШЕ, рядом с самим блоком (см. `[data-theme="light"] .model-readout`).
       Копия здесь была бы третьей по счёту в файле и перебивала бы ту, которую
       правящий найдёт грепом первой, — правка «не давала бы эффекта» без всякого
       следа причины (находка ревью 16.08.2026). */
    [data-theme="light"] .skeleton {
      background: linear-gradient(90deg, rgba(15, 23, 42, 0.05) 25%,
        rgba(15, 23, 42, 0.11) 37%, rgba(15, 23, 42, 0.05) 63%);
      background-size: 400% 100%;
    }
    /* Тень пузыря бота рассчитана на тёмный фон (чёрная, 30%): на жемчужном она
       читается грязным ореолом вокруг каждой реплики. */
    [data-theme="light"] .message-row.bot .bubble {
      border-color: rgba(99, 102, 241, 0.16);
      box-shadow: 0 4px 16px rgba(15, 23, 42, 0.07);
    }
    /* Наведение на вторичную кнопку уводило её в белое на белом — оставалась
       одна рамка. Ведём в другую сторону, к более плотному сланцу. */
    [data-theme="light"] .btn-secondary:hover {
      background: rgba(203, 213, 225, 0.75);
    }

    /* Светлая тема: полупрозрачное белое стекло вместо тёмных подложек, иначе
       модалка и карточки результата остаются серыми пятнами на жемчужном фоне. */
    [data-theme="light"] .mortgage-modal { background: rgba(15, 23, 42, 0.35); }
    [data-theme="light"] .mortgage-dialog { background: rgba(255, 255, 255, 0.96); }
    [data-theme="light"] .mortgage-dialog-head { background: rgba(241, 245, 249, 0.9); }
    [data-theme="light"] .result-card,
    [data-theme="light"] .notice,
    [data-theme="light"] .consent-badge { background: rgba(241, 245, 249, 0.85); }
    /* Смысловые цвета уведомлений возвращаем после общего фона: иначе тематическая
       заливка перебьёт по специфичности и все состояния станут одинаково серыми. */
    [data-theme="light"] .notice-ok { background: rgba(16, 185, 129, 0.12); }
    [data-theme="light"] .notice-warn { background: rgba(245, 158, 11, 0.14); }
    [data-theme="light"] .notice-error { background: rgba(244, 63, 94, 0.11); }
    [data-theme="light"] .notice-neutral { background: rgba(6, 182, 212, 0.11); }
    [data-theme="light"] .consent-badge.ok { background: rgba(16, 185, 129, 0.14); color: #047857; }
    [data-theme="light"] .consent-badge.pending { background: rgba(245, 158, 11, 0.16); color: #b45309; }
    [data-theme="light"] .result-row { border-bottom-color: rgba(15, 23, 42, 0.07); }
    [data-theme="light"] .consent-hint-warn { color: #b45309; }
    [data-theme="light"] .consent-hint-ok { color: #047857; }
    [data-theme="light"] .chip.chip-action { color: #b45309; }
    [data-theme="light"] .mortgage-dialog-close:hover { background: rgba(15, 23, 42, 0.08); }

    /* High-contrast fixes (WCAG AAA pass) */
    [data-theme="light"] .brand-title h1 {
      background: linear-gradient(to right, #0f172a, #4f46e5);
      -webkit-background-clip: text;
      background-clip: text;
      -webkit-text-fill-color: transparent;
    }
    [data-theme="light"] .stage-node {
      background: rgba(15, 23, 42, 0.06);
      color: #475569;
    }
    [data-theme="light"] .stage-node::after {
      color: rgba(0, 0, 0, 0.15);
    }
    [data-theme="light"] .stage-node.active {
      background: linear-gradient(135deg, #4f46e5, #7c3aed);
      color: #ffffff;
      box-shadow: 0 4px 14px rgba(79, 70, 229, 0.3);
    }
    [data-theme="light"] .stage-node.done {
      background: rgba(5, 150, 105, 0.12);
      color: #047857;
    }
    [data-theme="light"] .chip {
      background: #ffffff;
      border-color: rgba(0, 0, 0, 0.12);
      color: #0f172a;
    }
    [data-theme="light"] .chip:hover {
      border-color: #4f46e5;
      background: rgba(99, 102, 241, 0.08);
      color: #0f172a;
    }
    [data-theme="light"] .preset-btn:hover,
    [data-theme="light"] .btn-secondary:hover {
      border-color: rgba(99, 102, 241, 0.4);
    }
    [data-theme="light"] .fact-tag {
      background: rgba(99, 102, 241, 0.08);
      color: var(--text-main);
    }
    [data-theme="light"] .doc-link {
      color: #4f46e5;
    }

    /* Плашка пробного прогона: видна только вошедшему оператору.
       Цвет — предупреждающий, но не тревожный: это не ошибка, а режим.
       Крепится над шапкой, чтобы её нельзя было не заметить, сажая за экран
       живого посетителя. */
    .operator-mode-banner {
      display: flex;
      align-items: flex-start;
      gap: 10px;
      padding: 10px 16px;
      background: color-mix(in srgb, var(--accent-amber) 12%, transparent);
      border-bottom: 1px solid color-mix(in srgb, var(--accent-amber) 40%, transparent);
      color: var(--text-main);
      font-size: 0.86rem;
      line-height: 1.4;
    }

    .operator-mode-banner[hidden] { display: none; }

    .operator-mode-icon { flex-shrink: 0; font-size: 1.05rem; line-height: 1.2; }

    @media (max-width: 640px) {
      .operator-mode-banner { padding: 8px 12px; font-size: 0.8rem; }
    }
