/*
 * Оформление окна «Узла». Порядок файла: токены (цвета, кегли, размеры — одно
 * место на всё окно, светлая и тёмная тема), прежние имена переменных для
 * ещё не переведённых разделов, базовые компоненты (кнопки, поля, чипы,
 * баннер), затем экраны. Телефон — ОДНИМ блоком @media в самом конце: граница
 * 719 px включительно (спецификация редизайна, §3). Цвета задаются только
 * токенами: в тёмной теме меняются сами токены, а не правила.
 */
/* ===== Узел · итоговые токены. Вставляются в начало app/client/style.css вместо текущего :root ===== */
:root {
  color-scheme: light dark;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";
  --font-mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  /* кегли: на телефоне sm/md/chip растут (см. @media ниже) */
  --fs-xs: 12px; --fs-sm: 13px; --fs-md: 15px; --fs-lg: 17px; --fs-xl: 20px; --fs-2xl: 24px;
  --fs-preview: 14px; --fs-chip: 12px; --h-chip: 22px;
  --lh-tight: 1.25; --lh: 1.45; --fw-medium: 500; --fw-bold: 600;
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px;
  --r-xs: 4px; --r-sm: 6px; --r-md: 10px; --r-lg: 16px; --r-pill: 999px; --r-bubble: 10px;
  /* каркас: все шапки одной высоты — это и есть «ровно» */
  --h-bar: 64px; --h-bar-m: 56px; --h-strip: 44px; --w-rail: 72px; --w-list: 360px; --w-panel: 300px; --w-content: 880px;
  --h-control: 40px; --touch: 44px;
  /* поверхности и текст (контраст посчитан на белом) */
  --bg-app: #eef1ef; --surface: #ffffff; --surface-2: #f4f6f5; --surface-3: #e8ecea;
  --chat-bg: #efeae2; --chat-dot: rgba(70,55,30,.07);
  --text: #16201b;      /* 16.6:1 */
  --text-2: #4a5650;    /* 7.7:1 */
  --text-3: #5d6962;    /* 5.7:1; 4.9:1 на --bubble-out; 4.8:1 на --chat-bg */
  --border: #e2e7e4; --border-strong: #c6cfca;
  /* бренд: зелёный WhatsApp-семьи остаётся */
  --accent: #1f7a4d;    /* белый на нём 5.3:1 */
  --accent-hover: #17663f; --accent-soft: #e0f1e7; --accent-text: #17633e; /* 6.2:1 на soft */
  --on-accent: #ffffff; /* везде вместо жёсткого #fff на зелёном */
  --bubble-in: #ffffff; --bubble-out: #d9f3e0;
  --danger: #b42318; --danger-soft: #fdecea; --danger-border: #f1b5ae; --on-danger: #ffffff;
  --warn: #8a5300; --warn-soft: #fff3dc; --warn-border: #efd096;
  --info: #1b5e8c; --info-soft: #e5f0f9; --info-border: #bad4ea;
  --focus: #1f7a4d; --scrim: rgba(10,20,15,.45);
  --av-ink: #16201b;    /* тёмные инициалы на пастели в обеих темах */
  --chip-mix: 42%; --av-dim: 0%;
  --sh-1: 0 1px 2px rgba(16,24,20,.06);
  --sh-bubble: 0 1px .5px rgba(11,20,16,.16);
  --sh-pop: 0 10px 30px rgba(16,24,20,.16), 0 2px 6px rgba(16,24,20,.08);
  /* палитра стадий и ярлыков — без изменений (общая с сервером, тест читает эти строки) */
  --cvet-slate: #cbd5e1;
  --cvet-sky: #7dd3fc;
  --cvet-green: #86efac;
  --cvet-amber: #fcd34d;
  --cvet-red: #fca5a5;
  --cvet-violet: #c4b5fd;
  --cvet-teal: #5eead4;
  --cvet-pink: #f9a8d4;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg-app: #0c1110; --surface: #141a18; --surface-2: #1b2320; --surface-3: #242d2a;
    --chat-bg: #0f1513; --chat-dot: rgba(255,255,255,.035);
    --text: #e6ece9; --text-2: #b0bbb5;
    --text-3: #a3aea8;    /* 4.8:1 на --bubble-out, 7.7:1 на --surface */
    --border: #26302c; --border-strong: #3a4641;
    --accent: #3fb07c;    /* тёмный текст на нём 6.9:1 */
    --accent-hover: #55c290; --accent-soft: #173a2a; --accent-text: #79d6a9; --on-accent: #04140c;
    --bubble-in: #1c2421; --bubble-out: #15452f;
    --danger: #ff8f84; --danger-soft: #3a1714; --danger-border: #6e2b25; --on-danger: #2a0705;
    --warn: #f3c46b; --warn-soft: #33260c; --warn-border: #5e4616;
    --info: #8cc4ef; --info-soft: #12283a; --info-border: #24496a;
    --focus: #79d6a9; --scrim: rgba(0,0,0,.6);
    --chip-mix: 30%; --av-dim: 22%;
    --sh-1: 0 1px 2px rgba(0,0,0,.4); --sh-bubble: 0 1px .5px rgba(0,0,0,.5);
    --sh-pop: 0 10px 30px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.4);
  }
}
/* телефон: крупнее текст строк и чипов, поля 44 px */
@media (max-width: 719px) {
  :root { --fs-sm: 14px; --fs-md: 16px; --fs-preview: 15px; --fs-chip: 13px; --h-chip: 24px; --h-control: var(--touch); }
}
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body { margin: 0; font: var(--fs-md)/var(--lh) var(--font); color: var(--text); background: var(--bg-app); -webkit-font-smoothing: antialiased; }
button, input, select, textarea { font: inherit; color: inherit; }   /* убирает Arial у входа и моноширинный шрифт у заметок */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.sr-only { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
/* цвет чипа/аватара — классом, а не style="" (CSP style-src 'self') */
.c-slate { --c: var(--cvet-slate); } .c-sky { --c: var(--cvet-sky); } .c-green { --c: var(--cvet-green); } .c-amber { --c: var(--cvet-amber); }
.c-red { --c: var(--cvet-red); } .c-violet { --c: var(--cvet-violet); } .c-teal { --c: var(--cvet-teal); } .c-pink { --c: var(--cvet-pink); }

/* Прежние имена — разделы настроек, ещё не переведённые на новые токены
   (шаг 10 спецификации), продолжают работать и в тёмной теме. */
:root {
  --fon: var(--bg-app);
  --karta: var(--surface);
  --tekst: var(--text);
  --tihiy: var(--text-3);
  --gran: var(--border-strong);
  --glavniy: var(--accent);
}

/* ===== Базовые компоненты (спецификация, §4) ===== */
.ic { width: 20px; height: 20px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.8;
      stroke-linecap: round; stroke-linejoin: round; }
.ic.sm { width: 16px; height: 16px; }
.ic.xs { width: 13px; height: 13px; stroke-width: 2.2; }
.ic.lg { width: 24px; height: 24px; }
.ic.fill { fill: currentColor; stroke: none; }

/* --- Кнопки: одна основа, варианты и размеры --- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: var(--h-control); padding: 0 var(--sp-4); border: 1px solid transparent; border-radius: var(--r-pill);
  font-size: var(--fs-sm); font-weight: var(--fw-bold); line-height: 1; white-space: nowrap; cursor: pointer;
  background: var(--surface); color: var(--text); text-decoration: none; transition: background .12s, border-color .12s; }
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { background: var(--accent-hover); }
.btn-secondary { background: var(--surface); border-color: var(--border-strong); color: var(--text); }
.btn-secondary:hover { background: var(--surface-2); }
.btn-ghost { background: transparent; color: var(--accent-text); }
.btn-ghost:hover { background: var(--accent-soft); }
.btn-danger { background: var(--danger); color: var(--on-danger); }
.btn-danger-ghost { background: transparent; color: var(--danger); }
.btn-danger-ghost:hover { background: var(--danger-soft); }
.btn-sm { min-height: 32px; padding: 0 var(--sp-3); font-size: var(--fs-xs); }
.btn-block { width: 100%; min-height: 48px; font-size: var(--fs-md); }
.btn[disabled], .btn[aria-disabled="true"] { background: var(--surface-3); color: var(--text-3); border-color: transparent; cursor: default; }
.icon-btn { display: inline-grid; place-items: center; width: 40px; height: 40px; border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--text-2); cursor: pointer; position: relative; flex: none; }
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.icon-btn.on { background: var(--accent-soft); color: var(--accent-text); }
.icon-btn .count { position: absolute; top: 0; right: -2px; min-width: 18px; height: 18px; font-size: 11px; box-shadow: 0 0 0 2px var(--surface); }

/* --- Поля --- */
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > label, .field-label { font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--text-2); }
.input, .select, .textarea { width: 100%; min-height: var(--h-control); padding: 0 var(--sp-3);
  border: 1px solid var(--border-strong); border-radius: var(--r-md); background: var(--surface); color: var(--text); }
.input::placeholder, .textarea::placeholder { color: var(--text-3); }
.input:hover, .select:hover { border-color: var(--text-3); }
.input:focus, .select:focus, .textarea:focus { outline: 2px solid var(--focus); outline-offset: -1px; border-color: transparent; }
/* select без системного вида; шеврон — ::after у обёртки, цвет из токена, работает в обеих темах */
.select { appearance: none; padding-right: 36px; cursor: pointer; background: var(--surface); }
.select-wrap { position: relative; display: block; min-width: 0; }
.select-wrap::after { content: ""; position: absolute; right: 15px; top: 50%; width: 7px; height: 7px; margin-top: -6px;
  border: solid var(--text-3); border-width: 0 1.8px 1.8px 0; transform: rotate(45deg); pointer-events: none; }
.field-hint { font-size: var(--fs-sm); color: var(--text-3); }
.field-error { display: flex; gap: 8px; align-items: flex-start; font-size: var(--fs-sm); color: var(--danger); line-height: 1.4; }
.field-error .ic { margin-top: 1px; }
.input.invalid { border-color: var(--danger); }
.prefix-input { display: flex; align-items: center; border: 1px solid var(--border-strong); border-radius: var(--r-md); background: var(--surface); }
.prefix-input span { padding: 0 2px 0 var(--sp-3); color: var(--text-2); font-weight: var(--fw-medium); font-size: 17px; }
.prefix-input .input { border: 0; min-height: 48px; font-size: 17px; letter-spacing: .02em; background: transparent; }
.prefix-input .input:focus { outline: none; }
.prefix-input:focus-within { outline: 2px solid var(--focus); outline-offset: -1px; border-color: transparent; }
.switch { appearance: none; width: 40px; height: 24px; border-radius: var(--r-pill); background: var(--border-strong);
  position: relative; cursor: pointer; flex: none; margin: 0; transition: background .15s; }
.switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; box-shadow: var(--sh-1); transition: transform .15s; }
.switch:checked { background: var(--accent); }
.switch:checked::after { transform: translateX(16px); }

/* --- Чипы: стадия (заливка) / ярлык (обводка) / ожидание / ничей --- */
.chip { display: inline-flex; align-items: center; gap: 5px; height: var(--h-chip); padding: 0 8px; border-radius: var(--r-pill);
  font-size: var(--fs-chip); font-weight: var(--fw-medium); white-space: nowrap; color: var(--text); flex: none; }
.chip::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--c); flex: none;
  box-shadow: 0 0 0 1px rgba(0,0,0,.18) inset; }
.chip.stage { background: var(--surface-3); background: color-mix(in srgb, var(--c) var(--chip-mix), var(--surface)); }
.chip.stage::before { background: color-mix(in srgb, var(--c), #000 22%); }
.chip.label { border: 1px solid var(--border-strong); background: var(--surface); }
.chip.more { border: 1px solid var(--border-strong); background: var(--surface-2); color: var(--text-2); font-weight: var(--fw-bold); padding: 0 7px; }
.chip.more::before { display: none; }
.chip .chip-x { display: inline-grid; place-items: center; width: 20px; height: 20px; margin-right: -4px; border: 0; border-radius: 50%;
  background: transparent; color: var(--text-2); cursor: pointer; padding: 0; }
.chip .chip-x:hover { background: var(--surface-3); color: var(--text); }
.chip.big { height: 30px; padding: 0 6px 0 10px; font-size: var(--fs-sm); }
.wait { display: inline-flex; align-items: center; gap: 4px; height: var(--h-chip); padding: 0 8px; border-radius: var(--r-pill);
  font-size: var(--fs-chip); font-weight: var(--fw-bold); white-space: nowrap; flex: none; }
.wait.t0 { background: var(--surface-3); color: var(--text-2); }       /* до 15 мин */
.wait.t1 { background: var(--warn-soft); color: var(--warn); }         /* 15–60 мин */
.wait.t2 { background: var(--danger-soft); color: var(--danger); }     /* больше часа */
/* «никем не занят»: пунктирная обводка + точка-кольцо — не держится на одном цвете и не путается с залитой стадией */
.free { display: inline-flex; align-items: center; gap: 5px; height: var(--h-chip); padding: 0 8px; border-radius: var(--r-pill);
  border: 1.5px dashed var(--accent); background: transparent; color: var(--accent-text); font-size: var(--fs-chip); font-weight: var(--fw-bold); white-space: nowrap; flex: none; }
.free::before { content: ""; width: 7px; height: 7px; border-radius: 50%; border: 1.5px solid currentColor; flex: none; }
/* «ведёт бот» вместо «никем не занят» у бот-диалога: тот же размер и место, но без пунктира и кольца - диалог не ждёт, пока его возьмут, им уже занимается бот;
   нейтральная заливка и тёмный текст читаются в обеих темах (токены поверхностей и текста переопределены для тёмной) */
.bot-owner { display: inline-flex; align-items: center; gap: 5px; height: var(--h-chip); padding: 0 8px; border-radius: var(--r-pill);
  border: 1px solid var(--border-strong); background: var(--surface-2); color: var(--text-2); font-size: var(--fs-chip); font-weight: var(--fw-bold); white-space: nowrap; flex: none; }
.bot-owner::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.count { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--r-pill);
  background: var(--accent); color: var(--on-accent); font-size: var(--fs-xs); font-weight: var(--fw-bold); line-height: 1; flex: none; }
.count.muted { background: var(--surface-3); color: var(--text-2); }

/* --- Аватар --- */
.av { display: inline-grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; flex: none;
  background: var(--cvet-slate); /* фолбэк для iOS ≤16.1 без color-mix */
  background: color-mix(in srgb, var(--c, var(--cvet-slate)), #000 var(--av-dim, 0%)); color: var(--av-ink); font-weight: var(--fw-bold); font-size: 17px; letter-spacing: .02em; }
.av.s36 { width: 36px; height: 36px; font-size: 14px; }
.av.s40 { width: 40px; height: 40px; font-size: 15px; }
.av.s20 { width: 20px; height: 20px; font-size: 9px; }
.av.s72 { width: 72px; height: 72px; font-size: 26px; }
.av.unknown { background: var(--surface-3); color: var(--text-2); }

/* --- Баннер (одна форма для связи, канала, справочников, ошибок ленты) --- */
.banner { display: flex; gap: var(--sp-3); align-items: flex-start; padding: var(--sp-3) var(--sp-4);
  border: 1px solid; border-radius: var(--r-md); font-size: var(--fs-sm); line-height: 1.4; }
.banner > .ic { margin-top: 1px; }
.banner b { display: block; font-size: var(--fs-md); margin-bottom: 2px; }
.banner .banner-body { flex: 1; min-width: 0; }
.banner .banner-body p { margin: 0; color: var(--text-2); }
.banner .btn { align-self: center; }
.banner.info { background: var(--info-soft); border-color: var(--info-border); color: var(--text); }
.banner.info > .ic { color: var(--info); }
.banner.warn { background: var(--warn-soft); border-color: var(--warn-border); color: var(--text); }
.banner.warn > .ic { color: var(--warn); }
.banner.danger { background: var(--danger-soft); border-color: var(--danger-border); color: var(--text); }
.banner.danger > .ic { color: var(--danger); }
.banner.flat { border-radius: 0; border-width: 0 0 1px; }
/* Полоса паузы бота над лентой (bot_pause.js): слово, затем кнопка; на узком экране кнопка уходит под слово, а не за край, и горизонтальной прокрутки нет */
.bot-pause { flex-wrap: wrap; align-items: center; justify-content: space-between; }
.bot-pause-text { flex: 1 1 220px; min-width: 0; overflow-wrap: anywhere; }
/* «Ответ не нужен» (components/no_reply.js): вопрос и итог — полосой над
   лентой, как пауза бота; кнопки уходят под текст, когда тесно. */
.no-reply-confirm, .no-reply-note { flex-wrap: wrap; align-items: center; }
.no-reply-confirm .banner-body, .no-reply-note .banner-body { flex: 1 1 220px; min-width: 0; }
.no-reply-actions { display: flex; gap: var(--sp-2); flex: none; }
.no-reply-ask { flex: none; white-space: nowrap; }

/* --- Пустое состояние --- */
.empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--sp-2);
  padding: var(--sp-8) var(--sp-6); color: var(--text-2); }
.empty .empty-ic { display: grid; place-items: center; width: 64px; height: 64px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-text); margin-bottom: var(--sp-2); }
.empty .empty-ic .ic { width: 28px; height: 28px; }
.empty h3 { margin: 0; font-size: var(--fs-lg); color: var(--text); }
.empty p { margin: 0; max-width: 36ch; font-size: var(--fs-sm); }
.empty .btn { margin-top: var(--sp-3); }

/* --- Скелетон --- */
.sk { background: linear-gradient(90deg, var(--surface-3) 0, var(--surface-2) 50%, var(--surface-3) 100%);
  background-size: 200% 100%; animation: sk 1.2s linear infinite; border-radius: var(--r-sm); }
@keyframes sk { to { background-position: -200% 0; } }
.chip[hidden] { display: none !important; }
.splash { min-height: 100%; display: grid; place-content: center; justify-items: center; gap: 14px; padding: 36px 16px;
  color: var(--text-2); font-size: var(--fs-sm); background: var(--bg-app); }
.spinner { width: 28px; height: 28px; border-radius: 50%; border: 3px solid var(--accent-soft); border-top-color: var(--accent);
  animation: spin .9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ===== Экраны ===== */
/* Вход (шаг 9, кадры d-login, m-login, m-login-code): карточка на мягком
   градиенте; та же карточка у страницы «нет связи» (offline.html). */
.login-wrap { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; align-items: center; padding: 9vh var(--sp-4) var(--sp-6);
  background: var(--bg-app); background: radial-gradient(120% 45% at 50% 0%, var(--accent-soft), transparent 70%), var(--bg-app); }
.login { width: 100%; max-width: 380px; display: flex; flex-direction: column; gap: var(--sp-4); padding: var(--sp-6) var(--sp-5);
  background: var(--surface); border: 1px solid var(--border); border-radius: 20px; box-shadow: var(--sh-pop); }
.login-brand { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; margin-bottom: var(--sp-1); }
.login-brand .logo-mark { width: 56px; height: 56px; border-radius: 16px; font-size: 26px; margin-bottom: 4px; }
.login-brand h1 { margin: 0; font-size: var(--fs-2xl); line-height: 1.2; }
.login-brand p { margin: 0; color: var(--text-2); font-size: var(--fs-sm); }
.login .field-hint, .login .field-error { margin: 0; }
.login .btn-block .ic { width: 18px; height: 18px; }
.login-foot { margin: var(--sp-5) 0 0; max-width: 340px; text-align: center; font-size: var(--fs-sm); color: var(--text-2); }
.login-product { margin: var(--sp-6) 0 0; font-size: var(--fs-xs); color: var(--text-3); display: flex; align-items: center; gap: 6px; }
.login-product .logo-mark { width: 18px; height: 18px; border-radius: 5px; font-size: 10px; }
.code-input { text-align: center; font-size: 26px; letter-spacing: .5em; min-height: 56px; font-variant-numeric: tabular-nums; padding-left: .5em; }
.sent-to { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); padding: var(--sp-2) var(--sp-1) var(--sp-2) var(--sp-3);
  background: var(--surface-2); border-radius: var(--r-md); font-size: var(--fs-sm); color: var(--text-2); }
.sent-to b { display: block; font-size: var(--fs-md); color: var(--text); font-variant-numeric: tabular-nums; }
.resend { margin: 0; text-align: center; font-size: var(--fs-sm); color: var(--text-3); }
@media (min-width: 720px) {
  .login-wrap { justify-content: center; padding: var(--sp-8); }
  .login { max-width: 400px; padding: var(--sp-8) var(--sp-8) var(--sp-6); }
}
.offline .offline-retry { margin-top: var(--sp-1); }
.splash .logo-mark { width: 56px; height: 56px; border-radius: 16px; font-size: 26px; }
.splash p { margin: 0; }
.splash { min-height: 100vh; min-height: 100dvh; }

.note { margin: 0; color: var(--tihiy); }

/* ===== Каркас окна (шаг 3 спецификации) =====
   Рейл 72 px слева и место (переписка или настройки) справа. На телефоне тот
   же nav.rail становится таб-баром снизу (блок @media в конце файла). */
.app-shell {
  display: grid;
  grid-template-columns: var(--w-rail) minmax(0, 1fr);
  height: 100vh;
  /* На телефоне 100vh — высота БЕЗ панели адреса и клавиатуры, и нижняя
     строка окна (поле ответа) уезжала под них. dvh — видимая сейчас высота;
     браузер без dvh возьмёт строку выше. */
  height: 100dvh;
  background: var(--surface);
  overflow: hidden;
}
.place { min-width: 0; min-height: 0; display: flex; flex-direction: column; }
/* Полосы о связи и канале — во всю ширину окна, над рейлом тоже (ревью
   ветки): окно отступает сверху на их высоту (--banner-h ставит
   ShellBanners в chat.js), и линия шапок в 64 px остаётся ровной. */
.app-shell { position: relative; padding-top: var(--banner-h, 0px); }
.app-shell .shell-banners { position: absolute; top: 0; left: 0; right: 0; z-index: 6; }
.shell-banners:empty { display: none; }

.rail { display: flex; flex-direction: column; align-items: center; gap: var(--sp-1); padding-bottom: var(--sp-3);
  background: var(--surface-2); border-right: 1px solid var(--border); min-height: 0; }
.rail-logo { display: grid; place-items: center; height: var(--h-bar); width: 100%; border-bottom: 1px solid var(--border); margin-bottom: var(--sp-2); flex: none; }
.logo-mark { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 12px; background: var(--accent);
  color: var(--on-accent); font-weight: 700; font-size: 19px; }
.rail-item { display: flex; flex-direction: column; align-items: center; gap: 3px; width: 64px; padding: 6px 0 4px;
  border: 0; background: transparent; color: var(--text-2); font-size: 11px; font-weight: var(--fw-medium);
  cursor: pointer; border-radius: var(--r-md); text-decoration: none; position: relative; }
.rail-item .pill { display: grid; place-items: center; width: 52px; height: 32px; border-radius: var(--r-pill); }
.rail-item:hover .pill { background: var(--surface-3); }
.rail-item.active { color: var(--accent-text); font-weight: var(--fw-bold); }
.rail-item.active .pill { background: var(--accent-soft); }
.rail-item .count { position: absolute; top: 0; right: 2px; min-width: 18px; height: 18px; font-size: 11px; box-shadow: 0 0 0 2px var(--surface-2); }
.rail-spacer { flex: 1; }
.rail-me-wrap { position: relative; }
.rail-me { border: 0; padding: 0; background: none; cursor: pointer; border-radius: 50%; display: block; }
.rail-me.on .av { box-shadow: 0 0 0 2px var(--surface-2), 0 0 0 4px var(--accent); }

/* Меню сотрудника (рейл → аватар) */
.popover { position: absolute; z-index: 20; min-width: 270px; padding: var(--sp-2); border-radius: var(--r-lg); background: var(--surface);
  border: 1px solid var(--border); box-shadow: var(--sh-pop); }
.me-menu { left: calc(100% + 10px); bottom: 0; }
.pop-head { display: flex; gap: var(--sp-3); align-items: center; padding: var(--sp-2) var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--border); margin-bottom: var(--sp-1); }
.pop-head .nm { font-weight: var(--fw-bold); }
.pop-head .rl { font-size: var(--fs-sm); color: var(--text-2); }
.menu-note { display: flex; align-items: center; gap: var(--sp-2); margin: 0; padding: 6px var(--sp-2); font-size: var(--fs-sm); color: var(--text-2); }
.menu-item { display: flex; align-items: center; gap: var(--sp-3); width: 100%; min-height: 40px; padding: 0 var(--sp-2); border: 0; border-radius: var(--r-sm);
  background: transparent; text-align: left; cursor: pointer; font-size: var(--fs-md); color: var(--text); }
.menu-item:hover { background: var(--surface-2); }
.menu-item .ic { color: var(--text-2); }
.menu-item.danger, .menu-item.danger .ic { color: var(--danger); }
.menu-item[disabled] { opacity: .6; cursor: default; }
.menu-error { padding: 6px var(--sp-2); margin: 0; }

/* Шапка любой колонки: высота одна на всех — это и есть «ровно» */
.bar { display: flex; align-items: center; gap: var(--sp-3); height: var(--h-bar); padding: 0 var(--sp-4);
  border-bottom: 1px solid var(--border); background: var(--surface); flex: none; min-width: 0; }
.bar-title { min-width: 0; flex: 1; }
.bar-title h1, .bar-title h2 { margin: 0; font-size: var(--fs-lg); font-weight: var(--fw-bold); line-height: var(--lh-tight);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-sub { display: flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--accent); }
.dot.bad { background: var(--danger); }
.dot.off { background: var(--text-3); }

/* Плашка канала под названием салона */
.channel-pill { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-height: 22px; margin: 2px 0 0 -6px; padding: 0 8px 0 6px;
  border: 0; border-radius: var(--r-pill); background: transparent; color: var(--text-2); font-size: var(--fs-xs); text-align: left; }
.channel-pill .t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.channel-pill.warn { background: var(--warn-soft); color: var(--warn); font-weight: var(--fw-bold); margin-left: 0; }
.channel-pill.warn .dot { background: var(--warn); }
.channel-pill.bad { background: var(--danger-soft); color: var(--danger); font-weight: var(--fw-bold); margin-left: 0; }
.channel-pill.bad .dot { background: var(--danger); }
/* Плашка-кнопка — тем, кому открыт раздел «Салон и WhatsApp» (chat.js). */
.channel-pill.as-button { cursor: pointer; font: inherit; font-size: var(--fs-xs); }
.channel-pill.as-button:hover { background: var(--surface-2); color: var(--text); }
.channel-pill.as-button.warn:hover { background: var(--warn-soft); color: var(--warn); }
.channel-pill.as-button.bad:hover { background: var(--danger-soft); color: var(--danger); }
.channel-pill .ic { width: 12px; height: 12px; flex: none; color: currentColor; opacity: .7; }

/* Переписка: полосы сверху, под ними — колонки */
.chat-shell { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.chat-screen { flex: 1; min-height: 0; display: grid; grid-template-columns: var(--w-list) minmax(0, 1fr); position: relative; }
.sidebar { display: flex; flex-direction: column; min-width: 0; min-height: 0; border-right: 1px solid var(--border); background: var(--surface); }
.sidebar > .banner { margin: var(--sp-2) var(--sp-3) 0; }
.sidebar > .empty { flex: 1; justify-content: center; }
.conversation { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--chat-bg); position: relative; }
.pick-empty { flex: 1; display: grid; place-items: center; background: var(--chat-bg); }

/* Шапка диалога: аватар, имя, «номер · кто ведёт», одна кнопка */
.dialog-header { display: flex; align-items: center; gap: var(--sp-3); flex: 1; min-width: 0; }
.dh-text { flex: 1; min-width: 0; }
.dh-name { margin: 0; font-size: var(--fs-md); font-weight: var(--fw-bold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.3; }
.dh-sub { font-size: var(--fs-sm); color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dh-sub .me { color: var(--accent-text); font-weight: var(--fw-bold); }
.dialog-assign { flex: none; }
.dialog-back { display: none; }
.conv-tools { display: flex; gap: 2px; align-items: center; flex: none; }
.conv-tools .sep { width: 1px; height: 24px; background: var(--border); margin: 0 6px; }
.conversation > .banner:not(.flat) { margin: var(--sp-2) var(--sp-3) 0; flex: none; }
.dialog-header-error { flex: none; }

/* Ширина списка: на 720–1279 он уже, переписке остаётся больше (кадр d-1024) */
@media (max-width: 1279px) {
  :root { --w-list: 320px; }
}

/* ===== Список диалогов (шаг 8 спецификации) =====
   Вкладки-пилюли, строка из трёх линий: имя и срочность / превью и счётчик /
   стадия, ярлыки и кто ведёт. Состояния: скелетон, пустая вкладка, отказ
   первой загрузки, конец очереди «Ждут ответа». */
.dialog-list { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.dialog-tabs { display: flex; gap: 6px; padding: var(--sp-2) var(--sp-3); flex: none; overflow-x: auto; scrollbar-width: none; }
.dialog-tabs button { display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px; border-radius: var(--r-pill);
  border: 0; background: var(--surface-2); color: var(--text-2); font-size: var(--fs-sm); font-weight: var(--fw-medium); cursor: pointer; white-space: nowrap; flex: none; }
.dialog-tabs button:hover { background: var(--surface-3); }
.dialog-tabs button.active { background: var(--accent-soft); color: var(--accent-text); font-weight: var(--fw-bold); }
.dialog-tabs .n { font-size: var(--fs-xs); font-weight: var(--fw-bold); }
.dialog-tabs .n.hot { color: var(--on-accent); background: var(--accent); border-radius: var(--r-pill); padding: 1px 6px; }
/* Поиск по имени и номеру клиента (решение владельца 7 октября 2026, кадр
   d-chat): поле над вкладками. Свой крестик вместо браузерного — у type=search
   в Chromium он свой, и двух крестиков рядом быть не должно. На телефоне поле
   открывается лупой в шапке списка (блок @media в конце файла). */
.list-tools { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3) 0; flex: none; }
.list-tools .dialog-tabs { padding: 0 0 var(--sp-2); }
.search { display: flex; align-items: center; gap: var(--sp-2); height: 36px; padding: 0 var(--sp-1) 0 var(--sp-3); border-radius: var(--r-md);
  background: var(--surface-2); color: var(--text-3); }
.search input { border: 0; background: transparent; flex: 1; min-width: 0; height: 100%; padding: 0; outline: none; color: var(--text);
  font: inherit; font-size: var(--fs-sm); }
.search input::placeholder { color: var(--text-3); }
.search input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; display: none; }
.search:focus-within { outline: 2px solid var(--focus); outline-offset: -2px; }
.search-clear { display: inline-grid; place-items: center; width: 28px; height: 28px; border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--text-2); cursor: pointer; flex: none; }
.search-clear:hover { background: var(--surface-3); color: var(--text); }
.list-search-toggle { display: none; }
.search-empty h3 { overflow-wrap: anywhere; }
.dialog-rows { list-style: none; margin: 0; padding: 0; overflow-y: auto; flex: 1; min-height: 0; border-top: 1px solid var(--border); }

.dialog-row { display: grid; grid-template-columns: 48px minmax(0, 1fr); gap: var(--sp-3); padding: 0 0 0 var(--sp-3);
  cursor: pointer; position: relative; outline-offset: -2px; }
.dialog-row:hover { background: var(--surface-2); }
.dialog-row.selected { background: var(--accent-soft); }
.dialog-row.selected::before { content: ""; position: absolute; left: 0; top: 8px; bottom: 8px; width: 3px; border-radius: 0 3px 3px 0; background: var(--accent); }
.dialog-row > .av { margin-top: 12px; }
.dialog-row-body { display: flex; flex-direction: column; gap: 4px; padding: 10px var(--sp-3) 10px 0; border-bottom: 1px solid var(--border); min-width: 0; }
.dialog-row.selected .dialog-row-body { border-bottom-color: transparent; }
.rline { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.dialog-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-md); font-weight: var(--fw-medium); }
.needs-reply .dialog-name { font-weight: var(--fw-bold); }
.dialog-time { font-size: var(--fs-xs); color: var(--text-3); flex: none; }
.dialog-preview { flex: 1; min-width: 0; font-size: var(--fs-preview); color: var(--text-2); display: flex; align-items: center; gap: 4px; }
.dialog-preview .t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.needs-reply .dialog-preview:not(.muted) { color: var(--text); }
.dialog-preview.muted { color: var(--text-3); font-variant-numeric: tabular-nums; }
.dialog-phone { font-variant-numeric: tabular-nums; }
.dialog-preview .you { color: var(--text-3); flex: none; }
.dialog-preview .ic { color: var(--text-3); }
.dialog-preview .ic.ok { color: var(--accent-text); }
.dialog-preview .ic.bad { color: var(--danger); }
.dialog-chips { flex: 1; min-width: 0; display: flex; flex-wrap: nowrap; gap: 4px; overflow: hidden; }
.dialog-chips .chip { flex: none; }
.dialog-owner { display: inline-flex; align-items: center; gap: 5px; flex: none; font-size: var(--fs-chip); color: var(--text-2); max-width: 45%; }
.dialog-owner .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dialog-owner.me { color: var(--accent-text); font-weight: var(--fw-bold); }

/* Конец вкладки «Ждут ответа» (из C) */
.list-end { list-style: none; padding: var(--sp-5) var(--sp-6) var(--sp-8); text-align: center; font-size: var(--fs-sm); color: var(--text-3); }
.list-end .ic { display: block; margin: 0 auto 6px; color: var(--accent-text); }
/* Пустая вкладка и отказ первой загрузки — по центру колонки */
.list-empty { flex: 1; justify-content: center; border-top: 1px solid var(--border); }
.empty .empty-ic.bad { background: var(--danger-soft); color: var(--danger); }
.empty .empty-detail { font-size: var(--fs-xs); color: var(--text-3); overflow-wrap: anywhere; }
/* Скелетон списка: пять строк-заготовок вместо «Загрузка…» */
.dialog-skeleton { flex: 1; min-height: 0; overflow: hidden; border-top: 1px solid var(--border); padding: var(--sp-2) 0; }
.sk-row { display: grid; grid-template-columns: 48px minmax(0, 1fr); gap: var(--sp-3); padding: 10px var(--sp-3); }
.sk-av { width: 48px; height: 48px; border-radius: 50%; }
.sk-lines { display: flex; flex-direction: column; gap: 8px; padding-top: 4px; }
.sk-lines .sk { display: block; height: 10px; }
.sk-l1 { width: 55%; } .sk-l2 { width: 85%; } .sk-l3 { width: 35%; }

/* ===== Лента переписки (шаг 4 спецификации) =====
   Пузыри с хвостиком, время внутри пузыря, разделители дней, фон с точками.
   .message-list — прокручиваемая область, .feed — её содержимое: за высотой
   обоих следит ResizeObserver (лента держится у нижнего края, В12). */
.message-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  background-color: var(--chat-bg); background-image: radial-gradient(var(--chat-dot) 1.1px, transparent 1.4px); background-size: 20px 20px; }
.feed { display: flex; flex-direction: column; gap: 2px; min-height: 100%; justify-content: flex-end;
  padding: var(--sp-3) clamp(16px, 6%, 72px) var(--sp-3); }
.message-list-empty { margin: auto; color: var(--text-3); }
.day { align-self: center; margin: var(--sp-2) 0; padding: 4px 12px; border-radius: var(--r-sm); background: var(--surface);
  box-shadow: var(--sh-bubble); font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--text-2); }
.load-older {
  align-self: center;
  /* margin: 0 — не косметика. Надпись «Загружаем…» это <p>, у которого от
     браузера свои отступы сверху и снизу, а кнопка — <button> без них. Пока
     отступы были разные, замена кнопки на надпись меняла высоту ленты НАД
     тем, что читает оператор, и его место уезжало на два десятка точек в
     момент нажатия «загрузить ещё» — замерено живьём (задача 13). Одинаковая
     коробка у обоих состояний убирает смещение в источнике, не поправкой
     прокрутки задним числом. */
  margin: 0 0 var(--sp-2);
  padding: 6px 14px;
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  cursor: pointer;
}
/* Рамки нет, но её место остаётся за прозрачной рамкой той же толщины —
   иначе коробка снова станет на две точки ниже кнопки. */
.load-older.loading { border-color: transparent; background: none; cursor: default; }

.msg { display: flex; flex-direction: column; align-items: flex-start; }
.msg.out { align-items: flex-end; }
.msg[data-tail] { margin-top: 8px; }   /* хвостик — атрибутом: тест требует class="msg out" ровно */
.day + .msg { margin-top: 0; }
.bubble { position: relative; max-width: min(540px, 72%); padding: 6px 9px 7px 10px; border-radius: var(--r-bubble);
  background: var(--bubble-in); box-shadow: var(--sh-bubble); font-size: var(--fs-md); line-height: 1.4; overflow-wrap: anywhere; }
.msg.out .bubble { background: var(--bubble-out); }
.msg.in[data-tail] .bubble { border-top-left-radius: 3px; }
.msg.out[data-tail] .bubble { border-top-right-radius: 3px; }
.msg-text { margin: 0; display: inline; white-space: pre-wrap; }
.msg-meta { float: right; display: inline-flex; align-items: center; gap: 3px; margin: 8px 0 -5px 12px; font-size: 11px; color: var(--text-3); line-height: 1; }
.msg-status { display: inline-flex; align-items: center; gap: 3px; }
.msg-status.sent { color: var(--accent-text); font-weight: 700; }
.msg-status.failed { color: var(--danger); }
.msg-status.held { color: var(--warn); }
.msg[data-state="failed"] .bubble { box-shadow: 0 0 0 1.5px var(--danger-border); }
.msg[data-state="held"] .bubble { box-shadow: 0 0 0 1.5px var(--warn-border); }
.msg-fail { display: flex; align-items: center; gap: 6px var(--sp-2); flex-wrap: wrap; justify-content: flex-end; max-width: min(540px, 84%);
  margin-top: 5px; font-size: var(--fs-xs); color: var(--danger); font-weight: var(--fw-bold); text-align: right; }
.msg.in .msg-fail { justify-content: flex-start; }
.msg-fail.held { color: var(--warn); }
.msg-fail .why { font-weight: var(--fw-medium); color: var(--text-2); }
.msg-fail .fail-t { display: inline-flex; align-items: flex-start; gap: 6px; text-align: left; flex: 0 1 auto; min-width: 0; line-height: 1.35; }
.msg-fail .fail-t .ic { margin-top: 1px; }
.msg-retry { display: inline-flex; align-items: center; gap: 5px; height: 32px; padding: 0 10px; border-radius: var(--r-pill);
  border: 1px solid var(--danger-border); background: var(--surface); color: var(--danger); font-size: var(--fs-xs); font-weight: var(--fw-bold); cursor: pointer; }
.msg-fail.held .msg-retry { border-color: var(--warn-border); color: var(--warn); }
.msg-fail .msg-edit { border-color: var(--border-strong); color: var(--text-2); }
.msg-note { margin: 4px 0 0; max-width: min(540px, 84%); font-size: var(--fs-xs); color: var(--text-2); text-align: right; }

/* Фото: 260 в ширину, высота — по размерам от сервера; без них 4:3 */
.bubble.media { padding: 3px; }
.msg-image-link { display: block; border-radius: 8px; overflow: hidden; line-height: 0; }
.msg-image { display: block; width: 260px; height: auto; max-width: 100%; background: var(--surface-3); }
.msg-image.no-size { aspect-ratio: 4 / 3; object-fit: cover; }
.bubble:not(.media) .msg-image-link { margin: -3px -6px 4px -7px; }
.bubble.media .msg-meta { position: absolute; right: 9px; bottom: 9px; margin: 0; float: none; color: #fff;
  text-shadow: 0 1px 3px rgba(0,0,0,.6); }
.bubble.media .msg-status.sent { color: #fff; }

/* Файл: плитка типа, имя, размер, «скачать» */
.msg-file { display: grid; grid-template-columns: 40px minmax(0, 1fr) 32px; gap: var(--sp-3); align-items: center; min-width: min(240px, 100%);
  padding: 8px; margin: -2px -3px 4px; border-radius: 8px; background: var(--surface-2);
  background: color-mix(in srgb, var(--text) 5%, transparent); text-decoration: none; color: inherit; }
.msg-file.gone { grid-template-columns: 40px minmax(0, 1fr); }
.msg-file.gone p { margin: 0; font-size: var(--fs-sm); color: var(--text-2); overflow-wrap: anywhere; }
.file-tile { display: grid; place-items: center; width: 40px; height: 48px; border-radius: 6px; background: var(--danger-soft); color: var(--danger);
  font-size: 11px; font-weight: 800; letter-spacing: .03em; overflow: hidden; }
.msg-file.gone .file-tile { background: var(--surface-3); color: var(--text-2); }
.file-text { display: flex; flex-direction: column; min-width: 0; }
.file-name { font-size: var(--fs-sm); font-weight: var(--fw-medium); overflow-wrap: anywhere; line-height: 1.3; }
.file-meta { font-size: var(--fs-xs); color: var(--text-3); }
.file-dl { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--border-strong); color: var(--text-2); }
/* Голосовое, аудио, видео — проигрыватель в ленте (message_list.js MediaPlayer). */
.msg-media { display: flex; flex-direction: column; gap: 6px; min-width: min(260px, 100%); margin: -2px -3px 4px; }
/* 280: уже этого Chrome прячет у проигрывателя время «0:03 / 0:12». Ширина
   задана числом: пузырь подстраивается под содержимое, и процент от него
   замыкался бы сам на себя; потолок — от ширины экрана телефона. */
.msg-media.audio { width: 280px; max-width: calc(100vw - 96px); padding: 8px; border-radius: 8px; background: var(--surface-2);
  background: color-mix(in srgb, var(--text) 5%, transparent); }
.media-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-2); }
.media-title { font-size: var(--fs-sm); font-weight: var(--fw-medium); overflow-wrap: anywhere; }
.media-meta { font-size: var(--fs-xs); color: var(--text-3); white-space: nowrap; }
.msg-media audio { width: 100%; min-width: 0; height: 40px; }
.msg-media video { display: block; max-width: 100%; border-radius: 8px; background: #000; }
.msg-media video.no-size { width: 260px; aspect-ratio: 16 / 9; height: auto; }
.media-dl { display: inline-flex; align-items: center; gap: 4px; align-self: flex-start; font-size: var(--fs-xs); color: var(--accent-text); text-decoration: none; }
.media-dl:hover { text-decoration: underline; }
.media-broken { margin: 0; font-size: var(--fs-sm); color: var(--text-2); }
.msg-attachment-gone .msg-image.partial { width: 200px; margin-bottom: 4px; opacity: .7; border-radius: 8px; }

/* Фото крупно — поверх окна */
.viewer { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: 56px 16px 16px;
  background: rgba(0,0,0,.85); }
.viewer img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 4px; }
.viewer-bar { position: absolute; top: 8px; right: 8px; display: flex; gap: var(--sp-2); align-items: center; }
.viewer-close { color: #fff; }
.viewer-close:hover { background: rgba(255,255,255,.15); color: #fff; }

/* ===== Поле ответа (шаг 5 спецификации): скрепка | текст | «Отправить» =====
   Поле — пилюля в одну строку, растёт до 160 px. На компьютере кнопка со
   словом, на телефоне круглая (слово — для экранного чтеца). */
.composer { display: flex; flex-direction: column; gap: 6px; padding: 10px var(--sp-4); background: var(--surface-2); border-top: 1px solid var(--border); flex: none; }
.composer-extra { display: flex; flex-direction: column; gap: 6px; padding: 0 0 0 52px; }
.composer-error { margin: 0; }
.composer-file { display: inline-flex; align-self: flex-start; align-items: center; gap: 6px; max-width: 100%; margin: 0; height: 30px; padding: 0 6px 0 10px;
  border: 1px solid var(--border-strong); border-radius: var(--r-pill); background: var(--surface); font-size: var(--fs-sm); }
.composer-file .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.composer-file .ic { color: var(--text-2); }
.chip-x { display: inline-grid; place-items: center; width: 20px; height: 20px; border: 0; border-radius: 50%;
  background: transparent; color: var(--text-2); cursor: pointer; padding: 0; flex: none; }
.chip-x:hover { background: var(--surface-3); color: var(--text); }
.composer-row { display: flex; align-items: flex-end; gap: var(--sp-2); }
.attach { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; color: var(--text-2); cursor: pointer; flex: none; position: relative; }
.attach:hover { background: var(--surface-3); }
.attach:focus-within { outline: 2px solid var(--focus); outline-offset: 2px; }
.attach input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.composer-text { flex: 1; min-width: 0; min-height: 44px; max-height: 160px; padding: 11px 16px; border: 1px solid var(--border); border-radius: 22px;
  background: var(--surface); color: var(--text); resize: none; line-height: 1.4; overflow-y: auto; field-sizing: content; }
.composer-text::placeholder { color: var(--text-3); }
.composer-text:focus { outline: 2px solid var(--focus); outline-offset: -1px; }
.composer-send { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 44px; padding: 0 18px 0 14px; border: 0; border-radius: var(--r-pill); flex: none;
  background: var(--accent); color: var(--on-accent); font-weight: var(--fw-bold); font-size: var(--fs-sm); cursor: pointer; }
.composer-send .ic { width: 18px; height: 18px; }
.composer-send:hover { background: var(--accent-hover); }
.composer-send[disabled] { background: var(--accent-soft); color: var(--accent-text); cursor: default; opacity: .75; }

/* Вместо поля, когда писать клиенту нельзя: одна-две строки с замком */
.composer-closed { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); background: var(--surface-2);
  border-top: 1px solid var(--border); font-size: var(--fs-sm); color: var(--text-2); flex: none; min-height: 65px; }
.composer-closed > .ic { color: var(--text-3); }
.composer-closed span { flex: 1; }
.composer-closed .btn { flex: none; }

/* ===== Настройки: каркас (шаг 10 спецификации, кадры d-settings, m-settings) =====
   Компьютер: навигация 300 px с группами и «Выйти» последней строкой,
   справа шапка 64 (раздел, строка пояснения, «← К переписке») и карточки
   шириной до 880. Телефон: «меню → раздел» (блок @media в конце файла). */
.settings-shell { display: grid; grid-template-columns: 300px minmax(0, 1fr); flex: 1; min-height: 0; background: var(--surface); }
.settings-nav { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--border); background: var(--surface); }
.settings-sections { flex: 1; min-height: 0; overflow-y: auto; padding: 0 var(--sp-2) var(--sp-4); }
.nav-group { margin: var(--sp-4) var(--sp-3) var(--sp-1); font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--text-3); }
.nav-item { display: flex; align-items: center; gap: var(--sp-3); width: 100%; min-height: 40px; padding: 0 var(--sp-3); border: 0; border-radius: var(--r-md);
  background: transparent; color: var(--text); cursor: pointer; text-align: left; font-size: var(--fs-md); }
.nav-item .ic { color: var(--text-2); }
.nav-item:hover { background: var(--surface-2); }
.nav-item.active { background: var(--accent-soft); color: var(--accent-text); font-weight: var(--fw-bold); }
.nav-item.active .ic { color: var(--accent-text); }
.nav-item > span:not(.tx) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.nav-item .chev { display: none; margin-left: auto; color: var(--text-3); }
.nav-item.danger, .nav-item.danger .ic { color: var(--danger); }
.nav-item[disabled] { opacity: .6; cursor: default; }
.nav-profile { display: none; }
.nav-pending { margin: var(--sp-3); font-size: var(--fs-sm); color: var(--text-3); }
.nav-sep { height: 1px; background: var(--border); margin: var(--sp-3) var(--sp-3) var(--sp-2); }
.settings-signout .field-error { padding: var(--sp-1) var(--sp-3); margin: 0; }
.settings-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.bar-h { margin: 0; font-size: var(--fs-lg); font-weight: var(--fw-bold); line-height: var(--lh-tight);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.settings-up { display: none; }
.settings-back { flex: none; }
.settings-content { flex: 1; min-height: 0; overflow-y: auto; background: var(--bg-app); min-width: 0; }
.settings-inner { max-width: var(--w-content); padding: var(--sp-6) var(--sp-8) var(--sp-10); }
.settings-inner > .banner { margin-bottom: var(--sp-4); }
/* Заголовок раздела уже стоит в шапке справа — внутри раздела он для
   экранного чтеца (тексты экранов сохранены, §6). */
.section-title { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.page-lead { margin: 0 0 var(--sp-5); color: var(--text-2); font-size: var(--fs-md); max-width: 62ch; }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1); min-width: 0; }
.card + .card, .card + .banner, .banner + .card { margin-top: var(--sp-5); }
.card-title { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-4) var(--sp-5) 0; margin: 0; font-size: var(--fs-md); font-weight: var(--fw-bold); }
.card-title .aside { margin-left: auto; font-weight: var(--fw-medium); color: var(--text-3); font-size: var(--fs-sm); }
.card-title .ic { color: var(--accent-text); }
.card-lead { margin: var(--sp-2) var(--sp-5) 0; color: var(--text-2); font-size: var(--fs-sm); max-width: 70ch; }
.card-note { margin: var(--sp-3) var(--sp-5); }
.card-body { padding: var(--sp-3) var(--sp-5) var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-3); }
.card-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
.menu-item .aside { margin-left: auto; font-size: var(--fs-xs); color: var(--text-3); }

/* «Мой профиль и сессии» */
.profile-card { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-5); }
.profile-who { display: flex; flex-direction: column; min-width: 0; }
.profile-who b { font-size: var(--fs-lg); overflow-wrap: anywhere; }
.profile-who span { color: var(--text-2); font-size: var(--fs-sm); }
.session-list { list-style: none; margin: var(--sp-3) 0 0; padding: 0; }
.session-row { display: grid; grid-template-columns: 40px minmax(0, 1fr) auto; gap: var(--sp-3); align-items: center; padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--border); }
.session-ic { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--surface-2); color: var(--text-2); }
.session-text { display: flex; flex-direction: column; min-width: 0; }
.session-text b { font-weight: var(--fw-medium); overflow-wrap: anywhere; }
.session-text small { font-size: var(--fs-xs); color: var(--text-3); }
.session-here { font-size: var(--fs-xs); color: var(--text-3); max-width: 160px; text-align: right; }

/* Раздел «Сотрудники» (шаг 10, §5.7, кадры d-settings, m-staff): карточка
   «Добавить сотрудника» с подписями над полями и карточка «Команда» —
   сетка «Сотрудник · Роль · Состояние · Действие», выключенные в той же
   сетке под строкой-группой. Цвет строки — вспомогательный намёк: слово
   «выключен» стоит в самой строке. Длинное имя одним словом переносится и
   не уводит строку за край (итоговое ревью, находка 12). */
.employee-form { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) 190px auto; gap: var(--sp-3); align-items: end;
  padding: var(--sp-3) var(--sp-5) 0; }
.employee-form-hint { margin-top: var(--sp-2); margin-bottom: var(--sp-5); }
.employees-table { margin-top: var(--sp-2); }
.table-head, .employee-row { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, .9fr) minmax(0, 1.2fr) 170px; gap: var(--sp-3);
  align-items: center; padding: 0 var(--sp-5); }
.table-head { height: 40px; font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--text-3); border-bottom: 1px solid var(--border); }
.table-head .r { text-align: right; }
.employee-row { min-height: 64px; border-bottom: 1px solid var(--border); }
.employees-table > :last-child { border-bottom: 0; }
.emp { display: flex; gap: var(--sp-3); align-items: center; min-width: 0; }
.emp-text { min-width: 0; }
.emp .nm { font-weight: var(--fw-medium); overflow-wrap: anywhere; }
.emp .sub { font-size: var(--fs-sm); color: var(--text-2); }
.emp .ph { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Роль в строке под именем — только у строки-карточки (уже 1024, ниже). */
.emp .sub-role, .emp .sub-dot { display: none; }
.rolecell { font-size: var(--fs-sm); overflow-wrap: anywhere; min-width: 0; }
.state { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm); color: var(--text-2); }
.state .dot { width: 7px; height: 7px; }
/* «Последний вход · устройство»: время, под ним устройство мелко. */
.state.lastseen { flex-direction: column; align-items: flex-start; gap: 0; min-width: 0; }
.state.lastseen small { font-size: var(--fs-xs); color: var(--text-3); overflow-wrap: anywhere; }
.emp .sub-seen { display: none; }
.row-act { justify-self: end; text-align: right; }
.employee-row .locked { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--text-3); text-align: left; line-height: 1.3; }
.group-row { padding: var(--sp-2) var(--sp-5); font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--text-3); background: var(--surface-2);
  border-bottom: 1px solid var(--border); border-top: 1px solid var(--border); margin-top: -1px; }
.employee-row.disabled .emp .nm, .employee-row.disabled .emp .sub, .employee-row.disabled .rolecell { color: var(--text-3); }
.employee-row.disabled .av { filter: grayscale(1); opacity: .65; }
.employee-row.confirming { background: var(--danger-soft); border-bottom: 0; }
.pill-off { display: inline-flex; align-items: center; height: 20px; padding: 0 8px; border-radius: var(--r-pill); background: var(--surface-3); color: var(--text-2);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); }
/* Подтверждение — строка на фоне --danger-soft под строкой сотрудника;
   залитая красная кнопка — только здесь (§4 «EmployeesTable»). «Отмена»
   стоит первой на глаз, а в разметке — второй: порядок кнопок держит тест
   и тот, кто проходит их клавишей Tab. */
.employee-confirm { display: flex; align-items: center; gap: var(--sp-3); padding: 0 var(--sp-5) var(--sp-4) calc(var(--sp-5) + 52px);
  background: var(--danger-soft); border-bottom: 1px solid var(--danger-border); font-size: var(--fs-sm); }
.employee-confirm p { margin: 0; flex: 1; }
.employee-confirm .confirm-no { order: 1; }
.employee-confirm .confirm-yes { order: 2; }

/* Раздел «Роли» (шаг 10, §5.8): форма-карточка «Новая роль» и каждая роль
   отдельной карточкой — переключатели прав с пояснениями, выбор области,
   «Удалить» в строке. Роль владельца сервер защищает структурно: у неё
   переключатели неактивны и кнопок нет вовсе. Цвет/бейдж — подсказка,
   слово «владелец» — источник смысла. */
.roles-list { margin-top: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-4); }
.roles-list > .card + .card { margin-top: 0; }
.role-form { display: flex; flex-direction: column; gap: var(--sp-4); padding: var(--sp-3) var(--sp-5) var(--sp-5); }
.role-form .field { max-width: 420px; }
.role-card { padding: 0 0 var(--sp-4); }
.role-head { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-4) var(--sp-5) 0; }
.role-head > .ic { color: var(--accent-text); }
.role-head .btn { flex: none; }
.role-name { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--sp-2); overflow-wrap: anywhere; word-break: break-word; }
.role-name b { font-size: var(--fs-md); }
.role-name-input { max-width: 360px; font-weight: var(--fw-bold); }
.role-owner-badge { display: inline-flex; align-items: center; height: 20px; padding: 0 8px; border-radius: var(--r-pill); background: var(--accent-soft);
  color: var(--accent-text); font-size: var(--fs-xs); font-weight: var(--fw-bold); flex: none; }
.role-body { display: grid; grid-template-columns: minmax(0, 1fr) 220px; gap: var(--sp-5); padding: var(--sp-3) var(--sp-5) 0; }
.role-part { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.role-form .role-scope { max-width: 260px; }
.role-rights { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.role-rights li + li { border-top: 1px solid var(--border); }
.role-rights label { display: flex; align-items: flex-start; gap: var(--sp-3); padding: 10px 0; cursor: pointer; }
.role-rights label .switch { margin-top: 1px; }
/* Две подписи у переключателя (итоговое ревью, находка 11): имя права — тем
   же словом, каким отказывает сервер, — и под ним перечень охраняемого. */
.role-right-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.role-right-name { font-weight: var(--fw-medium); font-size: var(--fs-md); }
.role-right-methods { font-size: var(--fs-xs); color: var(--text-3); overflow-wrap: anywhere; }
/* Пока висит вопрос, снятие ДРУГОГО права заблокировано (RightsFields) —
   подпись гаснет, чтобы недоступность было видно. */
.role-rights label.locked { color: var(--text-3); cursor: default; }
.switch[disabled] { opacity: .55; cursor: default; }
.role-card.owner .switch[disabled] { opacity: .8; }
/* Подтверждение снятия права и удаления роли — полоса под карточкой роли,
   залитая красная кнопка только в ней. */
.role-confirm, .stage-confirm, .label-confirm, .label-merge-confirm, .key-confirm { align-items: center; flex-wrap: wrap; }
.confirm-actions { display: flex; gap: var(--sp-2); flex: none; }
.roles-list > .banner { margin-top: calc(-1 * var(--sp-2)); }

/* ===== Правая панель «Клиент | Обсуждение» (шаг 6 спецификации) =====
   От 1440 — колонка 300 px в сетке; 720–1439 — поверх ленты (.overlay);
   телефон — шторка и отдельный экран (блок @media в конце файла). Панель
   смонтирована всегда, пока открыт диалог: закрытая прячется классом, а
   неактивная вкладка — атрибутом hidden (формы живут в разметке, §6). */
.conversation { flex-direction: row; }
.conv-main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; position: relative; }
/* Файл над перепиской (components/file_drop.js). Мимо курсора: события перетаскивания
   должны доходить до зоны, иначе подсказка мигала бы. */
.file-drop { position: absolute; inset: var(--sp-2); z-index: 5; display: flex; align-items: center; justify-content: center; gap: var(--sp-2);
  border: 2px dashed var(--accent); border-radius: var(--r-lg); background: var(--accent-soft); color: var(--accent-text);
  font-size: var(--fs-md); font-weight: 600; pointer-events: none; }
.conv-main > .banner:not(.flat) { margin: var(--sp-2) var(--sp-3) 0; flex: none; }
.details { width: var(--w-panel); flex: none; display: flex; flex-direction: column; min-height: 0;
  border-left: 1px solid var(--border); background: var(--surface); }
.details:not(.open) { display: none; }
.details.overlay { position: absolute; top: 0; right: 0; bottom: 0; z-index: 10; box-shadow: var(--sh-pop); }
.details-bar { padding: 0 var(--sp-2) 0 var(--sp-3); gap: var(--sp-2); }
.bar-gap { flex: 1; }
.details-back, .sheet-handle, .details-title { display: none; }
.details:focus { outline: none; }
.seg { display: inline-flex; padding: 3px; border-radius: var(--r-pill); background: var(--surface-2); gap: 2px; flex: none; }
.seg button { display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px; border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--text-2); font-size: var(--fs-sm); font-weight: var(--fw-medium); cursor: pointer; }
.seg button.active { background: var(--surface); color: var(--text); font-weight: var(--fw-bold); box-shadow: var(--sh-1); }
.seg .count { min-width: 18px; height: 18px; font-size: 11px; }
.panel-body { flex: 1; min-height: 0; overflow-y: auto; }
.panel-body[hidden] { display: none; }
.discussion-tab { display: flex; flex-direction: column; overflow: hidden; }

/* Карточка клиента */
.card-head { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: var(--sp-5) var(--sp-4) var(--sp-4);
  border-bottom: 1px solid var(--border); text-align: center; }
.card-head h3 { margin: 8px 0 0; font-size: var(--fs-lg); overflow-wrap: anywhere; }
.card-head .phone { font-size: var(--fs-md); color: var(--text-2); font-variant-numeric: tabular-nums; }
.card-head .phone.hidden-number { font-size: var(--fs-sm); color: var(--text-3); text-align: center; max-width: 260px; }
.card-sec { padding: var(--sp-4); border-bottom: 1px solid var(--border); display: flex; flex-direction: column; gap: var(--sp-2); }
.card-sec h4 { margin: 0; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--text-2); }
.dialog-status-error, .dialog-status-note { margin: var(--sp-3) var(--sp-4) 0; }
.status-empty { color: var(--text-3); font-size: var(--fs-sm); }
.stage-pick { position: relative; }
.stage-pick::before { content: ""; position: absolute; left: 14px; top: 50%; width: 10px; height: 10px; margin-top: -5px; border-radius: 50%;
  background: var(--c); background: color-mix(in srgb, var(--c), #000 22%); pointer-events: none; z-index: 1; }
.stage-pick.none::before { background: transparent; border: 1.5px dashed var(--text-3); }
.stage-pick .select { padding-left: 34px; }
.labels-box { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.label-query { flex: 1; min-width: 150px; min-height: 30px; height: 30px; border-radius: var(--r-pill); font-size: var(--fs-sm); border-style: dashed; }
.label-suggestions { display: flex; flex-wrap: wrap; gap: 6px; }
.label-suggestion { cursor: pointer; font: inherit; font-size: var(--fs-chip); }
.label-suggestion:hover { border-color: var(--accent); }
.label-create { align-self: flex-start; }
.person { display: flex; align-items: center; gap: var(--sp-3); min-height: 48px; }
.person .who { flex: 1; min-width: 0; }
.person .nm { font-size: var(--fs-md); font-weight: var(--fw-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.person .rl { font-size: var(--fs-xs); color: var(--text-2); }
.participants-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.tag { display: inline-flex; align-items: center; height: 18px; padding: 0 6px; border-radius: var(--r-xs); background: var(--surface-3);
  color: var(--text-2); font-size: 11px; font-weight: var(--fw-bold); margin-left: 4px; vertical-align: 1px; }
.tag.acc { background: var(--accent-soft); color: var(--accent-text); }
.participants .field-hint, .participants .field-error { margin: 0; }
details.disclose { border: 1px solid var(--border); border-radius: var(--r-md); }
details.disclose > summary { list-style: none; display: flex; align-items: center; gap: var(--sp-2); min-height: 44px; padding: 0 var(--sp-3);
  cursor: pointer; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--accent-text); }
details.disclose > summary::-webkit-details-marker { display: none; }
details.disclose > summary .chev { margin-left: auto; color: var(--text-3); transition: transform .15s; }
details.disclose[open] > summary .chev { transform: rotate(180deg); }
details.disclose form { display: flex; flex-direction: column; gap: var(--sp-3); padding: 0 var(--sp-3) var(--sp-3); }
details.disclose .field-hint { margin: 0; }
.av.s32 { width: 32px; height: 32px; font-size: 12px; }

/* Обсуждение: полоса «Клиент этого не видит», реплики, своё поле */
.discussion { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.discussion-note { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-4); font-size: var(--fs-xs); color: var(--text-2);
  background: var(--surface-2); border-bottom: 1px solid var(--border); flex: none; }
.discussion-body { flex: 1; min-height: 0; overflow-y: auto; }
.notes { list-style: none; margin: 0; padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-4); }
.notes .note { display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: var(--sp-2); color: var(--text); }
.note-head { display: flex; gap: 6px; align-items: baseline; font-size: var(--fs-sm); }
.note-head b { font-weight: var(--fw-bold); }
.note-head time { font-size: var(--fs-xs); color: var(--text-3); }
.note-text { font-size: var(--fs-md); line-height: 1.4; padding: 8px 10px; margin-top: 3px; background: var(--surface-2);
  border-radius: 3px var(--r-md) var(--r-md) var(--r-md); white-space: pre-wrap; overflow-wrap: anywhere; }
.notes .note.mine .note-text { background: var(--accent-soft); }
.discussion-form { display: flex; flex-direction: column; gap: 6px; padding: 10px var(--sp-3); border-top: 1px solid var(--border); background: var(--surface-2); flex: none; }
.discussion-form .field-error { margin: 0; }
.discussion-row { display: flex; gap: var(--sp-2); align-items: flex-end; }
.discussion-input { flex: 1; min-width: 0; min-height: 44px; max-height: 120px; padding: 11px 14px; border-radius: 22px; border: 1px solid var(--border);
  background: var(--surface); color: var(--text); resize: none; line-height: 1.4; field-sizing: content; }
.discussion-input::placeholder { color: var(--text-3); }
.discussion-input:focus { outline: 2px solid var(--focus); outline-offset: -1px; }
.discussion-send { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; border: 0; background: var(--accent); color: var(--on-accent); flex: none; cursor: pointer; }
.discussion-send[disabled] { background: var(--accent-soft); color: var(--accent-text); cursor: default; opacity: .75; }

/* ===== Полоса контекста и шторка: только телефон (шаг 7) =====
   На компьютере стадия и ярлыки — в правой панели, «Вернуть в очередь» — в
   шапке, поэтому здесь они скрыты. */
.context-strip, .sheet-actions { display: none; }
.strip-stage { position: relative; flex: none; }
.strip-stage select { appearance: none; height: 32px; padding: 0 28px 0 24px; border-radius: var(--r-pill); border: 0; cursor: pointer;
  font-size: var(--fs-chip); font-weight: var(--fw-bold); color: var(--text);
  background: var(--surface-3); background: color-mix(in srgb, var(--c) var(--chip-mix), var(--surface)); }
.strip-stage::before { content: ""; position: absolute; left: 10px; top: 50%; width: 8px; height: 8px; margin-top: -4px; border-radius: 50%;
  background: var(--c); background: color-mix(in srgb, var(--c), #000 22%); pointer-events: none; }
.strip-stage.none select { background: var(--surface-2); }
.strip-stage.none::before { background: transparent; border: 1.5px dashed var(--text-3); }
.strip-stage::after { content: ""; position: absolute; right: 11px; top: 50%; width: 6px; height: 6px; margin-top: -5px;
  border: solid var(--text-2); border-width: 0 1.6px 1.6px 0; transform: rotate(45deg); pointer-events: none; }
.strip-labels { display: flex; gap: 6px; min-width: 0; overflow: hidden; flex: 0 1 auto; }
.strip-labels .chip { flex: none; }
.strip-add { flex: none; height: 32px; padding: 0 10px; border-radius: var(--r-pill); border: 1px dashed var(--border-strong);
  background: transparent; color: var(--accent-text); font-size: var(--fs-chip); font-weight: var(--fw-bold); cursor: pointer; white-space: nowrap; }
/* «Ответ не нужен» в полосе контекста телефона — справа, отдельно от
   стадии и ярлыков: это действие над диалогом, а не его свойство. */
.strip-no-reply { flex: none; margin-left: auto; display: inline-flex; align-items: center; gap: 4px; height: 32px; padding: 0 10px;
  border-radius: var(--r-pill); border: 1px solid var(--border-strong); background: var(--surface); color: var(--accent-text);
  font-size: var(--fs-chip); font-weight: var(--fw-bold); cursor: pointer; white-space: nowrap; }

/* Раздел «Возможности» (шаг 10, §5.8): видно только владельцу — карточки-
   строки с переключателем справа и словами о том, что появится и что
   исчезнет. Подтверждения нет: включение ничего не отнимает, а выключение
   лишь прячет разметку (features.ts), не удаляет её. */
.feature-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.feature-list > .card + .card { margin-top: 0; }
.feature-row { padding: var(--sp-4) var(--sp-5); }
.feature-toggle { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); cursor: pointer; }
.feature-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.feature-name { font-weight: var(--fw-bold); font-size: var(--fs-md); }
.feature-state { font-size: var(--fs-xs); color: var(--text-3); }
.feature-state.on { color: var(--accent-text); font-weight: var(--fw-bold); }
.feature-about { margin: var(--sp-2) 0 0; font-size: var(--fs-sm); color: var(--text-2); max-width: 70ch; }
.features > .banner { margin-bottom: var(--sp-4); }

/* Раздел «Ключи для программ» (шаг 10, §5.8): видно только владельцу.
   Карточка с «Выдать ключ» (primary) в шапке, форма key-form, выданный ключ
   — отдельной рамкой шрифтом --font-mono 13 и переносом по знакам (48
   знаков без пробелов иначе вылезли бы за край на телефоне), «Отозвать» —
   .btn-danger-ghost в строке. */
.card-title .key-new { margin-left: auto; }
.card-title .btn .ic { color: inherit; }
.key-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-2); padding: var(--sp-3) var(--sp-5) 0; }
.key-form .field { flex: 1 1 240px; }
.key-issued { margin: var(--sp-3) var(--sp-5) 0; padding: var(--sp-4); border: 1px solid var(--accent); border-radius: var(--r-md); background: var(--accent-soft); }
.key-issued-title { display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-2); font-weight: var(--fw-bold); color: var(--accent-text); }
.key-full { display: block; margin: 0 0 var(--sp-2); padding: var(--sp-2) var(--sp-3); font: 13px/1.5 var(--font-mono); word-break: break-all; user-select: all;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-sm); }
.key-issued-warning { margin: 0 0 var(--sp-3); color: var(--danger); font-size: var(--fs-sm); }
.key-list { list-style: none; margin: var(--sp-4) 0 0; padding: 0; }
/* Раздел «Салон и WhatsApp» (settings_salon.js) */
.salon-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--sp-2) var(--sp-5); margin: 0; font-size: var(--fs-sm); }
.salon-facts > div { display: contents; }
.salon-facts dt { color: var(--text-3); }
.salon-facts dd { margin: 0; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.salon-state .channel-pill { margin-left: 0; font-size: var(--fs-sm); min-height: 28px; padding: 0 10px; }
/* Исправный канал — без подложки: точка встаёт по левому краю заголовка и
   строк ниже, а не в 10 px от него (мелкая находка итогового ревью p2). */
.salon-state .channel-pill:not(.warn):not(.bad) { padding-left: 0; }
.salon-link-warning { margin: var(--sp-3) var(--sp-5) 0; }
.salon-link .key-issued { margin-bottom: var(--sp-5); }
.salon-link .card-body { padding-top: var(--sp-4); }
.salon-name-text { font-size: var(--fs-md); font-weight: var(--fw-medium); overflow-wrap: anywhere; margin-bottom: 0; }
.salon-name-form .field { max-width: 520px; }
.key-row { padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--border); }
.key-row.revoked .key-name, .key-row.revoked .key-hint, .key-row.revoked .key-meta { color: var(--text-3); }
.key-row-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
.key-ic { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; background: var(--surface-2); color: var(--text-2); flex: none; }
.key-name { font-weight: var(--fw-bold); flex: 1; min-width: 0; overflow-wrap: anywhere; }
.key-hint { font: 13px var(--font-mono); color: var(--text-2); }
.key-state { height: auto; min-height: 20px; white-space: normal; }
.key-row-head .btn { margin-left: auto; }
.key-meta { margin: var(--sp-1) 0 0 44px; font-size: var(--fs-sm); color: var(--text-2); }
.key-confirm { margin: var(--sp-3) 0 0; }
/* Оповещения ключа (settings_keys.js): под строкой «Выдан…», с тем же отступом слева; адрес переносится по знакам - длинный https-адрес без пробелов иначе вылез бы за край на телефоне */
.key-webhook { margin: var(--sp-2) 0 0 44px; }
.key-webhook .key-meta { margin: var(--sp-1) 0 0; }
.key-webhook code { font: 13px var(--font-mono); word-break: break-all; }
.key-webhook-warn { display: flex; align-items: flex-start; gap: var(--sp-2); color: var(--warn); font-weight: var(--fw-bold); }
.key-webhook-warn .ic { margin-top: 1px; flex: none; }
.key-webhook > .btn { margin-top: var(--sp-2); }
/* Отметка «бот» (решение 22): метка в строке ключа - тот же вид, что «ведёт бот» в списке диалогов (.bot-owner), чтобы владелец узнавал одно и то же;
   кнопка - под строкой «Выдан…» с тем же отступом; галочка формы выдачи - отдельной строкой под названием */
.key-actions { margin: var(--sp-2) 0 0 44px; }
.key-bot-check { display: flex; align-items: center; gap: var(--sp-2); flex: 1 1 100%; font-size: var(--fs-sm); }
.key-bot-check .switch { flex: none; }

/* Раздел «Статусы и ярлыки» (шаг 10, §5.8): две карточки — стадии и
   ярлыки, каждая видна, только если её блок включён (settings_statuses.js).
   Выключенная часть не молчит — полоса .statuses-off говорит, где
   включатель. В строке — чип в цвете стадии или ярлыка со словом внутри и
   тег вида стадии («завершающая: успех»): цвет — намёк, слово — смысл.
   «Выше» и «Ниже» — стрелками 44, «Править» и «Удалить» видны в строке. */
.statuses-off { margin: 0 0 var(--sp-4); }
.statuses .card + .banner, .statuses .banner + .card { margin-top: var(--sp-5); }
.inline-form { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.inline-form .input { flex: 1 1 200px; width: auto; }
.inline-form .select-wrap { flex: 0 1 200px; }
.inline-form > .field-error { flex-basis: 100%; margin: 0; }
.stage-form { padding: var(--sp-3) var(--sp-5) var(--sp-2); }
.stage-list, .label-list { list-style: none; margin: var(--sp-3) 0 0; padding: 0; }
.stage-row, .label-row { padding: 6px var(--sp-3) 6px var(--sp-5); border-top: 1px solid var(--border); }
.stage-row-view, .label-row-view { display: flex; align-items: center; gap: var(--sp-2); min-height: 44px; flex-wrap: wrap; }
.stage-row .chip, .label-row .chip { max-width: 100%; white-space: normal; height: auto; min-height: var(--h-chip); }
.stage-name, .label-name { font-weight: var(--fw-medium); overflow-wrap: anywhere; word-break: break-word; }
.stage-row-actions, .label-row-actions { display: flex; align-items: center; gap: 2px; margin-left: auto; flex-wrap: wrap; }
.stage-row-actions .icon-btn { width: 44px; height: 44px; }
.stage-row-actions .icon-btn[disabled] { opacity: .35; cursor: default; background: transparent; }
.ic.flip { transform: rotate(180deg); }
.stage-edit-form, .label-edit-form, .label-merge-pick { padding: 6px 0; }
.stages-block > .banner, .labels-block > .banner { margin: var(--sp-3) var(--sp-5) var(--sp-4); }
.labels-block .label-row .banner { margin: 6px 0; }
.stage-list:empty, .label-list:empty { display: none; }
.stages-block, .labels-block { padding-bottom: var(--sp-2); }
/* Кружок цвета (ColorDot в dialog_status.js) — цвет классом-атрибутом, не style="". */
.cvet-dot { display: inline-block; width: 14px; height: 14px; flex: none; border-radius: 50%; border: 1px solid var(--border-strong); background: var(--cvet-slate); }
.cvet-dot[data-color=sky] { background: var(--cvet-sky); } .cvet-dot[data-color=green] { background: var(--cvet-green); }
.cvet-dot[data-color=amber] { background: var(--cvet-amber); } .cvet-dot[data-color=red] { background: var(--cvet-red); }
.cvet-dot[data-color=violet] { background: var(--cvet-violet); } .cvet-dot[data-color=teal] { background: var(--cvet-teal); }
.cvet-dot[data-color=pink] { background: var(--cvet-pink); }

/* Раздел «Уведомления» (шаг 10, §5.8) — у каждого сотрудника, смотрится в
   основном с телефона. Три карточки: «Это устройство» (включить, пробное),
   «Мои устройства», «Что показывать» — переключатели справа от подписи.
   «Не настроены» — полосой .banner.warn. */
.push-settings > .banner { margin-bottom: var(--sp-4); }
.push-state { display: flex; align-items: center; gap: var(--sp-2); margin: 0; font-weight: var(--fw-medium); }
.push-state.on { color: var(--accent-text); }
.push-ios ol { margin: 6px 0; padding-left: 20px; color: var(--text-2); }
.push-ios .banner-body p + p { margin-top: 4px; }
.push-devices { list-style: none; margin: var(--sp-3) 0 0; padding: 0; }
.push-device { padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--border); }
.push-device-head { display: flex; align-items: center; gap: var(--sp-3); }
.push-device-name { flex: 1; min-width: 0; font-weight: var(--fw-medium); overflow-wrap: anywhere; }
.push-device-meta { margin: var(--sp-1) 0 0 52px; font-size: var(--fs-sm); color: var(--text-2); }
.push-devices-block { padding-bottom: var(--sp-2); }
.push-devices-block .card-note:last-child { margin-bottom: var(--sp-5); }
.push-prefs { display: flex; flex-direction: column; }
.push-check { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); padding: var(--sp-3) var(--sp-5); cursor: pointer;
  border-bottom: 1px solid var(--border); }
.push-check:first-of-type { margin-top: var(--sp-2); border-top: 1px solid var(--border); }
.push-check > span { min-width: 0; font-weight: var(--fw-medium); }
.push-check small { display: block; margin-top: 2px; font-weight: normal; font-size: var(--fs-sm); color: var(--text-2); }
.push-quiet { display: flex; flex-wrap: wrap; gap: var(--sp-3); padding: var(--sp-3) var(--sp-5); border-bottom: 1px solid var(--border); }
.push-quiet label { display: flex; align-items: center; gap: var(--sp-2); color: var(--text-2); }
.push-quiet .input { width: auto; }
.push-save { padding: var(--sp-4) var(--sp-5) var(--sp-5); }

/* ===================== ТЕЛЕФОН: до 719 px включительно =====================
   Один блок на всё окно (спецификация, §3): девять отдельных блоков по разным
   местам файла однажды разошлись бы порогом. */
@media (max-width: 719px) {
  /* Шапка диалога на телефоне (шаг 7, кадры m-chat и m-chat-free): в своём
     диалоге справа «Обсуждение (N)» и ⓘ; в ничьём — главная кнопка «Взять»
     (видимая высота 36, цель касания 44) и ⓘ. «Вернуть в очередь» — внизу
     шторки карточки. Под шапкой — полоса контекста 44 px. */
  .conv-bar .dialog-assign.btn-secondary { display: none; }
  .conv-bar .dialog-assign.btn-primary { min-height: 36px; padding: 0 16px; position: relative; }
  .conv-bar .dialog-assign.btn-primary::after { content: ""; position: absolute; inset: -5px -2px; }
  .conv-bar.act-take .discussion-toggle { display: none; }
  .conv-tools .sep { display: none; }
  .conv-tools .icon-btn { width: 44px; height: 44px; }
  /* В шапке телефона места нет («Взять», ⓘ и имя) — кнопка живёт в полосе
     контекста (.strip-no-reply). */
  .conv-tools .no-reply-ask { display: none; }
  .conv-tools .discussion-toggle { order: -1; }
  .context-strip { display: flex; align-items: center; gap: 6px; height: var(--h-strip); padding: 0 var(--sp-3);
    background: var(--surface); overflow: hidden; flex: none;
    /* Черта снизу — тенью, а не рамкой: рамка съедала у полосы пиксель, и
       цели касания стадии и «+ ярлык» выходили 43 вместо 44. */
    box-shadow: inset 0 -1px 0 var(--border); }
  .sheet-actions { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4) var(--sp-5); }

  /* Карточка клиента на телефоне — нижняя шторка до 88 % высоты, фон под
     ней затемнён и недоступен; обсуждение — отдельный экран со стрелкой «←»
     (кадры m-card и спецификация §3). */
  .sheet-scrim { position: fixed; inset: 0; z-index: 30; background: var(--scrim); }
  .details.sheet.open[data-tab="client"] { position: fixed; left: 0; right: 0; bottom: 0; z-index: 31; width: auto; max-height: 88%;
    border-left: 0; border-radius: var(--r-lg) var(--r-lg) 0 0; box-shadow: var(--sh-pop); padding-bottom: env(safe-area-inset-bottom); }
  .details.sheet[data-tab="client"] .sheet-handle { display: block; width: 36px; height: 4px; border-radius: 2px; background: var(--border-strong); margin: 8px auto 0; flex: none; }
  .details.sheet[data-tab="client"] .details-bar { border-radius: var(--r-lg) var(--r-lg) 0 0; }
  .details.sheet.open[data-tab="discussion"] { position: absolute; inset: 0; z-index: 20; width: auto; border-left: 0; }
  .details.sheet[data-tab="discussion"] .details-back { display: inline-grid; }
  /* Шторка карточки — голова как в кадре m-card: аватар, имя, номер и ✕
     справа; переключателя «Клиент | Обсуждение» на телефоне нет —
     обсуждение открывается своей кнопкой в шапке и идёт отдельным экраном
     с заголовком. */
  .details.sheet .seg { display: none; }
  .details.sheet[data-tab="discussion"] .details-title { display: block; flex: 1; min-width: 0; font-size: var(--fs-lg); font-weight: var(--fw-bold); }
  .details.sheet[data-tab="client"] .details-bar { position: absolute; top: 26px; right: var(--sp-2); height: auto; padding: 0;
    border: 0; background: transparent; z-index: 1; }
  .details.sheet[data-tab="client"] .card-head { padding-right: 60px; }
  .details.sheet[data-tab="discussion"] .details-close { display: none; }
  .details .icon-btn { width: 44px; height: 44px; }
  .details .select, .details .input:not(.label-query) { min-height: var(--touch); font-size: 16px; }
  .details .btn { min-height: var(--touch); }
  .card-head { flex-direction: row; text-align: left; padding: var(--sp-3) var(--sp-4); gap: var(--sp-3); }
  .card-head .av.s72 { width: 48px; height: 48px; font-size: 17px; }
  .card-head h3 { margin: 0; }
  .card-head > div { flex: 1; min-width: 0; }
  .discussion-input { font-size: 16px; }

  /* Поле ответа на телефоне: круглая «Отправить», слово — для экранного
     чтеца; низ — с запасом под жест «домой» (кадр m-chat). */
  .composer { padding: 6px var(--sp-2) calc(6px + env(safe-area-inset-bottom)); }
  .composer-row { gap: 4px; }
  .composer-extra { padding-left: 48px; }
  .composer-text { font-size: 16px; }
  .composer-send { width: 44px; padding: 0; border-radius: 50%; }
  .composer-send .send-word { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .composer-closed { font-size: var(--fs-sm); padding-bottom: calc(var(--sp-3) + env(safe-area-inset-bottom)); }
  /* Обсуждение на телефоне открывается значком в шапке — кнопка здесь
     сжимала объяснение до шести строк (ревью ветки). */
  .composer-closed-discuss { display: none; }

  /* Каркас на телефоне (шаг 3): один экран за раз. nav.rail становится
     таб-баром снизу «Диалоги | Настройки»; при открытом диалоге его нет —
     переписке нужен весь экран (кадры m-list, m-chat). */
  .app-shell { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; }
  .place { grid-row: 1; }
  .rail { grid-row: 2; display: grid; grid-template-columns: 1fr 1fr; gap: 0; height: calc(64px + env(safe-area-inset-bottom));
    padding: 0 0 env(safe-area-inset-bottom); border-right: 0; border-top: 1px solid var(--border); background: var(--surface); }
  .rail-logo, .rail-spacer, .rail-me-wrap { display: none; }
  .rail .rail-item { width: auto; height: 100%; justify-content: center; font-size: var(--fs-xs); border-radius: 0; }
  /* Число ждущих на «Диалогах» в таб-баре — у правого края значка (кадр m-list). */
  .rail .rail-item .count { top: 6px; right: calc(50% - 32px); box-shadow: 0 0 0 2px var(--surface); }
  .app-shell.dialog-open .rail { display: none; }
  /* Полоса над окном на телефоне — две строки текста, целиком — в подсказке
     (ревью ветки: полоса канала в четыре строки отодвигала список). */
  .shell-banners .banner { padding: var(--sp-2) var(--sp-3); gap: var(--sp-2); }
  .shell-banners .banner b { font-size: var(--fs-sm); }
  .shell-banners .banner-body p { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: var(--fs-xs); }
  .bar { height: var(--h-bar-m); }
  .chat-screen { grid-template-columns: minmax(0, 1fr); }
  .chat-screen.dialog-open .sidebar { display: none; }
  .chat-screen:not(.dialog-open) .conversation { display: none; }
  .sidebar { border-right: 0; }
  /* Список на телефоне (кадр m-list): вкладки 36, правое поле строки 16 */
  .dialog-tabs { gap: var(--sp-2); }
  .dialog-tabs button { height: 36px; padding: 0 14px; }
  /* Поиск на телефоне: лупа в шапке открывает поле; шрифт поля 16 px —
     иначе iOS увеличивает страницу при фокусе; поле и крестик — цели касания. */
  .list-search-toggle { display: inline-grid; width: 44px; height: 44px; margin-right: calc(-1 * var(--sp-2)); }
  .sidebar:not(.search-open) .list-tools .search { display: none; }
  .search { height: 44px; }
  .search input { font-size: 16px; }
  .search-clear { width: 44px; height: 44px; }
  .dialog-row-body { padding-right: var(--sp-4); }
  .conv-bar { padding: 0 var(--sp-1); gap: 2px; }
  .conv-bar .dialog-back { display: inline-grid; width: 44px; height: 44px; }
  .conv-bar .av { width: 36px; height: 36px; font-size: 14px; margin-right: var(--sp-3); }
  .conv-bar .dialog-header { gap: 0; }
  /* На телефоне сперва «ведёте вы», потом номер (§5.5, кадр m-chat):
     многоточие съедает конец строки, и кто ведёт диалог, должно уцелеть. */
  .dh-sub { font-size: var(--fs-xs); display: flex; min-width: 0; }
  .dh-sub > * { flex: none; }
  .dh-sub .dh-holder { order: -2; }
  .dh-sub .dh-dot { order: -1; white-space: pre; }
  .dh-sub .dh-phone { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

  /* Лента на телефоне (кадр m-chat): поля 10 px и пузыри до 84 % — на
     десктопных 6 % и 72 % сообщение ложилось в лишнюю строку. */
  .feed { padding: var(--sp-2) 10px; }
  .bubble { max-width: 84%; }

  /* Цели касания не меньше 44 px (Apple и Google; мельче — промахиваются).
     Видимый размер задаёт спецификация (§4: .btn-sm и «Повторить» 32,
     крестик чипа 20, вкладки 36) — его не трогаем, а область касания
     добираем прозрачным ::after тем же приёмом, что у «Взять» в шапке. */
  .icon-btn { width: 44px; height: 44px; }
  .btn-sm, .msg-retry, .strip-add, .strip-no-reply, .dialog-tabs button, .seg button, .chip-x, .label-suggestion, .load-older { position: relative; }
  /* inset считается от края ВНУТРИ рамки: у кнопок с рамкой 1 px добавка на
     пиксель больше (32 − 2 + 7 + 7 = 44). */
  .btn-sm::after, .msg-retry::after, .strip-add::after, .strip-no-reply::after { content: ""; position: absolute; inset: -7px 0; }
  .seg button::after { content: ""; position: absolute; inset: -6px 0; }
  .dialog-tabs button::after { content: ""; position: absolute; inset: -4px 0; }
  /* Подсказки ярлыка — кнопки 36 с промежутком 8: соседний ряд и «Завести
     ярлык» не перекрывают добавку. */
  .details .label-suggestions { gap: var(--sp-2); }
  .details .label-suggestion { height: 36px; padding: 0 12px; }
  .label-suggestion::after { content: ""; position: absolute; inset: -5px 0; }
  .load-older::after { content: ""; position: absolute; inset: -10px 0; }
  .chip-x::after { content: ""; position: absolute; inset: -12px; border-radius: 50%; }
  /* Плашка WhatsApp в шапке — кнопка в «Салон и WhatsApp» высотой 22 (мелкая
     находка итогового ревью p2): касание добираем до 44 тем же приёмом. */
  .channel-pill.as-button { position: relative; }
  .channel-pill.as-button::after { content: ""; position: absolute; inset: -11px 0; }
  /* В настройках и в шторке кнопки и так 44 (правила ниже и .details .btn):
     там добавка лишь залезала бы на соседнюю строку. */
  .settings-content .btn-sm::after, .details .btn-sm::after { content: none; }
  /* select не умеет ::after: высота 44, а видимая пилюля 32 — прозрачная
     рамка 6 px сверху и снизу, фон только внутри неё. */
  .strip-stage select, .strip-stage.none select { height: var(--touch); border: solid transparent; border-width: 6px 0; background-clip: padding-box; }
  /* Поле ярлыка — 44 и шрифт 16, как прочие поля телефона (кадр m-card):
     мельче iOS увеличивает страницу при фокусе. */
  .details .label-query { min-height: var(--touch); height: var(--touch); font-size: 16px; }

  /* Стадия в полосе контекста — по ширине выбранного названия, а не самого
     длинного варианта: иначе второй ярлык уходил в «+1» (кадр m-chat). */
  .strip-stage { max-width: 45%; min-width: 0; }
  .strip-stage select { max-width: 100%; field-sizing: content; padding-right: 26px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* Настройки на телефоне — «меню → раздел» (кадры m-settings, m-staff):
     меню карточками по группам, профиль сверху, «Выйти» отдельной строкой;
     раздел — отдельным экраном со стрелкой «←». */
  .settings-shell { grid-template-columns: minmax(0, 1fr); }
  .settings-shell[data-view="menu"] .settings-main { display: none; }
  .settings-shell[data-view="section"] .settings-nav { display: none; }
  /* Открытый раздел — отдельный экран со стрелкой «←», как открытый диалог:
     без таб-бара (кадр m-staff). Вводный абзац «Сотрудников» на телефоне
     не нужен: подсказка про код стоит под формой, про выключение — в самом
     вопросе. */
  .app-shell.section-open .rail { display: none; }
  .employees > .page-lead { display: none; }
  .settings-nav { border-right: 0; background: var(--bg-app); }
  .settings-sections { padding: var(--sp-3) var(--sp-3) var(--sp-5); }
  .nav-profile { display: flex; min-height: 72px; padding: var(--sp-2) var(--sp-3) var(--sp-2) var(--sp-4); background: var(--surface);
    border: 1px solid var(--border); border-radius: var(--r-lg); }
  .nav-profile:hover { background: var(--surface); }
  .nav-profile .tx { flex: 1; min-width: 0; display: flex; flex-direction: column; }
  .nav-profile .tx b { font-size: var(--fs-md); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .nav-profile .tx small { font-size: var(--fs-xs); color: var(--text-2); }
  .nav-group { margin: var(--sp-4) var(--sp-1) var(--sp-2); }
  .nav-list { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; }
  .nav-list .nav-item { border-radius: 0; min-height: 52px; padding: 0 var(--sp-3) 0 var(--sp-4); border-bottom: 1px solid var(--border); }
  .nav-list .nav-item:last-child { border-bottom: 0; }
  .nav-list .nav-item .ic:first-child { color: var(--accent-text); }
  .nav-item .chev { display: block; }
  .nav-item.active { background: transparent; color: var(--text); font-weight: inherit; }
  .nav-sep { display: none; }
  .settings-signout { margin-top: var(--sp-4); background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; }
  .settings-signout .nav-item { min-height: 52px; border-radius: 0; padding-left: var(--sp-4); }
  .settings-main-bar { padding: 0 var(--sp-2) 0 var(--sp-1); gap: 2px; }
  .settings-up { display: inline-grid; width: 44px; height: 44px; }
  .settings-back { display: none; }
  .settings-inner { padding: var(--sp-3) var(--sp-3) var(--sp-6); }
  .card-title { padding: var(--sp-3) var(--sp-4) 0; }
  .card-lead { margin: var(--sp-2) var(--sp-4) 0; }
  .card-note { margin: var(--sp-3) var(--sp-4); }
  .card-body { padding: var(--sp-3) var(--sp-4) var(--sp-4); }
  .card + .card { margin-top: var(--sp-3); }
  .session-row { padding: var(--sp-3) var(--sp-4); grid-template-columns: 40px minmax(0, 1fr); }
  .session-row > :last-child { grid-column: 2; justify-self: start; text-align: left; max-width: none; }

  /* «Сотрудники» на телефоне (кадр m-staff): поля формы столбиком, кнопка во
     всю ширину; строки команды — карточкой: аватар, имя, роль и состояние
     под ним, кнопка справа. Горизонтальной прокрутки нет. */
  .employee-form { display: flex; flex-direction: column; align-items: stretch; padding: var(--sp-3) var(--sp-4) 0; }
  .employee-form .btn { min-height: 48px; }
  .employee-form-hint { margin-bottom: var(--sp-4); }
  /* Строка команды карточкой — в блоке «уже 1024» ниже: тот же вид нужен
     и планшету стоймя. Здесь — только высота кнопки под палец. */
  .employee-row .row-act .btn { min-height: var(--touch); }
  .employee-confirm { flex-wrap: wrap; padding: 0 var(--sp-4) var(--sp-4); }
  .employee-confirm p { flex-basis: 100%; }
  .employee-confirm .btn { flex: 1; min-height: var(--touch); }

  /* Роли на телефоне: права и область столбиком, «Удалить» под именем. */
  .role-body { grid-template-columns: minmax(0, 1fr); padding: var(--sp-3) var(--sp-4) 0; gap: var(--sp-3); }
  .role-head { padding: var(--sp-3) var(--sp-4) 0; flex-wrap: wrap; }
  .role-form { padding: var(--sp-3) var(--sp-4) var(--sp-4); }
  .role-form .role-scope, .role-form .field { max-width: none; }
  .role-form .btn { width: 100%; min-height: 48px; }
  .confirm-actions { width: 100%; }
  .confirm-actions .btn { flex: 1; min-height: var(--touch); }

  /* Статусы на телефоне: формы столбиком, действия строки — под чипом. */
  .inline-form { flex-direction: column; align-items: stretch; }
  .inline-form .input, .inline-form .select-wrap { flex: none; width: 100%; }
  .inline-form .btn { min-height: var(--touch); }
  .stage-form { padding: var(--sp-3) var(--sp-4) var(--sp-2); }
  .stage-row, .label-row { padding: 6px var(--sp-3) 6px var(--sp-4); }
  .stage-row-actions, .label-row-actions { margin-left: 0; width: 100%; }
  .stage-row-actions .btn, .label-row-actions .btn { min-height: var(--touch); }

  /* Всё, что нажимают пальцем, не ниже 44 px (рекомендация Apple и Google:
     мельче — промахиваются). Правило — на экраны, ещё не переведённые на
     компоненты редизайна (вход, настройки): у переписки размеры заданы
     самими компонентами, и общее правило растягивало бы крестики чипов. */
  .settings-content button, .settings-content select, .settings-content textarea,
  .settings-content input:not([type=checkbox]):not([type=radio]):not([type=hidden]) {
    min-height: 44px;
  }
  input[type=checkbox]:not(.switch), input[type=radio] { width: 22px; height: 22px; }
  /* Уведомления на телефоне: строки устройств и переключатели — с полями 16. */
  .push-device { padding: var(--sp-3) var(--sp-4); }
  .push-device-meta { margin-left: 0; }
  .push-check, .push-quiet { padding: var(--sp-3) var(--sp-4); }
  .push-save { padding: var(--sp-4); }
  .push-save .btn, .push-here-block .card-actions .btn { width: 100%; min-height: 48px; }
}

/* Настройки на 720–1279 (кадр d-1024): навигация уже, сетка «Команды» и
   форма добавления не сжимают имя и номер до переносов. */
@media (min-width: 720px) and (max-width: 1279px) {
  .settings-shell { grid-template-columns: 260px minmax(0, 1fr); }
  .settings-inner { padding: var(--sp-5) var(--sp-5) var(--sp-8); }
  /* Форма в три колонки «Имя · Телефон · Роль», «Добавить» — строкой ниже
     слева: вдвоём со «Ролью» во второй строке правая половина пустовала. */
  .employee-form { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1fr); }
  .employee-form .btn { justify-self: start; }
  .table-head, .employee-row { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr) 104px 130px; padding: 0 var(--sp-4); }
  .employee-row .locked { font-size: 11px; }
}

/* Уже 1024 — телефон (кадр m-staff) и планшет стоймя (768–1023): четырём
   колонкам «Сотрудник · Роль · Состояние · Действие» не хватает места, имя
   на 760 рассыпалось по букве в строку. Строка команды — карточкой: аватар,
   имя, роль под ним, кнопка справа; состояние — только у выключенных. */
@media (max-width: 1023px) {
  .table-head { display: none; }
  /* Строка-карточка (кадр m-staff): имя и «вы»; «Роль · телефон» одной
     строкой; у владельца замок третьей строкой во всю ширину — колонкой
     справа он сжимал имя до переноса («Динара / Сейтказы»). */
  .employee-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "emp act"; gap: var(--sp-1) var(--sp-3);
    padding: var(--sp-3) var(--sp-4); }
  .employee-row .emp { grid-area: emp; }
  /* Вместо номера — последний вход (кадр m-staff): колонки здесь нет. */
  .employee-row.has-seen .emp .ph { display: none; }
  .employee-row.has-seen .emp .sub-seen { display: inline; }
  .employee-row .rolecell { display: none; }
  .emp .sub-role, .emp .sub-dot { display: inline; }
  .employee-row .state { display: none; }
  .employee-row.disabled { grid-template-areas: "emp act" "st act"; }
  .employee-row.disabled .state { display: inline-flex; grid-area: st; padding-left: 52px; }
  .employee-row .row-act { grid-area: act; }
  .employee-row.blocked { grid-template-columns: minmax(0, 1fr); grid-template-areas: "emp" "lock"; }
  .employee-row.blocked .row-act { grid-area: lock; justify-self: start; text-align: left; padding-left: 52px; }
}
@media (min-width: 720px) and (max-width: 1023px) {
  .settings-shell { grid-template-columns: 248px minmax(0, 1fr); }
  /* Трём колонкам здесь тесно: имя во всю ширину, телефон и роль рядом. */
  .employee-form { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .employee-form .field:first-child { grid-column: 1 / -1; }
}

/* «Настройки → Битрикс24» (client/screens/settings_bitrix.js): номер в линии
   — зелёная пилюля рядом с серой «выключен»; линия и кнопка — в одну строку,
   на узком экране переносятся. */
.pill-on { display: inline-flex; align-items: center; height: 20px; padding: 0 8px; border-radius: var(--r-pill);
  background: var(--accent-soft); color: var(--accent-text); font-size: var(--fs-xs); font-weight: var(--fw-bold); }
.settings-bitrix > .btn { margin-top: var(--sp-3); }
.bitrix-line-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; margin-top: var(--sp-3); }
.bitrix-line-row .select-wrap { min-width: 0; flex: 1 1 14em; }
.bitrix-fuse { color: var(--danger); }

/* Официальный номер (этап 5a): прочитано — цветные галочки, как у WhatsApp;
   выбор номера при нескольких каналах; окно 24 часа и выбор шаблона. */
.msg-status.sent.read { color: var(--info); }
.channel-switch select { max-width: 100%; min-height: 28px; margin-top: 4px; font: inherit; font-size: var(--fs-sm);
  color: var(--text); background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--r-sm); padding: 0 6px; }
.template-picker { display: grid; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--border); background: var(--surface); }
.template-note { display: flex; gap: 6px; align-items: flex-start; margin: 0; padding: 8px 10px; border-radius: var(--r-sm);
  background: var(--warn-soft); color: var(--warn); border: 1px solid var(--warn-border); font-size: var(--fs-sm); }
.template-field { display: grid; gap: 4px; font-size: var(--fs-sm); color: var(--text-2); }
.template-field select, .template-field input { min-height: var(--h-control); font: inherit; color: var(--text); background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--r-sm); padding: 0 10px; }
.template-preview { margin: 0; padding: 8px 10px; border-radius: var(--r-bubble); background: var(--bubble-out); white-space: pre-wrap; }
.template-loading, .template-empty { margin: 0; color: var(--text-2); font-size: var(--fs-sm); }
.template-picker .btn { justify-self: end; }
