* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--t-body);
  line-height: 1.55;
  color: var(--text);
  background: var(--canvas);
}

/* Переход темы — только цветовые свойства и только на поверхностях. */
body, .topbar, .row, .card, .modal, .machine-block, .day-summary,
.login-box, table.list, .btn, .chip, .copy-chip, input, select,
.internal, .thesis, .letter, .warnings {
  transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}
@media (prefers-reduced-motion: reduce) {
  body, .topbar, .row, .card, .modal, .machine-block, .day-summary,
  .login-box, table.list, .btn, .chip, .copy-chip, input, select,
  .internal, .thesis, .letter, .warnings {
    transition: none;
  }
}

.hidden { display: none !important; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

button { font: inherit; cursor: pointer; touch-action: manipulation; color: inherit; }
input, select { font: inherit; color: var(--text);   border-radius: var(--r-2);
}

:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ---- login ---- */

.login {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-4);
  overflow: hidden;
}

/* ---- фон входа: «живой чертёж» (язык лендинга) ---- */

.login-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* Лист виден краем: центр притушен, чтобы форма читалась поверх. */
  -webkit-mask-image: radial-gradient(65% 55% at 50% 50%, transparent 0%, #000 78%);
          mask-image: radial-gradient(65% 55% at 50% 50%, transparent 0%, #000 78%);
}
.login-bg svg {
  width: 100%;
  height: 100%;
  display: block;
  /* Очень медленный дрейф: лист «дышит», но не отвлекает. */
  animation: lg-drift 200s ease-in-out infinite alternate;
  transform-origin: 50% 50%;
}
@keyframes lg-drift {
  from { transform: scale(1.03) translate3d(-0.6%, -0.4%, 0); }
  to   { transform: scale(1.05) translate3d(0.6%, 0.4%, 0); }
}

.lg-grid-line   { stroke: var(--rule); stroke-width: 1; opacity: 0.55; }
.lg-grid-major-line { stroke: var(--rule); stroke-width: 1.2; opacity: 1; }

.lg-plan { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.lg-line { stroke: var(--text-2); stroke-width: 2; opacity: 0.9; }
.lg-thin { stroke-width: 1.4; opacity: 0.62; }
.lg-dim  { stroke: var(--text-3); stroke-width: 1.1; opacity: 0.55; stroke-dasharray: 7 6; }
.lg-node { stroke: var(--text-2); stroke-width: 1.8; opacity: 0.8; fill: none; }
.lg-main { stroke: var(--accent); stroke-width: 2.2; opacity: 0.72; }
.lg-main.lg-thin { stroke-width: 1.5; opacity: 0.5; }
.lg-hatch { stroke: var(--text-3); stroke-width: 1; opacity: 0.4; }
.lg-axis { opacity: 0.75; }

/* Прочерчивание: длина линий заведомо перекрыта dasharray, поэтому одна
   анимация годится для всех путей без вычисления getTotalLength в JS. */
.lg-draw {
  stroke-dasharray: 2400;
  stroke-dashoffset: 2400;
  /* Цикл длинный и бесшовный: линия прочерчивается, долго стоит готовой,
     затем гаснет ЯРКОСТЬЮ, а не «стиранием» обратным ходом — рывка на стыке
     нет, потому что кадр 100% совпадает с кадром 0% (offset 2400, opacity 0). */
  animation: lg-draw 150s cubic-bezier(.35, 0, .2, 1) infinite;
  animation-delay: var(--d, 0s);
}
@keyframes lg-draw {
  0%   { stroke-dashoffset: 2400; opacity: 0; }
  2%   { opacity: 1; }
  18%  { stroke-dashoffset: 0; opacity: 1; }
  88%  { stroke-dashoffset: 0; opacity: 1; }
  97%  { stroke-dashoffset: 0; opacity: 0; }
  100% { stroke-dashoffset: 2400; opacity: 0; }
}

/* Поток по магистрали: пунктир, ползущий бесконечно (как на лендинге). */
.lg-flow {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.4;
  stroke-dasharray: 5 14;
  opacity: 0.75;
  animation: lg-flow 14s linear infinite;
}
@keyframes lg-flow { to { stroke-dashoffset: -38; } }

@media (prefers-reduced-motion: reduce) {
  .login-bg svg { animation: none; transform: scale(1.02); }
  .lg-draw { animation: none; stroke-dashoffset: 0; }
  .lg-flow { animation: none; }
}

.login-box {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 22rem;
  /* Форма отделяется от чертежа рамкой, а не тенью: у чертежа теней нет,
     и мягкая растушевка — самый заметный признак «еще одного SaaS».
     Контурная линия толщиной line-main читается как рамка листа. */
  border: var(--line-main) solid var(--rule-strong);
  background: var(--elevated);
  padding: var(--s-6);
  border-radius: var(--r-3);
}
.login-box h1 { font-size: var(--t-head); margin: 0 0 var(--s-1); }
.login-hint { color: var(--text-2); margin: 0 0 var(--s-5); }
.login-box input {
  width: 100%;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--rule-control);
  background: var(--canvas);
  margin-bottom: var(--s-3);
  border-radius: var(--r-2);
}
.login-box button {
  width: 100%;
  padding: var(--s-2);
  border: 1px solid var(--btn-bg);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border-radius: var(--r-2);
}
.login-error { color: var(--accent); margin: var(--s-3) 0 0; }

/* ---- shell ---- */

.topbar {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: 0 var(--s-4);
  border-bottom: 1px solid var(--rule);
  background: var(--elevated);
  position: sticky;
  top: 0;
  z-index: 10;
  flex-wrap: wrap;
}
/* Знак — файл, а не набранные буквы; маска, чтобы наследовать currentColor и
   работать в обеих темах одним файлом. Пропорция знака 1,87 : 1
   (brand/identity/CONSTRUCTION.md). */
.a13-mark {
  display: block; flex: none;
  background: currentColor;
  -webkit-mask: url("brand/mark.svg") no-repeat center / contain;
          mask: url("brand/mark.svg") no-repeat center / contain;
}
.brand { height: 17px; width: 31.8px; margin: var(--s-3) 0; }
.login-mark { height: 26px; width: 48.6px; margin-bottom: var(--s-4); }
.tabs { display: flex; gap: var(--s-1); }
.tab {
  border: 0;
  background: none;
  padding: var(--s-3) var(--s-3);
  color: var(--text-2);
  border-bottom: 2px solid transparent;
  border-radius: var(--r-2);
}
.tab:hover { color: var(--text); }
.tab.active { color: var(--text); border-bottom-color: var(--accent); font-weight: 500; }
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: var(--s-2); }

/* Состояние машины: точка-индикатор вместо строки цифр в шапке. */
.machine-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-1) var(--s-2);
  border: 1px solid var(--rule);
  background: none;
  color: var(--text-2);
  font-size: var(--t-small);
  line-height: 1.2;
}
.machine-pill:hover { color: var(--text); border-color: var(--text-3); }
.machine-dot {
  width: 7px; height: 7px; border-radius: var(--r-round);
  background: var(--text-3);
  flex: none;
}
.machine-dot.ok   { background: var(--sys-ok); }
.machine-dot.warn { background: var(--sys-warn); }
.machine-dot.err  { background: var(--sys-err); }

/* ---- меню аккаунта ---- */

.account { position: relative; }
.account-btn {
  display: block;
  padding: 0;
  border: 0;
  background: none;
  border-radius: var(--r-round);
  line-height: 0;
}
.account-btn:hover .avatar { border-color: var(--text-3); }
.account-btn[aria-expanded="true"] .avatar { border-color: var(--text); }

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  border-radius: var(--r-round);
  border: 1px solid var(--rule);
  background: var(--sunken) center / cover no-repeat;
  color: var(--text-2);
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: 0.01em;
  overflow: hidden;
  flex: none;
}
.avatar-lg { width: 40px; height: 40px; font-size: var(--t-body); }
.avatar-sm { width: 24px; height: 24px; font-size: var(--t-micro); }
.avatar-xl { width: 64px; height: 64px; font-size: var(--t-title); }

.account-menu {
  position: absolute;
  top: calc(100% + var(--s-2));
  right: 0;
  min-width: 16rem;
  z-index: 60;               /* выше залипшей шапки (10), ниже модалки (100) */
  /* См. .login-box: всплывающее отделяется контуром, не тенью. */
  border: var(--line-thin) solid var(--rule-strong);
  background: var(--elevated);
  padding: var(--s-1) 0;
  border-radius: var(--r-3);
}
.account-head {
  display: flex;
  gap: var(--s-3);
  align-items: center;
  padding: var(--s-2) var(--s-3) var(--s-3);
}
.account-id { min-width: 0; }
.account-name { font-weight: 500; }
.account-mail,
.account-role { color: var(--text-2); font-size: var(--t-small); }
.account-mail { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-sep { height: 1px; background: var(--rule); margin: var(--s-1) 0; }
.account-section { padding: var(--s-1) var(--s-3) var(--s-2); }
.account-label {
  color: var(--text-3);
  font-size: var(--t-small);
  margin-bottom: var(--s-1);
}

.account-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--s-2) var(--s-3);
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  cursor: pointer;
  border-radius: var(--r-2);
}
.account-item:hover { background: var(--sunken); }
.account-danger { color: var(--accent); }

/* Сегментированный переключатель — общий вид для темы и подобных выборов. */
.seg { display: flex; border: 1px solid var(--rule); }
.seg button {
  flex: 1;
  border: 0;
  background: none;
  color: var(--text-2);
  padding: var(--s-1) var(--s-2);
  font-size: var(--t-small);
  border-radius: var(--r-2);
}
.seg button + button { border-left: 1px solid var(--rule); }
.seg button:hover { color: var(--text); background: var(--sunken); }
.seg button[aria-pressed="true"] {
  background: var(--sunken);
  color: var(--text);
  font-weight: 500;
}

main { max-width: 68rem; margin: 0 auto; padding: var(--s-5) var(--s-4) var(--s-8); }

h2 { font-size: var(--t-head); margin: 0 0 var(--s-3); }
h3 { font-size: var(--t-body); margin: var(--s-5) 0 var(--s-2); }

.muted-note { color: var(--text-3); }
.contact-issue {
  color: var(--text-3);
  font-size: var(--t-small);
  margin-top: var(--s-1);
  padding-left: var(--s-4);
  position: relative;
}
.contact-issue::before { content: "!"; position: absolute; left: 0; color: var(--accent); }
.load-error {
  color: var(--accent);
  border: 1px solid var(--rule);
  background: var(--elevated);
  padding: var(--s-3) var(--s-4);
}
.loading { color: var(--text-3); padding: var(--s-4) 0; }

/* ---- summary line ---- */

/* Шапка страницы: заголовок слева, дата — как метаданные справа. */
.page-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-4);
}
.page-head h2 { margin: 0; }
.page-meta {
  color: var(--text-3);
  font-size: var(--t-body);
  font-variant-numeric: tabular-nums;
}

/* Прогресс разбора дневной порции — одна главная величина вместо ряда
   равновеликих чисел (те читались как «статистика ради статистики»). */
.day-progress { margin-bottom: var(--s-5); }
.day-progress-top {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  margin-bottom: var(--s-2);
}
.day-progress-count {
  font-size: var(--t-head);
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
}
.day-progress-count b { font-weight: 600; color: var(--text); }
.day-progress-word { color: var(--text-2); }
.day-progress.is-done .day-progress-word { color: var(--sys-ok); }

.bar {
  height: 3px;
  background: var(--rule);
  overflow: hidden;
}
.bar span {
  display: block;
  height: 100%;
  background: var(--text);
  transition: width 0.24s cubic-bezier(0.22, 1, 0.36, 1);
}
.day-progress.is-done .bar span { background: var(--sys-ok); }
@media (prefers-reduced-motion: reduce) { .bar span { transition: none; } }

.result-note {
  margin: 0 0 var(--s-2);
  color: var(--text-3);
  font-size: var(--t-small);
  font-variant-numeric: tabular-nums;
}
.section-note {
  margin: calc(-1 * var(--s-1)) 0 var(--s-4);
  color: var(--text-2);
  max-width: 62ch;
}

.day-progress-note {
  margin: var(--s-2) 0 0;
  color: var(--text-3);
  font-size: var(--t-small);
}

/* Оставлено для вкладки «Машина», где ряд счётчиков — это и есть диагностика. */
.day-summary {
  display: flex;
  gap: var(--s-5);
  flex-wrap: wrap;
  border: 1px solid var(--rule);
  background: var(--elevated);
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-5);
  border-radius: var(--r-3);
}
.day-summary .num {
  font-size: var(--t-head);
  font-weight: 600;
  display: block;
  font-variant-numeric: tabular-nums;
}
.day-summary .lbl { color: var(--text-2); font-size: var(--t-small); }

/* ---- chips ---- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  border: 1px solid var(--rule);
  color: var(--text-2);
  font-size: var(--t-micro);
  line-height: 1.4;
  padding: var(--s-hair) var(--s-2);
  white-space: nowrap;
  border-radius: var(--r-1);
}
.chip-decided { border-color: var(--accent); color: var(--accent); }
.chip-role { border-style: dashed; }

/* ---- rows (компактный список: Сегодня + Сигналы) ---- */

.rows { border: 1px solid var(--rule); background: var(--elevated); }
.row {
  display: grid;
  /* тип · объект · регион · сумма · когда · контакт · контрагент.
     Колонка суммы — 7.4rem: в 5.8rem не помещалось «42,494 млн руб.»
     (три знака после запятой у десятков миллионов — это точность до тысячи
     рублей, канон TOV §3), и число наезжало на дату соседней колонки. */
  grid-template-columns: 7.2rem minmax(9rem, 2fr) 9.5rem 7.4rem 6.4rem 3.1rem minmax(0, 11rem);
  gap: 0 var(--s-3);
  align-items: center;
  width: 100%;
  text-align: left;
  border: 0;
  border-bottom: 1px solid var(--rule);
  background: none;
  padding: var(--s-2) var(--s-3);
  color: var(--text);
}
.row:last-child { border-bottom: 0; }
.row:hover { background: var(--sunken); }
.row-decided { color: var(--text-3); }
.row-decided .row-name { color: var(--text-3); }
.row .chip-play { justify-self: start; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.row-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.row-name .chip-decided { margin-left: var(--s-2); }
.row-region, .row-cp {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-2);
  font-size: var(--t-small);
  min-width: 0;
}
.row-sum {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  font-size: var(--t-small);
  text-align: right;
}
.row-date {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: var(--t-small);
  color: var(--text-2);
}
.row-rel { color: var(--text-3); margin-left: var(--s-1); font-size: var(--t-small); }
.row-contact { display: inline-flex; gap: var(--s-1); color: var(--text-2); }
.row-contact .off { visibility: hidden; }
.row-contact svg { width: 14px; height: 14px; }

/* ---- card (модалка: общая для Сегодня и Сигналов) ---- */

.card { background: var(--elevated);   border-radius: var(--r-3);
}
.card.decided .card-title { color: var(--text-2); }
.card-head { display: flex; gap: var(--s-2); align-items: center; flex-wrap: wrap; margin-bottom: var(--s-2); }
.card-head-spacer { flex: 1; }
.chip-id .val {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  color: var(--text-3);
  max-width: 16rem;
}
.past-note { margin: 0 0 var(--s-2); }
.card-title { font-weight: 500; font-size: var(--t-sub); margin: 0 0 var(--s-1); line-height: 1.4; }

details.fullname { margin: 0 0 var(--s-2); }
details.fullname summary {
  cursor: pointer;
  color: var(--text-3);
  font-size: var(--t-small);
  user-select: none;
}
details.fullname p {
  margin: var(--s-1) 0 0;
  color: var(--text-2);
  font-size: var(--t-body);
  overflow-wrap: anywhere;
}

dl.fields {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--s-1) var(--s-4);
  margin: var(--s-2) 0;
  align-items: baseline;
}
dl.fields dt { color: var(--text-2); }
dl.fields dd { margin: 0; overflow-wrap: anywhere; }

.why-now { border-left: 3px solid var(--accent); padding-left: var(--s-3); margin: var(--s-3) 0; }

.internal {
  border: 1px dashed var(--rule);
  background: var(--canvas);
  padding: var(--s-2) var(--s-3);
  margin: var(--s-3) 0;
  font-size: var(--t-small);
}
.internal-label { color: var(--accent); font-size: var(--t-small); margin-bottom: var(--s-1); }

/* ---- история работы по карточке (журнал: сигнал + контрагент) ---- */

.history {
  border: 1px solid var(--rule);
  background: var(--canvas);
  padding: var(--s-2) var(--s-3);
  margin: var(--s-3) 0;
  font-size: var(--t-small);
}
.history-label { color: var(--text-3); font-size: var(--t-small); margin-bottom: var(--s-1); }
.history ul { margin: 0; padding: 0; list-style: none; }
.history li {
  padding: var(--s-hair) 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.history .hist-ts {
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
}
.history .hist-scope { color: var(--text-3); }
.history .muted-note { margin: 0; }

.gate-fail { color: var(--accent); }

/* ---- copy chips (один клик — значение в буфере) ---- */

.copy-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  border: 1px solid var(--rule-control);
  background: var(--canvas);
  color: var(--text);
  padding: var(--s-hair) var(--s-2);
  font-size: var(--t-small);
  max-width: 100%;
  border-radius: var(--r-2);
}
.copy-chip:hover { border-color: var(--text-2); background: var(--sunken); }
.copy-chip .ic { display: inline-flex; color: var(--text-3); flex-shrink: 0; }
.copy-chip .ic svg { width: 13px; height: 13px; }
.copy-chip .val {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.copy-chip.copied { border-color: var(--accent); }
.copy-chip.copied .ic { color: var(--accent); }
.copy-strip { display: flex; gap: var(--s-2); flex-wrap: wrap; margin: var(--s-1) 0; }

/* ---- письмо-черновик ---- */

.warnings {
  color: var(--text-3);
  font-size: var(--t-small);
  margin: var(--s-3) 0 var(--s-1);
  padding: 0;
  list-style: none;
}
.warnings li { padding-left: var(--s-4); position: relative; }
.warnings li::before { content: "!"; position: absolute; left: 0; color: var(--accent); }

.letter-label { color: var(--text-3); font-size: var(--t-small); margin: var(--s-3) 0 var(--s-1); }
.letter {
  border: 1px solid var(--rule);
  background: var(--canvas);
  padding: var(--s-3) var(--s-4);
  margin: 0 0 var(--s-2);
  font-size: var(--t-body);
}
.letter p { margin: 0 0 var(--s-3); white-space: pre-line; overflow-wrap: anywhere; }
.letter p:last-child { margin-bottom: 0; }
.letter p:first-child { color: var(--text-2); }

/* ---- buttons ---- */

.btn-row { display: flex; gap: var(--s-2); flex-wrap: wrap; margin-top: var(--s-3); }
.btn {
  border: 1px solid var(--rule-strong);
  background: var(--elevated);
  color: var(--text);
  padding: var(--s-2) var(--s-4);
  border-radius: var(--r-2);
}
.btn:hover { background: var(--sunken); }
.btn.primary { background: var(--btn-bg); color: var(--btn-fg); }
.btn.quiet { border-color: var(--rule); color: var(--text-2); }
.btn.danger-link {
  border: 0;
  background: none;
  color: var(--text-3);
  text-decoration: underline;
  padding: var(--s-2) var(--s-1);
}
.btn:disabled { opacity: 0.45; cursor: default; }

/* Кнопки решений прижаты к низу модалки — доступны без прокрутки. */
.card-actions {
  position: sticky;
  bottom: 0;
  background: var(--elevated);
  border-top: 1px solid var(--rule);
  margin: var(--s-4) calc(-1 * var(--s-5)) 0;
  padding: var(--s-3) var(--s-5) var(--s-1);
}
.card-actions .btn-row { margin-top: 0; }
.card-actions .copy-row { margin-bottom: var(--s-2); }

/* ---- filters / tables ---- */

.filters {
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
  margin-bottom: var(--s-4);
}
.filters input, .filters select {
  padding: var(--s-2) var(--s-2);
  border: 1px solid var(--rule);
  background: var(--elevated);
}
.filters input[type="search"] { flex: 1; min-width: 12rem; }

table.list {
  overflow: hidden;
  width: 100%;
  border-collapse: collapse;
  background: var(--elevated);
  border: 1px solid var(--rule);
  border-radius: var(--r-3);
}
table.list th, table.list td {
  text-align: left;
  padding: var(--s-2) var(--s-2);
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
}
table.list th { color: var(--text-2); font-weight: 500; font-size: var(--t-small); white-space: nowrap; }
table.list td { font-variant-numeric: tabular-nums; }
.cell-name { max-width: 26rem; overflow-wrap: anywhere; }
.pager { display: flex; gap: var(--s-2); align-items: center; margin: var(--s-4) 0; color: var(--text-2); }

/* ---- machine ---- */

.machine-block {
  border: 1px solid var(--rule);
  background: var(--elevated);
  padding: var(--s-4) var(--s-4);
  margin-bottom: var(--s-4);
  border-radius: var(--r-3);
}
.machine-block h3 { margin-top: 0; }
.status-ok { color: var(--text); }
.status-bad { color: var(--accent); }
.steps { margin: var(--s-2) 0 0; padding-left: var(--s-5); color: var(--text-2); font-size: var(--t-small); }
pre.log-tail {
  background: var(--canvas);
  border: 1px solid var(--rule);
  padding: var(--s-2) var(--s-3);
  overflow-x: auto;
  font-size: var(--t-small);
}

/* ---- modal ---- */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: var(--backdrop);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: var(--s-5) var(--s-4);
  z-index: 50;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.modal {
  position: relative;
  background: var(--elevated);
  border: 1px solid var(--rule);
  max-width: 46rem;
  width: 100%;
  padding: var(--s-4) var(--s-5) var(--s-4);
  max-height: calc(100vh - var(--s-7));
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: var(--r-3);
}
.modal-close {
  position: absolute;
  top: 0.55rem;
  right: 0.6rem;
  border: 0;
  background: none;
  color: var(--text-2);
  padding: var(--s-1);
  display: flex;
  z-index: 2;
}
.modal-close svg { width: 16px; height: 16px; }
.modal-close:hover { color: var(--text); }

/* ---- toast ---- */

.toast {
  position: fixed;
  bottom: var(--s-5);
  left: 50%;
  transform: translateX(-50%);
  border: 1px solid var(--rule);
  background: var(--elevated);
  color: var(--text);
  padding: var(--s-2) var(--s-4);
  z-index: 100;
  max-width: 90vw;
  border-radius: var(--r-2);
}

/* ---- crm ---- */

.crm-add {
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
  margin: var(--s-3) 0 var(--s-4);
}
.crm-add input {
  padding: var(--s-2) var(--s-2);
  border: 1px solid var(--rule);
  background: var(--elevated);
  color: var(--text);
}
.crm-head { margin-bottom: var(--s-3); }
.crm-head h2 { margin-bottom: var(--s-hair); }
.crm-closed-title { margin: var(--s-5) 0 var(--s-2); font-size: var(--t-body); }
.crm-secondary { margin-top: var(--s-6); border-top: 1px solid var(--rule); padding-top: var(--s-3); }
.crm-secondary summary { cursor: pointer; color: var(--text-2); margin-bottom: var(--s-3); }

.pipe-board {
  display: grid;
  grid-template-columns: repeat(4, minmax(11rem, 1fr));
  gap: var(--s-3);
  align-items: start;
}
.pipe-board-closed { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.pipe-col {
  background: var(--sunken);
  border: 1px solid var(--rule);
  min-height: 8rem;
}
.pipe-col-head {
  display: flex;
  justify-content: space-between;
  padding: var(--s-2) var(--s-3);
  border-bottom: 1px solid var(--rule);
  font-size: var(--t-small);
}
.pipe-col-body { padding: var(--s-2); display: flex; flex-direction: column; gap: var(--s-2); }
.pipe-empty { margin: var(--s-2); font-size: var(--t-small); }
.pipe-card {
  text-align: left;
  width: 100%;
  background: var(--elevated);
  border: 1px solid var(--rule);
  padding: var(--s-2) var(--s-3);
  color: var(--text);
  cursor: pointer;
  font: inherit;
}
.pipe-card:hover { border-color: var(--rule-strong); }
.pipe-card-top { display: flex; flex-wrap: wrap; gap: var(--s-1); margin-bottom: var(--s-1); }
.pipe-card-name { font-weight: 600; margin-bottom: var(--s-hair); }
.pipe-card-co { font-size: var(--t-small); color: var(--text-2); margin-bottom: var(--s-1); }
.pipe-card-meta { display: flex; flex-direction: column; gap: var(--s-hair); font-size: var(--t-small); color: var(--text-2); }
.pipe-overdue { color: var(--accent); }

.chip-row { display: flex; flex-wrap: wrap; gap: var(--s-1); margin-bottom: var(--s-2); }
.chip {
  display: inline-block;
  border: 1px solid var(--rule);
  padding: var(--s-hair) var(--s-2);
  font-size: var(--t-micro);
  color: var(--text-2);
}
.chip-soft { background: var(--sunken); }
.stage-switcher {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1);
  margin: var(--s-3) 0 var(--s-4);
}
.stage-btn {
  border: 1px solid var(--rule);
  background: var(--elevated);
  color: var(--text-2);
  padding: var(--s-1) var(--s-2);
  font: inherit;
  cursor: pointer;
}
.stage-btn.is-active {
  border-color: var(--rule-strong);
  color: var(--text);
}
.people-list, .task-list, .act-list, .books {
  margin: var(--s-1) 0 var(--s-3);
  padding-left: var(--s-4);
  color: var(--text-2);
}
.people-list li, .task-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-3);
  align-items: center;
  margin-bottom: var(--s-1);
}
.pipe-modal-title { margin: var(--s-1) 0 var(--s-1); font-size: var(--t-head); }
.btn-ghost {
  border: 0;
  background: none;
  color: var(--accent);
  padding: 0;
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
}

/* ---- mobile (390px и уже) ---- */

/* Порог поднят с 760 до 980 px: на полосе 761–813 px сумма фиксированных
   колонок строки превышала доступную ширину, и единственный растяжимый трек —
   НАЗВАНИЕ ОБЪЕКТА — схлопывался в ноль. В списке оставались регион, сумма и
   контрагент, а главного поля не было вовсе, молча. Теперь на этой полосе
   работает раскладка в поток, где имя занимает всю строку. */
@media (max-width: 980px) {
  main { padding: var(--s-4) var(--s-2) var(--s-8); }
  .topbar { gap: var(--s-2); padding: 0 var(--s-2); }
  .topbar-meta { display: none; }
  .tab { padding: var(--s-3) var(--s-2); }

  .row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-hair) var(--s-3);
    padding: var(--s-2) var(--s-3);
  }
  .row-name { flex-basis: 100%; order: -1; white-space: normal; }
  .row-region, .row-cp { max-width: 11rem; }
  .row-sum { text-align: left; }

  dl.fields { grid-template-columns: 1fr; gap: 0; }
  dl.fields dt { margin-top: var(--s-2); }
  table.list .hide-sm { display: none; }
  .modal { padding: var(--s-4) var(--s-4) var(--s-4); max-height: calc(100vh - var(--s-6)); }
  .modal-backdrop { padding: var(--s-4) var(--s-2); }
  .card-actions { margin: var(--s-4) calc(-1 * var(--s-4)) 0; padding: var(--s-3) var(--s-4) var(--s-1); }
  .pipe-board { grid-template-columns: 1fr; }
}

/* -- CRM editing v1 (drag, inline forms, new deal) ------------------------- */
.pipe-card[draggable="true"] { cursor: grab; }
.pipe-card.dragging { opacity: 0.45; cursor: grabbing; }
.pipe-col.drag-over { outline: 2px dashed var(--accent); outline-offset: -2px; }
.crm-head { display: flex; align-items: baseline; gap: var(--s-4); flex-wrap: wrap; }
.crm-head #opp-new { margin-left: auto; }
.opp-edit { display: flex; flex-direction: column; gap: var(--s-2); margin: var(--s-3) 0; }
.opp-edit[hidden] { display: none; } /* author display:flex иначе перебивает UA-стиль [hidden] */
.opp-edit label {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  font-size: var(--t-small);
  color: var(--text-2);
}
.opp-edit input, .opp-edit textarea, .opp-edit select { width: 100%; font: inherit; }
.pipe-modal-title { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.pipe-modal-title .btn { font-size: var(--t-micro); font-weight: 400; }
.task-actions { display: inline-flex; gap: var(--s-1); align-items: center; }
.task-row, .people-list li { display: flex; gap: var(--s-2); align-items: center; flex-wrap: wrap; }
.task-row > span:first-child { flex: 1; }
.inline-form { display: flex; gap: var(--s-1); flex-wrap: wrap; flex: 1; }
/* Тот же случай, что у .opp-edit: авторский display перебивает UA-стиль
   [hidden], и скрытая форма правки оставалась бы на экране. */
.inline-form[hidden] { display: none; }
.inline-form input { font: inherit; }

/* -- Почта (TZ-MAIL-V0.md) -------------------------------------------------- */
.mail-rows {
  border: 1px solid var(--rule);
  background: var(--elevated);
  display: flex;
  flex-direction: column;
}
.mail-row {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  padding: var(--s-2) var(--s-3);
  border: 0;
  border-bottom: 1px solid var(--rule);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.mail-row:last-child { border-bottom: 0; }
.mail-row:hover, .mail-row:focus-visible { background: var(--sunken); }
.mail-row-top { display: flex; justify-content: space-between; gap: var(--s-3); align-items: baseline; }
.mail-subject { font-weight: 600; }
.mail-row-mid { display: flex; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; }
.mail-row-bottom { display: flex; gap: var(--s-2); align-items: baseline; min-width: 0; }
.mail-snippet {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}
.mail-chip-unlinked { border-style: dashed; color: var(--text-3); }
.mail-filter-unlinked {
  display: inline-flex;
  gap: var(--s-1);
  align-items: center;
  color: var(--text-2);
  white-space: nowrap;
}
.mail-link-box {
  border: 1px solid var(--rule);
  background: var(--sunken);
  padding: var(--s-2) var(--s-3);
  margin: var(--s-3) 0 var(--s-4);
}
.mail-link-box select { max-width: 24rem; }
.mail-thread { display: flex; flex-direction: column; gap: var(--s-3); }
.mail-msg {
  border: 1px solid var(--rule);
  background: var(--elevated);
  padding: var(--s-2) var(--s-3);
}
.mail-msg-out { border-left: 3px solid var(--accent); }
.mail-msg-head {
  display: flex;
  gap: var(--s-2);
  align-items: baseline;
  flex-wrap: wrap;
  margin-bottom: var(--s-2);
}
.mail-msg-head > span:last-child { margin-left: auto; }
.mail-msg-text {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 24rem;
  overflow-y: auto;
}
.mail-msg-atts { display: flex; gap: var(--s-2); flex-wrap: wrap; margin-top: var(--s-2); }
.mail-att {
  border: 1px solid var(--rule);
  padding: var(--s-1) var(--s-2);
  text-decoration: none;
  color: inherit;
}
.mail-att:hover { background: var(--sunken); }
@media (max-width: 640px) {
  .mail-row-top, .mail-row-mid { flex-direction: column; gap: var(--s-hair); }
}

/* -- История цен в карточке сделки (24.07.2026) ----------------------------- */
.price-list { list-style: none; padding: 0; margin: 0 0 var(--s-2); }
.price-row {
  display: flex;
  gap: var(--s-2);
  align-items: baseline;
  flex-wrap: wrap;
  padding: var(--s-1) 0;
  border-bottom: 1px dashed var(--rule);
}
.price-row:last-child { border-bottom: 0; }
.price-side {
  border: 1px solid var(--rule);
  padding: 0 var(--s-2);
  font-size: var(--t-small);
}
.price-client .price-side { border-color: var(--accent); color: var(--accent); }
.price-setamount {
  display: inline-flex;
  gap: var(--s-1);
  align-items: center;
  color: var(--text-2);
  font-size: var(--t-small);
  margin-bottom: var(--s-2);
}

/* ---- Инженеры (реестр из TG-чатов) ---------------------------------------- */

.team-row {
  grid-template-columns:
    minmax(0, 15.5rem) minmax(0, 4rem) minmax(0, 1fr)
    minmax(0, 11rem) minmax(0, 9.5rem) minmax(0, 12rem);
  cursor: pointer;
}
.team-head {
  cursor: default;
  color: var(--text-3);
  font-size: var(--t-small);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.team-head:hover { background: none; }
/* Разделы/скиллы — строго одна строка: лишние теги прячет JS (fitTagRow) и
   ставит маркер «…». nowrap + overflow:hidden, теги не сжимаются. */
.team-row .team-razdely {
  display: flex; flex-wrap: nowrap; gap: var(--s-1);
  overflow: hidden; min-width: 0;
}
.team-row .team-razdely .chip { flex: 0 0 auto; }
.tag-more { border-style: dashed; color: var(--text-2); cursor: default; }
.is-hidden { display: none !important; }
.chip-skill { border-style: dotted; color: var(--text-2); }
.team-row .team-contact { overflow: hidden; }
.team-row .team-contact .copy-chip { max-width: 100%; }
@media (max-width: 720px) {
  .team-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .team-head { display: none; }
  /* На мобильном узкая колонка «Проект» не влезает отдельным столбцом —
     показываем как первую строку блока, во всю ширину. */
  .team-row .team-project { grid-column: 1 / -1; order: -1; }
}
/* Свой (ручной) инженер и метка закрепления за сделкой */
.chip-mine { border-color: var(--accent); color: var(--accent); }
.chip-assign { border-color: var(--accent); color: var(--accent); }
/* Колонка «Проект» — отдельная узкая ячейка (не лепится к имени, 25.07.2026:
   было «уродски» рядом с именем). Значок = инженер уже закреплён за сделкой
   в CRM; список сделок — в title. Пусто — как в остальных пустых ячейках. */
.team-row .team-project { display: flex; align-items: center; }
/* Метка «закреплён за сделкой» — вторичная информация, а не главное действие
   на экране. Раньше она красилась как основная кнопка (сплошная заливка) и
   оказывалась самым громким элементом таблицы. */
.chip-inproject {
  border-color: var(--rule);
  background: none;
  color: var(--text-2);
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-1); min-width: 1.5rem; height: 1.5rem; padding: 0 var(--s-1);
  border-radius: var(--r-1);
}
.team-row:hover .chip-inproject { color: var(--text); }
.chip-inproject .icon { width: 0.85em; height: 0.85em; }
.chip-inproject-n { font-size: var(--t-micro); font-variant-numeric: tabular-nums; }
.team-row-project .row-name { font-weight: 600; }

/* -- Статус карточки инженера (26.07.2026) ----------------------------------
   Отказ — состояние, а не бренд: цвет системный багрянец (сурик здесь запрещен
   — он значит «действие»). Обе пометки красные (решение основателя): отказ
   есть отказ, разница между «отказался» и «не писать» — в тексте и значке,
   а не в громкости. У активных метки нет вовсе. */
.chip-status { display: inline-flex; align-items: center; gap: var(--s-1); }
.chip-status-declined,
.chip-status-do_not_contact {
  border-color: var(--sys-err);
  color: var(--sys-err);
  background: var(--sys-err-bg);
}
.chip-status .icon { width: 0.85em; height: 0.85em; }
/* Строка того, кому писать нельзя: имя приглушено, но строка читаема и
   кликабельна — карточку открыть надо, чтобы увидеть причину. */
.team-row-dnc .team-name-text,
.team-row-dnc .team-contact { color: var(--text-3); }
.team-row-dnc .copy-chip { opacity: 0.7; }

/* Полоса на странице инженера — стоит НАД контактами. */
.eng-status-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  margin: var(--s-2) 0 var(--s-4);
  border: 1px solid var(--rule);
  border-left-width: 3px;
}
.eng-status-banner .icon { margin-top: var(--s-hair); }
.eng-status-banner-declined,
.eng-status-banner-do_not_contact {
  border-left-color: var(--sys-err);
  background: var(--sys-err-bg);
  color: var(--sys-err);
}
/* Управляющая строка карточки инженера — две колонки вместо трех у сделки. */
.eng-control { grid-template-columns: minmax(9rem, 12rem) minmax(12rem, 1fr); }
@media (max-width: 720px) { .eng-control { grid-template-columns: 1fr; } }

/* Список закреплений на карточке инженера и странице сделки (переиспользует
   раскладку people-list/task-list). */
.eng-assign-list { list-style: none; margin: var(--s-2) 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-1); }
.eng-assign-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.eng-assign-link { color: var(--text); text-decoration: underline; text-underline-offset: 2px; }
.eng-assign-link:hover { color: var(--accent); }
.eng-custom-contacts { display: flex; flex-wrap: wrap; gap: var(--s-1); margin-top: var(--s-2); }
.eng-edit-contacts { display: flex; flex-direction: column; gap: var(--s-1); margin: var(--s-1) 0; }
.eng-edit-contacts .ee-contacts { display: flex; flex-direction: column; gap: var(--s-1); }





.toast-ok { background: var(--sys-ok-bg); color: var(--sys-ok); border-color: var(--sys-ok); }
.toast-err { background: var(--sys-err-bg); color: var(--sys-err); border-color: var(--sys-err); }
.toast-info { background: var(--sys-info-bg); color: var(--sys-info); border-color: var(--sys-info); }
.toast-warn { background: var(--sys-warn-bg); color: var(--sys-warn); border-color: var(--sys-warn); }

/* -- Иконки (эмодзи запрещены) ---------------------------------------------- */
.icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.12em;
  flex-shrink: 0;
}
.btn-ghost .icon { width: 1.05em; height: 1.05em; }

/* -- Карточка сделки — страница /crm/op/{id} -------------------------------- */
.opp-page {
  max-width: 46rem;
  margin: 0 auto;
}
.back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  color: var(--text-2);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.back-link:hover { color: var(--text); border-bottom-color: var(--rule); }
.opp-head { margin: var(--s-2) 0 var(--s-4); }
.opp-status {
  display: flex;
  gap: var(--s-2);
  align-items: center;
  border: 1px solid var(--rule);
  background: var(--elevated);
  padding: var(--s-2) var(--s-3);
  margin-bottom: var(--s-4);
}
.opp-status-label { color: var(--text-2); white-space: nowrap; }
.opp-status input { flex: 1; font: inherit; }
.opp-section { margin-bottom: var(--s-2); }
.opp-history { margin-top: var(--s-5); }
.pipe-status { color: var(--text); font-weight: 500; }

/* -- Удаление сделки --------------------------------------------------------- */
.opp-danger {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px dashed var(--rule);
}
.btn-danger { color: var(--sys-err); border-color: var(--sys-err); }
.btn-danger:hover { background: var(--sys-err-bg); }
.btn-danger-solid {
  background: var(--sys-err);
  border: 1px solid var(--sys-err);
  color: var(--sys-err-on);
}
.opp-danger-confirm {
  display: inline-flex;
  gap: var(--s-2);
  align-items: center;
  flex-wrap: wrap;
  color: var(--text-2);
}

/* -- Контакты человека (25.07.2026) ----------------------------------------- */
/* Одна сетка на всю форму: «название — значение — комментарий — удалить».
   У штатных полей название закрыто (.fr-fixed) — переименовать нельзя, поле
   разбирается кодом; у своих контактов название вводится. */
.crm-add-person { flex-wrap: wrap; }
.field-rows { display: flex; flex-direction: column; gap: var(--s-1); width: 100%; }
.p-contacts { display: flex; flex-direction: column; gap: var(--s-1); width: 100%; }
.fr-row {
  display: grid;
  grid-template-columns: 11rem minmax(0, 1.2fr) minmax(0, 1fr) auto;
  gap: var(--s-1);
  align-items: center;
  width: 100%;
}
.fr-row input { font: inherit; min-width: 0; }
.fr-fixed {
  padding: var(--s-1) var(--s-2);
  border: 1px solid var(--rule);
  background: var(--sunken);
  color: var(--text-2);
  font-size: var(--t-small);
  cursor: default;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fr-note { color: var(--text-2); }
/* Крестик и пустышка в его колонке одной ширины — иначе строки своих
   контактов разъезжаются относительно штатных. */
.fr-del-slot, .fr-row .ct-del {
  width: 1.75rem;
  min-width: 1.75rem;
  padding: 0;
  display: inline-flex;
  justify-content: center;
}
.inline-actions { display: inline-flex; gap: var(--s-1); }

@media (max-width: 720px) {
  .fr-row { grid-template-columns: 8rem minmax(0, 1fr) auto; }
  .fr-note { grid-column: 2 / 4; }
}


/* ---- карточка сделки: правила DESIGN-CARDS.md ---- */

.opp-head { margin-bottom: var(--s-4); }
.opp-head-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
}
.opp-title { font-size: var(--t-head); margin: 0; text-wrap: balance; }
.opp-sub { margin: var(--s-1) 0 0; color: var(--text-2); }

/* Строка управления: значения полей в ряд, без рамок вокруг каждого. */
/* Подписи в одной строке, значения — в другой: сетка из двух строк, а не
   выравнивание по низу. Раньше select и input рендерились разной высоты, и
   подписи «Стадия» / «Статус» / «Сумма» стояли на трёх разных уровнях. */
.opp-control {
  display: grid;
  grid-template-columns: minmax(9rem, 12rem) minmax(12rem, 1fr) minmax(6rem, auto);
  grid-template-rows: auto auto;
  gap: var(--s-1) var(--s-4);
  align-items: center;
  padding: var(--s-3) 0 var(--s-4);
  border-bottom: 1px solid var(--rule);
  margin-bottom: var(--s-5);
}
.ctl { display: contents; }
.ctl-label {
  grid-row: 1;
  color: var(--text-3);
  font-size: var(--t-small);
  align-self: end;
}
.ctl select,
.ctl input,
.ctl-value {
  grid-row: 2;
  height: 2.25rem;
  padding: 0 var(--s-2);
  border: 1px solid var(--rule);
  background: var(--canvas);
  width: 100%;
  min-width: 0;
  border-radius: var(--r-2);
}
/* Сумма — не поле ввода: та же высота и базовая линия, но без рамки. */
.ctl-value {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  border-color: transparent;
  background: none;
  padding: 0;
  font-size: var(--t-sub);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
@media (max-width: 720px) {
  .opp-control { grid-template-columns: 1fr; }
  .ctl-label, .ctl select, .ctl input, .ctl-value { grid-row: auto; }
  .ctl-value { justify-content: flex-start; }
}

/* Формы добавления свёрнуты: раскрываются по требованию, а не висят все сразу. */
.add-block { margin-top: var(--s-3); }
.add-block > summary {
  cursor: pointer;
  color: var(--text-2);
  font-size: var(--t-body);
  padding: var(--s-1) 0;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
}
.add-block > summary::-webkit-details-marker { display: none; }
.add-block > summary::before {
  content: "+";
  display: inline-block;
  width: 1.05rem; height: 1.05rem;
  line-height: 1rem;
  text-align: center;
  border: 1px solid var(--rule);
  color: var(--text-3);
}
.add-block > summary:hover { color: var(--text); }
.add-block[open] > summary::before { content: "−"; }
.add-block[open] > summary { margin-bottom: var(--s-2); }


/* ---- настройки ---- */

.set-section { margin-bottom: var(--s-6); }
.set-section h3 { margin: 0 0 var(--s-2); }
.set-profile { display: flex; gap: var(--s-4); align-items: flex-start; }
.set-profile-fields { flex: 1 1 20rem; max-width: 24rem; }
.set-profile-fields .btn-row { margin-top: var(--s-3); }
.set-pass { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: end; }
.set-pass .ctl { flex: 1 1 11rem; }
.set-users td { padding: var(--s-2) var(--s-2); border-bottom: 1px solid var(--rule); }
.set-users tr:last-child td { border-bottom: 0; }
.set-mail { color: var(--text-2); }
.set-actions { text-align: right; }


/* Ячейка имени инженера: аватар не участвует в обрезке текста, поэтому имя
   режется многоточием само по себе, а кружок остаётся на месте и по центру. */
.team-row .team-name-cell,
.team-head .team-name-cell {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-width: 0;
  overflow: hidden;
}
.team-name-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
/* Заголовок таблицы отступает на ширину аватара, чтобы «ИМЯ» стояло над именами. */
.team-head .team-name-cell { padding-left: calc(var(--s-5) + var(--s-2)); }


/* Шапка карточки инженера: фото слева, имя и метки — справа от него. */
.eng-head-main { display: flex; gap: var(--s-4); align-items: flex-start; }
.eng-head-id { flex: 1; min-width: 0; }
.eng-head-id .chip-row { margin-top: var(--s-1); }
.eng-photo-row { margin-top: var(--s-2); }


/* ---- редактируемый аватар: действие на самом кружке ---- */

.avatar-edit { position: relative; display: inline-block; line-height: 0; }
.avatar-edit .avatar { display: flex; }

/* Инициалы без фото — белым по сурику. Берём базовый тон (не осветлённый для
   тёмной темы): на нём белый держит контраст в обеих темах. */
.avatar-empty {
  background-color: var(--minium);
  border-color: transparent;
  color: var(--white);
  font-weight: 500;
}

.avatar-action {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-round);
  padding: 0;
  background: var(--scrim);
  color: var(--white);
  opacity: 0;
  transition: opacity 0.15s ease;
}
.avatar-action svg { width: 45%; height: 45%; }
.avatar-edit:hover .avatar-action,
.avatar-action:focus-visible { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .avatar-action { transition: none; } }


/* Подтверждение автосохранения: короткая зелёная рамка на самом поле —
   вместо кнопки «Сохранить» и всплывающего сообщения. */
.field-saved,
.field-failed {
  animation: field-flash 1.4s ease-out;
}
.field-saved { --flash: var(--sys-ok); }
.field-failed { --flash: var(--sys-err); }
@keyframes field-flash {
  0%   { border-color: var(--flash); box-shadow: 0 0 0 2px color-mix(in oklab, var(--flash) 30%, transparent); }
  70%  { border-color: var(--flash); box-shadow: 0 0 0 2px transparent; }
  100% { border-color: var(--rule); box-shadow: none; }
}
@media (prefers-reduced-motion: reduce) {
  .field-saved, .field-failed { animation: none; border-color: var(--flash); }
}

/* -- Заметка о закрытии задачи (25.07.2026) --------------------------------- */
.task-row-noted { flex-wrap: wrap; }
.task-done-note {
  flex-basis: 100%;
  padding-left: var(--s-4);
  border-left: 2px solid var(--rule);
  margin-top: var(--s-hair);
  font-size: var(--t-small);
}

/* -- Люди как сквозная сущность (25.07.2026) -------------------------------- */
/* Человек живёт на своей странице /crm/person/{id}: в сделке его имя — ссылка
   туда, а не просто текст. */
.person-link {
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}
.person-link:hover { border-bottom-color: var(--accent); color: var(--accent); }

/* Метка «числится за другой компанией» — статус, поэтому системный жёлтый,
   а не сурик (правило палитры: сурик — брендовое действие, не предупреждение). */
.chip-warn {
  border-color: var(--sys-warn);
  color: var(--sys-warn);
  background: var(--sys-warn-bg);
}

.person-chips { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-3); align-items: center; }

/* Подсказка «мы с ним уже общались» под формой нового человека. Не запрет —
   тёзки бывают; поэтому спокойная рамка, а не красная. */
.person-dupe { display: flex; flex-direction: column; gap: var(--s-2); margin: var(--s-2) 0; }
.dupe-card {
  border: 1px solid var(--rule);
  border-left: 3px solid var(--rule-strong);
  background: var(--sunken);
  padding: var(--s-2) var(--s-3);
}
.dupe-card p { margin: 0 0 var(--s-1); }
.dupe-card p:last-of-type { margin-bottom: var(--s-2); }
.dupe-strong { border-left-color: var(--sys-warn); }
.dupe-actions { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; }

/* Люди компании в форме новой сделки */
.nd-people { display: flex; flex-direction: column; gap: var(--s-1); }
.nd-people p { margin: 0 0 var(--s-1); }
.nd-person {
  display: flex;
  gap: var(--s-2);
  align-items: baseline;
  flex-direction: row;
}
.nd-person .muted-note { margin-left: var(--s-1); }

/* Кнопка «Люди» в шапке воронки стоит рядом с «+ сделка» */
.crm-head .btn.quiet {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  text-decoration: none;
}

/* Реестр людей: ФИО — главная колонка, ей нужна ширина, иначе браузер отдаёт
   место должности, а имя рвётся по буквам (общий .cell-name с его
   overflow-wrap: anywhere рассчитан на длинные названия объектов). */
.people-table th:first-child, .people-table td:first-child { min-width: 14rem; }
.people-table .cell-name { overflow-wrap: normal; }
.people-table td { vertical-align: middle; }
.people-search input { flex: 1; min-width: 20rem; }

/* -- Delivery-слой и рыночное досье (25.07.2026, TZ-TSEPOCHKA) -------------- */

/* «Мы по обе стороны» — предупреждение о состоянии дел, а не о поломке:
   системный жёлтый, как у метки «числится за другой компанией». Сурик здесь
   запрещён — он означает наше действие, а не факт. */
.conflict-note {
  border: 1px solid var(--sys-warn);
  background: var(--sys-warn-bg);
  color: var(--text);
  border-radius: var(--r-1);
  padding: var(--s-2) var(--s-3);
  margin: 0 0 var(--s-3);
  line-height: 1.45;
}

.site-list, .link-list, .market-list { list-style: none; padding: 0; margin: 0 0 var(--s-2); }
.site-row, .site-deal, .link-row {
  display: flex;
  gap: var(--s-2);
  align-items: baseline;
  flex-wrap: wrap;
  padding: var(--s-1) 0;
  border-bottom: 1px dashed var(--rule);
}
.site-row:last-child, .site-deal:last-child, .link-row:last-child { border-bottom: 0; }
.site-link { color: inherit; text-decoration: none; border-bottom: 1px solid var(--rule); }
.site-link:hover { border-bottom-color: var(--accent); color: var(--accent); }

/* Досье из графа: два столбца контрагентов на широком экране, один — на
   узком. Список намеренно короткий: карточка не отчёт, полное досье лежит
   в файле сборки. */
.market-section h4 { margin: var(--s-3) 0 var(--s-1); font-size: var(--t-body); }
.market-line { margin: 0 0 var(--s-2); }
.market-cols { display: flex; gap: var(--s-5); flex-wrap: wrap; }
.market-cols > div { flex: 1 1 16rem; min-width: 0; }
.market-list li {
  display: flex;
  gap: var(--s-2);
  justify-content: space-between;
  align-items: baseline;
  padding: var(--s-1) 0;
  border-bottom: 1px dashed var(--rule);
}
.market-list li:last-child { border-bottom: 0; }
.market-list li > span:first-child { overflow-wrap: anywhere; }
.market-groups li { border-bottom: 0; }

/* Якорь цены стоит НАД историей цен: это фон для разговора, а не наша цена. */
.price-anchor {
  margin: 0 0 var(--s-2);
  color: var(--text-muted);
  border-left: 2px solid var(--rule);
  padding-left: var(--s-2);
}
