/* Trelvis Web — тёмная тема в духе Trello (привычно команде) */

/* ---------- Переменные тем ---------- */
:root {
  --ui-scale: 1;
  --ui-scale-size: 100%;
  --ui-viewport-width: 100vw;
  --ui-viewport-height: 100dvh;
  --bg: #1d2125;
  --panel: #161a1d;
  --sidebar: #161a1d;
  --col: #101204;
  --card: #22272b;
  --card-hover: #2c333a;
  --text: #b6c2cf;
  --bright: #dcdfe4;
  --muted: #8c9bab;
  --accent: #579dff;
  --green: #4bce97;
  --red: #f87168;
  --yellow: #f5cd47;
  --purple: #9f8fef;
  /* «Отменено» (3111): приглушённый серый — закрыто, но не зелёное. Матрикс его
     сознательно не переопределяет: отказ и там остаётся серым. */
  --cancelled: #8d8f96;
  --line: #31383e;
  --radius: 12px;
  --field: #22272b;
  --active: #1c2b41;
  --soft: #333a41;
  --modal: #282e33;
  --comment-field: #1a1f23;
  --on-accent: #10151a;
  --accent-rgb: 87, 157, 255;
  --column-heading: var(--bright);
  --column-heading-weight: 800;
  --scroll-thumb: rgba(255,255,255,.14);
  --scroll-thumb-hover: rgba(255,255,255,.28);
  --board-scroll-track: rgba(var(--accent-rgb),.11);
  --board-scroll-thumb: rgba(var(--accent-rgb),.42);
  --board-scroll-thumb-hover: rgba(var(--accent-rgb),.68);
  --ui-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --ui-letter-spacing: normal;
  --pig-filter: none;
  --trelvis-tg-safe-top: max(var(--tg-safe-area-inset-top, 0px), env(safe-area-inset-top, 0px));
  --trelvis-tg-safe-right: max(var(--tg-safe-area-inset-right, 0px), env(safe-area-inset-right, 0px));
  --trelvis-tg-safe-bottom: max(var(--tg-safe-area-inset-bottom, 0px), env(safe-area-inset-bottom, 0px));
  --trelvis-tg-safe-left: max(var(--tg-safe-area-inset-left, 0px), env(safe-area-inset-left, 0px));
  --trelvis-tg-content-top: var(--tg-content-safe-area-inset-top, 0px);
  --trelvis-tg-content-right: var(--tg-content-safe-area-inset-right, 0px);
  --trelvis-tg-content-bottom: var(--tg-content-safe-area-inset-bottom, 0px);
  --trelvis-tg-content-left: var(--tg-content-safe-area-inset-left, 0px);
  /* Воздух между верхней панелью и липким заголовком колонки (трелвис 1966):
     заголовок останавливается не вплотную к панели, а с этим просветом, и в
     нём видны обои доски. Та же величина отделяет колонки от верха в покое. */
  --board-head-gap: 10px;
  /* contentSafeAreaInset Telegram отдаёт от края safe-area, а не экрана:
     полный отступ — сумма, max прятал шапку под «Закрыть»/«•••» (#12149). */
  --trelvis-tg-top: calc(var(--trelvis-tg-safe-top) + var(--trelvis-tg-content-top));
  --trelvis-tg-right: calc(var(--trelvis-tg-safe-right) + var(--trelvis-tg-content-right));
  --trelvis-tg-bottom: calc(var(--trelvis-tg-safe-bottom) + var(--trelvis-tg-content-bottom));
  --trelvis-tg-left: calc(var(--trelvis-tg-safe-left) + var(--trelvis-tg-content-left));
  --trelvis-tg-control-top: var(--trelvis-tg-top);
}
html[data-theme="matrix-dark"] {
  --bg: #0d120d;
  --panel: #0d120d;
  --sidebar: #08170c;
  --col: #0d120d;
  --card: #141c15;
  --card-hover: #1a281c;
  --text: #b8ffca;
  --bright: #d8ffe2;
  --muted: #9bffb8;
  --accent: #1eff5a;
  --green: #1eff5a;
  --red: #ff7b80;
  --yellow: #d8ff76;
  --purple: #a8ffbe;
  --line: #28442f;
  --field: #141c15;
  --active: #18351f;
  --soft: #213827;
  --modal: #101711;
  --comment-field: #0d120d;
  --on-accent: #0d120d;
  --accent-rgb: 30, 255, 90;
  --column-heading: #79ff9b;
  --column-heading-weight: 650;
  --scroll-thumb: rgba(30,255,90,.26);
  --scroll-thumb-hover: rgba(30,255,90,.52);
  --ui-font: ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --ui-letter-spacing: .015em;
  --pig-filter: none;
  color-scheme: dark;
}

/* ---------- Сброс, типографика, скроллбары ---------- */
* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
html { height: 100%; overflow: hidden; background: var(--bg); }
body { height: var(--ui-scale-size); width: var(--ui-scale-size); }
body {
  background: var(--bg);
  color: var(--text);
  font: 14px/1.45 var(--ui-font);
  letter-spacing: var(--ui-letter-spacing);
  overscroll-behavior: none;
  /* Длинная ссылка или слово без пробелов переносится, а не вылезает вправо
     (вёрстка Аллы, 28.09): срабатывает только когда слово не влезает в строку. */
  overflow-wrap: break-word;
  transform: scale(var(--ui-scale));
  transform-origin: top left;
}
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input, textarea, select {
  font: inherit; color: var(--bright); background: var(--field);
  border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; outline: none; width: 100%;
  /* Поле во flex/grid-строке сжимается до родителя, а не держит свою ширину
     по умолчанию (~20 знаков) и не торчит за правый край телефона. */
  min-width: 0; max-width: 100%;
}
input:focus, textarea:focus, select:focus { border-color: var(--accent); }
a { color: var(--accent); text-decoration: none; }

/* Firefox получает системный thin; WebKit — точные пиксели ниже. */
* { scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) transparent; }
@supports selector(::-webkit-scrollbar) {
  /* Не даём стандартному `thin` перекрыть точные размеры в WKWebView/Chromium. */
  * { scrollbar-width: auto; scrollbar-color: auto; }
  *::-webkit-scrollbar { width: 5px; height: 5px; }
  *::-webkit-scrollbar-track,
  *::-webkit-scrollbar-corner { background: transparent; }
  *::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: 999px; }
  *::-webkit-scrollbar-thumb:hover,
  *::-webkit-scrollbar-thumb:active { background: var(--scroll-thumb-hover); }
  .col-cards::-webkit-scrollbar,
  .col-rems::-webkit-scrollbar { width: 4px; height: 4px; }
}

#app { display: flex; height: 100%; overflow: hidden; }

/* ---------- Сайдбар ---------- */
#sidebar {
  width: 264px; min-width: 264px; background: var(--sidebar);
  border-right: 1px solid var(--line); display: flex; flex-direction: column;
}
body.side-hidden #sidebar {
  width: 0 !important; min-width: 0 !important; overflow: hidden; border-right: 0;
}
#side-resizer {
  width: 9px; margin-left: -9px; cursor: col-resize; flex: none;
  position: relative; z-index: 5; touch-action: none;
}
#side-resizer::after {
  content: ""; position: absolute; inset: 0 auto 0 3px; width: 3px; border-radius: 3px;
}
#side-resizer:hover::after, body.split-resizing #side-resizer::after { background: rgba(var(--accent-rgb),.55); }
body.side-hidden #side-resizer { margin-left: 0; border-left: 1px solid var(--line); }
.side-head { display: none; }
/* Верх панели (трелвис 721/722): логотип + версия слева, поиск правее */
.side-search { padding: 12px 12px 8px; display: flex; align-items: center; gap: 7px; }
.side-search input { flex: 1; min-width: 0; }
html[data-theme="matrix-dark"] #search-input {
  background: #071009; border-color: #254f30; border-radius: 5px;
  color: #b8ffca; caret-color: #79ff9b; box-shadow: inset 0 0 0 1px rgba(121,255,155,.035);
  letter-spacing: .04em;
}
html[data-theme="matrix-dark"] #search-input:focus {
  border-color: #4d9a5f; box-shadow: inset 0 0 0 1px rgba(121,255,155,.08), 0 0 0 1px rgba(121,255,155,.08);
}
html[data-theme="matrix-dark"] #search-input::placeholder { color: #5f9270; }
#side-nav { flex: 1; overflow-y: auto; padding: 0 8px 8px; }
.side-pig-wrap {
  position: relative; flex: none; display: inline-flex; border-radius: 8px;
  outline: none;
}
.side-pig-wrap:focus-visible { box-shadow: 0 0 0 2px var(--accent); }
.side-pig {
  width: 32px; height: 32px; opacity: .94; border-radius: 9px; flex: none;
  object-fit: cover; filter: none; transition: opacity .15s ease, border-color .15s ease;
  border: 1px solid rgba(255,255,255,.12);
}
.side-pig[data-shape="round"] { border-radius: 50%; }
.side-pig-wrap:hover .side-pig { opacity: 1; border-color: rgba(255,255,255,.24); }
.sync-dot {
  position: absolute; right: -4px; bottom: -3px; width: 15px; height: 15px;
  border: 2px solid var(--sidebar); border-radius: 50%; background: var(--muted);
  color: var(--on-accent); display: grid; place-items: center; font: 900 9px/1 var(--ui-font);
}
.sync-dot::after { content: ""; }
.sync-dot.is-healthy { background: var(--green); box-shadow: none; }
.sync-dot.is-healthy::after { content: "✓"; }
.sync-dot.is-syncing { background: var(--yellow); animation: sync-pulse 1.2s ease-in-out infinite; }
.sync-dot.is-error, .sync-dot.is-stale, .sync-dot.is-never { background: var(--red); }
.sync-dot.is-error::after, .sync-dot.is-stale::after, .sync-dot.is-never::after { content: "!"; }
@keyframes sync-pulse { 50% { opacity: .42; transform: scale(.82); } }
.sync-summary {
  display: flex; align-items: center; gap: 8px;
  width: calc(100% - 16px); margin: 0 8px 9px; padding: 7px 10px;
  border: 1px solid var(--line); border-radius: 8px; text-align: left;
  color: var(--bright); background: rgba(var(--accent-rgb),.035);
}
.sync-summary:hover { background: var(--field); }
.sync-summary-copy { display: flex; flex: 1; min-width: 0; flex-direction: column; align-items: flex-start; gap: 1px; }
.sync-summary-copy b {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11.5px;
  font-weight: 700;
}
.sync-summary small { color: var(--muted); font-size: 10.5px; }
.sync-summary-close {
  flex: none; width: 22px; height: 22px; display: grid; place-items: center;
  border-radius: 6px; color: var(--muted); font-size: 16px;
}
.sync-summary-close:hover { color: var(--bright); background: var(--soft); }
.sync-summary.is-healthy { border-color: rgba(75,206,151,.32); }
.sync-summary.is-syncing { border-color: rgba(245,205,71,.42); }
.sync-summary.is-error, .sync-summary.is-stale, .sync-summary.is-never {
  border-color: rgba(248,113,104,.45);
}
.sync-status-grid {
  display: grid; grid-template-columns: auto 1fr; gap: 8px 14px; margin-top: 10px;
}
.sync-status-grid dt { color: var(--muted); }
.sync-status-grid dd { color: var(--bright); min-width: 0; overflow-wrap: anywhere; }
.sync-health { font-weight: 750; }
.sync-health.is-healthy { color: var(--green); }
.sync-health.is-syncing { color: var(--yellow); }
.sync-health.is-error, .sync-health.is-stale, .sync-health.is-never { color: var(--red); }
.sync-status-help {
  margin-top: 10px; padding: 10px 12px; border-radius: 8px;
  background: rgba(var(--accent-rgb),.08); color: var(--bright); line-height: 1.5;
}
.nav-item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 5px 10px; border-radius: 8px; color: var(--text); text-align: left; font-size: 14px;
}
.nav-item:hover { background: var(--field); }
.nav-item.active { background: var(--active); color: var(--accent); }
/* Карточку можно бросить прямо на имя доски (трелвис 5238): доска под пальцем
   подсвечивается как активная и обводится акцентом — видно, куда упадёт. */
.nav-item.nav-drop {
  background: var(--active); color: var(--accent);
  box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb),.85);
}
.nav-item .nv-emoji { width: 20px; text-align: center; flex: none; }
html[data-emoji="hidden"] .ava-emoji,
html[data-emoji="hidden"] .ava-img,
html[data-emoji="hidden"] .card-avatar,
html[data-emoji="hidden"] .comment .c-emoji,
html[data-emoji="hidden"] .decorative-emoji,
html[data-emoji="hidden"] .col-fixed-mark,
html[data-emoji="hidden"] .nav-item .nv-emoji:not(.project-dot) {
  display: none !important;
}
/* Счётчик уведомлений — спокойный, читаемый (без кричащего красного) */
.nv-count {
  margin-left: auto; background: var(--soft); color: var(--bright);
  font-size: 11px; font-weight: 700; border-radius: 9px; padding: 1px 7px;
}
/* Группы панели: крупный заголовок, сворачивание, плотный список */
.nav-group { margin-top: 12px; }
.nav-title { display: flex; align-items: center; padding: 0 2px; }
.nav-fold {
  display: flex; align-items: center; gap: 6px; flex: 1; min-width: 0;
  padding: 5px 8px; border-radius: 8px;
  color: var(--bright); font-size: 12.5px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .9px; text-align: left;
}
.nav-fold:hover { background: var(--field); }
.fold-arrow {
  color: var(--muted); font-size: 15px; line-height: 1; width: 18px; min-height: 24px;
  display: inline-flex; align-items: center; justify-content: center; flex: none;
}
.nav-title-act { display: flex; align-items: center; gap: 2px; }
.nav-group.closed .nav-sub { display: none; }
.nav-sub { padding-left: 4px; }
/* Строка человека: имя во всю ширину, ⚙/+ появляются поверх неё при наведении. */
.nav-row { display: flex; align-items: center; gap: 2px; position: relative; }
.nav-row .nav-item { flex: 1; min-width: 0; }
.nav-person { min-height: 34px; white-space: nowrap; }
.nav-person .ava-img { margin-right: 0; }
.nav-person-name {
  flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.nav-row-acts {
  position: absolute; z-index: 2; top: 50%; right: 2px; transform: translateY(-50%);
  display: flex; align-items: center; gap: 2px;
  padding-left: 6px; border-radius: 6px; background: var(--field);
  opacity: 0; pointer-events: none; transition: opacity .12s;
}
.nav-row:hover .nav-row-acts, .nav-row:focus-within .nav-row-acts { opacity: 1; pointer-events: auto; }
.nav-row:hover .nav-person, .nav-row:focus-within .nav-person {
  padding-right: 58px; background: var(--field);
}
/* На тач-экране наведения не бывает, а `pointer-events: none` не пропускает
   тап — значит и `:focus-within` недостижим. Других входов в «Настройки
   пространства» и «Новая доска» в интерфейсе нет, поэтому с телефона завести
   доску человеку было нечем (задача 1741). Показываем кнопки постоянно. */
@media (hover: none) {
  .nav-row-acts { opacity: 1; pointer-events: auto; }
  .nav-row .nav-person { padding-right: 58px; }
  .nav-row .nav-act, .nav-title .nav-act { opacity: 1; }
}
.nav-row-acts .nav-act { opacity: 1; }
.nav-act {
  color: var(--muted); font-size: 14px; padding: 3px 6px; border-radius: 6px;
  flex: none; opacity: 0; transition: opacity .12s;
}
.nav-row:hover .nav-act, .nav-title:hover .nav-act, .nav-act.on { opacity: 1; }
.nav-act:hover { color: var(--bright); background: var(--field); }
.nav-subhead {
  /* Ярче заголовки категорий (трелвис 832): читаются с одного взгляда */
  display: flex; align-items: center; gap: 9px; flex: 1; min-width: 0;
  padding: 7px 10px 5px; color: var(--bright); font-size: 12.5px; font-weight: 800;
  letter-spacing: .06em;
}
.nav-indent { padding-left: 26px; }
/* Дерево «Команды»: стрелка-раскрывашка у человека + отступ его проектов */
.nav-fold-mini {
  flex: none; width: 28px; min-height: 30px; padding: 4px 0; color: var(--muted);
  font-size: 15px; line-height: 1; text-align: center; border-radius: 7px;
}
.nav-fold-mini:hover { color: var(--bright); background: var(--field); }
.nav-fold-empty { pointer-events: none; }
.nav-indent2 { margin-left: 28px; width: calc(100% - 28px); }
.nav-dim { color: var(--muted); }
.nav-hint { color: var(--muted); font-size: 12px; padding: 3px 10px; }
.nav-board { font-size: 14px; }
.nav-project-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-metrics { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; flex: none; }
.badge {
  background: var(--soft); color: var(--bright); font-size: 10.5px; font-weight: 700;
  border-radius: 9px; padding: 1px 6px; margin-left: 4px; vertical-align: top;
}
.hidden { display: none !important; }

/* ---------- Топбар ---------- */
#main {
  position: relative; flex: 1; display: flex; flex-direction: column; min-width: 0;
  background-color: var(--bg); background-size: cover; background-position: center;
  transition: background-image .18s ease;
}
#main.board-bg-active { background-image: var(--active-board-bg); }
#topbar {
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
  border-bottom: 1px solid var(--line); background: var(--bg); min-height: 52px;
}
#crumbs { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; overflow: hidden; }
#crumbs .crumb-title { font-size: 16px; font-weight: 700; color: var(--bright); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#crumbs .crumb-sub { color: var(--muted); font-size: 13px; white-space: nowrap; }
.top-actions { display: flex; align-items: center; gap: 8px; }
.inspector-toggle { flex: none; }
.icon-btn { font-size: 17px; padding: 6px 9px; border-radius: 8px; position: relative; }
.icon-btn:hover { background: var(--field); }
.icon-btn.on { color: var(--accent); background: var(--active); }
/* Значок бургера стоит ровно по центру своей кнопки (трелвис 1912): у текстовой
   кнопки глиф ☰ садился на базовую линию и читался ниже середины. */
.burger {
  display: grid; place-items: center; width: 36px; height: 36px;
  padding: 0; font-size: 18px; line-height: 1;
}
/* Аварийный бургер (трелвис 1896): экраны, которые прячут верхнюю строку целиком
   («Мы с человеком»), обязаны сохранить вход в меню. Кнопка лежит поверх
   содержимого слева сверху, с учётом чёлки и панели Telegram. */
.floating-burger {
  position: fixed; z-index: 320;
  top: calc(21px + var(--trelvis-tg-control-top, 0px));
  left: calc(14px + env(safe-area-inset-left, 0px));
  width: 40px; height: 40px; border-radius: 13px;
  color: var(--bright); font-size: 23px;
  border: 1px solid var(--line); background: var(--panel);
  box-shadow: 0 6px 18px rgba(0,0,0,.32);
}
.floating-burger.hidden { display: none; }

/* Персональный масштаб всего интерфейса (трелвис 870/949). Подменю держится,
   пока курсор внутри или любой его элемент в фокусе. */
.scale-control { position: relative; display: flex; align-items: center; }
.scale-toggle { min-width: 53px; font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums; }
.scale-popover {
  position: fixed; z-index: 380; top: 0; left: 0;
  display: flex; align-items: center; gap: 7px; width: 260px;
  padding: 9px 10px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--modal); box-shadow: 0 10px 28px rgba(0,0,0,.36);
  opacity: 0; visibility: hidden; pointer-events: none;
  transform-origin: top left; transition: opacity .12s, visibility .12s;
}
.scale-popover.open {
  opacity: 1; visibility: visible; pointer-events: auto;
}
.scale-step, .scale-reset {
  flex: none; min-width: 30px; min-height: 30px; border-radius: 7px;
  background: var(--field); color: var(--bright); font-weight: 800;
}
.scale-step:hover, .scale-reset:hover { background: var(--active); color: var(--accent); }
.scale-reset { min-width: 43px; padding: 0 6px; font-size: 11px; }
#scale-range { min-width: 0; padding: 0; border: 0; accent-color: var(--accent); }

#me-chip { display: flex; align-items: center; gap: 6px; font-weight: 600; color: var(--bright);
  background: var(--field); padding: 5px 11px; border-radius: 16px; font-size: 13px; white-space: nowrap; }
#bell-badge { position: absolute; top: 0; right: 0; }

/* ---------- Контент/доска ---------- */
#content { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.app-loader {
  flex: 1; min-height: 0; display: grid; place-content: center; justify-items: center;
  gap: 13px; padding: 24px; text-align: center; color: var(--text);
}
.app-loader-error { min-height: 100vh; }
.app-loader-avatar { display: none; }
.app-loader-avatar.ready {
  width: 74px; height: 74px; display: grid; place-items: center; overflow: hidden;
  border-radius: 24px;
  box-shadow: 0 14px 38px rgba(0,0,0,.34); animation: loader-breathe 1.65s ease-in-out infinite;
}
.app-loader-avatar .app-loader-profile { width: 100%; height: 100%; object-fit: cover; font-size: 48px; }
.app-loader-copy { display: grid; gap: 2px; }
.app-loader-copy strong { color: var(--bright); font-size: 14px; }
.app-loader-copy span { color: var(--muted); font-size: 11.5px; }
.app-loader-track { width: 132px; height: 3px; overflow: hidden; border-radius: 999px; background: rgba(255,255,255,.10); }
.app-loader-track span { display: block; width: 42%; height: 100%; border-radius: inherit; background: var(--accent); animation: loader-track 1.15s ease-in-out infinite; }
@keyframes loader-breathe { 50% { transform: translateY(-3px); filter: brightness(1.08); } }
@keyframes loader-track { from { transform: translateX(-110%); } to { transform: translateX(345%); } }
.board-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.board-stage { flex: 1; min-width: 0; min-height: 0; display: flex; overflow: hidden; }
.board-stage > .board-wrap { min-width: 0; }

/* ---------- Правая панель (инспектор) ---------- */
.board-inspector { display: none; }
/* Ресайзер живёт ровно столько же, сколько сама панель (трелвис 2746): при
   закрытой панели он оставался пустой вертикальной полосой 9px с линией у
   правого края — «только место занимает». Во время перетаскивания полосу
   держим на экране, иначе схлопывание панели под пальцем рвёт драг. */
.board-inspector-resizer { display: none; }
.board-stage.inspector-open .board-inspector { display: flex; }
.board-inspector-resizer {
  width: 9px; flex: none; cursor: col-resize; touch-action: none; position: relative; z-index: 5;
}
.board-stage.inspector-open .board-inspector-resizer { display: block; margin-right: -9px; }
body.split-resizing .board-inspector-resizer { display: block; }
.board-inspector-resizer::after {
  content: ""; position: absolute; top: 0; bottom: 0; right: 0; width: 1px;
  background: var(--line); border-radius: 3px;
}
.board-stage.inspector-open .board-inspector-resizer::after { left: 0; right: auto; }
.ci-resizer::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: 3px; width: 3px; border-radius: 3px;
}
.board-inspector-resizer:hover::after, .ci-resizer:hover::after, body.split-resizing .board-inspector-resizer::after,
body.split-resizing .ci-resizer::after { width: 3px; background: rgba(var(--accent-rgb),.55); }
.board-inspector {
  width: var(--inspector-w,410px); flex: none; flex-direction: column; gap: 13px; padding: 13px 15px;
  overflow-y: auto; background: var(--sidebar); min-width: 0;
}
/* Полноценная карточка внутри правой панели (трелвис 1849): панель монтирует тот
   же рендер, что и модалка, поэтому снимает с него оконные повадки — ширину,
   тень, скругления и внешние поля. Сокращённого превью с кнопкой «Открыть
   полностью» больше нет: оно неизбежно расходилось с настоящей карточкой. */
.board-inspector.has-card { padding: 0; gap: 0; }
.board-inspector-card { flex: 1; min-height: 0; display: block; }
.board-inspector .board-inspector-card > .modal {
  width: 100%; max-width: none; margin: 0; padding: 0; overflow: visible;
  border: 0; border-radius: 0; box-shadow: none; background: transparent;
}
.board-inspector .card-detail-shell {
  --shell-px: 14px; --shell-py: 12px; padding-bottom: 20px;
}
/* В узкой панели длинные ряды переносятся, а медиа не распирает её вширь. */
.board-inspector .card-detail-topbar { flex-wrap: wrap; }
/* Панель показывает карточку без обводок (трелвис 1913): в узком столбце рамка
   вокруг чек-листа, рамка вокруг фото и рамка вокруг комментариев съедали
   ширину и превращали карточку в стопку коробок. Единственная рамка, которая
   остаётся, — у кнопок: иначе не видно, что на них жмут. */
.board-inspector .card-content-section,
.board-inspector .comments-box {
  margin: 18px 0; padding: 0; border: 0; border-radius: 0; background: transparent;
}
.board-inspector .card-brief,
.board-inspector .card-comments-summary,
.board-inspector .card-comments-section .comments-content,
.board-inspector .comments-content { padding-left: 0; padding-right: 0; }
/* В узкой панели заголовок чуть мельче модалки: 26px там съедает четыре строки. */
.board-inspector .card-detail-modal .card-title-input { font-size: 22px; }
.board-inspector .card-media-frame { border: 0; border-radius: 12px; }
.board-inspector .card-media-section.card-media-empty { margin-top: 0; }
.board-inspector .card-media-item, .board-inspector .card-media-stage img { max-width: 100%; }
/* Пока карточка летит с сервера — заголовок и серые полосы вместо пустоты. */
.board-inspector-stub { display: grid; gap: 10px; }
.board-inspector-stub .ui-close { justify-self: start; }
.board-inspector-head { display: flex; gap: 9px; align-items: flex-start; justify-content: space-between; }
/* Свой крестик внутри панели (трелвис 1852): закрывать её издалека, кнопкой в
   верхней строке, было неочевидно. */
.board-inspector-close {
  flex: none; width: 30px; height: 30px; display: grid; place-items: center;
  border-radius: 10px; color: var(--muted); font-size: 16px;
}
.board-inspector-close:hover { color: var(--bright); background: var(--soft); }
/* Кругляшок выполнения перед заголовком, как на карточке доски (трелвис 1848). */
.board-inspector-title-row { display: flex; align-items: flex-start; gap: 10px; }
.board-inspector-title-row .card-check.big { margin-top: 0; }
.board-inspector h2 { margin: -2px 0 0; font-size: 20px; color: var(--bright); line-height: 1.25; }
.board-inspector-project { display: flex; align-items: center; gap: 7px; min-width: 0; color: var(--bright); font-size: 16px; }
.board-inspector-project b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board-inspector-task-number { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.board-inspector-meta { display: flex; align-items: center; justify-content: space-between; gap: 12px; color: var(--muted); font-size: 11.5px; }
.board-inspector-sender, .board-inspector-column { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board-inspector-column { margin-left: auto; text-align: right; }
.board-inspector-control {
  width: fit-content; color: var(--red); border: 1px solid rgba(248,113,104,.48);
  background: rgba(248,113,104,.07); border-radius: 8px; padding: 5px 8px; font-size: 11.5px;
}
.board-inspector-description { white-space: pre-wrap; overflow-wrap: anywhere; color: var(--text); line-height: 1.5; }
.board-inspector-description small { display: block; color: var(--muted); margin-bottom: 4px; }
.project-inspector-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.project-inspector-status {
  width: fit-content; border-radius: 7px; padding: 3px 7px; background: var(--soft);
  color: var(--muted); font-size: 11px; font-weight: 800; text-transform: uppercase;
}
/* Колонки доски нейронок стоят в фиксированном порядке стадий и не таскаются
   мышью — курсор «схватить» на их шапке врал (трелвис 2235). */

/* ---------- Доска нейронок: статусы и сводка задачи ---------- */
.board[data-project] .col-head { cursor: default; }
.user-queue { color: #8f8ff3; }
.user-working { color: #fb9a4c; }
.user-question { color: var(--yellow); }
.user-blocked { color: var(--red); }
.user-review { color: var(--yellow); }
/* Отказ `👾 Элвиса` (3111): приглушённый серый — колонка закрытая, но не зелёная. */
.user-cancelled { color: var(--cancelled); }
.user-done { color: var(--green); }
.ktask-summary { display: grid; gap: 10px; }
.ktask-summary-block {
  border-left: 2px solid var(--line); padding: 1px 0 1px 10px; min-width: 0;
}
.ktask-summary-block.result { border-left-color: rgba(87,157,255,.65); }
.ktask-summary-block.verify { border-left-color: rgba(245,205,71,.72); }
.ktask-summary-label {
  margin-bottom: 4px; color: var(--muted); font-size: 10.5px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .055em;
}
.ktask-summary ul { display: grid; gap: 3px; margin: 0; padding-left: 17px; }
.ktask-summary li { color: var(--text); font-size: 12.5px; line-height: 1.38; overflow-wrap: anywhere; }
.project-inspector-question { display: grid; gap: 7px; color: var(--text); }
.project-inspector-question textarea { min-height: 58px; resize: vertical; background: var(--comment-field); }
.board-inspector-comments { display: grid; gap: 4px; }
.board-inspector-comment-section { display: grid; gap: 8px; margin-top: 4px; }
.board-inspector-comment-section textarea { min-height: 68px; resize: vertical; background: var(--comment-field); }
.board-inspector-comment-section .btn { justify-self: start; }
.board-inspector-last-comment {
  align-self: flex-end; max-width: 90%; margin-top: auto; color: var(--muted); font-size: 10.5px;
  line-height: 1.35; text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.board-inspector-last-comment:hover { color: var(--bright); }

/* ---------- Строка доски и общие кнопки ---------- */
.board-bar { display: flex; align-items: center; gap: 8px; padding: 10px 14px 0; flex-wrap: wrap; }
.board-bar .spacer { flex: 1; }
.bb-mobile-more { display: none; }
.btn {
  background: var(--field); border: 1px solid var(--line); padding: 7px 12px;
  border-radius: 8px; font-size: 13px; color: var(--bright); white-space: nowrap;
}
#me-chip.clickable { cursor: pointer; padding: 5px 8px; border-radius: 18px; }
#me-chip.clickable:hover { background: rgba(255,255,255,.08); }
.view-eye { font-size: 12px; color: #f5cd47; }
#view-as-bar {
  min-height: 36px; padding: 6px 14px; background: #3d2e05; color: #f5cd47;
  border-bottom: 1px solid #7a5d12; display: flex; gap: 12px; align-items: center;
  justify-content: center; font-size: 12.5px;
}
#view-as-bar button { color: #101214; background: #f5cd47; border-radius: 7px; padding: 5px 10px; font-weight: 800; }
body.view-as #quick-bar, body.view-as #quick-compose, body.view-as .nav-act { display: none !important; }
.btn:hover { background: var(--card-hover); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 700; }
.btn.danger { color: var(--red); border-color: #5b3536; }
.btn.small { padding: 4px 9px; font-size: 12px; }

/* ---------- Полотно доски, канвас, скелет ---------- */
.board {
  --board-zoom: 1; flex: 1; min-height: 0; display: block;
  overflow-x: auto; overflow-y: hidden; padding: var(--board-pad-top, 12px) 14px 16px;
  scroll-padding: 14px; touch-action: pan-x pan-y; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.board-canvas {
  display: flex; gap: 12px; align-items: flex-start; min-width: 100%; min-height: 100%;
  width: max-content; zoom: var(--board-zoom); transform-origin: top left;
}
.board.board-overview { overflow-y: auto; }
.board.board-overview .board-canvas {
  width: var(--board-overview-width, 200%); min-width: 0; min-height: max-content;
  flex-wrap: wrap; align-content: flex-start; gap: 26px; padding: 8px 8px 28px;
}
.board.board-overview.board-dense .board-canvas { row-gap: 18px; }
/* Зона «Добавить колонку» всегда последняя. В плотном режиме колонки
   расставляются по высоте через order, а терминал без order уезжал в середину
   и читался как «пустая полоса между колонками» (трелвис 1717). */
.board.board-dense .add-col { order: 9999; }
.board.board-overview .column {
  max-height: none; border: 1px solid rgba(255,255,255,.15);
  box-shadow: 0 10px 28px rgba(0,0,0,.28);
}
.board.board-overview .col-cards,
.board.board-overview .col-rems { flex: none; overflow-y: visible; }
.column {
  background: var(--col); border-radius: var(--radius);
  width: var(--col-w, 276px); min-width: var(--col-w, 276px);
  max-height: 100%; display: flex; flex-direction: column; position: relative;
  transition: width .18s ease, min-width .18s ease, box-shadow .18s ease;
}
/* Стандартный режим: даём канвасу детерминированную высоту. Иначе процентный
   max-height колонки не резолвится (родитель авто-высоты), колонка перерастает
   борд, а он режет низ (overflow-y:hidden) — вертикальной прокрутки внутри
   колонки нет. С фиксированной высотой список карточек скроллится сам (трелвис 1715). */
body:not(.board-scroll-all) .board.board-standard .board-canvas {
  height: 100%; min-height: 0;
}
/* Скелет тяжёлой доски (трелвис 1903): пока ответ сервера в пути, место занимают
   серые колонки нужного размера, а не пустой экран. */
.board.board-skeleton { overflow: hidden; }
.sk-column {
  flex: none; width: var(--col-w, 276px); min-width: var(--col-w, 276px);
  min-height: min(72vh, 700px);
  display: flex; flex-direction: column; gap: 8px; padding: 10px;
  background: var(--col); border-radius: var(--radius);
}
.sk-head, .sk-card {
  border-radius: 8px; background: rgba(255,255,255,.07);
  animation: sk-pulse 1.25s ease-in-out infinite;
}
.sk-head { height: 18px; width: 62%; margin-bottom: 4px; }
.sk-card { height: 48px; }
.sk-card.tall { height: 150px; }
.sk-column:nth-child(2n) .sk-card { animation-delay: .18s; }
.sk-column:nth-child(3n) .sk-card { animation-delay: .35s; }
@keyframes sk-pulse { 0%, 100% { opacity: .45; } 50% { opacity: .9; } }

/* content-visibility: auto здесь убран (трелвис 1903). Он экономил отрисовку, но
   в webview Telegram поверх масштабированного канваса (`zoom`) далёкие колонки
   оставались пустыми: быстрая прокрутка вправо-влево показывала голое место
   вместо карточек. Вместо него — обычная изоляция раскладки: она ничего не
   прячет, но не даёт колонке пересчитывать соседей. `paint` не берём: он
   обрезал бы ручку ширины, торчащую за правым краем колонки. */
.board .column { contain: layout style; }
/* Подсветка выбранной колонки убрана целиком (трелвис 1837): быстрая задача
   всегда уходит во «Входящие», и отмечать цель больше нечего. */

/* ---------- Колонка: свёрнутый вид, шапка, ручка ширины ---------- */
/* Свёрнутая колонка — узкая вертикальная полоса, как в Trello (трелвис 1791):
   название читается сверху вниз, в ширину уходит меньше 50 px. */
.column.collapsed {
  width: 46px !important; min-width: 46px !important;
  min-height: 130px !important; max-height: min(62vh, 560px) !important;
  align-self: flex-start; overflow: hidden; box-shadow: none !important;
}
/* Свёрнутая колонка — это по сути заголовок, поэтому она липнет к верху и не
   уезжает вместе со списком при вертикальной прокрутке (трелвис 1835). Только в
   стандартном режиме: в раскладке рядами липкие полосы из разных рядов
   наезжали друг на друга в нечитаемую кашу (трелвис 1875). */
.board.board-standard .column.collapsed {
  position: sticky; top: 0; z-index: 5;
}
/* В режиме одной колонки свёрнутые «Меня контролят» и «Я контролю» ведут себя
   как все остальные: обычная горизонтальная строка-заголовок, без вертикальной
   подписи и без липкости (трелвис 1877). */
.board.board-overview .column.collapsed {
  width: var(--col-w, 276px) !important; min-width: var(--col-w, 276px) !important;
  min-height: 0 !important; max-height: none !important;
}
.board.board-overview .column.collapsed .col-head {
  flex-direction: row; align-items: center; justify-content: flex-start;
  padding: 10px 10px 7px 14px; gap: 6px;
}
.board.board-overview .column.collapsed .col-title {
  writing-mode: horizontal-tb; max-height: none; overflow: hidden;
}
.board.board-overview .column.collapsed .col-count { writing-mode: horizontal-tb; }
.board.board-overview .column.collapsed .col-menu-btn { margin-left: auto; padding: 2px 8px; }
.column.collapsed .col-head {
  flex: none; min-height: 0; flex-direction: column; align-items: center;
  justify-content: flex-start; padding: 10px 4px 8px; margin: 0; border: 0;
  cursor: pointer; gap: 8px;
}
/* Высоту полосы задаёт само название: оно растёт вниз, пока помещается в
   ограничение колонки, и только потом обрезается. */
.column.collapsed .col-title {
  writing-mode: vertical-rl; text-orientation: mixed; flex: none;
  min-height: 0; max-height: calc(min(62vh, 560px) - 66px); overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis;
}
.column.collapsed .col-count { order: initial; writing-mode: vertical-rl; }
.column.collapsed .col-menu-btn { order: initial; margin: 0; padding: 4px 3px; }
.column.collapsed .col-fixed-mark,
.column.collapsed .col-cards,
.column.collapsed .col-rems,
.column.collapsed .col-foot,
.column.collapsed .col-resizer { display: none; }
/* Правая граница колонки: тянешь — все колонки уже/шире разом */
.col-resizer {
  position: absolute; top: 0; right: -7px; width: 12px; height: 100%;
  cursor: col-resize; z-index: 4; touch-action: none;
}
.col-resizer:hover, body.col-resizing .col-resizer {
  background: linear-gradient(90deg, transparent 4px, rgba(var(--accent-rgb),.30) 4px, rgba(var(--accent-rgb),.30) 8px, transparent 8px);
}
.col-head {
  /* Заголовки колонок чуть крупнее и с подчёркиванием-разделителем (трелвис 832) */
  display: flex; align-items: center; gap: 6px; padding: 10px 10px 7px 14px;
  font-weight: var(--column-heading-weight); color: var(--column-heading); font-size: 14px;
  border-bottom: 1px solid var(--line); margin-bottom: 4px;
  cursor: grab; user-select: none; -webkit-user-select: none;
}
.col-head .col-count { color: var(--muted); font-weight: 400; font-size: 12px; }
/* Те же «•••», что и везде (трелвис 1918): раньше здесь стоял одиночный глиф «⋯»
   мелким кеглем — точки сливались в чёрточку и кнопку не было видно. */
.col-head .col-menu-btn {
  margin-left: auto; color: var(--muted); border-radius: 6px; padding: 2px 7px;
  font-size: 13px; letter-spacing: .5px; line-height: 1;
}
.col-head .col-menu-btn:hover { background: var(--field); color: var(--bright); }
html[data-theme="matrix-dark"] .col-head .col-count,
html[data-theme="matrix-dark"] .col-head .col-menu-btn { color: var(--column-heading); }
.col-fixed-mark { font-size: 11px; }
.col-cards { flex: 1; overflow-y: auto; padding: 4px 8px; display: flex; flex-direction: column; gap: var(--card-gap, 6px); min-height: 8px; }
.col-foot { padding: 6px 8px 10px; }

/* ---------- Сквозная прокрутка и липкие шапки ---------- */
/* Просвет над липкими шапками — это поле ПЕРЕД доской, а не зона внутри её
   прокрутки (трелвис 1965, третья итерация). Шапки липнут на top: 0, то есть
   ровно на верхнем крае скролл-порта: всё, что уезжает выше, обрезает сам
   браузер на композиторе — синхронно с прокруткой, без JS и без гонки кадров.
   Прежняя схема «липнем на 10px ниже + clip-path по переменным из JS» на iOS
   отставала на кадр, и карточки мелькали в просвете над заголовком. */
body.board-scroll-all .board {
  --board-pad-top: 0px; overflow-y: auto; scrollbar-gutter: stable;
  margin-top: calc(8px + var(--board-head-gap, 10px));
  scrollbar-width: auto; scrollbar-color: var(--board-scroll-thumb) var(--board-scroll-track);
}
body.board-scroll-all .board-bar { padding-bottom: 8px; }
@supports selector(::-webkit-scrollbar) {
  body.board-scroll-all .board::-webkit-scrollbar { width: 10px; height: 10px; }
  body.board-scroll-all .board::-webkit-scrollbar-track {
    background: var(--board-scroll-track); border-radius: 999px;
  }
  body.board-scroll-all .board::-webkit-scrollbar-thumb {
    min-width: 40px; min-height: 40px; border: 2px solid transparent;
    background: var(--board-scroll-thumb); background-clip: padding-box; border-radius: 999px;
  }
  body.board-scroll-all .board::-webkit-scrollbar-thumb:hover,
  body.board-scroll-all .board::-webkit-scrollbar-thumb:active {
    background: var(--board-scroll-thumb-hover); background-clip: padding-box;
  }
  body.board-scroll-all .board::-webkit-scrollbar-corner { background: var(--board-scroll-track); }
  body.board-scroll-all .board::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
}
.board-scroll-all .column { max-height: none; background: transparent; }
/* Колонка обрезает своё содержимое по скруглению (трелвис 1917): под липкой
   шапкой карточки больше не выглядывают в вырезах верхних углов. */
.board-scroll-all .column { overflow: clip; }
/* Вырезы круглых углов липкой шапки закрываются самим состоянием, а не
   вычислениями (трелвис 2480). Пока колонка стоит на месте, углы скруглены и за
   ними фон доски — так и задумано. Как только колонка уехала верхом за кромку
   прокрутки, наблюдатель ставит шапке `stuck`, и вырезов просто не остаётся:
   верх шапки становится прямым, обрезать нечего.

   Здесь раньше стоял `clip-path: inset(--board-scroll-top - --col-top)`. Две
   переменные из JS — одна с прокрутки, другая с раскладки — расходились в
   webview Telegram (прокрутка меняется и без события scroll), и колонка
   срезалась целиком: на телефоне от неё оставалась полоска. Возвращать эту
   схему нельзя, сколько бы наблюдателей её ни страховало.
   Само правило `stuck` стоит в конце файла: телефонные правила ленты идут
   позже и с той же специфичностью перебили бы его здесь. */
.board-scroll-all .column.collapsed { min-height: 0; }
.board-scroll-all .col-cards,
.board-scroll-all .col-rems { flex: none; overflow-y: visible; }
.board-scroll-all .column > .col-head,
.board-scroll-all .column > .col-cards,
.board-scroll-all .column > .col-rems,
.board-scroll-all .column > .col-foot { background: var(--col); }
.board-scroll-all .col-cards { padding-top: 8px; }
.board-scroll-all .col-rems { padding-top: 4px; }
.board-scroll-all .col-foot { border-radius: 0 0 var(--radius) var(--radius); }
/* Ручка ширины уходит внутрь колонки: снаружи её срезал бы `overflow: clip`. */
.board-scroll-all .col-resizer { height: var(--column-surface-height, 100%); right: 0; }

/* ---------- Окна настроек: раскладки, папки, уведомления, отчёт ---------- */
.theme-owner-chip {
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 9px;
  border: 1px solid var(--line); border-radius: 999px; color: var(--muted);
  background: color-mix(in srgb, var(--field) 82%, transparent); font-size: 12px;
}
.install-app-button { color: var(--bright); }
.install-app-help { display: grid; grid-template-columns: 52px 1fr; gap: 12px; align-items: center; }
.install-app-help p { margin: 0 0 4px; line-height: 1.45; }
.install-app-help small { color: var(--muted); }
.install-app-icon {
  display: grid; place-items: center; width: 48px; height: 48px; border-radius: 16px;
  background: var(--accent); color: #08120a; font-size: 26px; font-weight: 800;
}
.page.task-report-page { width: 100%; max-width: 1180px; min-width: 0; margin: 0 auto; }
.layout-preset-link { justify-content: flex-start; margin: 10px 0 2px; }
.layout-preset-reason { color: var(--muted); font-size: 12px; margin-bottom: 10px; }
.layout-preset-list { display: grid; gap: 7px; margin-bottom: 12px; }
.layout-preset-row { display: grid; grid-template-columns: 1fr 38px; gap: 6px; }
.layout-preset-apply { display: flex; justify-content: space-between; align-items: center; gap: 12px; text-align: left; padding: 10px 12px; border: 1px solid var(--line); border-radius: 11px; background: var(--field); color: var(--text); }
.layout-preset-apply small { color: var(--muted); }
.layout-preset-delete { border: 1px solid var(--line); border-radius: 11px; background: var(--field); color: var(--muted); font-size: 20px; }
.layout-auto-row { display: grid; grid-template-columns: 1fr minmax(170px,1fr); gap: 10px; align-items: center; margin: 7px 0; }
.project-folder-row { padding-left: 14px; }
.project-folder-title { font-weight: 700; }
.folder-editor-list { display: grid; gap: 5px; max-height: min(52vh,520px); overflow: auto; margin: 7px 0 14px; }
.folder-editor-item { display: flex; align-items: center; gap: 8px; min-height: 42px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 10px; background: var(--field); }
.folder-editor-item label { display: flex; align-items: center; gap: 9px; flex: 1; min-width: 0; }
.folder-editor-item label span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.folder-order-actions { display: flex; gap: 3px; }
.folder-order-actions button { width: 32px; height: 30px; border-radius: 8px; color: var(--muted); background: transparent; border: 1px solid var(--line); }
.native-notification-toggle { display: flex; align-items: flex-start; gap: 10px; padding: 10px 0; }
.native-notification-toggle span { display: grid; gap: 3px; }
.native-notification-toggle small { color: var(--muted); }
.native-notification-projects { display: grid; grid-template-columns: 1fr 1fr; gap: 5px 12px; max-height: 260px; overflow: auto; }
.native-notification-project { display: flex; gap: 8px; align-items: center; padding: 5px 0; }
.native-notification-state { margin: 14px 0 8px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 10px; color: var(--muted); }
.native-notification-state.is-authorized { color: var(--success); }
.native-notification-state.is-denied { color: var(--danger); }
@media (max-width: 620px) { .native-notification-projects { grid-template-columns: 1fr; } }
.task-report-head { display: flex; align-items: end; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.task-report-head h2 { margin: 0 0 3px; }
.task-report-head span { color: var(--muted); font-size: 13px; }
.task-report-filters { display: grid; grid-template-columns: minmax(180px,2fr) repeat(4,minmax(120px,1fr)); gap: 8px; margin-bottom: 14px; }
.task-report-filters input,.task-report-filters select { min-width: 0; }
.task-report-row { border: 1px solid var(--line); border-radius: 12px; background: var(--col); margin-bottom: 7px; overflow: hidden; }
.task-report-row summary { display: grid; grid-template-columns: 68px minmax(180px,1fr) minmax(120px,.45fr) 120px; gap: 10px; align-items: center; padding: 11px 13px; cursor: pointer; list-style: none; }
.task-report-row summary::-webkit-details-marker { display: none; }
.task-report-id,.task-report-status { color: var(--muted); font-size: 12px; }
.task-report-title { font-weight: 700; }
.task-report-project { color: var(--project-color); font-size: 12px; }
.task-report-detail { display: flex; align-items: center; gap: 12px; padding: 0 13px 13px 81px; color: var(--muted); }
.task-report-detail p { flex: 1; margin: 0; color: var(--text); }
@media (max-width: 760px) {
  .task-report-filters { grid-template-columns: 1fr 1fr; }
  .task-report-filters input { grid-column: 1 / -1; }
  .task-report-row summary { grid-template-columns: 56px 1fr; }
  .task-report-project,.task-report-status { grid-column: 2; }
  .task-report-detail { align-items: flex-start; flex-direction: column; padding-left: 69px; }
}
/* Шапка колонки при сквозной прокрутке снова липкая (трелвис 1917): название
   колонки видно всегда, а список карточек уезжает под него. Просвет в вырезах
   скруглённых углов (из-за него шапку когда-то отлепили) закрыт иначе — сама
   колонка обрезает содержимое по своей скруглённой форме через `overflow:
   clip`. Именно clip, а не hidden: hidden сделал бы колонку scrollport и убил
   бы липкость. */
.board-scroll-all .col-head {
  position: sticky; top: 0; z-index: 6; flex: none; margin-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  transform: none; -webkit-clip-path: none; clip-path: none;
}
/* Служебная подпись доски и полоска прогресса убраны из широкой шапки
   (трелвис 1854): «доска сотрудника 4/220» ничего не решает, а место занимает. */
.board-bar .board-kind-note, .board-bar .board-progress { display: none; }

/* Шапка доски в одну строку (трелвис 1853). Строка быстрой задачи переехала
   внутрь верхней панели, поэтому теряет собственный фон, границу и отступы, а
   отдельный ряд действий доски скрывается: те же пункты живут в «•••». */
body.header-one-row #quick-bar {
  flex: 1; min-width: 0; min-height: 0; padding: 0;
  border-bottom: 0; background: transparent;
}
body.header-one-row #topbar { gap: 8px; }
body.header-one-row #crumbs { flex: none; }
body.header-one-row.quick-entry-visible .board-bar { display: none; }
body.header-one-row.quick-entry-visible .board { padding-top: 10px; }
/* В сквозной прокрутке этот отступ — тоже поле перед доской, не зона внутри
   прокрутки: иначе карточки уезжали бы в него над липкими шапками. */
body.board-scroll-all.header-one-row.quick-entry-visible .board {
  padding-top: 0;
  margin-top: calc(10px + var(--board-head-gap, 10px));
}
/* Верхняя панель — один сплошной фон (трелвис 1911). На доске с обоями строка
   быстрой задачи по правилу `#main.board-bg-active #quick-bar` брала себе
   матовое стекло и рисовала внутри непрозрачной шапки прямоугольник другого
   цвета: слева от «Оформления» была видна ступенька. В одну строку строка
   собственного фона иметь не должна. */
body.header-one-row.quick-entry-visible #main.board-bg-active #quick-bar,
body.header-one-row.tg-low-effects.quick-entry-visible #main.board-bg-active #quick-bar,
body.header-one-row.quick-entry-visible #quick-bar {
  background: transparent; border-color: transparent;
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
.board-scroll-all .board-wrap.has-bg .column {
  background: transparent; backdrop-filter: none;
}
.board-scroll-all .board-wrap.has-bg .col-cards,
.board-scroll-all .board-wrap.has-bg .col-rems,
.board-scroll-all .board-wrap.has-bg .col-foot {
  background: rgba(16, 18, 4, .82); backdrop-filter: blur(2px);
}
.board-scroll-all .board-wrap.has-bg .col-head { background: var(--col); }
/* В «Обзоре» вся колонка уезжает под верхнее стекло. Sticky остаётся только
   у стандартного Trello-ряда. */
body.board-scroll-all .board.board-overview .col-head {
  position: static; top: auto; z-index: auto; transform: none;
  -webkit-clip-path: none; clip-path: none;
}

/* ---------- Низ колонки: «Добавить», хвост, композер ---------- */
.add-card-btn { width: 100%; text-align: left; color: var(--muted); padding: 7px 10px; border-radius: 8px; font-size: 13px; }
.add-card-btn:hover { background: var(--field); color: var(--bright); }
/* Хвост гигантской колонки (трелвис 1959): сотни карточек «Выполнено» не
   раскатываются сразу — лента остаётся лёгкой, остальное по кнопке.
   Кнопка всегда последняя в колонке (трелвис 5150): `order` держит её внизу
   при любой операции — перенос карточки в самый низ больше не оставляет
   задачу под кнопкой. И она большая и яркая (трелвис 5151): человек в запаре
   должен видеть, что список показан не весь. */
.col-tail-more {
  order: 2; display: block; width: 100%; margin: 6px 0 2px; padding: 13px 10px;
  border-radius: 10px; background: var(--accent); color: #08121f;
  font-size: 14px; font-weight: 800; letter-spacing: .2px; text-align: center;
  box-shadow: 0 3px 12px rgba(var(--accent-rgb),.34);
}
.col-tail-more:hover { background: var(--accent); filter: brightness(1.1); }
/* Вторая строка «Добавить» — сверху колонки (трелвис 5160). Кнопка та же, ряд
   у́же: он стоит между шапкой и списком и не должен съедать высоту. */
.col-foot-top { padding: 3px 8px 1px; }
.board-scroll-all .col-foot-top { border-radius: 0; }
body.compact .col-foot-top { padding: 2px 6px 0; }
/* Пустая колонка: верхняя и нижняя «Добавить» стояли вплотную двумя одинаковыми
   строками (обход shots-1030, снимок 20-empty-board). Без карточек «сверху» и
   «снизу» — одно место, остаётся нижняя: у неё скругление низа колонки. */
.column > .col-foot-top:has(+ .col-cards:empty) { display: none; }
/* Переименование колонки на месте (трелвис 5156): поле встаёт ровно на место
   заголовка и наследует его кегль. */
.col-title-input {
  flex: 1; min-width: 0; font-size: inherit; font-weight: inherit;
  padding: 2px 7px; border-radius: 7px; background: var(--comment-field);
  border-color: var(--accent);
}
.inline-composer { display: flex; flex-direction: column; gap: 5px; }
.composer-input {
  width: 100%; background: var(--comment-field); border-color: var(--accent);
  color: var(--bright); font-size: 13px; padding: 8px 10px;
}
.composer-hint { display: flex; flex-direction: column; gap: 1px; color: var(--muted); font-size: 10.5px; padding: 0 3px; }
.col-foot.composing { padding-top: 4px; }

/* ---------- Мини-карточка на доске ---------- */
/* Ритм карточки живёт в переменных (трелвис 5234): плотные режимы меняют только
   их, а паддинги, обложка и бейджи подстраиваются сами — ни один пересчёт
   не расходится с другим. */
.card {
  --card-pad-y: 6px; --card-pad-x: 9px; --card-row-gap: 5px;
  background: var(--card); border-radius: 8px; padding: var(--card-pad-y) var(--card-pad-x);
  box-shadow: 0 1px 1px rgba(0,0,0,.35); cursor: pointer; user-select: none; -webkit-user-select: none;
  border: 1px solid transparent;
}
/* Обложка как в Trello: первая картинка карточки сверху мини-карточки */
.card-cover {
  margin: calc(-1 * var(--card-pad-y, 6px)) calc(-1 * var(--card-pad-x, 9px)) var(--card-row-gap, 5px);
  border-radius: 8px 8px 0 0; overflow: hidden; background: rgba(0,0,0,.15);
}
/* Высота обложки задана заранее (трелвис 1831): место под фото есть до загрузки,
   поэтому карточки не подпрыгивают, когда картинки приходят. */
.card-cover img { display: block; width: 100%; height: 150px; object-fit: cover; }
.card:hover { background: var(--card-hover); }
/* Карточка, открытая в правой панели, остаётся явно выбранной на доске
   (трелвис 1850): тонкая, но заметная зелёная рамка. */
.card.selected, .card[aria-current="true"] {
  border-color: var(--green); background: var(--card-hover);
  box-shadow: 0 0 0 2px var(--green), 0 1px 1px rgba(0,0,0,.35);
}
/* Межстрочное у заголовка карточки плотнее общего 1.45 (трелвис 5234): строка
   короче на пару пикселей, но текст не режется — минимум карточки остаётся
   целой строкой, переносы работают как раньше. */
.card .card-title { color: var(--bright); font-size: 13.5px; line-height: 1.3; word-break: break-word; display: flex; gap: 7px; align-items: flex-start; }
.card.done .card-title-text { color: var(--muted); }
.card-check {
  flex: none; width: 17px; height: 17px; border-radius: 50%; border: 2px solid var(--muted);
  margin-top: 1px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; color: transparent; transition: all .15s;
}
.card.done .card-check { background: var(--green); border-color: var(--green); color: var(--on-accent); }
.card-badges { display: flex; gap: 8px; margin-top: var(--card-row-gap, 5px); align-items: center; flex-wrap: wrap; color: var(--muted); font-size: 11.5px; line-height: 1.25; }
.card-badges .cb { display: inline-flex; gap: 3px; align-items: center; }
.cb.ctrl { color: var(--yellow); }
.card-avatar { margin-left: auto; font-size: 13px; }
.mirror-note { margin-top: var(--card-row-gap, 5px); color: var(--muted); font-size: 11.5px; line-height: 1.35; }
.mirror-note b { color: var(--yellow); font-weight: 600; }

/* ---------- Карточка-разделитель: секции внутри колонки (трелвис 5155) ----------
   Как в Trello: карточка, названная тремя минусами и больше, — не задача, а
   линия-заголовок секции. Ниже обычной карточки, без фона и тени: глаз читает
   её как границу, а не как ещё одну задачу. Клик по линии сворачивает всё до
   следующей линии, число справа — сколько карточек спрятано. Тип читается из
   названия, свёрнутость живёт в браузере — сервер про секции не знает. */
.card.card-sep {
  display: flex; align-items: center; gap: 8px; padding: 3px 4px;
  background: transparent; box-shadow: none; border-radius: 4px;
  color: var(--muted); font-size: 11px; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase;
}
.card.card-sep:hover { background: var(--soft); color: var(--bright); }
.card-sep-arrow { flex: none; font-size: 12px; line-height: 1; transition: transform .15s ease; }
.card.card-sep.collapsed .card-sep-arrow { transform: rotate(-90deg); }
.card-sep-label { flex: none; max-width: 70%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Черта берёт цвет самой линии, а не `--line`: на карточном фоне серая рамка
   почти не видна, а так линия светлеет вместе с наведением. */
.card-sep-line { flex: 1; min-width: 12px; height: 1px; background: currentColor; opacity: .34; }
.card-sep-count { flex: none; font-weight: 800; opacity: .75; }
.card-sep-count:empty { display: none; }
/* Карточек свёрнутой секции на экране просто нет — и dnd.js их пропускает. */
.card.sec-hidden { display: none; }

/* «Показать в списке» (трелвис 2170): найденная карточка вспыхивает трижды —
   на плотной доске одиночная подсветка взглядом не ловится. */
@keyframes trelvis-card-flash {
  0%, 100% { box-shadow: 0 1px 1px rgba(0,0,0,.35); }
  50% { box-shadow: 0 0 0 3px var(--yellow), 0 1px 1px rgba(0,0,0,.35); }
}
.card.card-flash { animation: trelvis-card-flash .62s ease-in-out 3; }
@media (prefers-reduced-motion: reduce) {
  .card.card-flash { animation: none; box-shadow: 0 0 0 3px var(--yellow), 0 1px 1px rgba(0,0,0,.35); }
}
.mirror-who { color: var(--purple); }

/* Напоминания (трелвис 496): карточки-шаблоны в колонке «Напоминания» */
.col-rems { display: flex; flex-direction: column; gap: var(--card-gap, 6px); padding: 0 8px; overflow-y: auto; min-height: 8px; }
.rem-card {
  background: var(--card); border-radius: 8px; padding: 6px 9px; cursor: pointer;
  border: 1px dashed var(--line); user-select: none; -webkit-user-select: none;
}
.rem-card:hover { background: var(--card-hover); }
.rem-card .card-title { color: var(--bright); font-size: 13.5px; line-height: 1.3; word-break: break-word; }
.rem-card.rem-off { opacity: .55; }
.rem-note { margin-top: 4px; color: var(--muted); font-size: 11.5px; line-height: 1.35; }
.rem-lbl { display: block; color: var(--muted); font-size: 12px; margin-bottom: 4px; }
.rem-when { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; color: var(--text); }
.rem-dow { display: inline-flex; gap: 4px; align-items: center; font-size: 13px; cursor: pointer; }
.rem-dow input { width: auto; }
.rem-when #rm-mday { width: 90px; }

/* Фон доски (трелвис 497) */
.board-wrap.has-bg {
  background: transparent;
}
.board-wrap.has-bg .board-bar {
  background: rgba(7, 14, 10, .52); border-radius: 0 0 18px 18px;
  -webkit-backdrop-filter: blur(18px) saturate(1.15); backdrop-filter: blur(18px) saturate(1.15);
}
.board-wrap.has-bg .column {
  /* Backdrop blur на каждой длинной колонке заново фильтровал обои при любом
     сдвиге. Полупрозрачность сохраняет вид, но прокрутка остаётся композитной. */
  background: rgba(12, 18, 13, .88);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
.bg-actions { display: flex; gap: 10px; align-items: center; }
.bg-actions label.btn { display: inline-flex; cursor: pointer; }
.bg-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 8px; max-height: 320px; overflow-y: auto; margin-top: 4px;
}
.bg-thumb {
  width: 100%; aspect-ratio: 16/10; object-fit: cover; border-radius: 8px;
  cursor: pointer; border: 2px solid transparent;
}
.bg-thumb:hover { border-color: var(--accent); }

/* Аватарки из Trello (трелвис 497): картинка вместо эмодзи, где она есть */
.ava-img {
  width: 20px; height: 20px; border-radius: 50%; object-fit: cover;
  flex: none; vertical-align: -4px; margin-right: 6px;
}
.ava-video { display: inline-block; background: transparent; }
.ava-emoji { display: inline-flex; align-items: center; justify-content: center; }
.ava-animated { animation: ava-bob 1.8s ease-in-out infinite; transform-origin: 50% 70%; }
@keyframes ava-bob { 0%,100% { transform: translateY(0) rotate(-4deg); } 50% { transform: translateY(-2px) rotate(4deg); } }
.ava-img.ava-sm { width: 16px; height: 16px; margin-right: 0; vertical-align: -3px; }
#me-chip .ava-img { margin-right: 4px; }

.add-col {
  min-width: 260px; width: 260px; background: rgba(255,255,255,.04);
  border-radius: var(--radius); padding: 8px;
}
.add-col button.ghost { width: 100%; text-align: left; color: var(--muted); padding: 8px 10px; border-radius: 8px; }
.add-col button.ghost:hover { background: var(--field); color: var(--bright); }
.add-col.composing { background: var(--column); }

/* DnD */
/* Перетаскиваемый элемент уходит из потока (трелвис 1832): пока он оставался на
   месте, вставленный placeholder добавлял ещё одну ширину колонки — соседняя
   колонка уезжала за край экрана и выглядела исчезнувшей. */
.card.dragging, .column.dragging { display: none !important; }
.drag-ghost {
  position: fixed; z-index: 1000; pointer-events: none; width: 260px;
  transform: rotate(3deg); box-shadow: 0 8px 24px rgba(0,0,0,.5);
}
/* Переносимая колонка должна читаться как предмет в руке (трелвис 1872): раньше
   призрак наследовал прозрачный фон колонки, сливался с доской и по экрану
   ездила «зелёная пустота» — сам слот вставки. Теперь это компактная плашка с
   названием: фон, рамка и никакого списка карточек. */
.column.drag-ghost {
  height: auto !important; max-height: none !important; min-height: 0 !important;
  background: var(--col) !important; border: 1px solid rgba(var(--accent-rgb),.6);
  border-radius: var(--radius); overflow: hidden; opacity: .96;
}
.column.drag-ghost .col-head { background: var(--col); border-bottom: 0; margin: 0; }
.column.drag-ghost .col-cards,
.column.drag-ghost .col-rems,
.column.drag-ghost .col-foot,
.column.drag-ghost .col-resizer { display: none !important; }
.board-moving-column .board-zoom-controls { border-color: rgba(var(--accent-rgb),.64); }

/* ---------- Пульт доски: масштаб, режим, раскладка ---------- */
/* Плавающий масштаб меняет только доску; пульт остаётся одного размера. */
.board-zoom-controls {
  position: fixed; z-index: 300; right: 8px; bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; gap: 2px; min-height: 40px; padding: 3px;
  overflow: hidden; border: 1px solid rgba(255,255,255,.12); border-radius: 16px;
  color: var(--bright); background: rgba(10,16,12,.54);
  -webkit-backdrop-filter: blur(18px) saturate(1.2); backdrop-filter: blur(18px) saturate(1.2);
  box-shadow: 0 8px 24px rgba(0,0,0,.24);
}
.board-zoom-controls button {
  min-width: 34px; height: 34px; padding: 0 8px; border-radius: 12px;
  font-size: 19px; line-height: 1; color: var(--bright); white-space: nowrap;
}
.board-zoom-controls .board-view-mode { min-width: 88px; font-size: 10.5px; font-weight: 850; }
/* Одна кнопка раскладки: подменю с готовой шириной колонок (трелвис 1920). */
.board-zoom-controls .board-layout { font-size: 15px; color: var(--muted); }
.board-zoom-controls button:active { background: rgba(var(--accent-rgb),.22); color: var(--accent); }
#board-zoom-value {
  min-width: 34px; display: grid; place-items: center; color: var(--muted); font-size: 9.5px;
  font-weight: 800; font-variant-numeric: tabular-nums;
}
.column-width-preview { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 10px; }
.column-width-preview span { color: var(--muted); font-size: 11px; }
.column-width-preview input { width: 100%; }
.column-width-value { margin: 12px 0; color: var(--accent); font-weight: 850; text-align: center; }
.column-width-presets { justify-content: center; }
/* Пока что-то тащат, текст не выделяется, а доска не пытается прокручиваться
   сама по себе — прокруткой во время переноса управляет только DnD (трелвис 1899). */
body.dnd-dragging { user-select: none; -webkit-user-select: none; }
body.dnd-dragging .board, body.dnd-dragging .col-cards { touch-action: none; }
.drop-slot { border-radius: 8px; background: rgba(var(--accent-rgb),.16); border: 1px dashed rgba(var(--accent-rgb),.45); }

/* ---------- Списки (уведомления, архив, корзина, история) ---------- */
.page { flex: 1; width: 100%; min-width: 0; overflow-y: auto; padding: 16px; max-width: 860px; }
.page h2 { color: var(--bright); font-size: 18px; margin-bottom: 12px; }
.filter-row { display: flex; gap: 6px; margin-bottom: 12px; flex-wrap: wrap; }
.chip { border: 1px solid var(--line); border-radius: 16px; padding: 5px 12px; font-size: 12.5px; color: var(--muted); }
.chip.active { background: var(--active); border-color: var(--accent); color: var(--accent); }
.list-item {
  display: flex; gap: 10px; padding: 10px 12px; border-radius: 10px; background: var(--card);
  margin-bottom: 8px; cursor: pointer; align-items: flex-start;
}
.list-item:hover { background: var(--card-hover); }
.list-item .li-emoji { flex: none; font-size: 16px; }
.list-item .li-body { flex: 1; min-width: 0; }
.list-item .li-text { color: var(--bright); font-size: 13.5px; word-break: break-word; }
.list-item .li-sub { color: var(--muted); font-size: 12px; margin-top: 2px; overflow-wrap: anywhere; }
.list-item.unread { border-left: 3px solid var(--accent); }
/* Заявка на вход: выбор слота — обычное поле шириной 100%, поэтому в flex-строке
   оно съедало имя человека и разбивало его в столбик по букве. */
.list-item select { flex: none; width: auto; max-width: 220px; }
/* Кнопки в строке (Команда, заявки) на телефоне съедали имя до столбика по букве (8920):
   на узком экране они переносятся под имя. */
@media (max-width: 560px) {
  .list-item { flex-wrap: wrap; }
  .list-item .li-body { flex-basis: calc(100% - 40px); }
}
.empty { color: var(--muted); text-align: center; padding: 40px 10px; }

/* Единая кнопка закрытия (трелвис 1810). Правило Элвиса: закрыть окно — всегда
   один и тот же прямоугольник со скруглёнными углами, всегда в левом верхнем
   углу, ровно под системным крестиком Telegram. Раньше крестики были разного
   вида и в разных углах: рука шла в системный «Закрыть» и роняла весь Трелвис. */
.ui-close {
  width: 40px; height: 40px; flex: none; display: grid; place-items: center; padding: 0;
  border: 1px solid var(--line); border-radius: 12px; background: rgba(255,255,255,.06);
  color: var(--bright); font-size: 25px; line-height: 1;
}
.ui-close:hover { border-color: var(--accent); color: var(--accent); background: var(--active); }

/* ---------- Модалки ---------- */
#modal-root:not(:empty) { position: fixed; inset: 0; z-index: 500; }
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,.6);
  display: flex; align-items: flex-start; justify-content: center; overflow-y: auto; padding: 40px 12px;
}
.modal {
  background: var(--modal); border: 1px solid var(--line); border-radius: 14px; width: 100%; max-width: 640px;
  padding: 18px; box-shadow: 0 12px 40px rgba(0,0,0,.55); margin-bottom: 40px;
}
.theme-modal { max-height: calc(100vh - 80px); overflow-y: auto; }
.modal.small { max-width: 440px; }
.modal-backdrop.ktask-host { display: block; padding: 0; overflow: hidden; }
.modal.ktask-modal {
  position: fixed; max-width: 760px; max-height: calc(100vh - 24px); overflow-y: auto;
  margin: 0; cursor: grab; touch-action: none;
}
.modal.ktask-modal.dragging { cursor: grabbing; user-select: none; }
.modal.ktask-modal button, .modal.ktask-modal input, .modal.ktask-modal textarea,
.modal.ktask-modal select, .modal.ktask-modal a { cursor: pointer; }
.modal.ktask-modal input, .modal.ktask-modal textarea, .modal.ktask-modal select { cursor: text; }
.modal h3 { color: var(--bright); font-size: 17px; margin-bottom: 12px; display: flex; align-items: flex-start; gap: 9px; }
.modal h3 .grow { flex: 1; }
.modal-close { color: var(--muted); font-size: 18px; padding: 2px 8px; border-radius: 6px; flex: none; }
.modal-close:hover { background: var(--soft); color: var(--bright); }
.m-row { margin-bottom: 12px; }
.m-label { color: var(--muted); font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px; margin-bottom: 5px; }
.m-actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.m-actions .spacer { flex: 1; }
textarea.m-desc { min-height: 90px; resize: vertical; }
.title-input { font-size: 16px; font-weight: 700; }

.pill-row { display: flex; gap: 6px; flex-wrap: wrap; }
.pill { border: 1px solid var(--line); border-radius: 14px; padding: 4px 10px; font-size: 12.5px; }
.pill.on { background: var(--active); border-color: var(--accent); color: var(--accent); }

.profile-people, .avatar-sources { display: grid; gap: 7px; }
.profile-person, .avatar-source {
  width: 100%; min-height: 42px; display: flex; align-items: center; gap: 9px;
  text-align: left; padding: 8px 10px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--field); color: var(--bright);
}
.profile-person:hover, .avatar-source:hover { background: var(--card-hover); border-color: var(--accent); }
.profile-eye, .source-check { margin-left: auto; color: var(--accent); }
.profile-interface {
  width: 100%; display: flex; align-items: center; gap: 12px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 9px; text-align: left; background: var(--field);
}
.profile-interface:hover { border-color: var(--accent); background: var(--card-hover); }
.profile-interface.active { border-color: var(--accent); background: var(--active); }
.profile-interface:disabled { opacity: .6; cursor: default; }
.profile-interface b, .profile-interface small { display: block; }
.profile-interface small { margin-top: 2px; color: var(--muted); font-size: 11.5px; }
.profile-scale-value { margin-left: auto; color: var(--accent); font-weight: 800; }
.profile-section { margin-top: 18px; }
.avatar-source.active { border-color: var(--accent); background: var(--active); }
.avatar-source-icon { width: 24px; text-align: center; font-size: 18px; }
.avatar-source b, .avatar-source small { display: block; }
.avatar-source small { color: var(--muted); font-size: 11.5px; margin-top: 2px; }

/* «📊 Мои задачи» в профиле (трелвис 2747, 2770, 2748) */
.modal.profile-modal { max-width: 520px; }
.profile-stats { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; }
.ps-head { display: flex; align-items: baseline; gap: 10px; }
.ps-big { color: var(--bright); font-size: 34px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.ps-head-text { color: var(--bright); font-size: 15px; }
.ps-head-text small { display: block; margin-top: 3px; color: var(--muted); font-size: 12px; }
.ps-note, .ps-foot { color: var(--muted); font-size: 12px; }
.ps-foot { margin-top: 6px; }
.ps-retry { justify-self: start; }
.ps-sub { margin-top: 12px; color: var(--bright); font-size: 13px; font-weight: 700; }
.ps-row {
  display: grid; grid-template-columns: 92px minmax(0, 1fr) 50px 50px; align-items: center; gap: 8px;
  font-size: 13px; min-height: 20px; font-variant-numeric: tabular-nums;
}
.ps-row-name { color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ps-row-name small { color: var(--muted); font-size: 11px; }
.ps-row-bar { height: 6px; border-radius: 3px; background: var(--soft); overflow: hidden; }
.ps-row-bar i { display: block; height: 100%; border-radius: 3px; background: var(--purple); }
.ps-row-n { color: var(--bright); text-align: right; font-weight: 700; }
.ps-row-d { color: var(--muted); text-align: right; font-size: 12px; white-space: nowrap; }
.ps-chart { position: relative; padding-left: 30px; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.ps-y-cap { color: var(--muted); font-size: 11px; margin: 0 0 6px -30px; }
.ps-plot { position: relative; height: 150px; border-bottom: 1px solid var(--line); }
.ps-grid-line { position: absolute; left: 0; right: 0; border-top: 1px solid var(--line); opacity: .55; }
.ps-grid-line span {
  position: absolute; right: calc(100% + 5px); top: -7px; color: var(--muted);
  font-size: 10.5px; font-variant-numeric: tabular-nums;
}
.ps-bars { position: absolute; inset: 0; display: flex; align-items: stretch; gap: 2px; }
.ps-bar {
  position: relative; flex: 1 1 0; width: 0; min-width: 0; display: flex; flex-direction: column-reverse;
  cursor: pointer; transition: opacity .12s;
}
.ps-bar i { display: block; width: 100%; flex: none; }
.ps-bar i:last-child { border-radius: 2px 2px 0 0; }
/* Пустой день — пустое место с подписью дня; выбранный день подсвечен полосой. */
.ps-bar.on { background: rgba(var(--accent-rgb), .12); border-radius: 3px 3px 0 0; }
.ps-chart.pointing .ps-bar:not(.on) { opacity: .45; }
.ps-days { display: flex; gap: 2px; margin-top: 4px; }
.ps-days span {
  flex: 1 1 0; width: 0; min-width: 0; text-align: center; color: var(--muted); font-size: 9.5px;
  letter-spacing: -.5px; white-space: nowrap; overflow: visible; font-variant-numeric: tabular-nums;
}
.ps-days span.we { color: var(--text); }
@media (max-width: 520px) { .ps-days span { font-size: 8px; letter-spacing: -.8px; } }
.ps-x-cap { color: var(--muted); font-size: 11px; margin-top: 4px; text-align: center; }
.ps-tip {
  position: absolute; top: 18px; z-index: 2; min-width: 150px; max-width: 220px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--modal);
  box-shadow: 0 6px 20px rgba(0,0,0,.35); font-size: 12px; pointer-events: none;
}
.ps-tip-head { color: var(--muted); font-size: 11.5px; }
.ps-tip-total { color: var(--bright); font-weight: 700; margin: 2px 0 4px; }
.ps-tip-row, .ps-legend-item { display: flex; align-items: center; gap: 6px; }
.ps-tip-row span { flex: 1; min-width: 0; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ps-tip-row b { color: var(--bright); font-variant-numeric: tabular-nums; }
.ps-tip-row i, .ps-legend-item i { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.ps-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 8px; font-size: 12px; color: var(--text); }
.ps-legend-item small { color: var(--muted); font-variant-numeric: tabular-nums; }
.ps-voice { display: grid; grid-template-columns: 96px 1fr; gap: 8px; font-size: 13px; color: var(--text); }
.ps-voice-when { color: var(--muted); }
.ps-voice b { color: var(--bright); }

/* ---------- Оформление ---------- */
.theme-modal { max-width: 620px; }
.appearance-toggle { white-space: nowrap; gap: 6px; }
.theme-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.theme-option {
  min-width: 0; text-align: left; border: 1px solid var(--line); border-radius: 12px;
  padding: 10px; background: var(--field); transition: border-color .15s ease, transform .15s ease;
}
.theme-option:hover { border-color: var(--accent); transform: translateY(-1px); }
.theme-option.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.theme-preview {
  height: 96px; display: grid; grid-template-columns: 32% 1fr; overflow: hidden;
  border: 1px solid var(--preview-line); border-radius: 9px; background: var(--preview-bg);
}
.theme-preview-side { background: var(--preview-side); padding: 10px 6px; }
.theme-preview-dot { display: block; width: 9px; height: 9px; border-radius: 50%; background: var(--preview-accent); margin-bottom: 10px; }
.theme-preview-line { display: block; height: 5px; border-radius: 3px; background: var(--preview-muted); opacity: .62; margin-top: 7px; }
.theme-preview-main { padding: 10px; }
.theme-preview-card { display: block; height: 28px; border-radius: 7px; background: var(--preview-card); margin: 11px 0 9px; }
.theme-preview-accent { display: block; height: 5px; width: 58%; border-radius: 3px; background: var(--preview-accent); }
.theme-option-copy { display: flex; align-items: center; gap: 8px; padding: 9px 2px 1px; }
.theme-option-copy b { color: var(--bright); flex: 1; }
.theme-option-copy small { color: var(--muted); display: block; margin-top: 2px; }
.theme-check { color: var(--accent); font-weight: 900; font-size: 16px; }
.emoji-choice-grid, .shape-choice-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 9px; }
.emoji-choice, .shape-choice {
  display: flex; align-items: center; gap: 10px; min-width: 0; text-align: left;
  padding: 11px 12px; border: 1px solid var(--line); border-radius: 11px; background: var(--field);
}
.emoji-choice { flex-direction: column; align-items: flex-start; }
.emoji-choice b, .emoji-choice small { display: block; }
.emoji-choice small { color: var(--muted); font-size: 11.5px; }
.emoji-choice:hover, .emoji-choice.active, .shape-choice:hover, .shape-choice.active {
  border-color: var(--accent); background: var(--active); box-shadow: 0 0 0 1px var(--accent);
}
.icon-choice-group + .icon-choice-group { margin-top: 13px; }
.icon-choice-heading { color: var(--muted); font-size: 11px; font-weight: 750; }
.icon-choice-grid { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 8px; margin-top: 7px; }
.icon-choice {
  min-width: 0; padding: 7px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--field); color: var(--muted); font-size: 10px; text-align: center;
}
.icon-choice:hover, .icon-choice.active { border-color: var(--accent); color: var(--bright); }
.icon-choice img { display: block; width: 42px; height: 42px; border-radius: 11px; margin: 0 auto 5px; object-fit: contain; }
.custom-icon-editor {
  display: flex; gap: 12px; align-items: center; margin-top: 12px; padding: 11px;
  border: 1px solid var(--line); border-radius: 11px; background: var(--field);
}
.custom-icon-preview { width: 58px; height: 58px; flex: none; }
.custom-icon-preview img { width: 100%; height: 100%; object-fit: cover; border-radius: 14px; }
.custom-icon-preview img[data-shape="round"] { border-radius: 50%; }
.custom-icon-copy { flex: 1; min-width: 0; }
.custom-icon-copy b, .custom-icon-copy small { display: block; }
.custom-icon-copy small { color: var(--muted); font-size: 11.5px; margin: 2px 0 8px; }
.team-icon-default {
  display: flex; align-items: center; gap: 12px; margin-top: 12px; padding: 11px;
  border: 1px solid var(--accent); border-radius: 11px; background: var(--active);
}
.team-icon-default img { width: 52px; height: 52px; flex: none; object-fit: cover; border-radius: 13px; }
.team-icon-default img[data-shape="round"] { border-radius: 50%; }
.team-icon-default span { min-width: 0; }
.team-icon-default b, .team-icon-default small { display: block; }
.team-icon-default small { color: var(--muted); font-size: 11.5px; margin-top: 2px; }
.icon-default-actions { align-items: center; }
.shape-demo { width: 34px; height: 34px; flex: none; background: linear-gradient(145deg,#3b3b3d,#111); border: 1px solid rgba(255,255,255,.2); }
.shape-demo.squircle { border-radius: 9px; }
.shape-demo.round { border-radius: 50%; }

.project-members { display: grid; gap: 7px; max-height: 330px; overflow-y: auto; }
.project-member-row {
  display: flex; align-items: center; gap: 10px; padding: 7px 9px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--field);
}
.project-member-name { flex: 1; min-width: 0; display: flex; align-items: center; gap: 7px; color: var(--bright); }
.project-member-row select { width: auto; min-width: 150px; background: var(--comment-field); }

/* ---------- Карточка в стиле Trello ---------- */
.chip-select {
  width: auto; max-width: 52%; background: transparent; border: 0;
  border-radius: 6px; padding: 2px 18px 2px 4px; font-size: 11.5px; color: var(--muted); text-align: right;
}
.chip-select:hover, .chip-select:focus { background: var(--field); color: var(--bright); border: 0; }
.card-head-row { display: flex; gap: 11px; align-items: flex-start; margin-bottom: 12px; }
.card-meta-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: -7px 0 9px 33px; color: var(--muted); font-size: 11.5px; }
/* Галочка «задача выполнена» — пальцевого размера (трелвис 1809). Опущена к низу
   первой строки названия (трелвис 1844): вверху она висела выше текста. */
.card-check.big {
  width: 32px; height: 32px; font-size: 19px; margin-top: 8px; flex: none;
  border-radius: 50%; border: 2px solid var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; color: transparent;
}
/* Телефонное правило `body.compact .card-check` ужимает галочку до 14px — оно
   про карточки доски и на кружок в открытой карточке распространяться не должно
   (трелвис 3344): рядом с крупным заголовком он превращался в точку и переставал
   попадать под палец. */
body.compact .card-check.big { width: 32px; height: 32px; font-size: 19px; }
.card-check.big:hover { border-color: var(--green); }
.card-check.big.done { background: var(--green); border-color: var(--green); color: var(--on-accent); }
.card-title-input { border: 0; background: none; padding: 2px 0; font-size: 19px; font-weight: 800; color: var(--bright); }
.card-title-input:focus { border: 0; }
.card-btn-row, .card-top-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.card-btn-row, .card-top-actions { position: relative; padding: 5px; margin: -5px; }
.card-btn-row { width: fit-content; max-width: 100%; }
.card-action {
  display: inline-flex; align-items: center; justify-content: flex-start; gap: 0;
  min-width: 32px; height: 32px; max-width: 32px; overflow: hidden; white-space: nowrap;
  border: 1px solid var(--line); border-radius: 8px; background: var(--field); color: var(--bright);
  transition: max-width .18s ease, border-color .18s ease, background .18s ease;
}
.card-action > span { width: 30px; flex: none; text-align: center; font-size: 15px; }
.card-action > b { padding-right: 10px; font-size: 12px; font-weight: 650; }
.card-btn-row:hover .card-action:not(.control-action), .card-btn-row:focus-within .card-action:not(.control-action),
.card-action:hover, .card-action:focus-visible { max-width: 150px; border-color: var(--accent); background: var(--active); }
.card-action.top { height: 30px; min-width: 30px; max-width: 30px; }
.card-action.top > span { width: 28px; }
.card-top-actions:hover .card-action.top, .card-top-actions:focus-within .card-action.top,
.card-action.top:hover, .card-action.top:focus-visible { max-width: 120px; }
.card-action.danger:hover { border-color: var(--red); color: var(--red); background: rgba(248,113,104,.10); }
.card-action.control-action {
  max-width: none; height: 32px; gap: 5px; padding-right: 10px; border-color: var(--line);
  color: var(--muted); background: transparent; overflow: visible;
}
.card-action.control-action > span { width: auto; padding-left: 8px; }
.card-action.control-action > b { padding-right: 0; }
.card-action.control-action:hover { color: var(--bright); background: var(--active); }
.card-action.control-action.active { color: var(--red); border-color: rgba(248,113,104,.52); background: rgba(248,113,104,.055); box-shadow: none; }
/* ---------- Карточка задачи: один понятный мобильный поток ---------- */
.modal-backdrop.card-detail-host { padding: 18px 10px; }
.modal.card-detail-modal {
  width: min(100%, 680px); max-width: 680px; padding: 0; overflow: hidden;
  background: var(--modal); border-radius: 20px;
}
/* Один общий отступ на всю карточку (трелвис 1915): верхняя строка растягивается
   на всю ширину отрицательными полями, поэтому её поля и внутренний отступ
   считаются от того же значения. Иначе в узкой правой панели крестик вылезал
   за край, тогда как остальное содержимое стояло с отступом. */
.card-detail-shell { --shell-px: 22px; --shell-py: 22px; padding: var(--shell-py) var(--shell-px); }
.card-person-link {
  width: 100%; display: flex; align-items: center; gap: 12px; padding: 2px 0 14px;
  text-align: left; color: var(--bright); border-bottom: 1px solid var(--line);
}
.card-person-link.no-link { cursor: default; }
.card-person-avatar {
  width: 44px; height: 44px; flex: none; border-radius: 50%; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center; font-size: 26px;
  background: var(--field);
}
.card-person-link > span:not(.card-person-avatar) { min-width: 0; flex: 1; }
.card-person-link strong, .card-person-link small { display: block; }
.card-person-link strong { color: var(--bright); font-size: 20px; font-weight: 850; }
.card-person-link small { margin-top: 1px; color: var(--muted); font-size: 11.5px; }
.card-person-link > b { color: var(--muted); font-size: 28px; font-weight: 400; }
.card-person-link:not(.no-link):hover > b { color: var(--accent); }
.card-person-link.compact {
  gap: 8px; min-height: 38px; padding: 4px 0 8px; border-bottom: 0;
}
.card-person-link.compact .card-person-avatar { width: 30px; height: 30px; font-size: 18px; }
.card-person-link.compact strong { font-size: 12.5px; }
.card-person-link.compact small { font-size: 10px; }
.card-person-link.compact > b { font-size: 20px; }
.outbox-status-banner {
  display: flex; flex-direction: row; align-items: center; gap: 8px; margin: 8px 0 12px; padding: 9px 11px;
  border: 1px solid var(--yellow); border-radius: 11px; color: var(--on-accent);
  background: var(--yellow); box-shadow: 0 8px 24px rgba(245,205,71,.15);
}
.outbox-status-banner strong { flex: none; font-size: 12.5px; font-weight: 950; line-height: 1.15; letter-spacing: .02em; }
.outbox-status-banner span { min-width: 0; font-size: 10.5px; line-height: 1.25; font-weight: 700; }
.outbox-status-banner.scheduled { border-color: var(--accent); background: var(--accent); }
.outbox-status-banner.hold { border-color: var(--red); background: var(--red); }
.outbox-status-banner.completed { border-color: var(--green); background: var(--green); }
.outbox-status-banner.cancelled { border-color: var(--red); background: var(--red); }
/* Верхняя строка карточки (трелвис 1802, 1809, 1815): крестик слева ровно под
   системным крестиком Telegram, рядом «•••» с редкими действиями, дальше кто
   кому поставил задачу, справа — колонка. */
.card-detail-topbar {
  position: sticky; top: 0; z-index: 8; display: flex; align-items: center; gap: 7px;
  margin: calc(-1 * var(--shell-py, 22px)) calc(-1 * var(--shell-px, 22px)) 10px;
  padding: 10px var(--shell-px, 22px) 8px;
  background: linear-gradient(180deg, var(--modal) 72%, transparent);
}
/* «•••» карточки живёт в подвале рядом с датой (трелвис 1839): в шапке он спорил
   с системными «•••» Telegram и не попадал под палец. */
.card-foot-more {
  width: 40px; height: 34px; flex: none; display: grid; place-items: center;
  border-radius: 11px; color: var(--muted); font-size: 13px; letter-spacing: .5px;
}
.card-foot-more:hover { color: var(--bright); background: var(--soft); }
.card-top-person {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 7px;
  padding: 4px 6px; border-radius: 10px; text-align: left; color: var(--bright);
}
.card-top-person:not(.no-link):hover { background: var(--soft); }
.card-top-person.no-link { cursor: default; }
.card-top-person strong {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px; font-weight: 850;
}
.card-top-person .card-person-avatar { width: 26px; height: 26px; font-size: 16px; }
/* Колонка — компактный чип по ширине названия, прижатый к правому краю
   (трелвис 1840): нативный select оставлял широкое пустое поле до стрелок. */
.card-top-column {
  flex: none; max-width: 46%; margin-left: auto; display: inline-flex;
  align-items: center; gap: 3px; padding: 4px 8px; border-radius: 9px;
  color: var(--muted); font-size: 11.5px; background: transparent;
}
.card-top-column > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-top-column > b { flex: none; font-size: 9px; font-weight: 400; opacity: .8; }
.card-top-column:hover { color: var(--bright); background: var(--soft); }
/* «Сохранено» при правке полей карточки (трелвис 5232). Пока подписи нет, её
   нет и в раскладке: display none, а не прозрачность, — иначе постоянная
   пустая колодка отжимала бы чип колонки влево всё время. */
.card-saved { display: none; flex: none; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.card-saved.show { display: inline-flex; align-items: center; }
.card-saved.err { color: var(--red); }
/* Подвал отделён линией (трелвис 3344): у страницы есть низ, а не обрыв. */
.card-meta-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 22px -6px 0; padding-top: 14px; border-top: 1px solid var(--line);
  color: var(--muted); font-size: 11.5px;
}
.card-foot-date { text-align: right; }
/* Метка повтора (трелвис 5482) уезжает вправо парой с датой: у подвала
   justify-content: space-between и было ровно двое детей, третий без своего
   margin-left повис бы посреди пустоты между «•••» и датой. */
.card-foot-repeat { margin-left: auto; color: var(--muted); font-size: 11.5px; white-space: nowrap; }
.card-detail-modal .card-head-row { margin: 0 0 7px; }
/* Заголовок в одну строку — кружок и текст на одной оптической линии (трелвис
   1933). В две строки ряд остаётся прежним: там выравнивание по верху и есть
   правильный вид. */
.card-head-row.title-one-line { align-items: center; }
.card-head-row.title-one-line .card-check.big { margin-top: 0; }
.card-detail-modal .card-head-row.title-one-line .card-title-input { min-height: 0; }
/* Заголовок — верхушка иерархии карточки (трелвис 3344): крупнее, плотнее по
   межбуквенному, всё служебное ушло в строку над ним и подпись под ним. */
.card-detail-modal .card-title-input {
  min-height: 40px; padding: 0; overflow: hidden; resize: none;
  font-size: 26px; line-height: 1.18; font-weight: 900; letter-spacing: -.015em;
}
/* Подпись под заголовком: аватар, «кто → кому», дата и счётчики, снизу линия. */
.card-byline {
  display: flex; align-items: center; gap: 10px; margin: 14px 0 0;
  padding-bottom: 16px; border-bottom: 1px solid var(--line);
}
.card-byline .card-person-avatar { width: 34px; height: 34px; font-size: 20px; }
.card-byline-who { min-width: 0; flex: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.card-byline-person { flex: none; max-width: 100%; margin: -4px -6px; }
.card-byline-when { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: 11.5px; }
.card-byline-badges { flex: none; display: flex; gap: 6px; }
.card-byline-badge {
  padding: 3px 8px; border-radius: 999px; background: var(--soft);
  color: var(--muted); font-size: 11.5px; font-weight: 700; white-space: nowrap;
}
.card-detail-modal .card-meta-row { margin: 0 0 16px; font-size: 12px; }
/* Разделы карточки отделяет воздух и мелкий заголовок капсом, а не рамка
   (трелвис 3344). Три одинаковых прямоугольника со скруглением 16 не давали
   глазу иерархии — карточка читалась как коробка коробок, и это и есть то
   «не хватает стиля». Панель это уже умела (1913), теперь так везде. */
.card-content-section {
  margin: 22px 0; padding: 0; border: 0; border-radius: 0; background: transparent;
}
.card-sec-head {
  display: flex; align-items: baseline; gap: 7px; margin: 0 0 10px;
  color: var(--muted); font-size: 11px; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase;
}
.card-sec-head b { font-weight: 800; opacity: .62; }
.card-section-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 12px;
}
.card-section-head strong, .card-section-head small { display: block; }
.card-section-head strong { color: var(--bright); font-size: 14px; font-weight: 850; }
.card-section-head small { margin-top: 2px; color: var(--muted); font-size: 11.5px; line-height: 1.35; }
.card-fold { padding: 0; }
.card-fold-summary {
  min-height: 46px; display: flex; align-items: center; gap: 9px; padding: 11px 13px;
  cursor: pointer; list-style: none;
}
.card-fold-summary::-webkit-details-marker { display: none; }
.card-fold-summary::before { content: "›"; color: var(--muted); font-size: 21px; line-height: 1; transform-origin: center; transition: transform .15s ease; }
.card-fold[open] > .card-fold-summary::before { transform: rotate(90deg); }
.card-fold-summary strong { color: var(--bright); font-size: 13.5px; }
.card-fold-summary small { margin-left: auto; color: var(--muted); font-size: 10.5px; text-align: right; }
.card-fold-body { padding: 0 13px 13px; }
/* Задачи · Голосовое · Скрыть (трелвис 1811) — один блок вместо «Описания» и
   «Чек-листа»: пункты диктовки и есть чек-лист. */
.card-brief { padding: 0; }
/* Заголовок раздела и переключатель — одной строкой, на узком экране в две
   (трелвис 3344): вкладки остаются пальцевыми, а раздел получает имя. */
.card-brief-head { display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap; margin-bottom: 10px; }
.card-brief-head .card-sec-head { margin: 0; }
.card-brief-tabs {
  flex: 1 1 260px; min-width: 0; display: flex; gap: 5px; padding: 3px;
  border-radius: 12px; background: var(--soft);
}
.card-brief-tabs button {
  flex: 1; min-height: 34px; padding: 6px 8px; border-radius: 9px;
  color: var(--muted); font-size: 12.5px; font-weight: 750;
}
.card-brief-tabs button.active { color: var(--on-accent); background: var(--accent); }
.card-brief-tabs button b { font-weight: 850; opacity: .8; }
.card-brief-pane { padding-top: 12px; }
.card-brief.brief-hidden .card-brief-pane { display: none; }
/* Описание и чек-лист внутри «Что делать» — два ясных раздела (трелвис 5157):
   текстовое поле стояло встык со строкой «Новый пункт», и человек путал, куда
   пишет. Делит их воздух и тонкая черта — та же, что закрывает подпись и
   подвал карточки; коробок вокруг блоков по-прежнему нет (правило 1913). */
.card-brief-part + .card-brief-part { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.card-brief-part.hidden + .card-brief-part { margin-top: 0; padding-top: 0; border-top: 0; }
.card-part-head {
  display: flex; align-items: baseline; gap: 7px; margin: 0 0 8px;
  color: var(--muted); font-size: 10.5px; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase; opacity: .85;
}
.card-part-head b { font-weight: 800; opacity: .62; }
/* Кнопка в заголовке раздела (трелвис 5482): размер и цвет как у всех «•••»
   (правило доски — 13px, цветом как бургер). margin-left: auto прижимает её к
   правому краю строки, иначе прилипла бы к счётчику посреди заголовка; своя
   opacity — чтобы кнопка не гасла вместе с подписью раздела. */
.card-part-action { margin-left: auto; opacity: 1; color: var(--muted); font-size: 13px; line-height: 1; }
.card-part-action:hover { color: var(--bright); }
/* Дословная диктовка — цитатой с цветной чертой слева (трелвис 3344): главное
   отличие Трелвиса от Trello видно сразу, а не тонет в общем сером тексте. */
.card-voice-text {
  padding: 11px 14px; border-left: 3px solid var(--accent); border-radius: 0 10px 10px 0;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  white-space: pre-wrap; word-break: break-word; color: var(--text); font-size: 13.5px; line-height: 1.55;
}
.card-text-edit { margin-top: 10px; padding: 6px 10px; border-radius: 9px; color: var(--muted); background: var(--soft); font-size: 11.5px; }
.card-text-edit:hover { color: var(--accent); }
.cl-item.pending { opacity: .55; }
.card-media-count { margin-bottom: 7px; color: var(--muted); font-size: 12px; text-align: right; }
.card-media-frame .card-media-del { position: absolute; z-index: 2; top: 8px; right: 8px; width: 28px; height: 28px; border-radius: 50%; color: #fff; background: rgba(0,0,0,.62); font-size: 17px; }
.card-media-frame {
  position: relative; min-height: 260px; overflow: hidden; border-radius: 14px;
  background: #090b0c; border: 1px solid var(--line);
}
.card-media-stage { width: 100%; min-height: 260px; display: grid; place-items: center; cursor: zoom-in; }
.card-media-item { display: block; width: 100%; height: 360px; object-fit: contain; background: #090b0c; }
.card-media-stage video { cursor: default; }
.card-media-arrow, .media-viewer-arrow {
  position: absolute; z-index: 2; top: 50%; transform: translateY(-50%); width: 44px; height: 56px;
  display: grid; place-items: center; border-radius: 12px; color: #fff; font-size: 38px;
  background: rgba(0,0,0,.58); backdrop-filter: blur(8px);
}
.card-media-arrow.prev, .media-viewer-arrow.prev { left: 10px; }
.card-media-arrow.next, .media-viewer-arrow.next { right: 10px; }
.card-media-thumbs { display: flex; gap: 8px; padding: 10px 0 2px; overflow-x: auto; }
.card-media-thumb-wrap { position: relative; flex: none; }
.card-media-thumb {
  width: 62px; height: 52px; overflow: hidden; display: grid; place-items: center;
  border: 2px solid transparent; border-radius: 9px; background: #090b0c;
}
.card-media-thumb.active { border-color: var(--accent); }
.card-media-thumb img { width: 100%; height: 100%; object-fit: cover; }
.card-media-video-thumb { color: #fff; font-size: 21px; }
.card-media-thumb-wrap .att-x {
  position: absolute; top: -5px; right: -5px; width: 20px; height: 20px; border-radius: 50%;
  color: #fff; background: rgba(0,0,0,.78); font-size: 13px; line-height: 20px;
}
.card-wide-button, .card-square-button, .card-outbox-action, .card-tool-button {
  border: 1px solid var(--line); background: var(--field); color: var(--bright); font-weight: 750;
}
.card-wide-button {
  width: 100%; min-height: 44px; margin-top: 9px; padding: 9px 13px; border-radius: 11px;
}
.card-wide-button:hover, .card-square-button:hover, .card-tool-button:hover { border-color: var(--accent); }
.card-wide-button.secondary { color: var(--muted); background: transparent; }
.card-attachment-add { margin: 12px 0 14px; }
.card-media-section .card-attachment-add { margin-bottom: 0; }
/* Пустой медиаблок — одна кнопка добавления, без рамки и лишнего воздуха (1625).
   Свой отступ кнопке больше не нужен: воздух между разделами задаёт секция. */
.card-media-section.card-media-empty { padding: 0; border: 0; background: transparent; }
.card-media-section.card-media-empty .card-attachment-add { margin: 0; }
/* Рамка в рамке убрана (трелвис 1913): у фото есть собственная обводка, внешняя
   коробка вокруг неё только дублировала контур и ела ширину. */
.card-media-section { padding: 0; border: 0; background: transparent; }
.card-files { display: grid; gap: 7px; margin-top: 10px; }
.card-file {
  display: flex; align-items: center; gap: 9px; min-height: 42px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--comment-field); cursor: pointer;
}
.card-file-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-file .att-x { flex: none; color: var(--muted); font-size: 18px; }
.outbox-actions {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; margin: 14px 0;
}
.outbox-actions.compact { display: block; }
.outbox-actions.compact .card-outbox-action.primary { width: 100%; }
.card-outbox-more { margin-top: 7px; border: 1px solid var(--line); border-radius: 11px; overflow: hidden; }
.card-outbox-more > summary { padding: 10px 12px; color: var(--muted); font-size: 11.5px; cursor: pointer; }
.card-outbox-more > div { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; padding: 0 7px 7px; }
.card-outbox-action { min-height: 48px; padding: 10px 12px; border-radius: 12px; text-align: left; }
.card-outbox-action.primary { grid-column: 1 / -1; border-color: var(--accent); background: var(--accent); color: var(--on-accent); }
.card-outbox-action.active { border-color: var(--yellow); color: var(--yellow); background: rgba(245,205,71,.08); }
.card-outbox-action.danger { color: var(--red); }
.card-content-section textarea.m-desc { min-height: 112px; background: var(--comment-field); }
.card-checklist-add { display: grid; grid-template-columns: 1fr 44px; gap: 8px; margin-top: 10px; }
.card-square-button { min-height: 42px; border-radius: 10px; font-size: 22px; }
/* Комментарии — такой же раздел без коробки, заголовок капсом (трелвис 3344).
   Селекторы двойные: общие правила `.comments-box`/`.comments-head` лежат ниже
   по файлу и при равной силе перебивали бы одиночный класс карточки. */
.comments-box.card-comments-section {
  margin: 22px 0 0; padding: 0; border: 0; border-radius: 0; background: transparent; overflow: visible;
}
.comments-head.card-comments-summary {
  min-height: 0; padding: 0; gap: 5px; color: var(--muted); font-size: 11px; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase;
}
.comments-head.card-comments-summary::before { width: auto; font-size: 10px; }
.comments-head.card-comments-summary:hover { color: var(--bright); }
.card-comments-summary strong { color: var(--bright); font-size: 15px; }
.card-comments-summary small { margin-left: auto; color: var(--muted); font-size: 11.5px; font-weight: 500; }
.card-comments-section .comments-content { padding: 12px 0 0; }
.comment-compose { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.comment-voice-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 7px; margin-bottom: 10px; }
.comment-voice-row .card-wide-button { margin: 0; border-color: var(--accent); color: var(--accent); }
.comment-voice-row .card-wide-button.stop { border-color: var(--red); color: var(--red); }
#cd-voice-status { color: var(--muted); font-size: 11.5px; }
#cd-voice-status[data-state="recording"] { color: var(--red); font-weight: 800; }
#cd-voice-status[data-state="ready"] { color: var(--green); }
#cd-voice-status[data-state="error"] { color: var(--red); }
.comment-voice-state { display: flex; align-items: center; gap: 8px; min-height: 34px; padding: 7px 10px; border-radius: 9px; }
.comment-voice-state[data-state="idle"] { display: none; }
.comment-voice-state[data-state="recording"] { color: var(--red); background: rgba(248,113,104,.10); border: 1px solid rgba(248,113,104,.45); }
.comment-record-dot { display: none; width: 9px; height: 9px; flex: none; border-radius: 50%; background: var(--red); }
.comment-record-wave { display: none; height: 18px; margin-left: auto; align-items: center; gap: 3px; }
.comment-record-wave i { width: 3px; height: 7px; border-radius: 3px; background: var(--red); animation: comment-wave .72s ease-in-out infinite alternate; }
.comment-record-wave i:nth-child(2) { animation-delay: -.18s; }
.comment-record-wave i:nth-child(3) { animation-delay: -.36s; }
.comment-record-wave i:nth-child(4) { animation-delay: -.54s; }
.comment-voice-state[data-state="recording"] .comment-record-dot { display: block; animation: comment-pulse 1s ease-in-out infinite; }
.comment-voice-state[data-state="recording"] .comment-record-wave { display: flex; }
@keyframes comment-pulse { 50% { opacity: .3; transform: scale(.72); } }
@keyframes comment-wave { to { height: 18px; } }
.mention-picker { margin-top: 7px; color: var(--muted); font-size: 12px; }
.mention-picker summary { cursor: pointer; }
.mention-picker .pill-row { margin-top: 8px; }
.comment-send-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.comment-send-row .primary { flex: 1; min-height: 44px; }
/* Блок «Действия» из карточки убран, его команды живут в «•••» (трелвис 1815).
   Кнопка-действие осталась только у контроля исходящей задачи. */
.card-tool-button { min-height: 40px; padding: 8px 11px; border-radius: 10px; color: var(--muted); }
.card-tool-button.active { color: var(--yellow); border-color: var(--yellow); }
.card-tool-button.danger { color: var(--red); }
/* 1699: контроль исходящей — видимая строка-действие во всю ширину */
.outbox-control-row { margin: 2px 0 16px; }
.outbox-control-row .card-tool-button { width: 100%; display: flex; align-items: center; justify-content: center; gap: 6px; min-height: 46px; font-size: 14px; }
.card-close-row { display: flex; justify-content: center; padding: 8px 0 2px; }
.card-close {
  min-width: 150px; min-height: 46px; border: 1px solid var(--line); border-radius: 13px;
  color: var(--bright); background: var(--field); font-size: 15px;
}
.finish-reason-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.finish-reason-actions .btn { min-height: 46px; }

/* Последние задачи сотрудника — промежуточный мобильный экран между карточкой
   и большой доской. Терминальные задачи не исчезают. */
.person-tasks-page {
  flex: 1; min-height: 0; overflow-y: auto; padding: 16px;
  background: linear-gradient(180deg, rgba(5,12,8,.34), rgba(5,12,8,.62));
}
.person-tasks-head {
  position: sticky; top: 0; z-index: 6; max-width: 760px; margin: 0 auto 12px;
  display: flex; align-items: center; gap: 12px; padding: 10px 14px 10px 10px;
  border: 1px solid rgba(255,255,255,.14); border-radius: 18px;
  background: rgba(7,14,10,.62); box-shadow: 0 12px 30px rgba(0,0,0,.22);
  -webkit-backdrop-filter: blur(22px) saturate(1.18); backdrop-filter: blur(22px) saturate(1.18);
}
.person-tasks-person { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; }
.person-tasks-person > span:last-child { min-width: 0; }
.person-tasks-person strong, .person-tasks-person small { display: block; }
.person-tasks-person strong { overflow: hidden; color: var(--bright); font-size: 16px; text-overflow: ellipsis; white-space: nowrap; }
.person-tasks-person small { margin-top: 2px; color: var(--muted); font-size: 11px; }
.person-tasks-avatar { width: 38px; height: 38px; flex: none; border-radius: 50%; object-fit: cover; display: grid; place-items: center; }
.person-tasks-close { border-color: rgba(255,255,255,.15); }
/* Место под аварийный бургер (трелвис 1896): без сдвига кнопка легла бы прямо
   на аватар человека. */
body.has-floating-burger .person-tasks-head { padding-left: 58px; }
.person-task-filters {
  max-width: 760px; margin: 0 auto 10px; display: flex; gap: 6px; overflow-x: auto;
  padding: 2px; scrollbar-width: none;
}
.person-task-filters::-webkit-scrollbar { display: none; }
.person-task-filters button {
  flex: none; padding: 7px 10px; border: 1px solid rgba(255,255,255,.12);
  border-radius: 999px; background: rgba(7,14,10,.52); color: var(--muted); font-size: 11.5px;
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
}
.person-task-filters button.active { border-color: var(--accent); color: var(--accent); background: rgba(var(--accent-rgb),.13); }
.person-task-list { max-width: 760px; margin: 0 auto; display: grid; gap: 8px; padding-bottom: 32px; }
.person-task-item {
  display: flex; align-items: stretch; overflow: hidden; border: 1px solid rgba(255,255,255,.12);
  border-radius: 16px; background: rgba(8,15,11,.72);
  -webkit-backdrop-filter: blur(17px) saturate(1.12); backdrop-filter: blur(17px) saturate(1.12);
  box-shadow: 0 8px 22px rgba(0,0,0,.18);
}
.person-task-item.completed { border-color: rgba(75,206,151,.28); }
.person-task-item.cancelled { opacity: .72; border-color: rgba(248,113,104,.28); }
.person-task-open { flex: 1; min-width: 0; display: flex; align-items: flex-start; gap: 0; padding: 12px 12px 12px 2px; text-align: left; }
/* Один кругляшок-кнопка (трелвис 1833): рамка и есть кругляшок, внутри пусто у
   активной задачи. Тап по нему сразу закрывает задачу, карточка не открывается. */
.person-task-state {
  width: 26px; height: 26px; flex: none; margin: 12px 0 0 12px; display: grid; place-items: center;
  border: 2px solid var(--accent); border-radius: 50%; color: var(--accent);
  font-size: 15px; font-weight: 900; cursor: pointer;
}
.person-task-state:hover { border-color: var(--green); color: var(--green); background: rgba(75,206,151,.10); }
.person-task-item.completed .person-task-state { border-color: var(--green); color: var(--green); }
.person-task-item.cancelled .person-task-state { border-color: var(--red); color: var(--red); }
.person-task-copy { min-width: 0; }
.person-task-copy strong, .person-task-copy small { display: block; }
.person-task-direction {
  display: inline-flex; margin-bottom: 4px; padding: 2px 7px; border-radius: 999px;
  color: var(--accent); background: rgba(var(--accent-rgb),.11); font-size: 9.5px; font-weight: 850;
}
.person-task-item.incoming .person-task-direction { color: var(--green); background: rgba(75,206,151,.10); }
.person-task-copy strong { color: var(--bright); font-size: 14px; line-height: 1.35; overflow-wrap: anywhere; }
.person-task-copy small { margin-top: 5px; color: var(--muted); font-size: 10.5px; line-height: 1.35; }
.person-task-copy small b { color: var(--accent); }
.person-task-item.completed .person-task-copy small b { color: var(--green); }
.person-task-item.cancelled .person-task-copy small b { color: var(--red); }
.person-task-more { width: 44px; flex: none; color: var(--muted); font-size: 16px; }
.person-task-more:hover { color: var(--bright); background: rgba(255,255,255,.06); }
.relationship-filters { margin-bottom: 5px; }
.state-filters { margin-bottom: 10px; }
.person-action-choices { display: grid; gap: 7px; }
.person-action-choice {
  min-height: 42px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 11px;
  color: var(--bright); background: var(--field); text-align: left;
}
.person-action-choice.active { border-color: var(--accent); color: var(--accent); }
.media-viewer-host { padding: 0; background: rgba(0,0,0,.94); }
.modal.media-viewer-modal {
  width: 100%; height: 100dvh; max-width: none; margin: 0; padding: 12px;
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto; border: 0; border-radius: 0; background: #060707;
}
.media-viewer-head { display: flex; justify-content: space-between; gap: 12px; padding: 4px 8px 10px; color: #fff; }
.media-viewer-head strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.media-viewer-stage-wrap { position: relative; min-height: 0; display: grid; place-items: center; overflow: hidden; }
.media-viewer-stage { width: 100%; height: 100%; display: grid; place-items: center; }
.media-viewer-item { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
.media-viewer-arrow:disabled { display: none; }
.outbox-time-presets { display: grid; gap: 8px; margin-bottom: 18px; }
.outbox-time-presets .btn { min-height: 42px; text-align: left; justify-content: flex-start; }
@media (max-width: 560px) {
  .modal-backdrop.card-detail-host { display: block; padding: 0; background: var(--modal); }
  .modal.card-detail-modal { min-height: 100dvh; max-width: none; margin: 0; border: 0; border-radius: 0; }
  .card-detail-shell { padding: 15px 14px calc(16px + env(safe-area-inset-bottom, 0px)); }
  /* На телефоне левый край кнопки совпадает с системным крестиком Telegram:
     отступ модалки (10px) + 6px = те же ~16px от края экрана. */
  .card-detail-topbar { margin: -15px -14px 7px; padding: 9px 10px 5px 6px; }
  .card-person-link { padding-top: 3px; }
  .outbox-status-banner { margin-top: 8px; }
  .card-media-section { margin: 4px -14px 14px; padding: 8px 14px 12px; border: 0; border-radius: 0; background: transparent; }
  /* Пустой медиаблок не должен вылезать за поля вместе с фото: иначе кнопка
     «Добавить фото, видео или файл» шире всех остальных секций (трелвис 1813). */
  .card-media-section.card-media-empty { margin-left: 0; margin-right: 0; padding: 0; }
  .card-media-frame, .card-media-stage { min-height: 0; }
  .card-media-item { height: min(68vh, 440px); }
  .outbox-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .card-outbox-action { min-height: 52px; }
  .card-content-section { padding: 14px; }
  .card-content-section.card-fold { padding: 0; }
  /* 1717: overview на телефоне — читаемая вертикальная лента колонок на всю ширину.
     CSS zoom в webview Telegram ненадёжен (у части клиентов не применяется — отсюда
     «слишком крупно»), а разновысокие колонки в одном ряду оставляли широкие пустые
     полосы. Складываем колонки в один вертикальный поток и не полагаемся на zoom. */
  /* Промежуток между колонками вдвое шире (трелвис 1931): в одной вертикальной
     ленте колонки сливались, и границу приходилось искать глазами. */
  /* Лента — «рама»: боковые поля и просвет сверху вынесены НАРУЖУ прокрутки
     (margin), скролл-порт скруглён сверху, а колонки стоят ровно по его
     краям. Тогда и линию обрезки над заголовком, и вырезы его круглых углов
     режет сам браузер на композиторе — синхронно с пальцем, без JS (трелвис
     1965, третья итерация). */
  .board.board-overview {
    padding-left: 0; padding-right: 0;
    margin-left: 16px; margin-right: 16px;
    border-radius: var(--radius) var(--radius) 0 0;
  }
  .board.board-overview .board-canvas {
    flex-direction: column; flex-wrap: nowrap;
    width: 100% !important; gap: 20px !important; row-gap: 20px !important;
    padding: 0 0 calc(22px + env(safe-area-inset-bottom, 0px));
  }
  .board.board-overview .column { width: 100% !important; min-width: 0 !important; }
  /* Свёрнутые «Меня контролят» и «Я контролю» в ленте — такие же широкие, как
     остальные (трелвис 1968): узкая плашка обрезала название на полуслове. */
  .board.board-overview .column.collapsed {
    width: 100% !important; min-width: 0 !important;
  }
  /* Ритм карточки в ленте задаётся теми же переменными, что и везде (трелвис
     5234). Объявленные здесь напрямую `gap` и `padding` перебивали плотные
     пороги и `body.compact` — на телефоне ужатие полной колонки не работало
     вовсе; а поля 7/9 расходились с обложкой (-8/-10 из базового правила) и
     давали полоску фона по её краю. Один источник — переменные. */
  .board.board-overview .col-cards { --card-gap: 6px; }
  .board.board-overview .card { --card-pad-y: 7px; --card-pad-x: 9px; }
  /* «Слишком крупно» из 1717 — это не только масштаб, но и типографика: в ленте
     на телефоне карточка ужимается, чтобы на экран влезало больше задач.
     Масштаб при этом больше не заперт на 100 % — кнопки −/+ и пинч работают. */
  .board.board-overview .card .card-title { font-size: 12.5px; line-height: 1.3; }
  /* Название колонки вдвое крупнее (трелвис 1931): на телефоне этот режим
     основной, и заголовок должен читаться сразу, а не наравне с карточками. */
  .board.board-overview .col-head { padding-top: 10px; padding-bottom: 8px; }
  .board.board-overview .col-head .col-title { font-size: 25px; line-height: 1.15; }
  /* «•••» остаётся общего размера 13px — правило доски одно для всех мест. */
  /* Счётчик задач растёт вместе с названием (трелвис 1967): рядом с крупным
     заголовком мелкая цифра выглядела забытой. */
  .board.board-overview .col-head .col-count { font-size: 19px; }
  .board.board-overview .card-badges { font-size: 10.5px; }
}

/* Чек-лист */
.cl-bar { height: 6px; background: var(--soft); border-radius: 3px; overflow: hidden; margin: 2px 0 8px; }
.cl-fill { height: 100%; background: var(--green); transition: width .2s; }
.cl-item { display: flex; gap: 9px; align-items: flex-start; padding: 4px 4px; border-radius: 6px; }
.cl-item:hover { background: var(--field); }
.cl-item:hover .cl-x { opacity: 1; }
.cl-check {
  flex: none; width: 16px; height: 16px; border-radius: 4px; border: 2px solid var(--muted);
  font-size: 10px; color: transparent; display: inline-flex; align-items: center;
  justify-content: center; cursor: pointer; margin-top: 2px;
}
.cl-check:hover { border-color: var(--green); }
.cl-check.done { background: var(--green); border-color: var(--green); color: var(--on-accent); }
.cl-text { flex: 1; font-size: 13.5px; word-break: break-word; }
.cl-text.done { color: var(--muted); text-decoration: line-through; }
.cl-x { opacity: 0; color: var(--muted); padding: 0 6px; border-radius: 5px; flex: none; }
.cl-x:hover { color: var(--red); }
.cb.cl-ok { color: var(--green); }

/* Комментарии в карточке — один слитный блок: список + поле ввода вместе */
.comments-box {
  background: var(--field); border: 1px solid var(--line); border-radius: 12px;
  padding: 0; margin-top: 10px; overflow: hidden;
}
.comments-box textarea.m-desc, .comments-box input { background: var(--comment-field); }
.comments-head {
  color: var(--bright); font-size: 13px; font-weight: 750; cursor: pointer;
  list-style: none; padding: 10px 12px; user-select: none; display: flex; align-items: center; gap: 8px;
}
.comments-head::-webkit-details-marker { display: none; }
.comments-head::before { content: "▸"; color: var(--muted); display: inline-block; width: 18px; }
.comments-box[open] .comments-head::before { content: "▾"; }
.comments-last { margin-left: auto; max-width: 58%; color: var(--muted); font-size: 10.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: right; }
.comments-content { padding: 0 12px 12px; }
.card-tools { border-top: 1px solid var(--line); padding-top: 12px; }

.comment { display: flex; gap: 9px; margin-bottom: 10px; }
.comment .c-emoji { flex: none; font-size: 16px; margin-top: 2px; }
.comment .c-body { flex: 1; background: var(--field); border-radius: 10px; padding: 8px 11px; }
.comment .c-head { display: flex; gap: 8px; align-items: baseline; margin-bottom: 3px; }
.comment .c-author { color: var(--bright); font-weight: 600; font-size: 12.5px; }
.comment .c-date { color: var(--muted); font-size: 11px; }
.comment .c-text { font-size: 13.5px; white-space: pre-wrap; word-break: break-word; }
/* Ответ нейронки (3677): логотип на белой подложке — чёрный OpenAI виден и в
   тёмных темах; под текстом мелко модель и эффорт. */
.comment .c-ai {
  flex: none; width: 20px; height: 20px; margin-top: 1px; border-radius: 50%;
  background: #fff; box-shadow: 0 0 0 1px var(--line);
  display: flex; align-items: center; justify-content: center;
}
.comment .c-ai img { width: 13px; height: 13px; display: block; }
.comment .c-model { margin-top: 4px; color: var(--muted); font-size: 10.5px; line-height: 1.3; }
.comment.report .c-body { border-left: 3px solid var(--yellow); }
.report-tag { color: var(--yellow); font-size: 11px; font-weight: 700; }

.att-grid { display: flex; gap: 8px; flex-wrap: wrap; }
.att {
  width: 92px; border-radius: 8px; overflow: hidden; background: var(--field); cursor: pointer;
  border: 1px solid var(--line); position: relative;
}
.att img { width: 100%; height: 64px; object-fit: cover; display: block; }
.att .att-name { font-size: 10px; color: var(--muted); padding: 3px 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.att .att-x { position: absolute; top: 2px; right: 2px; background: rgba(0,0,0,.6); border-radius: 6px; padding: 0 5px; color: #fff; font-size: 11px; }
.att-file { display: flex; align-items: center; justify-content: center; height: 64px; font-size: 24px; }

.hist-line { font-size: 12px; color: var(--muted); padding: 3px 0; }
.hist-line b { color: var(--text); font-weight: 600; }

/* ---------- Задача нейронки: три ясных уровня раскрытия (трелвис 862) ---------- */
.ktask-overline {
  display: flex; align-items: center; gap: 9px; margin: 10px 0 7px;
  color: var(--muted); font-size: 11.5px; font-weight: 700;
}
.kt-project { display: inline-flex; align-items: center; gap: 6px; color: var(--text); }
.kt-project i { width: 9px; height: 9px; border-radius: 50%; flex: none; box-shadow: 0 0 0 2px rgba(255,255,255,.07); }
.kt-project-name { color: var(--bright); font-size: 16px; }
.ktask-number { font-size: 10.5px; color: var(--muted); }
.ktask-toolbar { display: flex; align-items: center; gap: 7px; position: sticky; top: 0; z-index: 2; padding-bottom: 5px; background: var(--modal); }
.ktask-toolbar .modal-close { color: var(--bright); font-size: 12px; padding: 5px 9px; }
.ktask-title { margin-bottom: 7px !important; font-size: 22px !important; line-height: 1.2; }
.ktask-modal > .project-inspector-status { margin-bottom: 12px; }
.ktask-accept { width: 100%; min-height: 42px; margin: 0 0 12px; }
.ktask-modal > .ktask-summary { margin-bottom: 12px; }
.ktask-modal > .project-inspector-question { margin-bottom: 12px; }
.ktask-short {
  color: var(--bright); font-size: 14px; line-height: 1.45; white-space: pre-wrap;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.ktask-reveal {
  display: grid; grid-template-rows: 0fr; opacity: 0; visibility: hidden;
  transition: grid-template-rows .2s ease, opacity .16s ease, visibility 0s linear .2s;
}
.ktask-reveal-inner { min-height: 0; overflow: hidden; }
.ktask-modal[data-level="2"] .ktask-level2,
.ktask-modal[data-level="3"] .ktask-level2,
.ktask-modal[data-level="3"] .ktask-level3 {
  grid-template-rows: 1fr; opacity: 1; visibility: visible;
  transition: grid-template-rows .2s ease, opacity .2s ease, visibility 0s;
}
.ktask-modal[data-level="3"] .ktask-level2-actions { display: none; }
.ktask-section-title {
  margin: 18px 0 9px; padding-top: 12px; border-top: 1px solid var(--line);
  color: var(--bright); font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
}
.kt-info-row { margin: 0 0 11px; }
.kt-info-value { color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }
.kt-attachments { display: grid; gap: 7px; }
.kt-attachment {
  display: flex; gap: 9px; align-items: flex-start; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--field);
}
.kt-attachment b, .kt-attachment small { display: block; }
.kt-attachment small { margin-top: 2px; color: var(--muted); font-size: 11.5px; }
/* Вложение — ссылка на скачивание: курсор и подсветка говорят, что жать можно
   (трелвис 3618). Файл, ещё не доехавший в облако, гаснет и не притворяется живым. */
a.kt-attachment { text-decoration: none; color: inherit; cursor: pointer; }
a.kt-attachment:hover { border-color: var(--accent); background: var(--field-hover, var(--field)); }
.kt-attachment.missing { opacity: .6; }
.kt-attachment-meta { color: var(--muted); }
a.kt-attachment:hover .kt-attachment-meta { color: var(--bright); }
/* Ссылка, а не кнопка: скачивание должен уметь запустить сам браузер, поэтому
   тут <a download> в шкуре кнопки (трелвис 3617). */
.ktask-download { display: inline-flex; align-items: center; text-decoration: none; }
.kt-long-text { color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; font-size: 13px; line-height: 1.5; }
.kt-original { padding: 10px; border-radius: 8px; background: var(--comment-field); }
.kt-log { display: grid; gap: 6px; }
.kt-log-step { display: flex; gap: 9px; align-items: flex-start; color: var(--muted); }
.kt-log-step.done { color: var(--text); }
.kt-log-mark { width: 18px; color: var(--muted); text-align: center; flex: none; }
.kt-log-step.done .kt-log-mark { color: var(--green); }
.kt-log-step b, .kt-log-step small { display: block; }
.kt-log-step b { font-size: 12.5px; }
.kt-log-step small { color: var(--muted); font-size: 11px; margin-top: 1px; }
.kt-tech-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 0 18px; }
.kt-events { max-height: 220px; overflow: auto; }
.kt-event-time { float: right; color: var(--muted); margin-left: 8px; }

/* Тост обязан быть виден из открытой карточки (задача 1741): на телефоне её
   подложка непрозрачная и лежит в #modal-root с z-index 500 — при прежних 400
   сообщение «не сохранилось» рисовалось ПОД ней и человек молча терял правку.
   pointer-events: none — чтобы поднятый слой не перехватывал тапы по кнопкам. */
.toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
  background: var(--modal); color: var(--bright); border: 1px solid var(--line);
  padding: 10px 18px; border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,.5);
  z-index: 900; pointer-events: none; font-size: 13.5px; max-width: 90%;
}
.toast.err { border-color: var(--red); color: var(--red); }

.kbadge { font-size: 10.5px; border-radius: 6px; padding: 1px 6px; background: var(--soft); color: var(--text); }
.kbadge.fable { background: #3d2f57; color: var(--purple); }
.kbadge.review { background: #4d3b12; color: var(--yellow); }

.search-results { padding: 4px 0; }
.sr-group { color: var(--muted); font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px; margin: 12px 0 6px; }

/* ---------- Мобилка (Telegram WebApp) ---------- */
@media (max-width: 760px) {
  /* Крестик панели — слева и крупный (трелвис 1806, 1810): единое место закрытия,
     ровно под системным крестиком Telegram. */
  .side-head { display: flex; justify-content: flex-start; padding: 8px 10px 0; }
  .side-close { display: grid; }
  #side-resizer { display: none; }
  body.side-hidden #sidebar { display: flex; }  /* на мобиле панель — оверлей, не прячем насовсем */
  #sidebar {
    position: fixed; z-index: 420; left: 0; top: 0; bottom: 0;
    width: min(86%, 320px) !important; min-width: min(86%, 320px) !important;
    transform: translateX(-105%); transition: transform .22s ease; box-shadow: 12px 0 40px rgba(0,0,0,.45);
  }
  #sidebar.open { transform: translateX(0); }
  #side-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 410; display: none; }
  #side-backdrop.show { display: block; }
  .board { gap: 10px; padding: var(--board-pad-top, 10px) 10px 10px; scroll-snap-type: x proximity; }
  .column {
    width: min(var(--col-w, 276px), calc(var(--ui-viewport-width) - 28px));
    min-width: min(var(--col-w, 276px), calc(var(--ui-viewport-width) - 28px));
    scroll-snap-align: start;
  }
  .add-col { min-width: calc(var(--ui-viewport-width) * .7); width: calc(var(--ui-viewport-width) * .7); }
  .modal-backdrop { padding: 12px 8px; }
  #me-chip .me-name { display: none; }
  /* Комментарии на телефоне: список и переписка по очереди, не рядом */
  .ci-wrap { grid-template-columns: 1fr; }
  .ci-resizer { display: none; }
  .ci-list { border-right: 0; }
  .ci-pane { display: none; }
  .ci-wrap.show-pane .ci-list { display: none; }
  .ci-wrap.show-pane .ci-pane { display: flex; }
  .theme-grid { grid-template-columns: 1fr; }
  .board-inspector-resizer,
  .board-stage.inspector-open .board-inspector { display: none; }
  .inspector-toggle { display: none !important; }
}

/* ---------- Экран «Кто ты?» (самопривязка из Telegram) ---------- */
.claim-screen {
  display: flex; height: 100%; align-items: center; justify-content: center;
  padding: 24px; text-align: center; background: var(--bg); color: var(--text);
}
.claim-box { max-width: 440px; width: 100%; }
.claim-pig { font-size: 52px; margin-bottom: 12px; }
.claim-title { font-size: 20px; font-weight: 700; color: var(--bright); margin-bottom: 6px; }
.claim-sub { color: var(--muted); margin-bottom: 18px; }
.claim-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
.claim-btn {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 16px 10px; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); color: var(--bright); font-size: 15px;
}
.claim-btn:hover { background: var(--card-hover); border-color: var(--accent); }
.claim-emoji { font-size: 30px; }
.claim-err { margin-top: 14px; color: var(--red); min-height: 18px; }

/* Экран отчёта по контролю (5215): задача с описанием и запись могут не влезть
   в телефон — экран прокручивается, коробка по центру, пока помещается. */
.claim-screen.gate-screen { overflow-y: auto; align-items: flex-start; }
.gate-screen .claim-box { margin: auto 0; text-align: left; }
.gate-screen .claim-pig, .gate-screen .claim-title, .gate-screen .claim-sub { text-align: center; }
.gate-card {
  margin-bottom: 14px; padding: 12px 14px; border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--card); color: var(--bright);
}
.gate-desc {
  max-height: 30vh; overflow-y: auto; margin-top: 6px; color: var(--muted);
  font-size: 13px; white-space: pre-wrap;
}
.gate-screen textarea.gate-text { width: 100%; min-height: 90px; margin-bottom: 10px; background: var(--comment-field); }
.gate-screen .btn { width: 100%; min-height: 44px; }
.gate-screen .btn:disabled { opacity: .4; cursor: default; }
.gate-screen .gate-hint { margin: 18px 0 8px; font-size: 12.5px; }

/* ---------- Промпты: дифф и просмотр версий ---------- */
.diff-pre {
  max-height: calc(var(--ui-viewport-height) * .62); overflow: auto; background: var(--panel);
  border: 1px solid var(--line); border-radius: 8px; padding: 10px;
  font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  white-space: pre; color: var(--text);
}
.diff-pre .d-add { color: var(--green); }
.diff-pre .d-del { color: var(--red); }

/* ---------- Фишки v6: конфетти, прогресс доски, паутина, хоткеи ---------- */
.confetti-canvas { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 500; pointer-events: none; }

/* Стареющая карточка: 🕸 N дн — приглушённо, не кричит */
.cb-age { color: var(--muted); opacity: .7; }

/* Прогресс доски в шапке: M/N + тонкая полоска */
.board-progress { display: inline-flex; align-items: center; gap: 7px; }
.bp-nums { color: var(--bright); font-size: 12px; font-weight: 700; }
.bp-track {
  width: 90px; height: 4px; border-radius: 2px; background: var(--soft);
  overflow: hidden; display: inline-block;
}
.bp-fill { display: block; height: 100%; background: var(--green); border-radius: 2px; transition: width .25s; }

/* Бейдж загрузки на панели: открытые задачи человека и проекта (трелвис 720) */
.nv-load {
  margin-left: auto;
  padding: 1px 7px;
  border-radius: 9px;
  font-size: 11px;
  background: var(--bg-3, rgba(255,255,255,.08));
  color: var(--text-dim, #9aa3b2);
  flex: none;
}
/* Жёлтый бейдж: задачи, застрявшие из-за Элвиса (статус «уточнить») */
.nv-load.warn { margin-left: 4px; background: #4d3b12; color: var(--yellow); }
.nv-load + .nv-load { margin-left: 4px; }

/* Последние созданные задачи внизу панели (трелвис 725) */
.recent-item { display: grid; grid-template-columns: 20px auto minmax(0,1fr) auto; gap: 6px; align-items: center; }
/* Явные колонки (трелвис 1505): если точка проекта скрыта, остальные ячейки не съезжают,
   номер и время всегда видны целиком, сокращается только заголовок. */
.recent-item .nv-emoji { grid-column: 1; }
.recent-id { grid-column: 2; color: var(--muted); font-size: 10px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.recent-title { grid-column: 3; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.recent-ago { grid-column: 4; color: var(--muted); font-size: 10.5px; white-space: nowrap; text-align: right; font-variant-numeric: tabular-nums; }
.recent-more { color: var(--muted); font-size: 12px; justify-content: center; }

/* Область поиска (трелвис 498): «где искать» + подсказка распознанной доски */
.search-scope { margin: 2px 0 14px; color: var(--muted); font-size: 13px; }
.search-scope select {
  margin-left: 6px; padding: 5px 9px; border-radius: 8px;
  background: var(--field); color: var(--bright); border: 1px solid var(--line);
  font-size: 13px;
}
.search-scope-hint { margin-left: 8px; font-size: 12px; opacity: .85; }

/* Мелкая строка свежести на карточке (трелвис 724 + просьба Элвиса 12.07) */
.k-created { margin-top: 5px; color: var(--muted); font-size: 10.5px; opacity: .75; }
.card-created-line { margin-top: 12px; text-align: right; opacity: .8; }

/* Крошки: «папка › доска» */
.crumb-pre { flex: none; }

/* ---------- Выпадающее подменю (⋯ у карточки и колонки) ---------- */
/* Всплывающее меню должно быть выше открытой карточки (трелвис 1880): при
   z-index 320 меню «•••» честно открывалось, но пряталось под модалкой
   (#modal-root — 500), и нажатие выглядело как «ничего не происходит». */
.pop-menu {
  position: fixed; z-index: 620; min-width: 210px;
  background: var(--modal); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,.55); padding: 5px; display: flex; flex-direction: column;
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
}
.pop-menu > * { flex: none; }
.pop-item {
  text-align: left; padding: 8px 11px; border-radius: 7px;
  color: var(--bright); font-size: 13.5px;
}
.pop-item:hover { background: var(--soft); }
.pop-item.danger { color: var(--red); }
.pop-note { color: var(--muted); font-size: 11.5px; padding: 6px 11px; }

/* ---------- Компактная быстрая задача + Dictator ---------- */
#quick-bar {
  display: flex; align-items: center; gap: 7px; min-height: 48px;
  padding: 6px 12px; border-bottom: 1px solid var(--line); background: var(--panel);
}
#quick-bar.hidden { display: none; }
.qb-board-nav, .qb-board-menu {
  flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: 11px; color: var(--muted); font-size: 17px;
}
/* Бургер — главный вход к доскам, поэтому крупнее соседей (трелвис 1804). */
.qb-board-nav { width: 40px; height: 40px; border-radius: 13px; color: var(--bright); font-size: 23px; }
/* В широкой раскладке бургер уже есть в верхней панели (трелвис 1851): два
   одинаковых значка подряд слева читались как ошибка вёрстки. Видимость
   привязана к ширине, а не к платформе (трелвис 1901): на ≤760px верхняя строка
   скрыта целиком вместе со своим бургером, и в Telegram на Маке в компактном
   окне не оставалось ни одного входа в панель досок. */
@media (min-width: 761px) { .qb-board-nav { display: none; } }
/* Трелвис 1896: видимость входа в меню решает JS (burgerPlan), а не только
   ширина окна — в webview Telegram медиазапросы врут. Класс ставится лишь
   когда бургер верхней строки на экране и этот стал бы вторым. */
.qb-board-nav.burger-off { display: none; }
/* Зазоры по краям строки одинаковые на глаз (трелвис 1843): у «•••» он был заметно
   меньше, чем у крупного бургера слева. Размер и цвет — как у бургера, а не
   крупные кислотно-зелёные точки (трелвис 1918): раньше цвет брался из --muted,
   который в тёмно-зелёной теме заметно ярче беловатого значка меню. */
.qb-board-menu { margin-left: 4px; font-size: 13px; letter-spacing: .5px; color: var(--bright); }
.qb-board-nav:hover, .qb-board-menu:hover { color: var(--bright); background: rgba(255,255,255,.09); }
.qb-field {
  /* Поле остаётся компактным и прижатым влево даже на широком экране
     (трелвис 1845): свободная ширина не должна превращаться в гигантский ввод. */
  flex: 1; min-width: 0; max-width: 520px;
  display: grid; grid-template-columns: minmax(0,1fr) 34px 34px;
  align-items: center; gap: 3px; padding: 3px 4px 3px 10px;
  border: 1px solid rgba(255,255,255,.16); border-radius: 17px;
  background: rgba(8,14,10,.74); box-shadow: inset 0 1px 0 rgba(255,255,255,.04);
}
#quick-bar .qb-board-menu { margin-right: auto; }
/* Кнопка «Обновить» с временем последнего обновления (трелвис 5086, 5247).
   Живёт в правом конце шапки: в строке быстрой задачи на доске сотрудника и в
   ряду действий на остальных досках — эти два ряда никогда не видны вместе. */
.qb-refresh {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  margin-left: 8px; padding: 5px 10px; white-space: nowrap;
}
.qb-refresh .qb-refresh-ic { font-size: 14px; line-height: 1; }
.qb-refresh .qb-refresh-when { color: var(--muted); font-size: 11.5px; }
.qb-refresh .qb-refresh-when:empty { display: none; }
/* Пока идёт обновление, слово уступает место «обновляю…» — два глагола подряд
   в одной кнопке не нужны. */
.qb-refresh.is-busy .qb-refresh-word { display: none; }
/* На телефоне слова нет, а кнопка ужимается до значка и времени: в той же
   строке живут бургер, поле быстрой задачи и «•••», и подсказка «Задача
   Элвису» обязана остаться в одну строку (трелвис 1902) — на 375px ей нужно
   ~105px, столько поле и остаётся. Правило висит и на медиазапросе, и на
   классе `compact`: в webview Telegram запрос не единственный источник правды. */
@media (max-width: 760px) {
  .qb-refresh { gap: 3px; margin-left: 6px; padding: 4px 6px; }
  .qb-refresh .qb-refresh-word { display: none; }
  .qb-refresh .qb-refresh-ic { font-size: 12.5px; }
  .qb-refresh .qb-refresh-when { font-size: 10.5px; }
}
body.compact .qb-refresh { gap: 3px; margin-left: 6px; padding: 4px 6px; }
body.compact .qb-refresh .qb-refresh-word { display: none; }
body.compact .qb-refresh .qb-refresh-ic { font-size: 12.5px; }
body.compact .qb-refresh .qb-refresh-when { font-size: 10.5px; }
.qb-refresh.is-busy { opacity: .6; }
.qb-refresh.is-busy .qb-refresh-ic { animation: qb-refresh-spin 1s linear infinite; }
@keyframes qb-refresh-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .qb-refresh.is-busy .qb-refresh-ic { animation: none; }
}
#qb-inp {
  min-height: 34px; max-height: min(180px, 28vh); resize: none; overflow-y: auto;
  padding: 7px 2px 6px; border: 0; background: transparent; line-height: 1.38;
}
#qb-inp:focus { border: 0; }
.qb-record, .qb-send {
  width: 34px; height: 34px; display: grid; place-items: center; align-self: end;
  border: 1px solid rgba(var(--accent-rgb),.28); border-radius: 13px;
  font-size: 17px; font-weight: 850; color: var(--accent);
  background: rgba(8,16,11,.72);
}
.ic-mic { width: 1.15em; height: 1.15em; flex: none; vertical-align: -.2em; }
.qb-record .ic-mic { width: 19px; height: 19px; }
.qb-record:hover { border-color: rgba(var(--accent-rgb),.52); background: rgba(var(--accent-rgb),.12); }
.qb-record.is-recording { color: #fff; background: var(--red); }
.qb-send { opacity: .38; }
.qb-send.ready { opacity: 1; border-color: rgba(var(--accent-rgb),.55); background: rgba(var(--accent-rgb),.16); }
.qb-send:disabled { opacity: .24; }
.qb-context {
  position: absolute !important; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
#quick-compose {
  position: absolute; z-index: 270;
  top: var(--quick-compose-top, 102px); right: 12px; width: min(470px, calc(100% - 24px));
  padding: 10px; border: 1px solid rgba(255,255,255,.16); border-radius: 16px;
  background: rgba(10,16,12,.90); box-shadow: 0 16px 46px rgba(0,0,0,.42);
  -webkit-backdrop-filter: blur(20px) saturate(1.2); backdrop-filter: blur(20px) saturate(1.2);
}
.qb-compose-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 7px; }
.qb-compose-head > div { display: flex; flex: 1; min-width: 0; flex-direction: column; }
.qb-compose-head b { color: var(--bright); font-size: 14px; }
.qb-compose-head small { color: var(--muted); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qb-close { flex: none; width: 27px; height: 27px; border-radius: 7px; color: var(--muted); font-size: 19px; line-height: 1; }
.qb-close:hover { color: var(--bright); background: var(--soft); }
.qb-recorder {
  display: flex; align-items: center; gap: 8px; min-height: 34px; margin-bottom: 8px; padding: 5px 7px;
  border-radius: 8px; background: var(--comment-field);
}
.qb-rec-dot { width: 9px; height: 9px; flex: none; border-radius: 50%; background: var(--muted); opacity: .55; }
.qb-recorder[data-state="recording"] .qb-rec-dot { background: var(--red); opacity: 1; animation: qb-pulse 1s ease-in-out infinite; }
.qb-recorder[data-state="paused"] .qb-rec-dot { background: var(--yellow); opacity: 1; }
.qb-recorder[data-state="transcribing"] .qb-rec-dot { background: var(--accent); opacity: 1; animation: qb-pulse .8s ease-in-out infinite; }
.qb-recorder[data-state="ready"] .qb-rec-dot { background: var(--green); opacity: 1; }
.qb-recorder[data-state="error"] .qb-rec-dot { background: var(--red); opacity: 1; }
@keyframes qb-pulse { 50% { opacity: .35; transform: scale(.78); } }
#qb-timer { flex: none; min-width: 39px; color: var(--bright); font-size: 12px; font-variant-numeric: tabular-nums; }
.qb-status { flex: 1; min-width: 0; color: var(--muted); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qb-rec-action { flex: none; padding: 3px 7px; border-radius: 6px; color: var(--bright); background: var(--soft); font-size: 11px; }
.qb-rec-action:hover { background: var(--active); color: var(--accent); }
.qb-compose-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 7px; }
.qb-compose-actions .btn { width: auto; }

/* ---------- Реальные вопросы Элвису: компактно под проектной доской ---------- */
.wait-block {
  margin: 0 14px 10px; padding: 4px 0; border-top: 1px solid var(--line);
  max-height: min(150px, calc(var(--ui-viewport-height) * .22)); overflow-y: auto; flex: none;
}
.wait-item { min-height: 38px; display: flex; align-items: flex-start; gap: 8px; padding: 4px 30px 4px 0; position: relative; }
.wait-item + .wait-item { border-top: 1px solid rgba(255,255,255,.04); }
.wait-q {
  flex: 1; min-width: 0; padding: 0; border: 0; background: none; color: var(--text);
  font: inherit; font-size: 12px; line-height: 1.4; text-align: left; white-space: pre-wrap;
  overflow: visible; overflow-wrap: anywhere; text-overflow: clip;
}
.wait-q:hover { color: var(--bright); }
.wait-inp {
  width: min(300px, 35%); min-width: 150px; min-height: 30px; max-height: min(240px, 40vh);
  resize: vertical; overflow-y: auto; background: var(--comment-field); font: inherit; font-size: 12px;
  line-height: 1.4; padding: 5px 8px;
}
.wait-number { position: absolute; right: 2px; bottom: 3px; color: var(--muted); font-size: 8px; opacity: .62; }

/* ---------- 💬 Раздел «Комментарии»: список слева, переписка справа ---------- */
.ci-wrap {
  flex: 1; min-height: 0; display: grid;
  grid-template-columns: minmax(240px, var(--ci-list-w,330px)) 9px minmax(0,1fr);
}
.ci-list { overflow-y: auto; padding: 10px 8px; }
.ci-resizer { position: relative; cursor: col-resize; touch-action: none; border-left: 1px solid var(--line); }
.ci-item {
  display: flex; flex-direction: column; gap: 3px; width: 100%;
  text-align: left; padding: 9px 11px; border-radius: 10px; margin-bottom: 4px;
}
.ci-item:hover { background: var(--field); }
.ci-item.active { background: var(--active); }
.ci-title { color: var(--bright); font-size: 13.5px; font-weight: 600; overflow-wrap: anywhere; }
.ci-sub { color: var(--muted); font-size: 11.5px; }
.ci-last { color: var(--muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ci-pane { display: flex; flex-direction: column; min-width: 0; padding: 12px 14px; overflow: hidden; }
.ci-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.ci-card-title { flex: 1; min-width: 0; color: var(--bright); font-weight: 700; font-size: 15px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ci-comments { flex: 1; min-height: 0; overflow-y: auto; margin-bottom: 10px; }

/* ---------- Компактный режим (Aa): мельче карточки и панель ---------- */
/* На телефоне карточка задаёт тот же ритм через переменные (трелвис 5234):
   свои `margin-top` у бейджей здесь стоять не должны — иначе плотные режимы
   ниже до них не дотянутся. */
body.compact .card { --card-pad-y: 4px; --card-pad-x: 8px; --card-row-gap: 3px; border-radius: 6px; }
body.compact .card .card-title { font-size: 12px; gap: 6px; }
body.compact .card-check { width: 14px; height: 14px; font-size: 9px; }
body.compact .card-badges { font-size: 10px; gap: 6px; }
body.compact .k-created { font-size: 9px; margin-top: 3px; }
body.compact .col-cards { --card-gap: 5px; padding: 3px 5px; }
body.compact .col-head { font-size: 12px; padding: 8px 8px 4px 11px; }
body.compact .col-foot { padding: 4px 6px 7px; }
body.compact .add-card-btn { padding: 5px 8px; font-size: 12px; }
body.compact .nav-item { font-size: 12.5px; padding: 3px 8px; }
body.compact .nav-fold { font-size: 11px; }
body.compact .nv-load { font-size: 10px; padding: 0 6px; }
body.compact #topbar { min-height: 44px; padding: 6px 10px; }
body.compact #crumbs .crumb-title { font-size: 14px; }
body.compact .icon-btn { font-size: 15px; padding: 4px 7px; }
body.compact .mirror-note { font-size: 10.5px; }
body.compact .board { gap: 9px; padding: var(--board-pad-top, 9px) 10px 12px; }
body.compact .column {
  width: calc(var(--col-w, 276px) * .8);
  min-width: calc(var(--col-w, 276px) * .8);
}
@media (max-width: 760px) {
  .ci-wrap {
    width: 100%; min-width: 0;
    grid-template-columns: minmax(0, 1fr);
  }
  .ci-list { width: 100%; min-width: 0; }
  .ci-pane { display: none; width: 100%; min-width: 0; }
  .ci-wrap.show-pane .ci-list { display: none; }
  .ci-wrap.show-pane .ci-pane { display: flex; }
  .wait-item { flex-direction: column; padding-right: 28px; }
  .wait-inp { width: 100%; min-width: 0; }
  body.compact .column {
    width: min(calc(var(--col-w, 276px) * .8), calc(var(--ui-viewport-width) - 28px));
    min-width: min(calc(var(--col-w, 276px) * .8), calc(var(--ui-viewport-width) - 28px));
  }
  body.compact .add-col {
    min-width: min(200px, calc(var(--ui-viewport-width) - 28px));
    width: min(200px, calc(var(--ui-viewport-width) - 28px));
  }
  /* На телефоне доска использует одну верхнюю строку. Она лежит поверх обоев:
     при прокрутке обзорные колонки проходят под настоящим стеклом. */
  body.quick-entry-visible #topbar,
  body.quick-entry-visible .board-bar { display: none; }
  body.quick-entry-visible #quick-bar {
    position: absolute; z-index: 260; inset: 0 0 auto;
    min-height: 52px; padding: calc(7px + env(safe-area-inset-top, 0px)) 8px 7px;
    border-bottom: 1px solid rgba(255,255,255,.09);
    background: rgba(6,13,9,.43);
    -webkit-backdrop-filter: blur(22px) saturate(1.18); backdrop-filter: blur(22px) saturate(1.18);
  }
  /* Отступ под плавающей строкой — это поле ПЕРЕД доской, а не зона внутри
     её прокрутки (трелвис 1930, 1965). Иначе карточки уезжали в паддинг и
     торчали полоской над липким заголовком колонки. Правило одно на оба
     режима: и лента, и стандартный вид прячут содержимое ровно по краю
     прокрутки, а просвет `--board-head-gap` добавлен в то же поле. */
  body.quick-entry-visible .board {
    padding-top: 0;
    margin-top: calc(var(--board-float-head, calc(60px + env(safe-area-inset-top, 0px)))
      + var(--board-head-gap, 10px));
  }
  body.quick-entry-visible .qb-field { background: rgba(7,14,10,.58); }
  body.person-tasks-visible #topbar { display: none; }
  .person-tasks-page { padding: 10px; }
  .person-tasks-head { border-radius: 16px; }
  .modal.ktask-modal {
    width: calc(var(--ui-viewport-width) - 24px);
    max-width: calc(var(--ui-viewport-width) - 24px);
    overflow-x: hidden;
    /* touch-action: none нужен мышиному перетаскиванию на десктопе, но на
       телефоне он же запрещает прокрутку пальцем — низ длинной задачи был
       недостижим. Здесь перетаскивание не нужно: возвращаем прокрутку. */
    cursor: default;
    touch-action: pan-y;
    overscroll-behavior: contain;
  }
  .ktask-toolbar { flex-wrap: wrap; }
}
@media (max-width: 460px) {
  #topbar { gap: 5px; padding-left: 8px; padding-right: 8px; }
  .top-actions { gap: 2px; }
  .theme-modal { padding: 13px; }
  .btn.small.appearance-toggle { min-width: 32px; font-size: 0; padding: 5px 8px; }
  .btn.small.appearance-toggle span { font-size: 13px; }
  #me-chip { display: none; }
  #crumbs .crumb-pre, #crumbs .crumb-sub { display: none; }
  .emoji-choice-grid, .shape-choice-grid { grid-template-columns: 1fr; }
  .modal.ktask-modal { padding: 14px; }
  .kt-tech-grid { grid-template-columns: 1fr; }
  .kt-event-time { float: none; display: block; margin: 2px 0 0; }
}

/* Telegram сообщает безопасную область отдельными CSS-переменными. Правила стоят
   после compact/mobile, иначе shorthand `padding` компактного режима стирал верхний
   отступ и шапка оказывалась под часами и плавающими кнопками Telegram. */
body.tg-mobile.tg-fullscreen {
  --trelvis-tg-control-top: max(
    var(--trelvis-tg-top),
    calc(var(--trelvis-tg-safe-top) + 52px)
  );
}
body.tg-mobile #topbar,
body.tg-mobile.compact #topbar {
  padding-top: calc(8px + var(--trelvis-tg-control-top));
}
body.tg-mobile .side-head {
  padding-top: calc(8px + var(--trelvis-tg-control-top));
}
body.tg-mobile .modal-backdrop {
  padding: calc(10px + var(--trelvis-tg-control-top))
    calc(8px + var(--trelvis-tg-right))
    calc(10px + var(--trelvis-tg-bottom))
    calc(8px + var(--trelvis-tg-left));
}
body.tg-mobile .modal {
  max-height: calc(
    var(--ui-viewport-height) - var(--trelvis-tg-control-top) -
    var(--trelvis-tg-bottom) - 28px
  );
  overflow-y: auto;
}
/* Карточка прокручивается одним слоем (трелвис 1816). Раньше скроллились оба:
   фон-подложка и сама карточка с max-height — палец упирался в границу
   внутреннего слоя, и до нижних кнопок приходилось долистывать вторым движением. */
body.tg-mobile .modal-backdrop.card-detail-host {
  padding: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
}
body.tg-mobile .modal.card-detail-modal { max-height: none; overflow: visible; min-height: 100%; }
body.tg-mobile .card-detail-shell {
  padding: calc(9px + var(--trelvis-tg-control-top))
    calc(14px + var(--trelvis-tg-right))
    calc(24px + var(--trelvis-tg-bottom))
    calc(14px + var(--trelvis-tg-left));
}
body.tg-mobile .card-detail-topbar {
  /* Липнет к самому верху экрана, а крестик держит собственный внутренний
     отступ — ровно под системным крестиком Telegram. */
  top: 0;
  margin: calc(-9px - var(--trelvis-tg-control-top))
    calc(-14px - var(--trelvis-tg-right)) 10px
    calc(-14px - var(--trelvis-tg-left));
  padding: calc(9px + var(--trelvis-tg-control-top))
    calc(10px + var(--trelvis-tg-right)) 8px
    calc(6px + var(--trelvis-tg-left));
}
body.tg-mobile .person-tasks-head {
  padding-top: calc(10px + var(--trelvis-tg-control-top));
}
body.tg-mobile .appearance-toggle { font-size: 0; padding: 5px 8px; }
body.tg-mobile .appearance-toggle span { font-size: 13px; }
body.tg-mobile #me-chip { display: none; }
body.tg-mobile #crumbs .crumb-pre,
body.tg-mobile #crumbs .crumb-sub { display: none; }
body.tg-mobile { --radius: 18px; }
body.quick-entry-visible #main.board-bg-active #quick-bar {
  background: rgba(6,13,9,.52); border-color: rgba(255,255,255,.10);
  -webkit-backdrop-filter: blur(20px) saturate(1.18); backdrop-filter: blur(20px) saturate(1.18);
}
/* В full-screen Telegram системные Close/⋯ плавают поверх страницы. Своё поле
   ставим в свободный центр той же строки, а правое меню приложения убираем. */
body.tg-mobile.quick-entry-visible #quick-bar {
  padding: calc(var(--trelvis-tg-control-top) + 8px)
    calc(var(--trelvis-tg-right) + 8px)
    6px
    calc(var(--trelvis-tg-left) + 8px);
  border-bottom: 0; min-height: 0;
}
/* Бургер досок — слева и крупный, «•••» доски — справа от поля ввода (трелвис
   1804). Раньше обе кнопки жались слева: боялись системных Close/⋯ Telegram,
   но строка и так сдвинута вниз на --trelvis-tg-control-top и с ними не спорит.
   Две одинаковые мелкие кнопки подряд путали и не давали попасть пальцем. */
/* Тот же приём, что и в вебе на телефоне (трелвис 1930, 1965): отступ под
   плавающей строкой Telegram — поле перед доской в обоих режимах, плюс тот же
   просвет над липкими шапками. */
body.tg-mobile.quick-entry-visible .board {
  padding-top: 0;
  margin-top: calc(var(--board-float-head, calc(var(--trelvis-tg-control-top) + 58px))
    + var(--board-head-gap, 10px));
}
/* Бургер приподнят на пару пикселей (трелвис 1843): в Telegram его подсветка
   читалась ниже поля ввода, хотя геометрически стояла по центру строки. */
body.tg-mobile .qb-board-nav {
  width: 42px; height: 42px; border-radius: 14px; font-size: 25px; margin-bottom: 4px;
}
body.tg-mobile .qb-board-menu { width: 32px; height: 38px; border-radius: 13px; }
body.tg-mobile .qb-field {
  grid-template-columns: minmax(0,1fr) 32px 32px; border-radius: 19px;
}
/* Поле растёт по тексту и на телефоне тоже (1620). nowrap здесь держал его в
   одну строку: длинная задача уезжала за край, перенос по Shift+Enter не был
   виден, и «единое расширяемое поле» на телефоне не работало вовсе. */
body.tg-mobile #qb-inp {
  min-width: 0; font-size: 13px; white-space: pre-wrap; overflow-wrap: anywhere;
}
body.tg-mobile .qb-record,
body.tg-mobile .qb-send { width: 32px; height: 32px; }
body.tg-mobile .bb-desktop-action { display: none; }
body.tg-mobile .bb-mobile-more {
  display: grid; place-items: center; width: 34px; height: 30px;
  border-radius: 11px; background: rgba(10,16,12,.68);
}
body.tg-mobile .board-bar {
  flex-wrap: nowrap; min-height: 40px; padding: 6px 10px;
  background: rgba(6,13,9,.48); border-radius: 0 0 18px 18px;
  -webkit-backdrop-filter: blur(18px) saturate(1.15); backdrop-filter: blur(18px) saturate(1.15);
}
body.tg-mobile .board-kind-note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.tg-mobile .board { padding: var(--board-pad-top, 9px) 9px 72px; }
body.tg-mobile .board-canvas { gap: 9px; }
body.tg-mobile .column,
body.tg-mobile .card { border-radius: 14px; }
body.tg-mobile .card-cover { border-radius: 14px 14px 0 0; }
body.tg-mobile .board-zoom-controls {
  right: calc(7px + var(--trelvis-tg-right));
  bottom: calc(10px + var(--trelvis-tg-bottom));
}
/* iOS WebKit композитит каждый blur заново над большой фотографией доски.
   В Telegram оставляем матовое стекло цветом, без GPU-фильтра: это убирает
   фризы свайпа и zoom, сохраняя фон и контраст. */
body.tg-low-effects #main { transition: none; }
body.tg-low-effects.quick-entry-visible #quick-bar,
body.tg-low-effects #quick-compose,
body.tg-low-effects .board-bar,
body.tg-low-effects .board-zoom-controls,
body.tg-low-effects .person-tasks-head,
body.tg-low-effects .person-task-item,
body.tg-low-effects .person-task-filters button,
body.tg-low-effects .board-scroll-all .board-wrap.has-bg .col-cards,
body.tg-low-effects .board-scroll-all .board-wrap.has-bg .col-rems,
body.tg-low-effects .board-scroll-all .board-wrap.has-bg .col-foot {
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}
body.tg-low-effects.quick-entry-visible #quick-bar,
body.tg-low-effects .board-zoom-controls { background: rgba(7,14,10,.82); }
body.tg-low-effects.quick-entry-visible #main.board-bg-active #quick-bar {
  background: rgba(7,14,10,.82);
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}
body.tg-low-effects .column { transition: none; }
body.tg-low-effects .board.board-gesture-active .card { pointer-events: none; }
@media (max-width: 360px) {
  .task-report-filters { grid-template-columns: 1fr; }
  .task-report-filters input { grid-column: auto; }
  .board-zoom-controls { left: 8px; right: 8px; width: auto; justify-content: center; }
  .board-zoom-controls .board-view-mode {
    min-width: 34px; width: 34px; padding: 0; font-size: 0;
  }
  .board-zoom-controls .board-view-mode::before { content: "▦"; font-size: 15px; }
}
@media (max-width: 420px) {
  body.tg-mobile .board-zoom-controls .board-view-mode { min-width: 82px; padding-inline: 6px; }
}
body.tg-mobile #quick-compose { right: 9px; width: calc(100% - 18px); }

@media (prefers-reduced-motion: reduce) {
  .app-loader-avatar.ready, .app-loader-track span, .comment-record-dot, .comment-record-wave i { animation: none; }
  .column { transition: none; }
}

/* ---------- Пульт 🟤 Bulldozer (раздел «Нейронки», задача 1545) ---------- */
.bz-page { max-width: 860px; }
.bz-intro { color: var(--muted); font-size: 13px; line-height: 1.5; margin-bottom: 16px; }
.bz-intro b { color: var(--text); }
.bz-block { margin-bottom: 22px; }
.bz-block-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px; }
.bz-block-head h3 { margin: 0; font-size: 15px; }
.bz-block-sub { color: var(--muted); font-size: 12px; }
.bz-stages { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.bz-stage {
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 12px; display: flex; flex-direction: column; gap: 8px;
}
.bz-stage-title { font-weight: 700; font-size: 13px; }
.bz-stage-title small { display: block; color: var(--muted); font-weight: 400; font-size: 11px; margin-top: 2px; }
.bz-field { display: flex; flex-direction: column; gap: 3px; font-size: 11px; color: var(--muted); }
.bz-field select {
  background: var(--bg); color: var(--text); border: 1px solid var(--line);
  border-radius: 8px; padding: 6px 8px; font-size: 13px;
}
.bz-actions { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.bz-actions .spacer { flex: 1; }
.bz-proj {
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 14px; margin-bottom: 12px;
}
.bz-proj-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.bz-proj-head b { font-size: 15px; }
.bz-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.bz-tag {
  margin-left: auto; font-size: 11px; color: var(--accent);
  border: 1px solid var(--line); border-radius: 999px; padding: 1px 8px;
}
.bz-plan, .bz-active { display: flex; flex-direction: column; gap: 4px; }
.bz-prow, .bz-arow {
  display: flex; align-items: center; gap: 10px; font-size: 13px;
  padding: 5px 8px; border-radius: 8px; background: var(--bg);
}
.bz-prow-no, .bz-arow-no { color: var(--muted); font-variant-numeric: tabular-nums; flex: none; width: 30px; }
.bz-prow-cfg, .bz-arow-cfg { flex: 1; }
.bz-prow-cnt { color: var(--muted); }
.bz-arow-state { color: var(--muted); }
.bz-arow.bz-state-running { outline: 1px solid var(--accent); }
.bz-arow.bz-state-failed .bz-arow-state { color: var(--red); }
.bz-report { color: var(--muted); font-size: 12px; margin-top: 4px; }
.bz-overflow, .bz-plan-empty { color: var(--muted); font-size: 12px; margin-top: 6px; }
.bz-dialog-sub { color: var(--muted); font-size: 12px; margin-bottom: 10px; }
#bz-proj-editor .bz-stages { grid-template-columns: 1fr; }
@media (max-width: 640px) {
  .bz-stages { grid-template-columns: 1fr; }
}

/* ---------- Сборка пачки задач для 🟤 Bulldozer (задача 1742) ---------- */
.batch-page { max-width: 860px; }
.batch-summary {
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px; margin-bottom: 12px;
}
.batch-summary-line { font-size: 14px; }
.batch-note { color: var(--muted); font-size: 12px; margin-top: 6px; }
.batch-warn { color: var(--red); font-size: 12px; margin-top: 6px; }
.batch-row-sub .batch-warn { display: inline; font-size: inherit; margin: 0; }
.batch-controls {
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px; margin-bottom: 14px;
  display: flex; flex-wrap: wrap; gap: 12px 18px;
}
.batch-field { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: var(--muted); }
.batch-field select {
  background: var(--bg); color: var(--text); border: 1px solid var(--line);
  border-radius: 8px; padding: 6px 8px; font-size: 13px;
}
.batch-modes { display: flex; gap: 6px; flex-wrap: wrap; }
.batch-actions { display: flex; align-items: center; gap: 8px; width: 100%; flex-wrap: wrap; }
.batch-actions .spacer { flex: 1; }
/* Кнопка гаснет, когда запускать нечего: одна проверка disabled в JS, но без
   этого правила выключенная кнопка выглядела рабочей и нажималась впустую. */
.batch-actions .btn:disabled { opacity: .4; cursor: default; }
.batch-list { display: flex; flex-direction: column; gap: 6px; }
.batch-row {
  display: flex; align-items: center; gap: 10px;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  padding: 8px 12px; cursor: pointer;
}
.batch-row.chosen { border-color: var(--accent); }
.batch-row input { flex: none; width: 16px; height: 16px; accent-color: var(--accent); }
.batch-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.batch-row-title { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.batch-row-sub { color: var(--muted); font-size: 11px; }
.batch-skipped { cursor: default; opacity: 0.75; }
.batch-subhead { margin: 16px 0 8px; font-size: 14px; color: var(--bright); }
.batch-list + .batch-actions { margin-top: 14px; }

/* ---------- Телефонная доска: колонка прячется под свой заголовок ----------
   Трелвис 1930/1931, вторая итерация. Первая правка вылечила только стандартный
   вид, а 👾 Элвис смотрит доску в режиме «в одну колонку»: там заголовок вообще
   не липнул, и лента колонок свободно проезжала над названием.

   Теперь на телефоне лента ведёт себя как список секций: заголовок колонки
   стоит на месте, содержимое исчезает ровно под ним, выше — ничего.

   Правила висят на классе `body.compact` (его ставит JS по ширине окна), а не
   только внутри @media: в webview Telegram ширина считается по-своему, и
   медиазапрос — не единственный источник правды. Стоят в самом конце файла,
   чтобы перебить общее «в обзоре шапка не липнет». */
body.compact.quick-entry-visible .board {
  padding-top: 0;
  margin-top: calc(var(--board-float-head, calc(var(--trelvis-tg-control-top, 0px) + 58px))
    + var(--board-head-gap, 10px));
}
body.compact .board.board-overview .col-head,
body.compact.board-scroll-all .board.board-overview .col-head {
  position: sticky; top: 0; z-index: 6;
  margin-bottom: 0; background: var(--col);
  border-radius: var(--radius) var(--radius) 0 0;
  padding-top: 10px; padding-bottom: 8px;
  transform: none; -webkit-clip-path: none; clip-path: none;
}
/* Колонка обрезает себя сама — иначе карточки выглядывают в вырезах круглых
   углов над шапкой. Именно clip: hidden сделал бы колонку scrollport и убил
   липкость (тот же урок, что и в стандартном виде). Ширина — ровно канвас,
   то есть ровно скролл-порт: только так скруглённая рама режет углы шапки. */
body.compact .board.board-overview .column {
  overflow: clip; width: 100% !important; min-width: 0 !important;
}
body.compact .board.board-overview .col-head .col-title { font-size: 25px; line-height: 1.15; }
/* Цифра рядом с названием — того же роста, что и название (трелвис 1967). */
body.compact .board.board-overview .col-head .col-count { font-size: 19px; }
/* Та же «рама», что и в @media: просвет и боковые поля — снаружи прокрутки,
   скруглённый верх скролл-порта режет углы заголовка на композиторе. */
body.compact .board.board-overview,
body.tg-mobile .board.board-overview {
  padding-left: 0; padding-right: 0;
  margin-left: 16px; margin-right: 16px;
  border-radius: var(--radius) var(--radius) 0 0;
}
body.compact .board.board-overview .board-canvas {
  flex-direction: column; flex-wrap: nowrap; width: 100% !important;
  gap: 20px; row-gap: 20px;
  padding: 0 0 calc(22px + env(safe-area-inset-bottom, 0px));
}
/* Свёрнутая колонка в ленте занимает всю ширину, как обычная (трелвис 1968). */
body.compact .board.board-overview .column.collapsed {
  width: 100% !important; min-width: 0 !important;
}
body.compact .board-wrap.has-bg .board.board-overview .col-head { background: var(--col); }
/* Свёрнутые «Меня контролят» и «Я контролю» в ленте — обычные строки-заголовки,
   липнуть им нечем и незачем. */
body.compact .board.board-overview .column.collapsed .col-head { position: static; }

/* ---------- Плотность списка: чем полнее колонка, тем ниже карточки (трелвис 5234) ----------

   Порог считает сам браузер количественным селектором — никакого JS, никаких
   переменных из раскладки (тот же урок, что и у липких шапок: два источника
   правды расходятся). Считать надо именно карточки, отсюда `of .card`: по
   всем детям `.col-cards` в счёт попадали кнопка хвоста `.col-tail-more`
   («Показать все N») и подкладка перетаскивания `.drop-slot`, и первый тир
   срабатывал на десяти задачах вместо одиннадцати.

   Ужимаются только вертикальные паддинги, промежуток и высота обложки;
   горизонтальные поля, кегль и переносы заголовка не трогаются, поэтому
   минимум карточки остаётся одной целой строкой текста — заголовок не режется
   никогда.

   Специфичность с `of .card` и `:has` — четыре «класс»-единицы: правила
   перебивают и телефонный `body.compact`, и ленту `.board.board-overview`
   (три единицы), поэтому плотность работает во всех режимах доски. Движок,
   не знающий `of` или `:has`, правило целиком пропускает — колонка остаётся с
   обычным ритмом, ломаться нечему.

   Второй тир (19 карточек) достаётся длинным колонкам с раскрытым хвостом:
   свёрнутая показывает не больше `COLUMN_TAIL_LIMIT` = 12 карточек. Это ровно
   тот случай, ради которого тир и нужен — «Показать все N» в «Выполнено». */
.col-cards > .card:nth-last-child(n+11 of .card),
.col-cards > .card:nth-last-child(n+11 of .card) ~ .card { --card-pad-y: 4px; --card-row-gap: 3px; }
.col-cards:has(> .card:nth-last-child(n+11 of .card)) { --card-gap: 5px; }
.col-cards > .card:nth-last-child(n+11 of .card) .card-cover img,
.col-cards > .card:nth-last-child(n+11 of .card) ~ .card .card-cover img { height: 120px; }
.col-cards > .card:nth-last-child(n+19 of .card),
.col-cards > .card:nth-last-child(n+19 of .card) ~ .card { --card-pad-y: 3px; --card-row-gap: 2px; }
.col-cards:has(> .card:nth-last-child(n+19 of .card)) { --card-gap: 4px; }
.col-cards > .card:nth-last-child(n+19 of .card) .card-cover img,
.col-cards > .card:nth-last-child(n+19 of .card) ~ .card .card-cover img { height: 96px; }

/* Колонка-цель переноса подсвечивается целиком (трелвис 5149): карточку видно
   куда уедет, даже если её будущее место сейчас за краем экрана — и не надо
   мотать доску вверх, чтобы попасть в короткую колонку. Стоит здесь, в конце:
   выше идут правила телефонной ленты с той же специфичностью, они перебили бы
   подсветку по порядку. С правилами обоев одного места в файле мало: у
   `.board-wrap.has-bg .column` три класса против двух у `.column.col-drop`, и
   на доске с обоями подсветки не было вовсе — поэтому у неё свой селектор с
   `.board-wrap.has-bg`. При сквозной прокрутке свой фон носят дети колонки,
   поэтому красим и их. */
.column.col-drop,
.board-wrap.has-bg .column.col-drop,
.board-scroll-all .column.col-drop > .col-head,
.board-scroll-all .column.col-drop > .col-cards,
.board-scroll-all .column.col-drop > .col-foot,
.board-scroll-all .board-wrap.has-bg .column.col-drop > .col-head,
.board-scroll-all .board-wrap.has-bg .column.col-drop > .col-cards,
.board-scroll-all .board-wrap.has-bg .column.col-drop > .col-foot {
  background: color-mix(in srgb, var(--accent) 17%, var(--col));
}
.column.col-drop {
  outline: 2px solid rgba(var(--accent-rgb),.75); outline-offset: -2px;
  box-shadow: 0 0 0 4px rgba(var(--accent-rgb),.16);
}

/* Прилипшая шапка теряет скругление верхних углов (трелвис 2480). Пока колонка
   стоит на месте, углы круглые и за ними фон доски; как только её верх ушёл за
   кромку прокрутки, вырезов больше нет — и просвечивать в них нечему. Это
   заменило страховочный `clip-path` по переменным из JS, который при
   рассинхроне съедал колонку целиком. Стоит в конце файла: телефонные правила
   ленты выше идут с той же специфичностью и перебили бы правило раньше. */
.board-scroll-all .col-head.stuck,
body.compact .board.board-overview .col-head.stuck,
body.compact.board-scroll-all .board.board-overview .col-head.stuck {
  border-top-left-radius: 0; border-top-right-radius: 0;
}

/* Шпаргалка горячих клавиш (трелвис 5483). Весь вид окна одним блоком: раньше
   .hk-row и .hk-key жили у прогресса доски, и половина стилей в одном месте, а
   половина в другом — заготовка следующего дефекта. Цвета только переменными,
   окно обязано читаться в обеих темах. Место — после последнего правила
   `stuck` и до печатных стилей в конце файла (BOARD-RULES). */
.hk-sheet { display: flex; flex-direction: column; gap: 14px; }
.hk-group { display: flex; flex-direction: column; gap: 2px; }
.hk-group-title {
  color: var(--muted); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
}
.hk-row { display: flex; align-items: center; gap: 12px; padding: 5px 0; }
.hk-key {
  min-width: 36px; text-align: center; background: var(--field); border: 1px solid var(--line);
  border-radius: 6px; padding: 2px 8px; color: var(--bright);
  font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.hk-act { color: var(--bright); font-size: 13px; }
.hk-note {
  margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--line);
  color: var(--muted); font-size: 12px; line-height: 1.45;
}
/* Вход в шпаргалку прячем там, где клавиш нет. Двумя правилами сразу: в
   webview Телеграма медиазапрос не единственный источник правды (BOARD-RULES). */
@media (max-width: 760px) {
  .nav-item.nav-hotkeys { display: none; }
}
body.compact .nav-item.nav-hotkeys { display: none; }

/* Экран замка: одна строка ввода и кнопка — больше там ничего быть не должно. */
.lock-form { display: flex; gap: 8px; margin-top: 14px; }
.lock-form input { flex: 1; }
.lock-form .btn { flex: none; }

/* «Что нового» (трелвис 5251). Плашка — фиксированная полоска, а не строка в
   потоке над доской: весь воздух перед доской это margin скролл-порта, а на
   телефоне верхняя строка с быстрой задачей лежит поверх доски и накрыла бы
   её собой (BOARD-RULES). Место — НАД пультом масштаба справа внизу: слева
   плашка легла бы на нижний край боковой панели с состоянием синхронизации, а
   по центру — на тост. Пульт высотой 40px от низа, отсюда 64px. */
#whatsnew-bar {
  position: fixed; z-index: 300;
  right: calc(8px + env(safe-area-inset-right, 0px));
  bottom: calc(64px + env(safe-area-inset-bottom, 0px));
  max-width: min(430px, calc(100vw - 24px));
  display: flex; align-items: center; gap: 10px;
  padding: 7px 8px 7px 13px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--modal); color: var(--text); font-size: 12.5px;
  box-shadow: 0 8px 24px rgba(0,0,0,.34);
}
#whatsnew-bar .wn-copy { display: grid; gap: 1px; min-width: 0; }
#whatsnew-bar .wn-copy b { color: var(--bright); font-size: 12.5px; }
#whatsnew-bar .wn-copy small {
  color: var(--muted); font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#whatsnew-bar .btn { flex: none; }
#whatsnew-bar .wn-close {
  flex: none; width: 26px; height: 26px; border-radius: 8px;
  color: var(--muted); font-size: 16px; line-height: 1;
}
#whatsnew-bar .wn-close:hover { background: var(--soft); color: var(--bright); }
/* На узком экране пульт растягивается во всю ширину — плашка тоже, ровно над
   ним. Правило дублируется на классе body.compact: в webview Telegram
   медиазапрос — не единственный источник правды (BOARD-RULES). */
@media (max-width: 760px) {
  #whatsnew-bar {
    left: calc(8px + env(safe-area-inset-left, 0px));
    right: calc(8px + env(safe-area-inset-right, 0px));
    max-width: none;
  }
}
body.compact #whatsnew-bar {
  left: calc(8px + env(safe-area-inset-left, 0px));
  right: calc(8px + env(safe-area-inset-right, 0px));
  max-width: none;
}
body.tg-mobile #whatsnew-bar {
  left: calc(7px + var(--trelvis-tg-left));
  right: calc(7px + var(--trelvis-tg-right));
  bottom: calc(60px + var(--trelvis-tg-bottom));
}

/* Окно «Подробнее»: свежая запись сверху, прошлые — раскрывающимся списком. */
.modal.whatsnew-modal { max-height: calc(100vh - 80px); overflow-y: auto; }
.whatsnew-modal .wn-empty { color: var(--muted); font-size: 13px; }
.whatsnew-modal .wn-latest-date {
  color: var(--muted); font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .6px;
}
.whatsnew-modal .wn-latest-title { display: block; color: var(--bright); font-size: 15px; margin-top: 2px; }
.whatsnew-modal .wn-md { font-size: 13px; line-height: 1.5; }
.whatsnew-modal .wn-md ul { margin: 8px 0 0; padding-left: 18px; }
.whatsnew-modal .wn-md li { margin-bottom: 5px; }
.whatsnew-modal .wn-md p { margin: 8px 0 0; }
.whatsnew-modal .wn-md code {
  background: var(--soft); border-radius: 5px; padding: 1px 4px; font-size: 12px;
}
.whatsnew-modal .wn-past-label { margin-top: 18px; }
.whatsnew-modal .wn-past-item { border-top: 1px solid var(--line); }
.whatsnew-modal .wn-past-head {
  display: flex; align-items: baseline; gap: 9px; width: 100%;
  padding: 9px 2px; text-align: left; color: var(--text); font-size: 13px;
}
.whatsnew-modal .wn-past-date { flex: none; color: var(--muted); font-size: 11.5px; }
.whatsnew-modal .wn-past-title { flex: 1; min-width: 0; }
.whatsnew-modal .wn-past-mark { flex: none; color: var(--muted); font-size: 11px; }
.whatsnew-modal .wn-past-body { padding: 0 2px 10px; font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.whatsnew-modal .wn-past-body ul { margin: 0; padding-left: 18px; }
.whatsnew-modal .wn-past-body li { margin-bottom: 5px; }
.whatsnew-modal .wn-past-body p { margin: 0 0 6px; }

/* ---------- Панель множественного выбора карточек (трелвис 5481) ----------
   Правый нижний угол — три этажа, и одновременно занят он только одним. Пульт
   доски (`bottom: 14px`) и плашка «Что нового» (`bottom: 64px`, на телефоне
   60px) стоят там постоянно, панель выбора приходит на минуту. Поэтому она
   берёт НИЖНИЙ этаж пульта, а обоих соседей на время режима гасит класс
   `body.picking`: иначе в день выкатки, когда плашка показана всей команде,
   три панели легли бы стопкой друг на друга. Гашение — чистый CSS без второго
   состояния в JS: вышел из режима, класс снят — соседи вернулись сами. */
body.picking #board-zoom-controls,
body.picking #whatsnew-bar { display: none; }

#card-pick-bar {
  position: fixed; z-index: 300;
  right: calc(8px + env(safe-area-inset-right, 0px));
  bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  max-width: min(760px, calc(100vw - 24px));
  display: flex; align-items: center; gap: 6px;
  padding: 6px 7px 6px 12px; border: 1px solid var(--line); border-radius: 16px;
  background: var(--modal); color: var(--text);
  box-shadow: 0 8px 24px rgba(0,0,0,.34);
  /* Шесть действий и счётчик в узкое окно не влезают: панель едет вбок, а не
     режет последнюю кнопку. Дети не сжимаются — иначе «Архивировать»
     схлопнулось бы в столбик из букв. */
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
}
#card-pick-bar::-webkit-scrollbar { height: 0; }
#card-pick-bar > * { flex: none; }
#card-pick-bar .pick-count {
  padding: 0 4px; color: var(--bright); font-size: 12.5px; font-weight: 800;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
#card-pick-bar .pick-act {
  min-height: 32px; padding: 5px 10px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--field); color: var(--bright); font-size: 12.5px; white-space: nowrap;
}
#card-pick-bar .pick-act:hover { background: var(--card-hover); border-color: rgba(var(--accent-rgb),.55); }
#card-pick-bar .pick-act:active { background: rgba(var(--accent-rgb),.22); color: var(--accent); }
/* «Архивировать» уносит пачку с доски: красная буквами и рамкой, но не заливкой
   — сплошная красная кнопка среди пяти обычных сама просится под палец. */
#card-pick-bar .pick-act.danger {
  color: var(--red); border-color: color-mix(in srgb, var(--red) 45%, var(--line));
}
#card-pick-bar .pick-act.danger:hover {
  border-color: var(--red); background: color-mix(in srgb, var(--red) 14%, var(--field));
}
#card-pick-bar .pick-close {
  width: 32px; height: 32px; border-radius: 10px; display: grid; place-items: center;
  color: var(--muted); font-size: 16px; line-height: 1;
}
#card-pick-bar .pick-close:hover { background: var(--soft); color: var(--bright); }

/* На узком экране панель во всю ширину, как пульт и плашка, и кнопки уходят
   вторым рядом: прокрутку вбок на телефоне не замечают и решают, что действий
   пять. Правило дублируется на классе body.compact — в webview Telegram
   медиазапрос не единственный источник правды (BOARD-RULES). */
@media (max-width: 760px) {
  #card-pick-bar {
    left: calc(8px + env(safe-area-inset-left, 0px));
    right: calc(8px + env(safe-area-inset-right, 0px));
    max-width: none; flex-wrap: wrap; justify-content: flex-end; row-gap: 5px;
  }
}
body.compact #card-pick-bar {
  left: calc(8px + env(safe-area-inset-left, 0px));
  right: calc(8px + env(safe-area-inset-right, 0px));
  max-width: none; flex-wrap: wrap; justify-content: flex-end; row-gap: 5px;
}
/* В Телеграме поля берём у безопасных зон мини-приложения, как плашка «Что
   нового», а низ — у пульта: этаж тот же самый, панель встаёт на его место. */
body.tg-mobile #card-pick-bar {
  left: calc(7px + var(--trelvis-tg-left));
  right: calc(7px + var(--trelvis-tg-right));
  bottom: calc(10px + var(--trelvis-tg-bottom));
}
/* Без тяжёлых эффектов (iOS-webview): панель и так лежит на сплошном --modal,
   стекло ей не нужно вовсе — снимаем большую тень, которую композитор
   перерисовывает на каждый кадр прокрутки, и на всякий случай фильтр. */
body.tg-low-effects #card-pick-bar {
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
  box-shadow: 0 2px 8px rgba(0,0,0,.32);
}

/* Выделенная карточка — ОТДЕЛЬНОЕ правило ниже `.card.selected` (трелвис 5481).
   Зелёная рамка занята карточкой, открытой в правой панели, а в теме «Матрикс»
   --accent и --green — один и тот же зелёный: разницу нельзя строить на цвете.
   Поэтому она в форме — пунктирная обводка вместо сплошного кольца, акцентная
   подложка и галочка в углу. Так пачка читается в обеих темах, даже когда
   выбранная карточка одновременно открыта в правой панели (правило ниже —
   значит его вид и побеждает). */
.card.picked {
  position: relative;
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, var(--card));
  outline: 2px dashed var(--accent); outline-offset: 2px;
  box-shadow: 0 1px 1px rgba(0,0,0,.35);
}
/* Галочка внутри угла, а не снаружи: колонка обрезает себя сама
   (`overflow: clip`, BOARD-RULES), и вынесенный за край кружок срезало бы у
   первой карточки. */
.card.picked::after {
  content: "✓"; position: absolute; z-index: 2; top: 3px; right: 3px;
  width: 16px; height: 16px; border-radius: 50%; display: grid; place-items: center;
  background: var(--accent); color: var(--on-accent);
  font-size: 10px; font-weight: 900; line-height: 1;
  box-shadow: 0 1px 3px rgba(0,0,0,.45);
}

/* ---------- «Убрать дубли»: разбиение от DeepSeek (трелвис 5152) ---------- */
/* Окно читают глазами и решают рукой: у каждой группы видно причину, какая
   карточка останется и какие уйдут в архив. Разобранная группа не исчезает, а
   гаснет с подписью — по списку видно, что уже сделано, а что пропущено. */
.modal.dedupe-modal { max-width: 640px; }
.dd-hint { color: var(--muted); font-size: 12.5px; line-height: 1.45; }
.dd-list { max-height: 52vh; overflow: auto; }
.dd-group {
  margin-bottom: 10px; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--soft);
}
.dd-group.done { opacity: .55; }
.dd-reason { margin-bottom: 8px; font-size: 12.5px; color: var(--muted); }
.dd-card { display: flex; align-items: baseline; gap: 8px; padding: 3px 0; font-size: 13px; }
.dd-mark { flex: none; min-width: 66px; font-size: 11px; color: var(--muted); }
.dd-card.keep .dd-mark { color: var(--accent); }
.dd-title { flex: 1; min-width: 0; color: var(--text); }
.dd-id { flex: none; font-size: 11px; color: var(--muted); }
.dd-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }
.dd-state { font-size: 12px; color: var(--muted); }

/* ---------- Печать колонки: лист A4 «под ручку» (трелвис 5154) ---------- */
/* Один макет и в окне предпросмотра, и на бумаге: что человек видит в модалке,
   то и выйдет из принтера. Бумага всегда белая с чёрным текстом — в матричной
   теме печатать тёмный фон никто не станет, поэтому здесь фиксированные цвета,
   а не переменные темы. Размеры в pt и mm: браузер считает их в физические
   миллиметры листа, а не в пиксели экрана. */
.modal.print-modal { max-width: 800px; }
.print-hint { color: var(--muted); font-size: 12.5px; line-height: 1.45; }
.print-status { color: var(--accent); }
/* Лист в окне — уменьшенная копия бумаги: ширина ровно 190 мм (A4 без полей),
   в узкое окно он входит масштабом (JS ставит transform на .print-sheet и
   размер коробки на .print-fit). Перевёрстывать предпросмотр под экран нельзя:
   человек должен видеть ровно то, что выйдет из принтера. */
.print-paper { display: flex; justify-content: center; overflow: hidden; }
.print-fit { flex: none; }
.print-sheet {
  width: 190mm; transform-origin: top left; background: #fff; color: #1a1a1a;
  border: 1px solid rgba(0,0,0,.2); border-radius: 6px; padding: 10mm 9mm;
  font: 9.5pt/1.35 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}
.print-head {
  display: flex; align-items: baseline; gap: 10px;
  border-bottom: 1.5px solid #1a1a1a; padding-bottom: 5px; margin-bottom: 8px;
}
.print-head b { font-size: 15pt; font-weight: 850; line-height: 1.15; }
.print-head span { margin-left: auto; color: #666; font-size: 8.5pt; text-align: right; }
/* Две колонки газетой, а не сеткой: задачи переливаются со страницы на
   страницу, и на листе их десяток с лишним, а не три штуки на белом поле. */
.print-grid { columns: 2; column-gap: 10mm; }
.print-task {
  display: flex; gap: 2.5mm; break-inside: avoid; page-break-inside: avoid;
  border-bottom: 1px dashed #bbb; padding-bottom: 2mm; margin-bottom: 2.5mm;
}
.print-box {
  flex: none; width: 4mm; height: 4mm; margin-top: 1mm;
  border: 1.2px solid #1a1a1a; border-radius: 1px;
  display: flex; align-items: center; justify-content: center;
  font-size: 7pt; line-height: 1; color: #1a1a1a;
}
.print-task.done .print-box::after { content: "✓"; }
.print-body { flex: 1; min-width: 0; }
.print-task b { display: block; font-size: 11pt; font-weight: 800; line-height: 1.2; }
.print-task em {
  display: block; font-style: normal; color: #555; font-size: 8.5pt;
  margin-top: 1mm; line-height: 1.3;
}
.print-task em:empty { display: none; }
.print-rule { display: block; height: 1px; background: #ddd; margin-top: 1.6mm; }
.print-foot {
  display: flex; gap: 10px; justify-content: space-between; color: #888; font-size: 8pt;
  border-top: 1px solid #ddd; padding-top: 4px; margin-top: 8px;
}
.print-after {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 14px; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--soft); font-size: 13px; color: var(--muted);
}
.print-after span { flex: 1; min-width: 200px; }

/* ---------- Мастер проверок: очередь приёмки 👾 Элвиса (задача 1547) ---------- */
/* Одна карточка на экране, решение кнопкой или свайпом. Карточка держится стиля
   доски (`--card` на `--line`), цвета — только переменными темы, иначе «Матрикс»
   поедет. Внутри живёт готовый `.ktask-summary`: своих рамок и коробок вокруг
   его блоков здесь нет, штатная левая линейка `.ktask-summary-block` остаётся
   единственной разметкой отчёта (правило 1913 — рамки только у кнопок).
   Место — после последнего правила `stuck` и до печатных стилей (BOARD-RULES). */
.rw-page { display: grid; gap: 12px; align-content: start; }
.rw-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rw-head .spacer { flex: 1; }
.rw-project { display: inline-flex; align-items: center; gap: 6px; color: var(--bright); font-size: 14px; }
.rw-number { color: var(--muted); font-size: 11.5px; }
.rw-card {
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  padding: 14px 16px; display: grid; gap: 12px; min-width: 0;
  /* Вертикаль остаётся браузеру, горизонталь забираем себе: без pan-y длинная
     карточка перестала бы прокручиваться пальцем. */
  touch-action: pan-y; transition: transform .18s ease;
}
.rw-card.dragging { transition: none; }
.rw-title { margin: 0; color: var(--bright); font-size: 20px; line-height: 1.22; overflow-wrap: anywhere; }
.rw-actions { display: flex; align-items: center; gap: 10px; }
.rw-actions .btn { min-height: 40px; }
.rw-return { display: none; gap: 8px; }
.rw-return.open { display: grid; }
.rw-return textarea { min-height: 76px; resize: vertical; background: var(--comment-field); }
.rw-return-actions { display: flex; gap: 8px; justify-content: flex-end; }
.rw-nav { display: flex; align-items: center; justify-content: center; gap: 14px; }
.rw-nav .btn { min-width: 46px; font-size: 17px; line-height: 1; }
.rw-count { color: var(--muted); font-size: 12px; font-weight: 700; }
.rw-empty { display: grid; gap: 10px; justify-items: center; padding: 34px 0; }
.rw-empty-emoji { font-size: 34px; line-height: 1; }
/* Пункт панели: число ждущих задач едет справа тем же `.nav-metrics`, что и
   нагрузка человека; цвет несёт значок `.nv-load.warn`, своего у пункта нет. */
.nav-review .nv-emoji { opacity: .92; }

/* Быстрое «принял» прямо на карточке колонки «👾 Элвис, проверь». `position` даём
   только карточке с этой кнопкой — общий `.card` трогать нельзя, под ним вся доска. */
.card:has(.card-quick-accept) { position: relative; }
.card:has(.card-quick-accept) .card-title { padding-right: 19px; }
.card-quick-accept {
  position: absolute; top: 2px; right: 2px; z-index: 2;
  border: 0; border-radius: 6px; background: transparent; color: var(--muted);
  padding: 2px 4px; font-size: 13px; line-height: 1; cursor: pointer;
  opacity: 0; transition: opacity .12s ease;
}
.card:hover .card-quick-accept { opacity: 1; }
/* `:focus-visible` обязателен: без него кнопку не видно с клавиатуры вообще. */
.card-quick-accept:focus-visible {
  opacity: 1; outline: 2px solid rgba(var(--accent-rgb),.75); outline-offset: 1px;
}
.card-quick-accept:hover { background: var(--soft); }

@media (max-width: 760px) {
  .rw-card { padding: 12px 13px; border-radius: 12px; }
  .rw-title { font-size: 18px; }
  .rw-actions .btn { flex: 1; min-height: 46px; font-size: 14px; }
  .rw-nav { justify-content: space-between; }
  .rw-nav .btn { min-width: 62px; min-height: 42px; }
  .card-quick-accept { opacity: 1; }
}
/* Те же телефонные правила на классе body.compact: в webview Телеграма
   медиазапрос — не единственный источник правды (BOARD-RULES). */
body.compact .rw-card { padding: 12px 13px; border-radius: 12px; }
body.compact .rw-title { font-size: 18px; }
body.compact .rw-actions .btn { flex: 1; min-height: 46px; font-size: 14px; }
body.compact .rw-nav { justify-content: space-between; }
body.compact .rw-nav .btn { min-width: 62px; min-height: 42px; }
body.compact .card-quick-accept { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .rw-card { transition: none; }
  .card-quick-accept { transition: none; }
}

@media print {
  @page { size: A4; margin: 12mm 10mm; }
  /* На бумагу уходит только лист: доска, плашки и тосты не печатаются, а
     подложка модалки перестаёт быть фиксированной — иначе браузер отдал бы
     один экран вместо всех страниц. */
  body.printing { background: #fff; }
  /* Корень страницы обрезан и отмасштабирован под интерфейс (html overflow:hidden,
     body transform:scale) — на печати это одна страница вместо всех и уехавший
     масштаб. На бумаге всё это снимаем. */
  html:has(body.printing), body.printing {
    height: auto !important; width: auto !important; overflow: visible !important;
    transform: none !important;
  }
  body.printing > *:not(#modal-root) { display: none !important; }
  body.printing #modal-root > *:not(.print-host) { display: none !important; }
  .print-host {
    position: static; display: block; padding: 0; overflow: visible; background: none;
  }
  .print-host .modal {
    max-width: none; margin: 0; padding: 0; border: 0; border-radius: 0;
    box-shadow: none; background: #fff;
  }
  .print-host .print-ui, .print-host .print-after { display: none !important; }
  /* !important здесь — против инлайновых размеров подгонки: их ставит JS,
     и без него на бумагу уехал бы уменьшенный лист в коробке по размеру окна. */
  .print-host .print-paper { display: block; overflow: visible; }
  .print-host .print-fit { width: auto !important; height: auto !important; }
  .print-host .print-sheet {
    width: auto; padding: 0; border: 0; border-radius: 0; box-shadow: none;
    transform: none !important;
  }
}
