/* Lead workspace — /crm/leads/:id/workspace
 *
 * Two zones: the client's card at 380px and their conversation taking
 * everything else. The right rail the first build had is gone — it was a second
 * context competing with the card for the same job while stealing 280px from
 * the only thing an operator reads all day. Its timeline is now a section of
 * the card; its rare actions live in the header's ••• menu.
 *
 * The composer is NOT styled here. It comes from src/composer-kit.css and is
 * shared with the Inbox; restyling it per screen is exactly the drift that
 * extracting it was meant to prevent.
 *
 * No hard min-width on .lw-page: a 1280px minimum overflowed by 16px at a
 * viewport of exactly 1279, before the media query fired. The floor is the two
 * columns' own minimums, which cannot disagree with themselves.
 */

/* Padding counts inside the declared width — otherwise a 380px column measures
 * 412px on screen and the spec is quietly wrong. */
.lw-page, .lw-page *, .lw-page *::before, .lw-page *::after { box-sizing: border-box; }

/* 100% of the CONTENT COLUMN, not of the window. At 100vh this screen was as
   tall as the viewport while starting below a topbar and a header, so its
   bottom — the composer — hung off the end of the page. Measured inside the
   real shell: page top 94, height 900, bottom 994 in a 900px window, composer
   94px below the fold and 124px of page scroll on a screen that must never
   scroll. The harness never caught it because it mounted the page as the root
   of the document, where 100vh and "the space I was given" are the same thing.
   The shell rule that gives this 100% something to be 100% OF lives in
   redesign.css, beside the .workspace it applies to. */
.lw-page { display: flex; height: 100%; min-height: 0; overflow: hidden; }

/* ── the card ──────────────────────────────────────────────────────────── */
.lw-card {
  width: 380px; min-width: 360px; max-width: 400px;
  overflow-y: auto; min-height: 0; padding: 16px;
  border-inline-end: 1px solid rgb(var(--ch-line) / .16);
}
.lw-back { background: none; border: 0; color: var(--lw-ink-soft); font: inherit; cursor: pointer; padding: 0 0 12px; }
.lw-back:hover { color: var(--lw-ink); }

.lw-identity { display: flex; gap: 11px; align-items: center; margin-bottom: 14px; }
.lw-avatar {
  width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center;
  background: rgb(var(--ch-accent) / .16); color: var(--lw-ink-bright); font-weight: 600; font-size: 16px; flex: 0 0 auto;
}
.lw-identity-text { min-width: 0; }
.lw-name { display: block; color: var(--lw-ink); font-size: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lw-identity-meta { display: flex; gap: 6px; align-items: center; margin-top: 4px; }
.lw-elapsed { color: var(--lw-ink-soft); font-size: 12px; }

/* Main / Statistics / Media / Products — owner asked (2026-08-24) for the
   card to have tabs matching his own Kommo layout. Underline-on-active,
   same idiom the accounting workspace's own tab row already uses. */
.lw-card-tabs { display: flex; gap: 4px; margin-bottom: 12px; border-bottom: 1px solid rgb(var(--ch-line) / .14); }
.lw-card-tab {
  padding: 7px 10px; border: none; background: transparent; color: var(--lw-ink-soft);
  font: inherit; font-size: 12.5px; cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.lw-card-tab:hover { color: var(--lw-ink); }
.lw-card-tab.is-active { color: var(--lw-ink-bright); border-bottom-color: rgb(var(--ch-accent) / .8); font-weight: 500; }

.lw-stats-panel { display: flex; flex-direction: column; gap: 2px; }
.lw-stat-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 2px; border-bottom: 1px solid rgb(var(--ch-line) / .08);
}
.lw-stat-row:last-child { border-bottom: none; }
.lw-stat-label { color: var(--lw-ink-soft); font-size: 12.5px; }
.lw-stat-value { color: var(--lw-ink); font-size: 13px; font-weight: 500; }

.lw-headline {
  display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; margin-bottom: 4px;
  border-radius: 12px; background: rgb(var(--ch-lift) / .035); border: 1px solid rgb(var(--ch-line) / .14);
}
.lw-headline-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.lw-headline-row strong { color: var(--lw-ink); font-size: 14px; text-align: end; }
/* Stage/Owner picker, 2026-08-23 — same right-aligned slot the static <strong>
   used to sit in, just editable. appearance:none + a custom chevron for the
   same reason as .lw-task-input's own select fix: the OS-native arrow renders
   garbled over a dark custom-styled select otherwise. */
.lw-headline-select {
  appearance: none; -webkit-appearance: none;
  border: 1px solid rgb(var(--ch-line) / .18); border-radius: 7px;
  background-color: rgb(var(--ch-lift) / .05);
  color: var(--lw-ink); font-size: 13px; font-weight: 600;
  padding-block: 4px 4px; padding-inline: 8px 22px; max-width: 60%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238a94a8' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
}
.lw-headline-select:disabled { opacity: .6; }

/* How long the lead has sat in its CURRENT stage — not since it was created.
   Three tiers, colour-coded the same way this product's own risk language
   already works (green/amber/red), so a manager reads staleness at a glance
   instead of doing the subtraction themselves. */
/* Shrunk 2026-08-23 — owner-flagged live ("наполовину надо уменьшить"):
   text one size down, the bar itself thinner, and the gap between them
   tightened so the whole indicator reads as a quiet footnote under Stage/
   Owner rather than a third thing competing for attention on the card. */
.lw-stage-age { display: flex; flex-direction: column; gap: 3px; margin-top: -2px; }
.lw-stage-age-text { font-size: 10px; }
.lw-stage-age-bar { display: block; height: 2px; border-radius: 1px; background: rgb(var(--ch-line) / .5); overflow: hidden; position: relative; }
.lw-stage-age-bar::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.lw-stage-age-fresh .lw-stage-age-text { color: var(--rp-green); }
.lw-stage-age-fresh .lw-stage-age-bar::after { background: rgb(var(--ch-green) / .55); width: 25%; }
.lw-stage-age-warm .lw-stage-age-text { color: var(--rp-amber); }
.lw-stage-age-warm .lw-stage-age-bar::after { background: rgb(var(--ch-amber) / .6); width: 60%; }
.lw-stage-age-stale .lw-stage-age-text { color: var(--rp-red); }
.lw-stage-age-stale .lw-stage-age-bar::after { background: rgb(var(--ch-red) / .65); width: 100%; }

.lw-section { margin-top: 16px; }
.lw-section-title {
  margin: 0 0 8px; font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--lw-ink-mid);
}
.lw-summary {
  margin: 0; color: var(--lw-ink-bright); font-size: 13px; line-height: 1.55;
  display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden;
}
.lw-field {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  min-height: 38px; border-bottom: 1px solid rgb(var(--ch-line) / .08);
}
.lw-field-label { color: var(--lw-ink-soft); font-size: 12px; flex: 0 0 auto; }
.lw-field-value {
  color: var(--lw-ink); font-size: 13px; text-align: end; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lw-field-empty { color: var(--lw-ink-faint); }

/* EVERY ORDINARY FIELD, TYPED STRAIGHT INTO THE CARD — 2026-08-19.
   Replaces the Email/Company Edit/Save/Cancel toggle this file shipped with
   hours earlier (kept the row height and label style from .lw-field so the
   card's rhythm did not change, only the mode did): the owner's own bar was
   "type into it, it saves", so every plain field on the card is now one of
   these, always, with no button to press first. */
.lw-field-editable { align-items: center; }
.lw-field-input {
  flex: 1 1 auto; min-width: 0; max-width: 220px; text-align: end;
  background: rgb(var(--ch-lift) / .04); border: 1px solid rgb(var(--ch-line) / .22);
  border-radius: 6px; padding: 4px 8px; color: var(--lw-ink-bright); font: inherit; font-size: 13px;
}
.lw-field-input:focus { border-color: rgb(var(--ch-accent) / .5); outline: none; }
.lw-field-textarea { max-width: none; width: 100%; text-align: start; resize: vertical; line-height: 1.5; }
.lw-field-editable:has(.lw-field-textarea) { flex-direction: column; align-items: stretch; min-height: 0; }
/* The saving/saved/error micro-state, next to the field it belongs to — never
   a card-wide banner a manager has to match back to one of nine inputs. */
.lw-field-status { font-size: 11px; flex: 0 0 auto; white-space: nowrap; }
.lw-field-saving { color: var(--lw-ink-dim); }
.lw-field-saved { color: var(--lw-ok-2); }
.lw-field-error { color: var(--lw-late); }

/* ── the phone, which is the point of the card ────────────────────────────
   It used to be a <span> of dead text, with a Call button floating above it
   that read a DIFFERENT field. The number is now the control: clicking it, or
   the handset beside it, places the same callback the button did. When the
   line cannot dial the number stays visible and copyable and the row explains
   why — a blocked line is a reason not to ring, not a reason to hide the
   client's phone. */
.lw-phone { position: relative; align-items: center; }
.lw-phone-actions { display: flex; align-items: center; gap: 4px; min-width: 0; }
/* The number reads as the FACT it is. It carried a button's border, tint and
   hover for as long as it was one; leaving those on a <span> would be the
   worst of both — something that looks pressable and does nothing. Selectable
   on purpose, so it can still be read back and copied by hand. */
.lw-phone-number {
  padding: 3px 0; color: var(--lw-ink); font: inherit; font-size: 14px;
  font-variant-numeric: tabular-nums; letter-spacing: .01em;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  user-select: text;
}
.lw-phone-call, .lw-phone-more {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 8px;
  border: 1px solid rgb(var(--ch-line) / .22); background: rgb(var(--ch-lift) / .03);
  color: var(--lw-ink-bright); font: inherit; font-size: 12px; line-height: 1; cursor: pointer;
}
.lw-phone-call.is-dialable { border-color: rgb(var(--ch-green) / .45); color: var(--rp-green); }
.lw-phone-call.is-dialable svg { display: block; }
.lw-phone-call[disabled] { opacity: .45; cursor: not-allowed; }
.lw-phone-more:hover, .lw-phone-call.is-dialable:hover { background: rgb(var(--ch-lift) / .07); }
/* «Мария звонит» — beside the handset, and deliberately NOT styled like it.
   The two buttons do different things to a real customer's phone: 📞 rings the
   manager's own handset, this one sends the AI agent. Identical styling would
   invite the wrong one, so this carries its own label and a violet accent that
   matches Maria everywhere else in the product, while 📞 keeps the blue that
   has always meant "your line". Not a wider version of the same control. */
.lw-phone-maria {
  flex: 0 0 auto; height: 26px; padding: 0 9px; border-radius: 8px;
  border: 1px solid rgb(var(--ch-violet) / .22); background: rgb(var(--ch-lift) / .03);
  color: var(--lw-ink-bright); font: inherit; font-size: 12px; line-height: 1;
  white-space: nowrap; cursor: pointer;
}
.lw-phone-maria.is-dialable {
  border-color: rgb(var(--ch-violet) / .48); color: var(--lw-violet);
  background: rgb(var(--ch-violet) / .12);
}
.lw-phone-maria.is-dialable:hover { background: rgb(var(--ch-violet) / .22); }
/* Dimmed, never hidden. Hiding it would leave "why can Maria not call?" with
   nowhere to be asked; the tooltip carries the server's own answer. */
.lw-phone-maria[disabled] { opacity: .45; cursor: not-allowed; }
/* ВЫБОР СЦЕНАРИЯ — на самой кнопке «Мария звонит», не в меню «▾».
   Шире соседнего меню, потому что каждая строка несёт две: имя сценария и
   ПОВОД, с которым Мария начнёт разговор. По поводу и выбирают — «свежая
   заявка» и «возврат уснувшего» отличаются не названиями, а первой фразой,
   которую услышит человек. Прижато к концу строки, как и меню номера, чтобы
   на узкой карточке не выезжать за край. */
.lw-maria-menu {
  position: absolute; top: 34px; inset-inline-end: 0; z-index: 26; width: 268px; padding: 6px;
  border-radius: 12px; background: var(--lw-panel);
  border: 1px solid rgb(var(--ch-violet) / .32);
  box-shadow: 0 16px 40px rgb(var(--ch-drop));
}
.lw-maria-head {
  margin: 2px 4px 6px; padding: 0 6px;
  font-size: 0.68rem; letter-spacing: 0.02em; text-transform: uppercase;
  color: var(--u16);
}
.lw-maria-menu ul { list-style: none; margin: 0; padding: 0; }
.lw-maria-menu button {
  width: 100%; display: flex; flex-direction: column; gap: 2px;
  text-align: start; padding: 7px 8px; border-radius: 8px; border: 0;
  background: none; color: var(--lw-ink-bright); font: inherit; cursor: pointer;
}
.lw-maria-menu button:hover { background: rgb(var(--ch-violet) / .12); }
.lw-maria-name { font-size: 13px; line-height: 1.3; }
.lw-maria-why { font-size: 11px; line-height: 1.4; color: var(--u16); }
/* «Без сценария» — отделено чертой и приглушено: это запасной путь, а не
   равноправный пятый сценарий. */
.lw-maria-plain {
  border-top: 1px solid var(--u14, rgba(255, 255, 255, 0.10));
  margin-top: 4px; padding-top: 4px;
}
.lw-maria-plain .lw-maria-name { color: var(--u16); }
.lw-phone-menu {
  position: absolute; top: 34px; inset-inline-end: 0; z-index: 25; width: 218px; padding: 6px;
  border-radius: 12px; background: var(--lw-panel); border: 1px solid rgb(var(--ch-line) / .28);
  box-shadow: 0 16px 40px rgb(var(--ch-drop));
}
.lw-phone-menu ul { list-style: none; margin: 0; padding: 0; }
.lw-phone-menu button {
  width: 100%; text-align: start; padding: 7px 8px; border-radius: 8px; border: 0;
  background: none; color: var(--lw-ink-bright); font: inherit; font-size: 13px; cursor: pointer;
}
.lw-phone-menu button:hover { background: rgb(var(--ch-lift) / .06); }
.lw-phone-menu button[disabled] { opacity: .45; cursor: not-allowed; }
.lw-phone-note {
  margin: 6px 4px 2px; color: var(--pk-amber); font-size: 11px; line-height: 1.45;
}
.lw-phone-copied { color: var(--lw-ok-2); font-size: 11px; margin-inline-start: 8px; }
.lw-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.lw-tags-block { display: flex; flex-direction: column; gap: 8px; }
.lw-tag-chip { display: inline-flex; align-items: center; gap: 5px; }
.lw-tag-remove {
  border: 0; background: none; color: inherit; opacity: .6; cursor: pointer;
  font: inherit; font-size: 12px; line-height: 1; padding: 0;
}
.lw-tag-remove:hover { opacity: 1; }
.lw-tag-add { display: flex; align-items: center; gap: 8px; }
.lw-tag-add .lw-field-input { max-width: none; flex: 1 1 auto; text-align: start; }
.lw-tag-add-btn {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px; line-height: 1;
  border: 1px solid rgb(var(--ch-line) / .24); background: rgb(var(--ch-lift) / .04);
  color: var(--lw-ink); font-size: 16px; cursor: pointer;
}
.lw-tag-add-btn:hover { border-color: rgb(var(--ch-accent) / .55); color: var(--lw-ink-bright); }
.lw-empty { color: var(--lw-ink-dim); font-size: 12px; margin: 0; }
.lw-warn { color: var(--lw-warm); }

.lw-fold { border-top: 1px solid rgb(var(--ch-line) / .1); margin-top: 14px; padding-top: 10px; }
.lw-fold summary {
  cursor: pointer; color: var(--lw-ink-soft); font-size: 12px; list-style: none;
  text-transform: uppercase; letter-spacing: .06em;
}
.lw-fold summary::-webkit-details-marker { display: none; }
.lw-fold summary::before { content: "▸ "; }
.lw-fold[open] summary::before { content: "▾ "; }
/* «Заметки» видно сразу (владелец, 12 сентября: «покрась слово заметки или
   выдели»): тёплый жёлтый, как у бумажной заметки, крупнее соседних свёрток. */
.lw-fold-notes summary {
  color: #f5c451; font-size: 13px; font-weight: 700;
  padding: 4px 8px; border-radius: 8px; background: rgba(245, 196, 81, .10);
  display: inline-block;
}
.lw-fold-notes summary:hover { background: rgba(245, 196, 81, .18); }
.lw-tech .lw-field-value { word-break: break-all; white-space: normal; }

.lw-timeline { list-style: none; margin: 8px 0 0; padding: 0; }
.lw-timeline li {
  display: flex; gap: 8px; align-items: baseline; padding: 6px 0;
  border-bottom: 1px solid rgb(var(--ch-line) / .08); font-size: 12px;
}
.lw-actor { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: var(--lw-ink-mid); }
.lw-actor-ai { color: var(--lw-accent); }
.lw-actor-operator { color: var(--lw-ok); }
.lw-actor-import { color: var(--lw-warm); }
.lw-kind { color: var(--lw-ink); flex: 1; }
.lw-timeline time { color: var(--lw-ink-dim); font-size: 11px; }

/* ── the conversation ──────────────────────────────────────────────────── */
.lw-main { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 0; }

.lw-head {
  position: relative; height: 56px; min-height: 56px; display: flex; align-items: center; gap: 8px;
  padding: 0 16px; border-bottom: 1px solid rgb(var(--ch-line) / .16);
}
.lw-head-name {
  font-size: 15px; color: var(--lw-ink); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; max-width: 40ch;
}
/* «Клиент WhatsApp · …7903» is not a name and must not be dressed as one. It
   keeps its size — it is still the row's identity — and loses the full-white
   weight a real name gets, so the difference is legible without a badge. */
.lw-name.is-standin, .lw-head-name.is-standin { color: var(--lw-ink-standin); font-weight: 500; }
.lw-spacer { flex: 1; }
.lw-menu-btn {
  width: 34px; height: 30px; border-radius: 9px; cursor: pointer; letter-spacing: 1px;
  border: 1px solid rgb(var(--ch-line) / .24); background: rgb(var(--ch-lift) / .03); color: var(--lw-ink-bright);
}
/* ── МЕНЮ «•••» ПО ГРУППАМ (24 сентября 2026) ────────────────────────────────
   Владелец прислал снимок: десять одинаковых белых строк одним столбцом, серая
   мёртвая строка «Звонков по этому лиду нет», сноска в три строки под меню — и
   «Удалить лид» тем же белым, что всё остальное. Последнее — не вкус, а вес
   правил: `.lw-menu button` (класс + тег) весит больше `.lw-menu-danger` (один
   класс), и красный цвет строки был объявлен, но ни разу не показан.
   Теперь: подписи групп, у каждой строки значок и одна высота, видимый фокус
   с клавиатуры, подсказка — одной строкой под своим пунктом, «Удалить лид» —
   последним, за чертой, цветом опасности дизайн-системы (--rp-red). Меню не
   выходит за край: высота до низа колонки переписки (--lw-menu-room, считает
   fitMenuSoon в LeadWorkspacePage.js), остальное прокручивается внутри. */
.lw-menu {
  position: absolute; top: 48px; inset-inline-end: 12px; z-index: 25; width: 264px; padding: 6px;
  border-radius: 14px; background: var(--lw-panel); border: 1px solid rgb(var(--ch-line) / .28);
  box-shadow: 0 18px 44px rgb(var(--ch-drop));
  max-height: var(--lw-menu-room, 70vh); overflow-y: auto; overscroll-behavior: contain;
}
/* Два класса — перевешивает `.lw-menu { width: 300px }` из pack-design.css,
   который грузится позже: самой длинной строке («Экспорт карточки и переписки
   (.txt)») со значком нужно ~300 px. */
.lw-head > .lw-menu, .lw-card-head > .lw-menu { width: 316px; }
.lw-menu ul { list-style: none; margin: 0; padding: 0; }
.lw-menu li { display: flex; flex-direction: column; align-items: stretch; }
.lw-menu button {
  flex: 0 0 auto; text-align: start; padding: 8px; border-radius: 9px; border: 0; background: none;
  color: var(--lw-ink-bright); font: inherit; font-size: 13px; cursor: pointer;
}
.lw-menu button[disabled] { opacity: .5; cursor: not-allowed; }
.lw-menu .lw-mi {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 34px;
  padding-block: 7px; padding-inline: 10px;
}
.lw-menu .lw-mi:hover:not([disabled]) { background: rgb(var(--ch-lift) / .07); }
.lw-menu .lw-mi:focus-visible { outline: 2px solid rgb(var(--ch-accent) / .85); outline-offset: -2px; }
.lw-mi-ico { flex: 0 0 auto; width: 16px; height: 16px; color: var(--lw-ink-soft); }
.lw-menu .lw-mi:not(.lw-menu-danger):hover .lw-mi-ico,
.lw-menu .lw-mi:not(.lw-menu-danger):focus-visible .lw-mi-ico { color: var(--lw-ink-bright); }
.lw-mi-label { flex: 1 1 auto; min-width: 0; }
/* Подсказка под своим пунктом: мельче, тише, с отступом под текст строки
   (значок 16 + зазор 10 + поле 10). */
.lw-mi-note { margin: -3px 0 5px; padding-inline: 36px 10px; font-size: 11px; line-height: 1.4; color: var(--lw-ink-dim); }
.lw-mi-note-group { margin-top: 2px; }
.lw-menu-group + .lw-menu-group { margin-top: 4px; padding-top: 4px; border-top: 1px solid rgb(var(--ch-line) / .12); }
.lw-menu-cap {
  margin: 7px 10px 3px; font-size: 10.5px; font-weight: 600; line-height: 1.3;
  letter-spacing: .08em; text-transform: uppercase; color: var(--lw-ink-dim);
}
/* Разрядка рвёт связное арабское письмо — у арабского подписи без неё. */
[dir="rtl"] .lw-menu-cap { letter-spacing: 0; }
.lw-menu-note { margin: 8px 0 0; padding-inline: 10px; font-size: 11px; color: var(--lw-ink-dim); line-height: 1.45; }
/* The one irreversible row in this menu — a hairline above it and its own
   colour keep it from reading as just another reversible action like Add a
   task or Pause Maria. */
.lw-menu-danger-list { margin-top: 2px; }
.lw-menu-danger-row { margin-top: 4px; padding-top: 6px; border-top: 1px solid rgb(var(--ch-line) / .18); }
/* Класс + класс: одного `.lw-menu-danger` мало против `.lw-menu button`. */
.lw-menu .lw-menu-danger { color: var(--rp-red); }
.lw-menu .lw-menu-danger .lw-mi-ico { color: currentColor; }
.lw-menu .lw-menu-danger:hover:not([disabled]) { background: rgb(var(--ch-red) / .10); }
.lw-menu .lw-menu-danger.is-armed { background: rgb(var(--ch-red) / .16); font-weight: 600; }
.lw-menu-error { color: var(--t450); }
/* Телефон: меню — лист снизу во всю ширину, пункты под палец. */
@media (max-width: 760px) {
  .lw-head > .lw-menu, .lw-card-head > .lw-menu {
    position: fixed; top: auto; inset-inline: 8px; inset-block-end: 8px; z-index: 62;
    width: auto; max-height: 78vh; padding: 8px; border-radius: 16px;
  }
  .lw-menu .lw-mi { min-height: 44px; }
}

/* The only scrolling region in the centre column. A flex column, so a thread
   shorter than the box can be pushed to its end — see .lw-thread below. */
.lw-scroll { flex: 1; overflow-y: auto; min-height: 0; padding: 16px; display: flex; flex-direction: column; }
/* A SHORT CALL SHOULD NOT LEAVE A BLANK CANVAS.
   The thread starts at the top of a 620px box, so a two-turn call left ~460px
   of empty dark between the last line and the closing bar, reading as "the
   rest failed to load".

   `margin-top: auto` and not `min-height: 100% + justify-content: flex-end`.
   A percentage min-height resolves against the parent's height while ignoring
   its 16px padding, which asks for a box taller than the space it is given —
   and flex-end then packs the content against an edge that is already past
   the bottom. An auto margin can only ever consume FREE space, so it cannot
   overflow by construction: short threads sit against the closing bar, long
   ones scroll from the top exactly as before.

   Note there are TWO .lw-thread elements on this screen — this one, and the
   transcript inside a call's fold in the card. Measure the one under
   .lw-main. */
.lw-thread { display: flex; flex-direction: column; gap: 10px; margin-top: auto; }
.lw-daysep { align-self: center; color: var(--lw-ink-dim); font-size: 11px; padding: 6px 0; }
.lw-msg { display: flex; }
.lw-msg-in { justify-content: flex-start; }
.lw-msg-out { justify-content: flex-end; }
.lw-bubble {
  max-width: 72%; padding: 9px 12px; border-radius: 14px;
  background: rgb(var(--ch-lift) / .05); border: 1px solid rgb(var(--ch-line) / .14);
}
.lw-msg-agent .lw-bubble { background: rgb(var(--ch-blue) / .14); border-color: rgb(var(--ch-accent) / .34); }
.lw-msg-operator .lw-bubble { background: rgb(var(--ch-ok) / .12); border-color: rgb(var(--ch-ok) / .34); }
.lw-who { display: block; font-size: 11px; color: var(--lw-ink-soft); margin-bottom: 3px; }
.lw-text { margin: 0; color: var(--lw-ink); font-size: 14px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
.lw-meta { display: flex; gap: 8px; align-items: center; margin-top: 4px; color: var(--lw-ink-dim); font-size: 11px; }
.lw-evidence { color: var(--lw-ink-soft); }
/* WhatsApp's own tick language: one/two grey ticks, two blue for read, a
   warning glyph — never a tick — for a delivery WhatsApp itself refused. */
.lw-ticks { display: inline-flex; align-items: center; color: var(--lw-ink-dim); line-height: 0; }
.lw-tick + .lw-tick { margin-inline-start: -6px; }
.lw-ticks-read { color: rgb(var(--ch-blue) / 1); }
.lw-ticks-failed {
  display: inline-flex; align-items: center; justify-content: center;
  width: 13px; height: 13px; border-radius: 50%; line-height: 1;
  background: rgb(var(--ch-red) / .18); color: rgb(var(--ch-red) / 1);
  font-size: 10px; font-weight: 700;
}
.lw-sys {
  align-self: center; color: var(--lw-ink-mid); font-size: 11px; padding: 4px 10px;
  border-radius: 999px; background: rgb(var(--ch-lift) / .03);
}
/* Звонок в переписке (11 Sep 2026): плашка конца звонка и карточка итога —
   не пузыри Марии, а заметки ленты посередине. */
.lw-call-end {
  display: inline-flex; align-items: center; gap: 10px; font-size: 12px; padding: 5px 12px;
  border: 1px solid rgb(var(--ch-line) / .18); background: rgb(var(--ch-lift) / .04);
}
.lw-call-end-time { color: var(--lw-ink-dim); font-size: 11px; }
.lw-call-summary {
  align-self: center; width: min(560px, 92%); padding: 10px 14px; border-radius: 14px;
  border: 1px solid rgba(96, 165, 250, .28); background: rgba(96, 165, 250, .07);
}
.lw-call-summary-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 4px; font-size: 12.5px; color: var(--lw-ink-bright); }
.lw-call-summary-head time { color: var(--lw-ink-dim); font-size: 11px; font-weight: 400; }
.lw-call-summary-text { margin: 0; font-size: 13px; line-height: 1.5; color: var(--lw-ink); white-space: pre-wrap; }
/* Длинный итог сворачивается кнопкой «Показать полностью», а не обрывается. */
.lw-call-summary.is-clamped .lw-call-summary-text {
  display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden;
}
.lw-call-summary-more { margin-top: 6px; }
/* Реплика звонка, оборванная на полуслове, и тишина на линии (12 Sep 2026). */
.lw-cut-tag {
  display: inline-block; margin-top: 4px; padding: 1px 7px; border-radius: 999px; font-size: 10.5px;
  color: var(--lw-warm); border: 1px solid rgb(var(--ch-warm) / .4); background: rgb(var(--ch-warm) / .08);
}
.lw-call-silence {
  display: inline-flex; align-items: center; gap: 10px; font-size: 11.5px; font-style: italic;
  border: 1px dashed rgb(var(--ch-line) / .24);
}
.lw-empty-state { display: grid; place-items: center; height: 100%; color: var(--lw-ink-dim); }

/* ── states ────────────────────────────────────────────────────────────── */
.lw-state { display: flex; }
.lw-skeleton { animation: lw-pulse 1.4s ease-in-out infinite; background: rgb(var(--ch-lift) / .04); }
.lw-skeleton-card { width: 380px; }
.lw-skeleton-main { flex: 1; }
@keyframes lw-pulse { 0%, 100% { opacity: .5; } 50% { opacity: .85; } }
/* Заглушка загрузки той же формы, что и карточка (15 сентября 2026, см.
   LoadingShell в LeadWorkspacePage.js): колонки — настоящие .lw-card и
   .lw-main, здесь только полосы внутри них. Высоты — как у блоков, которые
   встанут на их место: личность 52, полоса контекста и скоринг 65 (24 сентября
   2026: причины свёрнуты, строка канала ушла в полосу — было 72 и ~200,
   замерено на 1440: от имени до вкладок 145 px), вкладки 40, поле ответа 128.
   Поле ответа важнее всех: оно стоит внизу колонки, и заглушка другой высоты
   сдвинула бы переписку в момент прихода карточки. */
.lw-card-loading { pointer-events: none; }
.lw-card-loading > .lw-skeleton { border-radius: 12px; margin-bottom: 14px; }
.lw-skel-identity { height: 52px; }
.lw-skel-score { height: 65px; }
.lw-skel-tabs { height: 40px; }
.lw-skel-block { height: 165px; }
.lw-skel-block-tall { height: 345px; }
.lw-skel-name { width: 220px; height: 22px; border-radius: 8px; }
/* Отступы — как у настоящего поля ответа (0 8px 10px, composer-kit.css): иначе
   его верх прыгал на 9 px в момент прихода карточки. Сам композер этот файл
   не стилизует (test-crm-lead-workspace). */
.lw-main > .lw-skel-composer { height: 128px; flex: 0 0 auto; margin: 0 8px 10px; border-radius: 12px; }
.lw-error { margin: auto; max-width: 480px; text-align: center; padding: 32px; }
.lw-error h2 { color: var(--lw-ink); margin: 0 0 8px; font-size: 18px; }
.lw-error p { color: var(--lw-ink-soft); margin: 0 0 16px; }
.lw-primary {
  height: 34px; padding: 0 16px; border-radius: 999px; cursor: pointer;
  border: 1px solid rgb(var(--ch-accent) / .45); background: var(--pk-blue); color: var(--rp-on-accent); font: inherit; font-size: 13px;
}

/* A possible-duplicate notice inside a form panel — e.g. LeadCreatePanel,
   when boardroom_crm_save_lead refuses reason "duplicate_phone". Warm, not
   red: this is a question for the operator, not a failure. */
.lw-warn-box {
  margin: 0 0 16px; padding: 12px 14px; border-radius: 10px;
  background: rgb(var(--ch-warm) / .1); border: 1px solid rgb(var(--ch-warm) / .35);
}
.lw-warn-box p { margin: 0 0 10px; color: var(--lw-warm); font-size: 13px; line-height: 1.5; }

/* Below 1280 the card narrows to its floor; the conversation keeps the rest. */
@media (max-width: 1279px) {
  .lw-card { width: 360px; min-width: 340px; }
}

/* Way into the workspace from the Inbox thread header. */
.chatpane-openworkspace {
  margin-top: 8px; height: 30px; padding: 0 12px; border-radius: 999px;
  border: 1px solid rgb(var(--ch-accent) / .45); background: rgb(var(--ch-blue) / .14); color: var(--lw-ink-bright);
  font: inherit; font-size: 12px; cursor: pointer; align-self: flex-start;
}
.chatpane-openworkspace:hover { background: rgb(var(--ch-blue) / .24); }

/* Honest empty state. In the flow inside .lw-scroll, so it can never reach the
   composer — a structural guarantee, not a z-index someone will change later. */
.lw-empty-state { display: flex; flex-direction: column; align-items: center;
  justify-content: center; height: 100%; gap: 10px; text-align: center; padding: 24px; }
.lw-empty-art { opacity: .9; }
.lw-empty-title { margin: 0; color: var(--lw-ink-bright); font-size: 15px; }
.lw-empty-copy { margin: 0; color: var(--lw-ink-dim); font-size: 13px; max-width: 34ch; }

/* A template went instead of the operator's text. Stated, never assumed —
   the customer received an invitation to reopen the conversation, not the
   sentence that was typed, and the screen must say which. */
.lw-template-notice {
  margin: 0; padding: 9px 16px; font-size: 12px; line-height: 1.45; color: var(--lw-warm);
  background: rgb(var(--ch-warm) / .09); border-top: 1px solid rgb(var(--ch-warm) / .24);
}

/* ── the lead's tasks, inside «Следующий шаг» ──────────────────────────────
   A task belongs to a lead, so it is created and closed where the lead is.
   There is no delete control: the database refuses a hard delete of a CRM
   record, and a button that always fails is worse than no button. */
.lw-tasks { margin-top: 10px; }
.lw-task-list { list-style: none; margin: 0 0 8px; padding: 0; }
.lw-task {
  display: flex; gap: 8px; align-items: flex-start; padding: 7px 0;
  border-bottom: 1px solid rgb(var(--ch-line) / .08);
}
.lw-task:last-child { border-bottom: 0; }
.lw-task-check {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; cursor: pointer;
  border: 1px solid rgb(var(--ch-line) / .34); background: rgb(var(--ch-lift) / .03);
  color: var(--lw-ink-bright); font: inherit; font-size: 12px; line-height: 1;
}
.lw-task-check:hover { border-color: rgb(var(--ch-ok) / .6); color: var(--lw-ok); }
.lw-task-check[disabled] { opacity: .5; cursor: not-allowed; }
.lw-task-body { min-width: 0; flex: 1; }
.lw-task-title { display: block; color: var(--lw-ink); font-size: 13px; line-height: 1.4; }
.lw-task.done .lw-task-title { color: var(--lw-ink-dim); text-decoration: line-through; }
.lw-task-meta { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 5px; }
.lw-task-due, .lw-task-owner {
  height: 26px; padding: 0 6px; border-radius: 7px; font: inherit; font-size: 11px;
  border: 1px solid rgb(var(--ch-line) / .2); background: rgb(var(--ch-lift) / .03); color: var(--lw-ink-bright);
  max-width: 100%;
}
.lw-task-dim { color: var(--lw-ink-mid); font-size: 11px; }
.lw-task-pri { color: var(--lw-warm); font-size: 11px; }
.lw-task-late { color: var(--lw-late); font-size: 11px; }
.lw-task.overdue .lw-task-due { border-color: rgb(var(--ch-late2) / .5); }

/* Was plain dim text — the same weight as any other empty state, on the one
   line that's actually an invitation to do something ("+ Create task" sits
   right under it). Blue rather than amber: .lw-callback-blocked's own
   comment reserves amber for a real blocker, and an empty task list is not
   one — this is a nudge, not a warning. */
.lw-task-none {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 8px; padding: 8px 10px; border-radius: 10px;
  border: 1px solid rgb(var(--ch-accent) / .3); background: rgb(var(--ch-blue) / .1);
  color: var(--lw-ink-bright); font-size: 12px; line-height: 1.4;
}
.lw-task-none::before { content: "🕓"; flex: none; font-size: 13px; }
.lw-task-add {
  width: 100%; height: 32px; border-radius: 9px; cursor: pointer; font: inherit; font-size: 13px;
  border: 1px dashed rgb(var(--ch-line) / .34); background: rgb(var(--ch-lift) / .02); color: var(--lw-ink-bright);
}
.lw-task-add:hover { border-color: rgb(var(--ch-accent) / .6); background: rgb(var(--ch-blue) / .1); }
.lw-task-add[disabled] { opacity: .5; cursor: not-allowed; }

.lw-task-form { display: flex; flex-direction: column; gap: 7px; }
.lw-task-row { display: flex; flex-wrap: wrap; gap: 7px; align-items: end; }
/* 120px было слишком мало: три контрола втискивались в одну строку, и на
   «Ответственный» с «Приоритет» оставалось по семьдесят пикселей текста —
   «Dmitrii Nikolaev» превращался в «Dmitrii Nikol…», а «Обычный» в «Р…».
   Владелец 31 августа прислал это как «артефакты, два поля».
   При 160px три контрола в узкую карточку не помещаются и переносятся на
   вторую строку, где у каждого появляется настоящая ширина. */
.lw-task-row > * { flex: 1 1 160px; min-width: 0; }
.lw-task-input {
  height: 32px; padding: 0 9px; border-radius: 9px; font: inherit; font-size: 13px;
  border: 1px solid rgb(var(--ch-line) / .24); background: rgb(var(--ch-lift) / .03); color: var(--lw-ink);
}
/* The owner and priority controls in the task form are native <select>
   elements sharing .lw-task-input with plain text inputs. Left unstyled, the
   OS renders its own arrow and (on some Windows/Chrome builds) its own
   closed-box chrome on top of ours — reported live as the label reading as
   garbled characters instead of "Обычный". appearance:none takes over the
   whole box; the chevron is drawn by hand so removing the native one loses
   nothing. */
select.lw-task-input {
  appearance: none; -webkit-appearance: none;
  /* ТЕКСТ ОБРЕЗАЛСЯ СНИЗУ, И ЭТО НЕ ШРИФТ И НЕ ШИРИНА.
     У правила была высота 32px и не было line-height. Chrome на Windows
     центрирует содержимое <select> не так, как <input>: без явной строки
     текст садится ниже середины и подрезается нижней границей. Соседние
     input'ы в той же строке выглядели правильно — отсюда и впечатление, что
     «поля битые», хотя правило одно на всех и различие только здесь.
     30px = 32 минус две рамки по пикселю. */
  line-height: 30px;
  /* Длинное имя обязано кончаться многоточием, а не обрывом на середине буквы. */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding-inline-end: 26px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238a94a8' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
}
/* ПОДПИСЬ, КОТОРУЮ ВИДНО ГЛАЗАМИ.
   У срока, ответственного и приоритета были только aria-label — их читает
   экранный диктор, а человек видел три безымянных поля и гадал, что в них.
   Подпись крошечная и приглушённая: она объясняет, не перетягивая внимание с
   самого поля. */
/* Подпись-объяснение под полем: кто его заполняет и когда оно сохраняется.
   Тише самого поля и тише его названия — она отвечает на вопрос, а не спорит
   за внимание. */
/* КНОПКА «ПРЕДЛОЖИТЬ ЗАДАЧУ» И ЕЁ ОБЪЯСНЕНИЕ.
   Кнопка приглушённая, не синяя: синяя тут одна — «Сохранить задачу», и
   именно она сохраняет. Предложение ничего не сохраняет, и выглядеть как
   главное действие оно не должно. */
.lw-task-suggest-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.lw-task-suggest {
  height: 30px; padding: 0 12px; border-radius: 999px; cursor: pointer;
  font: inherit; font-size: 12.5px; flex: 0 0 auto;
  border: 1px solid rgb(var(--ch-line) / .28); background: rgb(var(--ch-lift) / .05);
  color: var(--lw-ink);
}
.lw-task-suggest:hover:not([disabled]) { border-color: rgb(var(--ch-line) / .5); }
.lw-task-suggest[disabled] { opacity: .55; cursor: progress; }
.lw-task-suggest-note { font-size: 11px; line-height: 1.4; color: var(--lw-ink-mid); flex: 1 1 180px; }

.lw-field-hint {
  margin: 4px 0 0; font-size: 11px; line-height: 1.45; color: var(--lw-ink-mid);
}
.lw-task-field { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.lw-task-field-label {
  font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--lw-ink-mid);
}
.lw-task-note { height: auto; padding: 7px 9px; resize: vertical; }
.lw-task-cancel {
  height: 32px; padding: 0 14px; border-radius: 999px; cursor: pointer; font: inherit; font-size: 13px;
  border: 1px solid rgb(var(--ch-line) / .24); background: none; color: var(--lw-ink-soft); flex: 0 0 auto;
}
.lw-task-error { margin: 0; color: var(--lw-late); font-size: 12px; line-height: 1.4; }

.lw-task-done-fold { margin-bottom: 8px; }
.lw-task-done-fold summary {
  cursor: pointer; color: var(--lw-ink-mid); font-size: 11px; letter-spacing: .05em;
  text-transform: uppercase; list-style: none;
}
.lw-task-done-fold summary::-webkit-details-marker { display: none; }
.lw-task-done-fold summary::before { content: "▸ "; }
.lw-task-done-fold[open] summary::before { content: "▾ "; }

/* ── the approved-template fallback ────────────────────────────────────────
   Built 2026-08-22 as the sole content of a dedicated "no dialogue yet"
   screen for a lead with no channel and no reachable identity. That screen
   is gone — every lead now gets the same composer, addressed to whatever
   number the card or a call carries — and this block moved with the JS to
   become what appears UNDER the composer the moment WhatsApp refuses free
   text. The names still say "nodialogue" because the class did not change,
   only where it renders. */
.lw-nodialogue-greet {
  margin-top: 14px; padding-top: 14px; width: 100%;
  border-top: 1px solid rgb(var(--ch-line) / .16);
}
.lw-nodialogue-greet-title { margin: 0 0 8px; color: var(--lw-ink-bright); font-size: 13px; font-weight: 600; }
.lw-nodialogue-greet-note { margin: 0; color: var(--lw-ink-dim); font-size: 12px; line-height: 1.5; }
.lw-nodialogue-greet-note.is-error { color: var(--t450); }
.lw-nodialogue-greet-note.is-ok { color: var(--t209); }
.lw-nodialogue-greet-list { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.lw-nodialogue-greet-list button.is-armed { border-color: var(--t217); color: var(--t450); background: rgba(255, 120, 100, 0.09); }
.lw-nodialogue-greet-list button + .lw-nodialogue-greet-note { margin-top: 8px; width: 100%; }
.lw-template-fill { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.lw-template-fill-panel {
  display: flex; flex-direction: column; gap: 6px; width: 260px;
  padding: 10px; border-radius: 10px; background: rgb(var(--ch-line) / .06);
}
.lw-template-fill-preview { margin: 0 0 2px; color: var(--lw-ink-dim); font-size: 11px; line-height: 1.5; font-style: italic; }
.lw-template-fill-input {
  width: 100%; box-sizing: border-box; padding: 6px 8px; font-size: 12px;
  border-radius: 8px; border: 1px solid rgb(var(--ch-line) / .2);
  background: var(--lw-panel-bg, transparent); color: var(--lw-ink-bright);
}
.lw-template-fill-panel button.is-armed { border-color: var(--t217); color: var(--t450); background: rgba(255, 120, 100, 0.09); }

/* ── Calls ────────────────────────────────────────────────────────────────
   Derived from the thread, not fetched: one row per completed call, closed by
   default. The transcript is the expensive part and stays behind the fold —
   an operator scanning a lead wants to see THAT there were calls and how long
   they ran, before deciding to read one. */
.lw-calls { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.lw-call {
  border: 1px solid rgb(var(--ch-line) / .12);
  border-radius: 8px;
  padding: 9px 10px;
  background: rgb(var(--ch-lift) / .02);
}
.lw-call-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.lw-call-when { color: var(--lw-ink-bright); font-size: 13px; }
.lw-call-len { color: var(--lw-ink-dim); font-size: 12px; white-space: nowrap; }
/* ОДИН КЛАСС НА ДВЕ ВЕЩИ — ВОТ ПОЧЕМУ ИТОГ ОБРЕЗАЛСЯ (12 Sep 2026).
   Здесь стояло второе правило .lw-call-summary — для ряда в блоке «Звонки»,
   с обрезкой в три строки. Тот же класс носит карточка итога в переписке, и
   обрезка доставалась ей («итог звонка обрезан снизу»), а ряд получал рамку
   и фон карточки («пилюля»). У ряда теперь свои классы .lw-callrow-*. */
.lw-callrow { display: flex; flex-direction: column; gap: 6px; }
/* Двойной класс: .lw-call-pick ниже по файлу ставит display: block. */
.lw-call-pick.lw-callrow-top {
  display: flex; align-items: baseline; gap: 8px; width: 100%;
}
.lw-callrow-icon { flex: 0 0 auto; font-size: 13px; color: var(--lw-ink-soft); }
.lw-callrow-when { color: var(--lw-ink-bright); font-size: 13px; font-weight: 600; }
.lw-callrow-len { margin-inline-start: auto; color: var(--lw-ink-dim); font-size: 12px; white-space: nowrap; }
.lw-callrow-outcome { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.lw-callrow-end {
  display: inline-flex; align-items: center; padding: 2px 9px; border-radius: 999px;
  font-size: 11.5px; line-height: 1.5; border: 1px solid rgb(var(--ch-line) / .22);
  color: var(--lw-ink-bright); background: rgb(var(--ch-lift) / .04);
}
.lw-callrow-end.is-ok { border-color: rgb(var(--ch-ok) / .4); background: rgb(var(--ch-ok) / .1); }
.lw-callrow-end.is-warn { border-color: rgb(var(--ch-warm) / .45); background: rgb(var(--ch-warm) / .1); color: var(--lw-warm); }
.lw-callrow-end.is-muted { color: var(--lw-ink-soft); }
.lw-callrow-turns { color: var(--lw-ink-dim); font-size: 12px; }
.lw-callrow-summary {
  margin: 0; color: var(--lw-ink-note); font-size: 12.5px; line-height: 1.5; white-space: pre-wrap;
}
/* Три строки в списке — чтобы узнать звонок; остальное — «Показать полностью». */
.lw-callrow-summary.is-clamped {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.lw-callrow-summary.lw-empty { color: var(--lw-ink-dim); font-style: italic; }
.lw-callrow-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; justify-content: space-between; }
.lw-callrow-more, .lw-call-summary-more {
  padding: 0; border: 0; background: none; cursor: pointer; font: inherit; font-size: 12px;
  color: rgb(var(--ch-blue) / 1); text-decoration: underline; text-underline-offset: 2px;
}
.lw-callrow-review {
  margin-inline-start: auto; height: 28px; padding: 0 12px; border-radius: 999px; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--lw-ink-bright);
  border: 1px solid rgb(var(--ch-accent) / .45); background: rgb(var(--ch-blue) / .14);
}
.lw-callrow-review:hover { background: rgb(var(--ch-blue) / .24); }

/* ── звонок, который Мария сделает сама ───────────────────────────────────── */
.lw-sched-notice {
  margin: 0 0 8px; padding: 8px 10px; border-radius: 10px; font-size: 12.5px; line-height: 1.45;
  color: var(--lw-ink-bright); border: 1px solid rgb(var(--ch-ok) / .35); background: rgb(var(--ch-ok) / .09);
}
.lw-sched-form {
  display: flex; flex-direction: column; gap: 8px; margin: 0 0 10px; padding: 10px 12px;
  border-radius: 12px; border: 1px solid rgb(var(--ch-accent) / .38); background: rgb(var(--ch-blue) / .07);
}
.lw-sched-form-title { margin: 0; color: var(--lw-ink-bright); font-size: 13.5px; font-weight: 600; }
.lw-sched-mode { margin: 0; font-size: 12px; line-height: 1.5; color: var(--lw-ink-soft); }
.lw-sched-mode.is-auto { color: var(--lw-ink-bright); }
.lw-sched-mode.is-task { color: var(--lw-warm); }
.lw-sched-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.lw-sched-chip {
  height: 26px; padding: 0 10px; border-radius: 999px; cursor: pointer; font: inherit; font-size: 12px;
  border: 1px solid rgb(var(--ch-line) / .28); background: rgb(var(--ch-lift) / .04); color: var(--lw-ink-bright);
}
.lw-sched-chip:hover { border-color: rgb(var(--ch-accent) / .6); }
.lw-sched-warn { margin: 0; font-size: 11.5px; line-height: 1.45; color: var(--lw-warm); }
.lw-sched-buttons > * { flex: 0 0 auto; }
.lw-sched-list { list-style: none; margin: 0 0 10px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.lw-sched {
  display: flex; gap: 8px; align-items: flex-start; padding: 8px 10px; border-radius: 10px;
  border: 1px solid rgb(var(--ch-line) / .14); background: rgb(var(--ch-lift) / .02);
}
.lw-sched.is-waiting { border-color: rgb(var(--ch-accent) / .4); background: rgb(var(--ch-blue) / .07); }
.lw-sched-icon { flex: 0 0 auto; font-size: 14px; line-height: 1.4; }
.lw-sched-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.lw-sched-when { color: var(--lw-ink-bright); font-size: 12.5px; font-weight: 600; }
.lw-sched-status { font-size: 11.5px; color: var(--lw-ink-soft); }
.lw-sched-status.is-ok { color: var(--lw-ok); }
.lw-sched-status.is-warn { color: var(--lw-warm); }
.lw-sched-rule, .lw-sched-note { margin: 0; font-size: 11.5px; line-height: 1.45; color: var(--lw-ink-mid); white-space: pre-wrap; }
.lw-sched-actions { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.lw-sched-cancel {
  height: 26px; padding: 0 10px; border-radius: 999px; cursor: pointer; font: inherit; font-size: 12px;
  border: 1px solid rgb(var(--ch-line) / .28); background: none; color: var(--lw-ink-soft);
}
.lw-sched-cancel.is-armed { border-color: var(--t217); color: var(--t450); background: rgba(255, 120, 100, 0.09); font-weight: 600; }
/* THE ROW IS A PICKER NOW, not a container with a transcript folded into it.
   The whole row answers, and the selected one is marked, because a list whose
   selection is invisible makes the right column look like it changed on its
   own. */
.lw-call-pick {
  display: block; width: 100%; text-align: start; padding: 0;
  border: 0; background: none; color: inherit; font: inherit; cursor: pointer;
}
.lw-call:hover { border-color: rgb(var(--ch-line) / .28); }
.lw-call.is-active {
  border-color: rgb(var(--ch-accent) / .55);
  background: rgb(var(--ch-blue) / .10);
}
.lw-call-turns-count {
  display: block; margin-top: 6px; color: var(--lw-ink-dim); font-size: 11px;
  text-transform: uppercase; letter-spacing: .05em;
}
.lw-call-turns { margin-top: 6px; }

/* ── the selected call, in the right column ──────────────────────────────
   The client card is where a call is read, so this is the reading surface:
   header facts, Maria's verdict, the recording if one ever exists, then the
   turns. It replaces the flat message stream for voice, which was rendering
   the same turns the card was folding — the same conversation twice. */
.lw-callpane { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.lw-callpane-head {
  padding: 12px 16px; border-bottom: 1px solid rgb(var(--ch-line) / .14);
  background: rgb(var(--ch-lift) / .02);
}
.lw-callpane-title { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.lw-callpane-title strong { color: var(--lw-ink); font-size: 14px; }
.lw-callpane-len { color: var(--lw-ink-soft); font-size: 12px; }
.lw-callpane-of { color: var(--lw-ink-dim); font-size: 11px; margin-inline-start: auto; }
.lw-callpane-facts {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px 16px; margin: 10px 0 0;
}
.lw-callpane-fact dt {
  color: var(--lw-ink-mid); font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
}
/* Значения ПЕРЕНОСЯТСЯ (12 Sep 2026): в 380 px «Голосовой агент для ко…»
   прочитать было негде, и подсказка по наведению этого не спасала. */
.lw-callpane-fact dd {
  margin: 2px 0 0; color: var(--lw-ink); font-size: 13px; line-height: 1.4;
  overflow-wrap: anywhere;
}
/* Во вкладке «Итог и оценка» — по строке на факт: три колонки в 380 px
   превращали намерение в столбик из пяти строк по два слова. */
.lw-callpane-scroll .lw-callpane-facts { grid-template-columns: minmax(0, 1fr); gap: 8px; margin: 0 0 14px; }
.lw-callpane-outcome { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.lw-callpane-dir {
  display: inline-flex; align-items: center; padding: 2px 9px; border-radius: 999px; font-size: 11.5px;
  color: var(--lw-ink-soft); border: 1px solid rgb(var(--ch-line) / .22);
}
.lw-callpane-step {
  width: 22px; height: 22px; margin: 0 4px; border-radius: 6px; cursor: pointer; font: inherit; line-height: 1;
  border: 1px solid rgb(var(--ch-line) / .24); background: none; color: var(--lw-ink-bright);
}
.lw-callpane-step[disabled] { opacity: .35; cursor: default; }
.lw-callpane-tabs { display: flex; gap: 4px; margin-top: 10px; }
.lw-callpane-tab {
  height: 28px; padding: 0 12px; border-radius: 8px; cursor: pointer; font: inherit; font-size: 12.5px;
  border: 1px solid rgb(var(--ch-line) / .2); background: none; color: var(--lw-ink-soft);
}
.lw-callpane-tab.is-on {
  color: var(--lw-ink-bright); font-weight: 600;
  border-color: rgb(var(--ch-accent) / .55); background: rgb(var(--ch-blue) / .14);
}
.lw-callpane-block { margin: 0 0 14px; }
.lw-callpane-h {
  margin: 0 0 6px; color: var(--lw-ink-mid); font-size: 10.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
}
.lw-callpane-summary { margin: 0; color: var(--lw-ink); font-size: 13px; line-height: 1.55; white-space: pre-wrap; }
.lw-callpane-stats { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: var(--lw-ink); }
.lw-callpane-stats .is-warn { color: var(--lw-warm); }
.lw-callpane-stats .is-ok { color: var(--lw-ok); }
.lw-callpane-note { margin: 0 0 10px; font-size: 11.5px; line-height: 1.45; color: var(--lw-ink-mid); }
/* Стенограмма: время · кто · что. Строки, а не пузыри — это чтение, не чат. */
.lw-script { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.lw-script-row, .lw-script-silence, .lw-script-end {
  display: grid; grid-template-columns: 38px 58px minmax(0, 1fr); gap: 0 6px; align-items: baseline;
  padding: 5px 4px; border-radius: 8px;
}
.lw-script-row.is-agent { background: rgb(var(--ch-blue) / .06); }
.lw-script-at { color: var(--lw-ink-dim); font-size: 11px; font-variant-numeric: tabular-nums; }
.lw-script-who { color: var(--lw-ink-soft); font-size: 11.5px; font-weight: 600; }
.lw-script-row.is-agent .lw-script-who { color: rgb(var(--ch-blue) / 1); }
.lw-script-body { min-width: 0; }
.lw-script-text { margin: 0; color: var(--lw-ink); font-size: 13px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
.lw-script-tag {
  display: inline-block; margin-block-start: 3px; margin-inline-end: 6px; padding: 0 7px; border-radius: 999px; font-size: 10.5px;
  color: var(--lw-ink-soft); border: 1px solid rgb(var(--ch-line) / .24);
}
.lw-script-tag.is-cut { color: var(--lw-warm); border-color: rgb(var(--ch-warm) / .4); }
.lw-script-intended { margin: 3px 0 0; font-size: 12px; line-height: 1.45; color: var(--lw-ink-mid); font-style: italic; }
.lw-script-quiet { color: var(--lw-ink-mid); font-size: 12px; font-style: italic; }
.lw-script-pause { padding-block: 2px; padding-inline: 48px 4px; color: var(--lw-ink-dim); font-size: 11px; }
.lw-script-end { margin-top: 6px; border-top: 1px solid rgb(var(--ch-line) / .14); padding-top: 8px; }
.lw-script-endtext { grid-column: 2 / 4; font-size: 12.5px; font-weight: 600; color: var(--lw-ink-bright); }
.lw-script-end.is-warn .lw-script-endtext { color: var(--lw-warm); }
/* The recording row. It carries an <audio> when the workspace payload handed
   over a signed link for this call's conversation id, and the word
   "unavailable" when it did not — the same row either way, so the slot never
   silently vanishes and leaves the reader wondering whether audio exists. */
.lw-callpane-rec {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 16px; border-bottom: 1px solid rgb(var(--ch-line) / .12);
}
.lw-callpane-reclabel {
  color: var(--lw-ink-soft); font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
}
.lw-callpane-rec audio { height: 32px; flex: 1; min-width: 0; }
/* Quieter than the player it stands in for: a statement of fact, not a control.
   Same 32px row height so selecting between two calls does not make the panel
   below it jump. */
.lw-callpane-rec.is-absent { min-height: 48px; }
.lw-callpane-recnone { color: var(--lw-ink-quiet); font-size: 12px; }
.lw-callpane-empty { padding: 16px; }

/* ── Voice workspace, per the build spec ──────────────────────────────────
   360px left panel, 28px page padding, calm dark surfaces, one blue accent.
   The numbers are the spec's, not a guess: card 360, gap 16-20, radius 12-14. */
.lw-page { padding: 28px; gap: 20px; }
.lw-card {
  width: 360px; min-width: 360px; max-width: 360px;
  padding: 20px; border-inline-end: 0;
  border: 1px solid rgb(var(--ch-line) / .14); border-radius: 14px;
  background: rgb(var(--ch-lift) / .015);
}
.lw-main {
  border: 1px solid rgb(var(--ch-line) / .14); border-radius: 14px;
  background: rgb(var(--ch-lift) / .015); overflow: hidden;
}
/* A finished call is not a chat waiting for a reply. This replaces the composer
   for voice: a statement and the one action that exists, rather than a text box
   and a Send the server answers 409 for. */
.lw-voiceclose {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  /* THE BOTTOM-RIGHT CORNER IS NOT FREE ON THIS SCREEN.
     Boro parks itself there by default — 90px wide at a 12px gap, so it covers
     the last 102px of the viewport — and it sits at z-index 50, above
     everything this page draws. Measured at 1024: Boro 922–1012 × 776–888
     against «Создать задачу» at 869–987 × 816–854. The one action a finished
     call offers was behind the companion, unclickable, with nothing to
     indicate why. Boro stays where it is and stays draggable; the bar simply
     stops putting its button under him. */
  /* rtl-exempt: запас в 90px держит место под Boro, а Boro не зеркалится.
     Его исходная позиция считается в пикселях от правого края окна
     (boroCompanion.js, defaultPos) и дальше живёт там, куда его перетащили, —
     направление письма на это не влияет. Если перевести запас в
     padding-inline-end, в арабской раскладке он уедет налево, а компаньон
     останется справа, и кнопка снова окажется под ним — ровно тот дефект,
     ради которого этот запас и появился. */
  padding: 14px 16px; padding-right: 90px; border-top: 1px solid rgb(var(--ch-line) / .16);
  background: rgb(var(--ch-lift) / .02);
}
/* And the toast, which shares that corner at z-index 30. Measured at 1024:
   toast 826–886 over a CTA at 816–854 — a full cover for as long as it showed.
   120px clears the 89px bar and the page's own bottom padding. The composer
   does not need this: at 156px tall its Send already sits above the toast. */
body:has(.lw-voiceclose) .toast { bottom: 120px; }
.lw-voiceclose-text { min-width: 0; }
.lw-voiceclose-title { margin: 0; color: var(--lw-ink-bright); font-size: 14px; font-weight: 600; }
.lw-voiceclose-copy { margin: 3px 0 0; color: var(--lw-ink-soft); font-size: 12px; line-height: 1.5; }
.lw-voiceclose-cta { flex: 0 0 auto; white-space: nowrap; }
/* Amber is a real blocker and nothing else. */
.lw-callback-blocked {
  margin: 0 0 10px; padding: 8px 10px; border-radius: 12px;
  border: 1px solid rgb(var(--ch-amber) / .28); background: rgb(var(--ch-amber) / .10);
  color: var(--pk-amber); font-size: 12px; line-height: 1.45;
}
/* The block used to be the paragraph itself; it now wraps the explanation and
   the one route out of the blocked state, so the paragraph carries no margin. */
.lw-callback-blocked p { margin: 0; }
.lw-callback-fix {
  margin-top: 8px; padding: 5px 10px; border-radius: 9px;
  border: 1px solid rgb(var(--ch-amber) / .34); background: transparent;
  color: var(--pk-amber); font-size: 12px; cursor: pointer;
}
.lw-callback-fix:hover { background: rgb(var(--ch-amber) / .14); }
.lw-callback { width: 100%; margin-bottom: 10px; }
@media (max-width: 1120px) {
  .lw-page { padding: 20px; gap: 16px; }
  .lw-card { width: 320px; min-width: 320px; max-width: 320px; padding: 16px; }
}

/* ── the composer belongs to the person, not to the thread ─────────────────
   One chip per way to answer this contact, most recently used first. The strip
   sits directly above the shared composer and shares its top border, so the
   picker and the box read as one control rather than as a toolbar that happens
   to be near it. NOTHING HERE TOUCHES THE COMPOSER'S OWN CLASSES — that kit is
   shared with the Inbox and restyling it from a page stylesheet is how two
   screens come to disagree about the same control. A suite forbids it.

   HEIGHT IS THE WHOLE CONSTRAINT HERE. The centre column is a flex column whose
   scroller (.lw-scroll) takes the remainder; anything added between it and the
   composer is taken straight off the transcript. Measured in a browser at
   1536 CSS px: 41px with two chips, and it renders at all only when there is
   more than one channel to choose between — a single-channel contact loses
   nothing. The window notice above it is a further 36px, and only when the
   window is actually shut. */
.lw-reach {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 7px 16px; border-top: 1px solid rgb(var(--ch-line) / .16);
  background: rgb(var(--ch-lift) / .015);
}
.lw-reach-label { color: var(--lw-ink-dim); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
.lw-reach-chip {
  display: inline-flex; align-items: center; gap: 5px;
  /* styles.css gives EVERY button a 40px min-height. Measured in a browser at
     1536, that alone stood this strip at 55px — 55 pixels taken off the
     transcript on every multi-channel lead, for a chip whose text is 18px tall.
     Overridden here and nowhere else: the rule is right for a real button and
     wrong for a one-line selector living inside another control. */
  min-height: 26px;
  padding: 3px 10px; border-radius: 999px; cursor: pointer;
  border: 1px solid rgb(var(--ch-line) / .22); background: transparent;
  color: var(--lw-ink-soft); font-size: 12px; line-height: 1.5;
}
.lw-reach-chip:hover { border-color: rgb(var(--ch-line) / .38); color: var(--lw-ink-bright); }
.lw-reach-chip.is-on {
  border-color: rgb(var(--ch-accent) / .55); background: rgb(var(--ch-accent) / .12); color: var(--lw-ink-bright);
}
/* A shut window is marked on the chip while it is being chosen, not after the
   send comes back as a template. Amber, because it is a real constraint. */
.lw-reach-chip.is-shut { border-color: rgb(var(--ch-warm) / .38); }
.lw-reach-chip.is-shut.is-on { background: rgb(var(--ch-warm) / .12); }
.lw-reach-shut { font-size: 11px; opacity: .9; }

/* The window notice is the template notice's twin, said BEFORE anybody types
   rather than after a send came back as something else. Same colour on purpose:
   it is the same fact at a different moment. */
.lw-window-notice { border-top: 1px solid rgb(var(--ch-warm) / .24); }

/* Nothing to write to, and the reason why — never an inert text box.
   Same bar as .lw-voiceclose, including its 90px right padding: Boro parks in
   that corner at z-index 50 and would sit on top of the call button. */
.lw-noreach {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding-block: 14px 14px; padding-inline: 16px 90px; border-top: 1px solid rgb(var(--ch-line) / .16);
  background: rgb(var(--ch-lift) / .02);
}
body:has(.lw-noreach) .toast { bottom: 120px; }
.lw-noreach-text { min-width: 0; }
.lw-noreach-title { margin: 0; color: var(--lw-ink-bright); font-size: 14px; font-weight: 600; }
.lw-noreach-copy { margin: 3px 0 0; color: var(--lw-ink-soft); font-size: 12px; line-height: 1.5; }
.lw-noreach-copy.lw-dim { color: var(--lw-ink-dim); }
.lw-noreach-cta { flex: 0 0 auto; white-space: nowrap; }

/* The drawer stopped reprinting the conversation that is already on screen
   beside it (2026-08-16 — the owner asked why he was looking at two identical
   panels). What is left in that slot is one quiet line saying where the
   transcript is, so the panel reads as finished rather than truncated. */
.lw-callpane-elsewhere {
  margin: 0;
  padding: 16px;
  color: var(--pk-dim);
  font-size: 13px;
  line-height: 1.5;
}

/* ── «Написать письмо» on the lead card ───────────────────────────────────
   Sits directly under the Email field it acts on, so the address and the
   action read as one thing. A link, not a button element: it navigates, and
   dressing a navigation as a form control is how a card ends up with two
   things that look identical and behave differently. */
.lw-mail-button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: start;
  margin: 2px 0 6px;
  padding: 7px 13px;
  border-radius: 999px;
  border: 1px solid rgb(var(--ch-blue2) / .38);
  background: rgb(var(--ch-blue2) / .12);
  color: var(--pk-ink, inherit);
  font-size: .82rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.lw-mail-button:hover {
  background: rgb(var(--ch-blue2) / .2);
  border-color: rgb(var(--ch-blue2) / .55);
}
.lw-mail-button:focus-visible {
  outline: 2px solid rgb(var(--ch-blue2) / .7);
  outline-offset: 2px;
}

/* ── the email row, after the owner used it ──────────────────────────────
   Reported the evening it shipped: the address was cut off mid-domain
   («notifications@marketplace.pipedriv…») while the button beside it took
   room the address needed. On a lead card the address IS the content and
   the button is one click — the proportions were backwards.

   The field gets the width; the button drops underneath it and shrinks to
   what it says. */
.lw-details-block .lw-mail-button {
  margin: 2px 0 10px;
  padding: 5px 11px;
  font-size: .78rem;
  align-self: start;
}
/* The address must be readable in full — that is the whole point of the row
   it sits in. Wrapping beats an ellipsis here: an address you cannot finish
   reading is an address you cannot check. */
.lw-details-block .lw-field-value,
.lw-details-block input[type="email"] {
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: break-word;
  white-space: normal;
  text-overflow: clip;
}

/* ── ТОВАРЫ В СДЕЛКЕ ──────────────────────────────────────────────────────
   Строка позиции — имя, количество, цена, итог. Количество редактируется на
   месте: открывать форму ради одной цифры дороже, чем её поменять. */
.lw-items { display: flex; flex-direction: column; gap: 6px; }

.lw-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 64px auto auto 28px;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid rgb(var(--ch-line) / .10);
}

.lw-item-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lw-item-qty {
  width: 100%;
  text-align: center;
  font-variant-numeric: tabular-nums;
  background: rgb(var(--ch-lift) / .04);
  border: 1px solid rgb(var(--ch-line) / .16);
  border-radius: 6px;
  padding: 3px 4px;
  color: inherit;
  font: inherit;
}
.lw-item-price, .lw-item-line { font-variant-numeric: tabular-nums; white-space: nowrap; }
.lw-item-price { opacity: .7; font-size: .86em; }
.lw-item-x {
  background: none; border: 0; cursor: pointer; color: inherit; opacity: .5;
  font-size: 1.05em; line-height: 1;
}
.lw-item-x:hover { opacity: 1; }

.lw-items-total {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px solid rgb(var(--ch-line) / .16);
}
.lw-items-total strong { font-size: 1.15em; font-variant-numeric: tabular-nums; }
.lw-items-synced { font-size: .82em; opacity: .6; }
.lw-items-apply {
  background: none; border: 1px solid rgb(var(--ch-line) / .3); border-radius: 999px;
  padding: 4px 12px; font: inherit; font-size: .84em; cursor: pointer; color: inherit;
}
.lw-items-apply:hover { border-color: currentColor; }

.lw-catalog { margin-top: 12px; }
.lw-catalog-toggle {
  background: none; border: 1px dashed rgb(var(--ch-line) / .3); border-radius: 999px;
  padding: 5px 12px; font: inherit; font-size: .86em; cursor: pointer; color: inherit; opacity: .85;
}
.lw-catalog-toggle:hover { opacity: 1; }
.lw-catalog-list { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.lw-catalog-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  width: 100%; text-align: start; cursor: pointer; color: inherit; font: inherit;
  background: rgb(var(--ch-lift) / .03);
  border: 1px solid rgb(var(--ch-line) / .12);
  border-radius: 8px; padding: 6px 10px;
}
.lw-catalog-row:hover { border-color: rgb(var(--ch-line) / .3); }
.lw-catalog-row small { opacity: .65; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ОТКУДА ПРИШЁЛ ЛИД — БАННЕР НАД СТАДИЕЙ.
   Стоит выше .lw-headline, потому что «откуда он» — контекст для всего, что
   менеджер прочтёт ниже. Логические свойства, а не left/right: карточка
   разворачивается вместе с интерфейсом при арабской раскладке. */
.lw-ad {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 12px; margin-bottom: 6px;
  border-radius: 12px;
  background: rgb(var(--ch-accent) / .07);
  border: 1px solid rgb(var(--ch-accent) / .22);
}
/* Креатив — 64px: узнать объявление в лицо этого достаточно, а место на
   карточке дороже. Ссылку выдаёт Meta и она протухает, поэтому при ошибке
   загрузки блок снимает сам себя (см. onError), и текст остаётся один. */
.lw-ad-shot {
  position: relative; flex: none;
  inline-size: 64px; block-size: 64px;
  border-radius: 9px; overflow: hidden;
  background: rgb(var(--ch-lift) / .06);
}
.lw-ad-shot img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }
.lw-ad-play {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: rgb(0 0 0 / .35); color: #fff; font-size: 18px;
}
.lw-ad-copy { min-inline-size: 0; display: flex; flex-direction: column; gap: 3px; }
.lw-ad-eyebrow {
  font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: rgb(var(--ch-accent) / .95);
}
.lw-ad-eyebrow em { font-style: normal; color: var(--lw-ink-soft); text-transform: none; letter-spacing: 0; }
/* Заголовок объявления — ДВЕ строки, не одна.
   Первая версия обрезала в одну строку с многоточием, и на снимке экрана было
   видно, чем это плохо: «Не верите? Проверьте бесплатно 7 ...» — заголовок
   короткий, но миниатюра съедает 64px, и обрезались последние два слова.
   Узнать объявление по обрубку нельзя, а именно ради узнавания баннер и
   существует. Две строки хватает почти всем реальным заголовкам; полный текст
   по-прежнему в title. */
.lw-ad-headline {
  color: var(--lw-ink-bright); font-size: 13.5px; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.lw-ad-body {
  margin: 0; color: var(--lw-ink-soft); font-size: 12px; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.lw-ad-foot {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 11px; color: var(--lw-ink-soft);
}
.lw-ad-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10.5px;
  padding: 1px 5px; border-radius: 5px; background: rgb(var(--ch-lift) / .07);
}
.lw-ad-link { color: rgb(var(--ch-accent) / .95); text-decoration: none; }
.lw-ad-link:hover { text-decoration: underline; }
@media (max-width: 560px) {
  .lw-ad-shot { inline-size: 48px; block-size: 48px; }
}

/* КРЕАТИВ ОБЪЯВЛЕНИЯ НА ВКЛАДКЕ «МЕДИА».
   По просьбе владельца 30 августа. В шапке карточки тот же креатив стоит
   маленьким — 64px, чтобы узнать объявление в лицо. Здесь наоборот: вкладка
   существует ради того, чтобы РАССМОТРЕТЬ, поэтому картинка во всю ширину.
   Ссылку выдаёт Meta и она протухает — при ошибке загрузки блок снимает себя
   сам (см. onError), подпись остаётся. */
.lw-media-h { margin: 0 0 8px; font-size: 0.82rem; color: var(--lw-ink-soft); font-weight: 600; }
.lw-media-ad { margin-bottom: 14px; }
.lw-media-shot {
  position: relative; margin: 0;
  border: 1px solid var(--lw-line, #223247); border-radius: 12px; overflow: hidden;
  background: var(--lw-surface-2, #121a25);
}
.lw-media-shot img { display: block; inline-size: 100%; block-size: auto; }
.lw-media-play {
  position: absolute; inset-block-start: 12px; inset-inline-start: 12px;
  inline-size: 30px; block-size: 30px; border-radius: 50%;
  background: rgb(0 0 0 / .55); color: #fff;
  display: grid; place-items: center; font-size: 13px;
}
.lw-media-shot figcaption { padding: 11px 13px; display: flex; flex-direction: column; gap: 5px; }
.lw-media-shot figcaption strong { font-size: 0.88rem; color: var(--lw-ink); }
.lw-media-shot figcaption p { margin: 0; font-size: 0.8rem; color: var(--lw-ink-soft); }
.lw-media-shot figcaption a { font-size: 0.8rem; }

/* Страна по коду номера — рядом с самим номером, тише его.
   Это свойство номера, а не отдельный факт о клиенте: собственная строка
   заставила бы читать её как ещё одно поле, которое кто-то заполнял. */
.lw-phone-country {
  font-size: 0.76rem; color: var(--lw-ink-soft);
  margin-inline-start: 8px; white-space: nowrap;
}
/* Номер и страна в две строки: в одной строке страна с временем клиента
   сжимали номер до «+…» (владелец, 5 сентября). Кнопки справа не двигаются. */
.lw-phone-main { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; gap: 1px; }
.lw-phone-main .lw-phone-number { padding-bottom: 0; }
.lw-phone-main .lw-phone-country { margin-inline-start: 0; white-space: normal; line-height: 1.25; }

/* ФАЙЛЫ, ПРИСЛАННЫЕ КЛИЕНТОМ, на вкладке «Медиа». Список, а не сетка плиток:
   у вложения из переписки важны имя, размер и время, а не превью — по ним
   оператор решает, открывать ли, не тратя пять минут жизни подписанной
   ссылки. */
.lw-media-files { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.lw-file-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.lw-file-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 8px 10px; border: 1px solid rgb(255 255 255 / .08); border-radius: 10px;
  background: rgb(255 255 255 / .02);
}
.lw-file-open {
  border: 0; background: none; padding: 0; cursor: pointer;
  font: inherit; color: var(--sh-blue-2, #6ea8fe); text-align: left;
}
.lw-file-open:hover { text-decoration: underline; }
.lw-file-open:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.lw-file-meta { font-size: 11.5px; color: var(--rp-ink-3, #8b93a7); white-space: nowrap; }

/* ── ВЛОЖЕНИЕ В ПЕРЕПИСКЕ ──────────────────────────────────────────────────
   Фото показывается, голосовое слушается. До 1 сентября на их месте стояла
   строка текста, и владелец справедливо спросил, почему в других CRM видно,
   что прислал клиент, а здесь нет.

   Размер ограничен по ширине пузыря и по высоте: переписка не должна
   прокручиваться на два экрана из-за одной вертикальной фотографии. */
.lw-att { display: block; margin-top: 6px; }
.lw-att-image { line-height: 0; border-radius: 10px; overflow: hidden; }
.lw-att-img {
  display: block; max-width: 100%; max-height: 320px; width: auto; height: auto;
  border-radius: 10px; background: rgb(var(--ch-lift) / .06);
}
.lw-att-image:hover .lw-att-img { filter: brightness(1.06); }
.lw-att-video { max-width: 100%; max-height: 320px; border-radius: 10px; }
.lw-att-audio { margin-top: 8px; }
/* Плеер должен помещаться в пузырь и не растягивать его: у нативного контрола
   своя минимальная ширина, и без max-width он раздвигает переписку. */
.lw-att-player { display: block; width: 100%; max-width: 320px; height: 34px; }
.lw-att-file {
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 12px;
  border-radius: 10px; background: rgb(var(--ch-lift) / .06);
  border: 1px solid rgb(var(--ch-line) / .16); text-decoration: none;
}
.lw-att-file:hover { border-color: rgb(var(--ch-accent) / .40); }
.lw-att-name { color: var(--lw-ink); font-size: 13px; word-break: break-word; }

/* ── THREE VOICES, THREE COLOURS (2026-09-05, amoCRM spec item 2) ──────────
   Owner, 4 Sep: «пузыри агента, оператора и клиента почти неразличимы». The
   tints were .14/.12 alpha on a dark ground — the same grey to a tired eye.
   Agent: blue with a small «M» avatar at the bubble's foot. Operator: green.
   Customer: neutral lift. Layered after the original rules, same selectors,
   so they win by order. */
.lw-msg-agent .lw-bubble { background: rgb(var(--ch-blue) / .26); border-color: rgb(var(--ch-accent) / .55); }
.lw-msg-operator .lw-bubble { background: rgb(var(--ch-ok) / .22); border-color: rgb(var(--ch-ok) / .5); }
.lw-msg-customer .lw-bubble { background: rgb(var(--ch-lift) / .10); border-color: rgb(var(--ch-line) / .22); }
.lw-msg-out { align-items: flex-end; gap: 6px; }
.lw-msg-avatar {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: #fff; background: rgb(var(--ch-blue) / .9);
}
.lw-msg-operator .lw-msg-avatar { background: rgb(var(--ch-ok) / .9); }

/* ── THE CARD STARTS AT THE NAME (2026-09-05) ─────────────────────────────────
   Owner: «левый экран поднял бы». The head strip («‹ · ••• · Hide») no longer
   takes its own row: it floats in the card's top corner and the identity
   row moves up under it. pack-design's `.lw-card-head { position: relative }`
   stays for test-crm-delete-lead; this more specific rule outranks it. */
.lw-card { position: relative; }
.lw-card > .lw-card-head { position: absolute; top: 8px; inset-inline-end: 10px; padding: 0; gap: 6px; z-index: 3; }
.lw-card > .lw-card-head .lw-back { font-size: 20px; line-height: 1; padding: 0 6px; }
.lw-card > .lw-identity { margin-top: 2px; padding-inline-end: 150px; }
/* The name is a control now: click to rename. Same size as before. */
.lw-name-edit {
  background: none; border: 0; padding: 0; font: inherit; color: inherit; cursor: text; text-align: start;
  border-bottom: 1px dashed transparent;
}
.lw-name-edit:hover { border-bottom-color: rgb(var(--ch-line) / .5); }
.lw-name-input {
  font: inherit; font-weight: 700; color: var(--lw-ink-bright); background: rgb(var(--ch-lift) / .06);
  border: 1px solid rgb(var(--ch-accent) / .55); border-radius: 8px; padding: 2px 8px; min-width: 200px; max-width: 100%;
}

/* ── TASK CHECKBOX (2026-09-05) ───────────────────────────────────────────────
   Explicit min-height: a legacy `button { min-height: 40px }` won over the
   22px height and drew an oval. Open = empty ring, tick on hover; done = green. */
.lw-task-check { min-height: 0; height: 22px; width: 22px; padding: 0; display: inline-flex; align-items: center; justify-content: center; }
.lw-task-check.is-open::after { content: "✓"; opacity: 0; color: var(--lw-ok); transition: opacity .12s; }
.lw-task-check.is-open:hover::after { opacity: 1; }
.lw-task-check.is-done { background: rgb(var(--ch-ok) / .22); border-color: rgb(var(--ch-ok) / .6); color: var(--lw-ok); font-weight: 700; }
.lw-task-title.is-untitled { color: var(--lw-ink-dim); font-style: italic; }
.lw-task-owner { color-scheme: dark; }

/* ── DRAGGABLE BLOCKS (2026-09-05) ─────────────────────────────────────────────
   «⋮⋮» in the block's corner; drag it to move the block. The grip is the only
   drag origin (see cardBlocks), so inputs inside keep their text selection. */
.lw-block { position: relative; }
.lw-grip {
  position: absolute; top: 6px; inset-inline-end: 6px; z-index: 2;
  cursor: grab; color: var(--lw-ink-dim); font-size: 13px; letter-spacing: -2px; line-height: 1;
  padding: 2px 4px; border-radius: 6px; user-select: none;
}
.lw-grip:hover { color: var(--lw-ink); background: rgb(var(--ch-lift) / .08); }
.lw-block[draggable="true"] .lw-grip { cursor: grabbing; }
.lw-block.is-dragging { opacity: .45; }

/* ── EVENT FEED BESIDE THE CHAT (2026-09-05, amoCRM spec) ──────────────────── */
.lw-feed { border-bottom: 1px solid rgb(var(--ch-line) / .14); padding: 8px 14px 6px; max-height: 42%; overflow: auto; }
.lw-feed-bar { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 6px; }
.lw-feed-chip {
  height: 22px; padding: 0 9px; border-radius: 999px; font: inherit; font-size: 11px; cursor: pointer;
  border: 1px solid rgb(var(--ch-line) / .2); background: rgb(var(--ch-lift) / .05); color: var(--lw-ink-soft);
}
.lw-feed-chip.is-on { border-color: rgb(var(--ch-accent) / .55); background: rgb(var(--ch-blue) / .16); color: var(--lw-ink-bright); }
.lw-feed-search { flex: 1 1 140px; min-width: 120px; height: 22px; font: inherit; font-size: 11px; padding: 0 8px; border-radius: 7px; border: 1px solid rgb(var(--ch-line) / .2); background: rgb(var(--ch-lift) / .04); color: var(--lw-ink-bright); }
.lw-feed-count { color: var(--lw-ink-dim); font-size: 11px; }
.lw-feed-list { list-style: none; margin: 0; padding: 0; }
.lw-feed-day { color: var(--lw-ink-dim); font-size: 11px; padding: 6px 0 2px; border-top: 1px dashed rgb(var(--ch-line) / .14); }
.lw-feed-list > .lw-feed-day:first-child { border-top: 0; padding-top: 0; }
.lw-feed-row { display: grid; grid-template-columns: 44px auto minmax(0, 1fr); gap: 8px; align-items: baseline; padding: 2px 0; font-size: 12.5px; color: var(--lw-ink); }
.lw-feed-time { color: var(--lw-ink-dim); font-size: 11px; font-variant-numeric: tabular-nums; }
.lw-feed-actor { color: var(--lw-ink-soft); font-size: 11px; }
.lw-feed-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lw-feed-stage .lw-feed-text { color: var(--lw-ink-bright); }
.lw-feed-more summary { cursor: pointer; color: var(--lw-ink-dim); font-size: 11px; padding: 2px 0; padding-inline-start: 52px; list-style: none; }
.lw-feed-more summary::-webkit-details-marker { display: none; }
.lw-feed-more ul { list-style: none; margin: 0; padding: 0; }
.lw-feed-more .lw-feed-row { grid-template-columns: 44px minmax(0, 1fr); padding-inline-start: 8px; }

/* ── «‹» IN THE CARD'S LEFT CORNER, THE AVATAR ON THE SAME LINE (2026-09-05, owner) ──
   «Стрелочку — в левый угол; кружок клиента — выше». The head strip now spans
   the card's top edge: the back chevron is pushed to the left corner, «•••»
   and «Скрыть» stay on the right, and the identity row (avatar + name) comes
   up to the same line, indented past the chevron. The strip itself lets
   clicks through, so the name under it stays editable. */
.lw-card > .lw-card-head { inset-inline-start: 10px; justify-content: flex-end; pointer-events: none; }
.lw-card > .lw-card-head > * { pointer-events: auto; }
.lw-card > .lw-card-head .lw-back { margin-inline-end: auto; padding: 0; padding-inline-end: 4px; }
.lw-card > .lw-identity { margin-top: 0; padding-top: 6px; padding-inline-start: 22px; align-items: flex-start; }

/* ── STATISTICS TAB: HEADS AND A TONE PER ROW (2026-09-05) ────────────────────
   Response time is read against the owner's 15-minute benchmark: green within
   it, amber within the hour, red beyond. The tone colours the value only —
   the label stays quiet, so a red row still reads as a fact, not an alarm. */
.lw-stat-head { margin: 10px 0 2px; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--lw-ink-soft); }
.lw-stat-head:first-child { margin-top: 0; }
.lw-stat-good .lw-stat-value { color: rgb(var(--ch-ok)); }
.lw-stat-warn .lw-stat-value { color: rgb(var(--ch-amber)); }
.lw-stat-bad .lw-stat-value { color: rgb(var(--ch-red)); }

/* ── CARD SETUP PANEL (2026-09-05): custom fields + block visibility ─────────
   Sits above the identity row when opened from «…». Rows are one line each:
   name, type, options-or-key, three small buttons. */
.lw-ctor { margin: 10px 0 12px; padding: 12px 14px; border-radius: 12px; border: 1px solid rgb(var(--ch-accent) / .35); background: rgb(var(--ch-lift) / .04); }
.lw-ctor-head { display: flex; align-items: center; justify-content: space-between; }
.lw-ctor-head h3 { margin: 0; font-size: 15px; }
.lw-ctor-close { min-height: 0; width: 26px; height: 26px; border-radius: 8px; border: 1px solid rgb(var(--ch-line) / .3); background: none; color: var(--lw-ink-soft); font: inherit; font-size: 16px; cursor: pointer; }
.lw-ctor-sub, .lw-ctor-foot { margin: 4px 0 8px; font-size: 12px; color: var(--lw-ink-soft); }
.lw-ctor-error { margin: 4px 0 8px; font-size: 12.5px; color: rgb(var(--ch-red)); }
.lw-ctor-h { margin: 10px 0 6px; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--lw-ink-soft); }
.lw-ctor-rows { display: flex; flex-direction: column; gap: 6px; }
.lw-ctor-row, .lw-ctor-add { display: grid; grid-template-columns: minmax(0, 1.4fr) 92px minmax(0, 1.2fr) auto; gap: 6px; align-items: center; }
.lw-ctor-label, .lw-ctor-options, .lw-ctor-kind { min-height: 0; height: 30px; padding: 0 8px; border-radius: 8px; font: inherit; font-size: 12.5px; border: 1px solid rgb(var(--ch-line) / .3); background: rgb(var(--ch-lift) / .05); color: var(--lw-ink); }
.lw-ctor-key { font-size: 11.5px; color: var(--lw-ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lw-ctor-actions { display: flex; gap: 4px; }
.lw-ctor-btn { min-height: 0; height: 28px; padding: 0 8px; border-radius: 8px; border: 1px solid rgb(var(--ch-line) / .3); background: rgb(var(--ch-lift) / .05); color: var(--lw-ink); font: inherit; font-size: 12px; cursor: pointer; }
.lw-ctor-btn[disabled] { opacity: .4; cursor: default; }
.lw-ctor-btn.is-danger.is-armed { border-color: rgb(var(--ch-red) / .6); color: rgb(var(--ch-red)); }
.lw-ctor-btn.is-primary { border-color: rgb(var(--ch-accent) / .6); background: rgb(var(--ch-blue) / .18); font-weight: 600; }
.lw-ctor-add { margin-top: 8px; }
.lw-ctor-blocks { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.lw-ctor-block { font-size: 12.5px; color: var(--lw-ink); }
.lw-link-btn { min-height: 0; padding: 0; border: 0; background: none; color: rgb(var(--ch-accent)); font: inherit; font-size: inherit; cursor: pointer; text-decoration: underline; }

/* ── ПАНЕЛЬ СПРАВА ПОВЕРХ ЭКРАНА (24 сентября 2026) ──────────────────────────
   Была блоком В НАЧАЛЕ колонки карточки: нажали «Настроить карточку» внизу
   «Своих полей» — панель появилась наверху, за краем экрана, и человек решил,
   что ничего не произошло. Теперь это накладка на уровне страницы: подложка на
   всё окно (лёгкая — карточка слева читается, скрытый блок пропадает на
   глазах) и панель 460 px во всю высоту; шапка и «Закрыть» стоят на месте,
   прокручивается только середина. Слои — как у панели сделки на доске:
   подложка .kb-scrim 60, панель 61; Boro (50) остаётся под ними. */
.lw-ctor-layer { position: fixed; inset: 0; z-index: 60; }
.lw-ctor-scrim { position: absolute; inset: 0; background: light-dark(rgb(15 32 74 / .16), rgb(2 5 10 / .36)); }
.lw-ctor.lw-ctor-drawer {
  position: absolute; inset-block: 0; inset-inline-end: 0; z-index: 1;
  display: flex; flex-direction: column; width: min(460px, 100vw); margin: 0; padding: 0;
  border: 0; border-inline-start: 1px solid rgb(var(--ch-line) / .28); border-radius: 0;
  background: var(--lw-panel); box-shadow: 0 0 60px rgb(var(--ch-drop));
}
.lw-ctor-drawer > .lw-ctor-head {
  flex: 0 0 auto; gap: 10px; padding-block: 14px; padding-inline: 18px 14px;
  border-bottom: 1px solid rgb(var(--ch-line) / .16);
}
.lw-ctor-drawer .lw-ctor-head h3 { font-size: 16px; }
.lw-ctor-drawer .lw-ctor-head h3:focus { outline: none; }
.lw-ctor-drawer .lw-ctor-close { width: 32px; height: 32px; }
.lw-ctor-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-block: 10px 18px; padding-inline: 18px; }
.lw-ctor-drawer > .lw-ctor-done {
  flex: 0 0 auto; margin: 0; padding-block: 12px; padding-inline: 18px;
  border-top: 1px solid rgb(var(--ch-line) / .16); background: rgb(var(--ch-lift) / .03);
}
/* Телефон — во весь экран; крестик под палец; строка «Новое поле» переносится,
   а не сжимает поле названия до «Новс» (замер на 375 px). */
@media (max-width: 760px) {
  .lw-ctor.lw-ctor-drawer { width: 100vw; border-inline-start: 0; }
  .lw-ctor-drawer .lw-ctor-close { width: 40px; height: 40px; }
  .lw-ctor-drawer .lw-ctor-add { display: flex; flex-wrap: wrap; align-items: center; }
  .lw-ctor-drawer .lw-ctor-add > .lw-ctor-label { flex: 1 1 100%; }
}
/* «Наверх» (ui-polish.css) висит на <body> с z-index 45 — вне слоя <main>, и
   панель его не перекрывает: на 375 px круг ложился на «Закрыть» панели, а под
   меню-листом — на «Удалить лид». Пока открыто меню или панель, листать
   страницу под ними незачем — кнопки нет. */
body:has(.lw-ctor-layer) .br-to-top,
body:has(.lw-head > .lw-menu) .br-to-top { visibility: hidden; pointer-events: none; }
/* До 700 px сверху висит строка меню кабинета (.mobile-bar, fixed, z 57 — на
   <body>, вне <main>). <main> открывает свой слой (z-index 1), и никакой
   z-index панели изнутри его не перевесит: строка закрывала заголовок и «×»
   (замер на 375×812). Панель начинается под строкой — как и сам <main>. */
@media (max-width: 700px) {
  body.has-rail .lw-ctor.lw-ctor-drawer { inset-block-start: calc(65px + env(safe-area-inset-top)); }
}
.lw-ctor-done { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.lw-ctor-hint { font-size: 12px; color: var(--lw-ink-soft); }

/* Field type as four chips (the styled <select> drew «–», 2026-09-05). */
.lw-ctor-kinds { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.lw-ctor-kinds .lw-ctor-kind { width: auto; height: 26px; padding: 0 8px; border-radius: 999px; font-size: 11.5px; cursor: pointer; }
.lw-ctor-kinds .lw-ctor-kind.is-on { border-color: rgb(var(--ch-accent) / .7); background: rgb(var(--ch-blue) / .18); font-weight: 600; }
.lw-ctor-row, .lw-ctor-add { grid-template-columns: minmax(0, 1.2fr) auto minmax(0, 1fr) auto; }

/* Второй шаг конструктора (2026-09-07): «На доске» в колонке действий каждой
   строки поля (не пятой колонкой — на узкой панели она сжимала название в
   ноль) и стандарт пространства под списком блоков. */
.lw-ctor-actions { align-items: center; margin-inline-start: auto; }
/* Строка поля переносится, а не сжимает название: на панели в 326px (превью
   7 сентября) сетка отдавала полю названия 28px. Название держит минимум,
   действия уходят на вторую строку, когда не помещаются. */
.lw-ctor-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.lw-ctor-row .lw-ctor-label { flex: 1 1 150px; min-width: 130px; }
.lw-ctor-row .lw-ctor-options { flex: 1 1 140px; min-width: 120px; }
.lw-ctor-row .lw-ctor-key { flex: 0 1 auto; max-width: 40%; }
.lw-ctor-board { display: inline-flex; align-items: center; gap: 4px; margin-inline-end: 4px; white-space: nowrap; font-size: 11.5px; color: var(--lw-ink-soft); cursor: pointer; }
.lw-ctor-board input { margin: 0; }
.lw-ctor-board.is-on { color: var(--lw-ink); }
.lw-ctor-std { margin-top: 10px; padding: 8px 10px; border-radius: 10px; border: 1px dashed rgb(var(--ch-line) / .35); }
.lw-ctor-std-note { margin: 0 0 6px; font-size: 12px; color: var(--lw-ink-soft); }
.lw-ctor-std-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.lw-ctor-btn.is-danger { border-color: rgb(var(--ch-red) / .35); }

/* Мария выполняет задачи сама — переключатель на каждого клиента (5 сентября). */
.lw-task-maria {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin: 0 0 10px; padding: 8px 10px; border-radius: 10px;
  border: 1px dashed var(--line, rgba(255, 255, 255, 0.14));
  cursor: pointer; font-size: 13px;
}
.lw-task-maria.is-on { border-style: solid; border-color: var(--accent, #6d5dfc); }
.lw-task-maria input { margin: 0; accent-color: var(--accent, #6d5dfc); }
.lw-task-maria-title { font-weight: 600; }
.lw-task-maria .lw-task-dim { flex-basis: 100%; padding-inline-start: 24px; }
/* v2 (12 сентября): срок действия и «сама ставит следующую» — под переключателем. */
.lw-task-maria-more { display: flex; flex-direction: column; gap: 6px; margin: -4px 0 10px; padding-inline-start: 10px; font-size: 12.5px; }
.lw-task-maria-term { display: flex; align-items: center; gap: 8px; }
.lw-task-maria-term select { font: inherit; padding: 3px 6px; border-radius: 8px; }
.lw-task-maria-next { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; cursor: pointer; }
.lw-task-maria-next input { margin: 0; accent-color: var(--accent, #6d5dfc); }
.lw-task-maria-next.is-on > span:first-of-type { font-weight: 600; }
.lw-task-maria-next .lw-task-dim { flex-basis: 100%; padding-inline-start: 22px; }

/* Который час у клиента — рядом со страной; «поздно» подсвечено (5 сентября). */
.lw-phone-time { opacity: 0.8; font-variant-numeric: tabular-nums; }
.lw-phone-time.is-late { color: #f0b34a; opacity: 1; font-weight: 600; }

/* Метка шаблона возврата — читаемо, не «[re-engagement template: …]» (5 сентября). */
.lw-template { font-style: italic; opacity: 0.92; }

/* ДОКУМЕНТЫ ПО ШАБЛОНУ — вкладка карточки (фаза 1, 7 сентября 2026).
   Предпросмотр показывается моноширинным текстом намеренно: это исходник
   документа, а не его печатный вид; печатный открывается по ссылке, где у
   него своя вёрстка и своя кнопка «сохранить в PDF». */
.lw-docs-panel { display: grid; gap: 12px; }
.lw-docs-pick { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.lw-docs-select {
  flex: 1 1 220px; min-width: 0; padding: 7px 10px;
  border: 1px solid var(--lw-line, #2a3242); border-radius: 8px;
  background: var(--lw-field, rgba(11, 16, 24, 0.55)); color: var(--lw-ink, #e8edf5);
  font: inherit; font-size: 13px;
}
.lw-docs-error { margin: 0; color: var(--rp-warn, #f0b429); font-size: 12.5px; }
.lw-docs-link { margin: 0 0 8px; font-size: 12.5px; }
.lw-docs-preview {
  padding: 10px 12px; border: 1px solid var(--lw-line, #2a3242); border-radius: 10px;
  background: rgba(11, 16, 24, 0.35);
}
.lw-docs-text {
  margin: 0; max-height: 320px; overflow: auto; white-space: pre-wrap; word-break: break-word;
  font: 12px/1.55 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--lw-ink, #e8edf5);
}
/* 11 сентября: превью — страницей, как у клиента; пустые поля — предупреждением. */
.lw-docs-frame { width: 100%; height: 460px; border: 0; border-radius: 8px; background: #fff; }
.lw-docs-blanks { margin: 0 0 8px; color: var(--rp-warn, #f0b429); font-size: 12.5px; }
.lw-docs-list { display: grid; gap: 6px; }
.lw-docs-row {
  display: flex; align-items: center; gap: 8px; justify-content: space-between;
  padding: 7px 10px; border: 1px solid var(--lw-line, #2a3242); border-radius: 8px;
  font-size: 12.5px;
}
.lw-docs-state { color: var(--lw-muted, #93a0b4); font-size: 11.5px; }

/* ── ПОЛОСА КОНТЕКСТА ПОД ИМЕНЕМ (24 сентября 2026) ─────────────────────────
   Сумма · стадия · ответственный · следующая задача · «агент на паузе →
   менеджер» · долг · последняя активность — одной полосой под именем, чтобы
   карточка проходила «тест десяти секунд» (аудит экранов, Top-15 №7). Фишка —
   короткий факт, подробность — в подсказке, нажатие ведёт к разделу ниже.
   Общий `button { min-height: 40px }` из styles.css здесь сжат до строки, как
   у .lw-reach-chip: правило верное для кнопки и неверное для фишки.
   Логические свойства — полоса разворачивается вместе с арабской раскладкой. */
/* ОДНОЙ СТРОКОЙ СЕМЬ ФАКТОВ НЕ ВСТАЮТ — ЗАМЕРЕНО, А НЕ ПРЕДПОЛОЖЕНО. На 1440
   карточка 520 px, внутри 486; фишки лида l1 из превью в первой редакции —
   979 px. Прокрутка вбок спрятала бы ровно то, ради чего полоса есть («агент
   на паузе», «долг»), поэтому полоса переносится: на 1440 — две строки
   («что · где · кто · дальше» и «сейчас · деньги · последнее касание»), на
   телефоне — сколько нужно. Фишки ужаты под это: 11.5 px, поля 7 px. */
.lw-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: -4px 0 10px; }
.lw-strip-chip {
  display: inline-flex; align-items: center; gap: 3px; max-width: 100%; min-width: 0;
  min-height: 0; height: auto; padding: 2px 7px; border-radius: 999px;
  border: 1px solid rgb(var(--ch-line) / .2); background: rgb(var(--ch-lift) / .04);
  color: var(--lw-ink); font: inherit; font-size: 11.5px; line-height: 1.55; white-space: nowrap;
}
button.lw-strip-chip { cursor: pointer; }
button.lw-strip-chip:hover { border-color: rgb(var(--ch-accent) / .5); color: var(--lw-ink-bright); }
.lw-strip-chip:focus-visible { outline: 2px solid rgb(var(--ch-accent) / .7); outline-offset: 1px; }
.lw-strip-ic { font-size: 10.5px; line-height: 1; }
.lw-strip-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.lw-strip-value { font-weight: 600; color: var(--lw-ink-bright); }
/* Название задачи обрезается, срок — никогда: он и есть «когда». Полное
   название — в подсказке фишки и в «Следующем шаге», куда она ведёт. */
.lw-strip-task .lw-strip-text { max-width: 14ch; }
.lw-strip-when { color: var(--lw-ink-soft); white-space: nowrap; }
.lw-strip-when::before { content: "·"; margin-inline-end: 4px; opacity: .7; }
.lw-strip-extra { font-size: 10.5px; font-weight: 700; }
.lw-strip-chip.is-overdue { color: rgb(var(--ch-red)); border-color: rgb(var(--ch-red) / .45); background: rgb(var(--ch-red) / .1); }
.lw-strip-chip.is-overdue .lw-strip-when { color: inherit; }
.lw-strip-chip.is-paused { color: var(--lw-warm); border-color: rgb(var(--ch-warm) / .42); background: rgb(var(--ch-warm) / .1); }
.lw-strip-chip.is-owes { color: rgb(var(--ch-amber)); border-color: rgb(var(--ch-amber) / .4); background: rgb(var(--ch-amber) / .08); }
/* Канал — цветом мессенджера по рамке, как у чипа канала в шапке переписки;
   незнакомый канал цвета не получает (--chip-brand не задан). */
.lw-strip-last { color: var(--lw-ink-soft); border-color: var(--chip-brand, rgb(var(--ch-line) / .2)); }

/* ── AI-СВОДКА НАВЕРХУ ВКЛАДКИ: ПУСТАЯ — ИЗ КВАЛИФИКАЦИИ (24 сентября 2026) ── */
.lw-summary-derived { display: flex; flex-direction: column; gap: 3px; }
.lw-summary-line { margin: 0; color: var(--lw-ink-bright); font-size: 13px; line-height: 1.5; }
.lw-summary-k {
  margin-inline-end: 6px; color: var(--lw-ink-soft); font-size: 10.5px;
  letter-spacing: .06em; text-transform: uppercase;
}

/* ── ХРОНОЛОГИЯ: ЧАС, ДЕНЬ, «БЛИЖАЙШЕЕ», «ДАЛЬШЕ» (24 сентября 2026) ──────────
   Строка — сетка «время · кто · что», подробность — второй строкой под «что».
   «Ближайшее и просроченное» закреплено сверху, просроченное красным; «Дальше»
   замыкает список пунктирной рамкой — это не событие, а следующий шаг. */
.lw-activity { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.lw-tl-upcoming {
  padding: 8px 10px; border-radius: 10px;
  border: 1px solid rgb(var(--ch-line) / .16); background: rgb(var(--ch-lift) / .03);
}
.lw-tl-head {
  display: flex; align-items: center; gap: 6px; margin: 0 0 6px;
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--lw-ink-mid);
}
.lw-tl-count {
  min-width: 18px; padding: 0 6px; border-radius: 999px; text-align: center; letter-spacing: 0;
  background: rgb(var(--ch-lift) / .1); color: var(--lw-ink);
}
.lw-tl-up-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.lw-tl-up { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px; font-size: 12.5px; color: var(--lw-ink); }
.lw-tl-up.is-overdue, .lw-tl-up.is-overdue .lw-tl-when { color: rgb(var(--ch-red)); }
.lw-tl-up-ic { font-size: 11px; }
.lw-tl-up-title { flex: 1 1 140px; min-width: 0; overflow-wrap: anywhere; }
.lw-tl-when { color: var(--lw-ink-soft); font-size: 11.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.lw-tl-link { font-size: 11.5px; color: rgb(var(--ch-accent)); }
.lw-timeline .lw-tl-day {
  display: block; padding: 10px 0 3px; border-bottom: 0;
  font-size: 11px; letter-spacing: .03em; color: var(--lw-ink-dim);
}
.lw-timeline .lw-tl-day:first-child, .lw-timeline .lw-tl-earlier + .lw-tl-day { padding-top: 2px; }
.lw-timeline .lw-tl-earlier { display: block; padding: 0 0 4px; border-bottom: 0; }
.lw-timeline .lw-tl-row {
  display: grid; grid-template-columns: 40px auto minmax(0, 1fr);
  column-gap: 8px; row-gap: 1px; align-items: baseline;
}
.lw-tl-time { color: var(--lw-ink-dim); font-size: 11px; font-variant-numeric: tabular-nums; }
.lw-tl-detail { grid-column: 3; color: var(--lw-ink-soft); font-size: 11.5px; line-height: 1.45; overflow-wrap: anywhere; }
.lw-tl-row.is-ai .lw-kind { color: var(--lw-ink-bright); }
/* «Отменить» у действия AI (26 сентября 2026): под строкой, в колонке текста.
   Кнопка — ссылкой, но с высотой под палец; отказ сервера — красным словами. */
.lw-tl-undo, .lw-tl-undo-note, .lw-tl-undo-done { grid-column: 3; font-size: 11.5px; line-height: 1.45; }
.lw-tl-undo { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 10px; }
.lw-tl-undo .lw-tl-undo-btn { padding: 6px 0; font-size: 11.5px; font-weight: 600; }
.lw-tl-undo .lw-tl-undo-btn[disabled] { cursor: progress; opacity: .7; text-decoration: none; }
.lw-tl-undo-note, .lw-tl-undo-done { color: var(--lw-ink-dim); font-style: italic; }
.lw-tl-undo-error { flex: 1 1 100%; color: rgb(var(--ch-red)); overflow-wrap: anywhere; }
/* «AI» у имени агента: действие машины не путается с действием человека. */
.lw-ai-tag {
  display: inline-block; margin-inline-end: 4px; padding: 0 4px; border-radius: 4px;
  font-size: 9px; font-weight: 700; letter-spacing: .04em; line-height: 1.55; vertical-align: 1px;
  color: var(--rp-on-accent, #fff); background: rgb(var(--ch-accent) / .85);
}
.lw-timeline .lw-tl-next {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
  margin-top: 6px; padding: 7px 10px; border-radius: 9px;
  border: 1px dashed rgb(var(--ch-accent) / .45); background: rgb(var(--ch-accent) / .06);
}
.lw-tl-next-k { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: rgb(var(--ch-accent)); }
.lw-tl-next-title { min-width: 0; overflow-wrap: anywhere; }
.lw-timeline .lw-tl-next.is-overdue { border-color: rgb(var(--ch-red) / .5); background: rgb(var(--ch-red) / .08); }
.lw-tl-next.is-overdue .lw-tl-next-k, .lw-tl-next.is-overdue .lw-tl-when { color: rgb(var(--ch-red)); }

/* ── ТЕЛЕФОН: ОДНА ПАНЕЛЬ ЗА РАЗ (24 сентября 2026, аудит G2) ────────────────
   Замер на 390 px: .lw-card 360 px, .lw-main — 2 px, переписка ломалась по
   буквам. Ниже 760 px (граница телефона в этом продукте) на экране одна
   панель: карточка, если она открыта; переписка, если карточку убрали
   («💬 Переписка» в шапке карточки — .lw-panel-chat, обратно — «Клиент» в
   шапке переписки); разбор звонка, если его открыли («Закрыть» — назад).
   Сетку ставит pack-design.css, и он подключён ПОСЛЕ этого файла:
   .lw-page.has-card (два класса) и .lw-page.has-card.has-drawer (три).
   Удвоенный .lw-page ниже перевешивает каждое правило на один класс — без
   !important. Переписка по-прежнему прокручивается сама (.lw-scroll), страница
   горизонтально не прокручивается. */
.lw-panel-chat {
  display: none; flex: 0 0 auto; align-items: center; min-height: 0;
  height: 28px; padding: 0 11px; border-radius: 8px;
  border: 1px solid rgb(var(--ch-accent) / .45); background: rgb(var(--ch-blue) / .14);
  color: var(--lw-ink-bright); font: inherit; font-size: 12px; white-space: nowrap; cursor: pointer;
}
@media (max-width: 760px) {
  .lw-page.lw-page.has-card,
  .lw-page.lw-page.has-drawer,
  .lw-page.lw-page.has-card.has-drawer { grid-template-columns: minmax(0, 1fr); }
  .lw-page.lw-page.has-card > .lw-main,
  .lw-page.lw-page.has-drawer > .lw-main,
  .lw-page.lw-page.has-drawer > .lw-card { display: none; }
  .lw-card .lw-panel-hide { display: none; }
  .lw-card .lw-panel-chat { display: inline-flex; }
  .lw-card > .lw-identity { padding-inline-end: 132px; }
  .lw-head { height: auto; min-height: 56px; flex-wrap: wrap; row-gap: 6px; padding-block: 8px; }
  .lw-head-name { max-width: 100%; }
  .lw-card-tabs { overflow-x: auto; scrollbar-width: none; }
  .lw-card-tab { flex: 0 0 auto; }
  /* Фишка задачи на телефоне может занять всю строку: название режется, только
     когда в строку не помещается (min-width: 0 у текста), а не на 14 знаках. */
  .lw-strip-task .lw-strip-text { max-width: none; }
}

/* ЧЕК-ЛИСТ ЭТАПА ПОД ВЫБОРОМ ЭТАПА (26 сентября 2026, план 10B): пункты,
   которые надо закрыть, чтобы увести сделку дальше. Логические свойства —
   карточка открывается и справа налево. */
.lw-stage-checklist { display: flex; flex-direction: column; gap: 4px; margin-block-start: 8px; }
.lw-stage-checklist .lw-field-label { margin: 0; }
.lw-stage-checklist-items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.lw-stage-checklist .lw-check { display: flex; align-items: flex-start; gap: 8px; color: var(--lw-ink); font-size: 13px; cursor: pointer; overflow-wrap: anywhere; }
.lw-stage-checklist .lw-check input { margin-block-start: 2px; flex: 0 0 auto; }
.lw-stage-checklist .lw-muted { color: var(--lw-ink-soft); font-size: 12px; }
.lw-stage-checklist .lw-error { margin: 0; padding: 0; max-width: none; text-align: start; color: #f87171; font-size: 12px; }
